hmac_done.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. /* Submited by Dobes Vandermeer ([email protected]) */
  12. #include "mycrypt.h"
  13. /*
  14. (1) append zeros to the end of K to create a B byte string
  15. (e.g., if K is of length 20 bytes and B=64, then K will be
  16. appended with 44 zero bytes 0x00)
  17. (2) XOR (bitwise exclusive-OR) the B byte string computed in step
  18. (1) with ipad (ipad = the byte 0x36 repeated B times)
  19. (3) append the stream of data 'text' to the B byte string resulting
  20. from step (2)
  21. (4) apply H to the stream generated in step (3)
  22. (5) XOR (bitwise exclusive-OR) the B byte string computed in
  23. step (1) with opad (opad = the byte 0x5C repeated B times.)
  24. (6) append the H result from step (4) to the B byte string
  25. resulting from step (5)
  26. (7) apply H to the stream generated in step (6) and output
  27. the result
  28. */
  29. #ifdef HMAC
  30. #define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
  31. int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen)
  32. {
  33. unsigned char *buf, *isha;
  34. unsigned long hashsize, i;
  35. int hash, err;
  36. _ARGCHK(hmac != NULL);
  37. _ARGCHK(hashOut != NULL);
  38. /* test hash */
  39. hash = hmac->hash;
  40. if((err = hash_is_valid(hash)) != CRYPT_OK) {
  41. return err;
  42. }
  43. /* get the hash message digest size */
  44. hashsize = hash_descriptor[hash].hashsize;
  45. /* allocate buffers */
  46. buf = XMALLOC(HMAC_BLOCKSIZE);
  47. isha = XMALLOC(hashsize);
  48. if (buf == NULL || isha == NULL) {
  49. if (buf != NULL) {
  50. XFREE(buf);
  51. }
  52. if (isha != NULL) {
  53. XFREE(isha);
  54. }
  55. return CRYPT_MEM;
  56. }
  57. /* Get the hash of the first HMAC vector plus the data */
  58. if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) {
  59. goto __ERR;
  60. }
  61. /* Create the second HMAC vector vector for step (3) */
  62. for(i=0; i < HMAC_BLOCKSIZE; i++) {
  63. buf[i] = hmac->key[i] ^ 0x5C;
  64. }
  65. /* Now calculate the "outer" hash for step (5), (6), and (7) */
  66. hash_descriptor[hash].init(&hmac->md);
  67. if ((err = hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE)) != CRYPT_OK) {
  68. goto __ERR;
  69. }
  70. if ((err = hash_descriptor[hash].process(&hmac->md, isha, hashsize)) != CRYPT_OK) {
  71. goto __ERR;
  72. }
  73. if ((err = hash_descriptor[hash].done(&hmac->md, buf)) != CRYPT_OK) {
  74. goto __ERR;
  75. }
  76. /* copy to output */
  77. for (i = 0; i < hashsize && i < *outlen; i++) {
  78. hashOut[i] = buf[i];
  79. }
  80. *outlen = i;
  81. err = CRYPT_OK;
  82. __ERR:
  83. XFREE(hmac->key);
  84. #ifdef CLEAN_STACK
  85. zeromem(isha, hashsize);
  86. zeromem(buf, hashsize);
  87. zeromem(hmac, sizeof(*hmac));
  88. #endif
  89. XFREE(isha);
  90. XFREE(buf);
  91. return err;
  92. }
  93. #endif