dsa_verify_hash.c 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis
  2. *
  3. * LibTomCrypt is a library that provides various cryptographic
  4. * algorithms in a highly modular and flexible manner.
  5. *
  6. * The library is free for all purposes without any express
  7. * guarantee it works.
  8. *
  9. * Tom St Denis, [email protected], http://libtomcrypt.org
  10. */
  11. #include "mycrypt.h"
  12. #ifdef MDSA
  13. int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
  14. const unsigned char *hash, unsigned long inlen,
  15. int *stat, dsa_key *key)
  16. {
  17. mp_int r, s, w, v, u1, u2;
  18. unsigned long x, y;
  19. int err;
  20. _ARGCHK(sig != NULL);
  21. _ARGCHK(hash != NULL);
  22. _ARGCHK(stat != NULL);
  23. _ARGCHK(key != NULL);
  24. /* default to invalid signature */
  25. *stat = 0;
  26. if (siglen < PACKET_SIZE+2+2) {
  27. return CRYPT_INVALID_PACKET;
  28. }
  29. /* is the message format correct? */
  30. if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_DSA, PACKET_SUB_SIGNED)) != CRYPT_OK) {
  31. return err;
  32. }
  33. /* skip over header */
  34. y = PACKET_SIZE;
  35. /* init our variables */
  36. if ((err = mp_init_multi(&r, &s, &w, &v, &u1, &u2, NULL)) != MP_OKAY) {
  37. return mpi_to_ltc_error(err);
  38. }
  39. /* read in r followed by s */
  40. x = ((unsigned)sig[y]<<8)|((unsigned)sig[y+1]);
  41. y += 2;
  42. if (y + x > siglen) {
  43. err = CRYPT_INVALID_PACKET;
  44. goto done;
  45. }
  46. if ((err = mp_read_unsigned_bin(&r, (unsigned char *)sig+y, x)) != MP_OKAY) { goto error; }
  47. y += x;
  48. /* load s */
  49. x = ((unsigned)sig[y]<<8)|((unsigned)sig[y+1]);
  50. y += 2;
  51. if (y + x > siglen) {
  52. err = CRYPT_INVALID_PACKET;
  53. goto done;
  54. }
  55. if ((err = mp_read_unsigned_bin(&s, (unsigned char *)sig+y, x)) != MP_OKAY) { goto error; }
  56. /* w = 1/s mod q */
  57. if ((err = mp_invmod(&s, &key->q, &w)) != MP_OKAY) { goto error; }
  58. /* u1 = m * w mod q */
  59. if ((err = mp_read_unsigned_bin(&u1, (unsigned char *)hash, inlen)) != MP_OKAY) { goto error; }
  60. if ((err = mp_mulmod(&u1, &w, &key->q, &u1)) != MP_OKAY) { goto error; }
  61. /* u2 = r*w mod q */
  62. if ((err = mp_mulmod(&r, &w, &key->q, &u2)) != MP_OKAY) { goto error; }
  63. /* v = g^u1 * y^u2 mod p mod q */
  64. if ((err = mp_exptmod(&key->g, &u1, &key->p, &u1)) != MP_OKAY) { goto error; }
  65. if ((err = mp_exptmod(&key->y, &u2, &key->p, &u2)) != MP_OKAY) { goto error; }
  66. if ((err = mp_mulmod(&u1, &u2, &key->p, &v)) != MP_OKAY) { goto error; }
  67. if ((err = mp_mod(&v, &key->q, &v)) != MP_OKAY) { goto error; }
  68. /* if r = v then we're set */
  69. if (mp_cmp(&r, &v) == MP_EQ) {
  70. *stat = 1;
  71. }
  72. err = CRYPT_OK;
  73. goto done;
  74. error : err = mpi_to_ltc_error(err);
  75. done : mp_clear_multi(&r, &s, &w, &v, &u1, &u2, NULL);
  76. return err;
  77. }
  78. #endif