hmac_sha1.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /**
  2. * @file hmac_sha1.c Implements HMAC-SHA1 as of RFC 2202
  3. *
  4. * Copyright (C) 2010 Creytiv.com
  5. */
  6. #include <string.h>
  7. #include <stdint.h>
  8. #ifdef USE_OPENSSL
  9. #include <openssl/sha.h>
  10. #include <openssl/hmac.h>
  11. #include <openssl/err.h>
  12. #else
  13. #include "sha.h"
  14. #endif
  15. #include "hmac.h"
  16. /** SHA-1 Block size */
  17. #ifndef SHA_BLOCKSIZE
  18. #define SHA_BLOCKSIZE (64)
  19. #endif
  20. /**
  21. * Function to compute the digest
  22. *
  23. * @param k Secret key
  24. * @param lk Length of the key in bytes
  25. * @param d Data
  26. * @param ld Length of data in bytes
  27. * @param out Digest output
  28. * @param t Size of digest output
  29. */
  30. void hmac_sha1(const uint8_t *k, /* 密钥 */
  31. size_t lk, /* 密钥的长度 */
  32. const uint8_t *d, /* 数据 */
  33. size_t ld, /* 数据长度*/
  34. uint8_t *out, /* 输出的数据 */
  35. size_t *t) /* 输出的数据大小 */
  36. {
  37. #ifdef USE_OPENSSL
  38. if (!HMAC(EVP_sha1(), k, (int)lk, d, ld, out, t))
  39. {
  40. ERR_clear_error();
  41. }
  42. #else
  43. SHA_CTX ictx, octx;
  44. uint8_t isha[SHA_DIGEST_LENGTH], osha[SHA_DIGEST_LENGTH];
  45. uint8_t key[SHA_DIGEST_LENGTH];
  46. uint8_t buf[SHA_BLOCKSIZE];
  47. size_t i;
  48. if (lk > SHA_BLOCKSIZE) /* 密钥的长度是否大于64 */
  49. {
  50. SHA_CTX tctx;
  51. SHA1_Init(&tctx);
  52. SHA1_Update(&tctx, k, lk);
  53. SHA1_Final(key, &tctx);
  54. k = key;
  55. lk = SHA_DIGEST_LENGTH;
  56. }
  57. /**** Inner Digest ****/
  58. SHA1_Init(&ictx);
  59. /* Pad the key for inner digest */
  60. for (i = 0; i < lk; ++i)
  61. {
  62. buf[i] = k[i] ^ 0x36; /* 按位异或 */
  63. }
  64. for (i = lk; i < SHA_BLOCKSIZE; ++i)
  65. {
  66. buf[i] = 0x36;
  67. }
  68. SHA1_Update(&ictx, buf, SHA_BLOCKSIZE);
  69. SHA1_Update(&ictx, d, ld);
  70. SHA1_Final(isha, &ictx);
  71. /**** Outer Digest ****/
  72. SHA1_Init(&octx);
  73. /* Pad the key for outter digest */
  74. for (i = 0; i < lk; ++i)
  75. {
  76. buf[i] = k[i] ^ 0x5c;
  77. }
  78. for (i = lk; i < SHA_BLOCKSIZE; ++i)
  79. {
  80. buf[i] = 0x5c;
  81. }
  82. SHA1_Update(&octx, buf, SHA_BLOCKSIZE);
  83. SHA1_Update(&octx, isha, SHA_DIGEST_LENGTH);
  84. SHA1_Final(osha, &octx);
  85. /* truncate and print the results */
  86. *t = *t > SHA_DIGEST_LENGTH ? SHA_DIGEST_LENGTH : *t;
  87. memcpy(out, osha, *t);
  88. #endif
  89. }