hmac.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #include <string.h>
  2. #if defined(USE_GNUTLS)
  3. #include <gnutls/gnutls.h>
  4. #include <gnutls/crypto.h>
  5. #elif defined(__APPLE__)
  6. #define USE_CC_CRYPT 1
  7. #include <CommonCrypto/CommonDigest.h>
  8. #elif defined(_WIN32)
  9. #define USE_WIN_CRYPT 1
  10. #include <windows.h>
  11. #include <wincrypt.h>
  12. #else
  13. #include <openssl/sha.h>
  14. #endif
  15. #include "hmac.h"
  16. #ifdef USE_CC_CRYPT
  17. #define SHA256_CTX CC_SHA256_CTX
  18. #define SHA256_Init CC_SHA256_Init
  19. #define SHA256_Update CC_SHA256_Update
  20. #define SHA256_Final CC_SHA256_Final
  21. #endif
  22. typedef struct
  23. {
  24. #ifdef _WIN32
  25. HCRYPTPROV prov;
  26. HCRYPTHASH sha;
  27. #elif defined(USE_GNUTLS)
  28. gnutls_hmac_hd_t hmac;
  29. #else
  30. SHA256_CTX sha;
  31. #endif
  32. unsigned char keybuf[64];
  33. } hmac_sha256_t;
  34. static void HMAC_SHA256_Init(hmac_sha256_t *hmac, const void *key, size_t length)
  35. {
  36. #ifdef USE_WIN_CRYPT
  37. int i;
  38. CryptAcquireContext(&hmac->prov,NULL,NULL,PROV_RSA_AES,CRYPT_VERIFYCONTEXT);
  39. if(length > 64) {
  40. unsigned char digest[32];
  41. HCRYPTHASH sha;
  42. DWORD bufLength = 32;
  43. CryptCreateHash(hmac->prov,CALG_SHA_256,0,0,&sha);
  44. CryptHashData(sha,(PBYTE)key,(DWORD)length,0);
  45. CryptGetHashParam(sha,HP_HASHVAL,hmac->keybuf,&bufLength,0);
  46. CryptDestroyHash(sha);
  47. }
  48. else memcpy(hmac->keybuf,key,length);
  49. for(i=length;i<64;i++) hmac->keybuf[i] = 0;
  50. for(i=0;i<64;i++) hmac->keybuf[i] ^= 0x36;
  51. CryptCreateHash(hmac->prov,CALG_SHA_256,0,0,&hmac->sha);
  52. CryptHashData(hmac->sha,hmac->keybuf,64,0);
  53. #elif defined(USE_GNUTLS)
  54. gnutls_hmac_init(&hmac->hmac, GNUTLS_MAC_SHA256, key, length);
  55. #else
  56. size_t i;
  57. if(length > 64) {
  58. unsigned char digest[32];
  59. SHA256_CTX sha;
  60. SHA256_Init(&sha);
  61. SHA256_Update(&sha,key,length);
  62. SHA256_Final(digest,&sha);
  63. memcpy(hmac->keybuf,digest,32);
  64. length = 32;
  65. }
  66. else memcpy(hmac->keybuf,key,length);
  67. for(i=length;i<64;i++) hmac->keybuf[i] = 0;
  68. for(i=0;i<64;i++) hmac->keybuf[i] ^= 0x36;
  69. SHA256_Init(&hmac->sha);
  70. SHA256_Update(&hmac->sha,hmac->keybuf,64);
  71. #endif
  72. }
  73. static void HMAC_SHA256_Update(hmac_sha256_t *hmac, const void *data, size_t length)
  74. {
  75. #ifdef USE_WIN_CRYPT
  76. CryptHashData(hmac->sha,(PBYTE)data,(DWORD)length,0);
  77. #elif defined(USE_GNUTLS)
  78. gnutls_hmac(hmac->hmac, data, length);
  79. #else
  80. SHA256_Update(&hmac->sha,data,length);
  81. #endif
  82. }
  83. static void HMAC_SHA256_Final(hmac_sha256_t *hmac, unsigned char *md)
  84. {
  85. #ifdef USE_WIN_CRYPT
  86. DWORD i, bufLength = 32;
  87. CryptGetHashParam(hmac->sha,HP_HASHVAL,md,&bufLength,0);
  88. CryptDestroyHash(hmac->sha);
  89. HCRYPTHASH sha;
  90. CryptCreateHash(hmac->prov,CALG_SHA_256,0,0,&sha);
  91. for(i=0;i<64;i++) hmac->keybuf[i] ^= 0x36 ^ 0x5c;
  92. CryptHashData(sha,hmac->keybuf,64,0);
  93. CryptHashData(sha,md,32,0);
  94. CryptGetHashParam(sha,HP_HASHVAL,md,&bufLength,0);
  95. CryptDestroyHash(sha);
  96. CryptReleaseContext(hmac->prov, 0);
  97. #elif defined(USE_GNUTLS)
  98. gnutls_hmac_deinit(hmac->hmac, md);
  99. #else
  100. int i;
  101. SHA256_Final(md,&hmac->sha);
  102. SHA256_CTX sha;
  103. SHA256_Init(&sha);
  104. for(i=0;i<64;i++) hmac->keybuf[i] ^= 0x36 ^ 0x5c;
  105. SHA256_Update(&sha,hmac->keybuf,64);
  106. SHA256_Update(&sha,md,32);
  107. SHA256_Final(md,&sha);
  108. #endif
  109. }
  110. void proxy2ch_HMAC_SHA256(const void *key, size_t keyLength, const void *data, size_t dataLength, void *macOut)
  111. {
  112. hmac_sha256_t hmac;
  113. HMAC_SHA256_Init(&hmac, key, keyLength);
  114. HMAC_SHA256_Update(&hmac, data, dataLength);
  115. HMAC_SHA256_Final(&hmac, macOut);
  116. }