hmac_init.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen)
  32. {
  33. unsigned char *buf;
  34. unsigned long hashsize;
  35. unsigned long i, z;
  36. int err;
  37. _ARGCHK(hmac != NULL);
  38. _ARGCHK(key != NULL);
  39. /* valid hash? */
  40. if ((err = hash_is_valid(hash)) != CRYPT_OK) {
  41. return err;
  42. }
  43. hmac->hash = hash;
  44. hashsize = hash_descriptor[hash].hashsize;
  45. /* valid key length? */
  46. if (keylen == 0) {
  47. return CRYPT_INVALID_KEYSIZE;
  48. }
  49. /* allocate ram for buf */
  50. buf = XMALLOC(HMAC_BLOCKSIZE);
  51. if (buf == NULL) {
  52. return CRYPT_MEM;
  53. }
  54. /* allocate memory for key */
  55. hmac->key = XMALLOC(HMAC_BLOCKSIZE);
  56. if (hmac->key == NULL) {
  57. XFREE(buf);
  58. return CRYPT_MEM;
  59. }
  60. /* (1) make sure we have a large enough key */
  61. if(keylen > HMAC_BLOCKSIZE) {
  62. z = HMAC_BLOCKSIZE;
  63. if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) {
  64. goto __ERR;
  65. }
  66. if(hashsize < HMAC_BLOCKSIZE) {
  67. zeromem((hmac->key) + hashsize, (size_t)(HMAC_BLOCKSIZE - hashsize));
  68. }
  69. keylen = hashsize;
  70. } else {
  71. XMEMCPY(hmac->key, key, (size_t)keylen);
  72. if(keylen < HMAC_BLOCKSIZE) {
  73. zeromem((hmac->key) + keylen, (size_t)(HMAC_BLOCKSIZE - keylen));
  74. }
  75. }
  76. /* Create the initial vector for step (3) */
  77. for(i=0; i < HMAC_BLOCKSIZE; i++) {
  78. buf[i] = hmac->key[i] ^ 0x36;
  79. }
  80. /* Pre-pend that to the hash data */
  81. hash_descriptor[hash].init(&hmac->md);
  82. if ((err = hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE)) != CRYPT_OK) {
  83. goto __ERR;
  84. }
  85. goto done;
  86. __ERR:
  87. /* free the key since we failed */
  88. XFREE(hmac->key);
  89. done:
  90. #ifdef CLEAN_STACK
  91. zeromem(buf, HMAC_BLOCKSIZE);
  92. #endif
  93. XFREE(buf);
  94. return err;
  95. }
  96. #endif