hmac.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*
  2. * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "internal/cryptlib.h"
  13. #include <openssl/hmac.h>
  14. #include <openssl/opensslconf.h>
  15. #include "hmac_local.h"
  16. int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
  17. const EVP_MD *md, ENGINE *impl)
  18. {
  19. int rv = 0, reset = 0;
  20. int i, j;
  21. unsigned char pad[HMAC_MAX_MD_CBLOCK_SIZE];
  22. unsigned int keytmp_length;
  23. unsigned char keytmp[HMAC_MAX_MD_CBLOCK_SIZE];
  24. /* If we are changing MD then we must have a key */
  25. if (md != NULL && md != ctx->md && (key == NULL || len < 0))
  26. return 0;
  27. if (md != NULL) {
  28. ctx->md = md;
  29. } else if (ctx->md) {
  30. md = ctx->md;
  31. } else {
  32. return 0;
  33. }
  34. /*
  35. * The HMAC construction is not allowed to be used with the
  36. * extendable-output functions (XOF) shake128 and shake256.
  37. */
  38. if ((EVP_MD_meth_get_flags(md) & EVP_MD_FLAG_XOF) != 0)
  39. return 0;
  40. if (key != NULL) {
  41. reset = 1;
  42. j = EVP_MD_block_size(md);
  43. if (!ossl_assert(j <= (int)sizeof(keytmp)))
  44. return 0;
  45. if (j < len) {
  46. if (!EVP_DigestInit_ex(ctx->md_ctx, md, impl)
  47. || !EVP_DigestUpdate(ctx->md_ctx, key, len)
  48. || !EVP_DigestFinal_ex(ctx->md_ctx, keytmp,
  49. &keytmp_length))
  50. return 0;
  51. } else {
  52. if (len < 0 || len > (int)sizeof(keytmp))
  53. return 0;
  54. memcpy(keytmp, key, len);
  55. keytmp_length = len;
  56. }
  57. if (keytmp_length != HMAC_MAX_MD_CBLOCK_SIZE)
  58. memset(&keytmp[keytmp_length], 0,
  59. HMAC_MAX_MD_CBLOCK_SIZE - keytmp_length);
  60. for (i = 0; i < HMAC_MAX_MD_CBLOCK_SIZE; i++)
  61. pad[i] = 0x36 ^ keytmp[i];
  62. if (!EVP_DigestInit_ex(ctx->i_ctx, md, impl)
  63. || !EVP_DigestUpdate(ctx->i_ctx, pad, EVP_MD_block_size(md)))
  64. goto err;
  65. for (i = 0; i < HMAC_MAX_MD_CBLOCK_SIZE; i++)
  66. pad[i] = 0x5c ^ keytmp[i];
  67. if (!EVP_DigestInit_ex(ctx->o_ctx, md, impl)
  68. || !EVP_DigestUpdate(ctx->o_ctx, pad, EVP_MD_block_size(md)))
  69. goto err;
  70. }
  71. if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->i_ctx))
  72. goto err;
  73. rv = 1;
  74. err:
  75. if (reset) {
  76. OPENSSL_cleanse(keytmp, sizeof(keytmp));
  77. OPENSSL_cleanse(pad, sizeof(pad));
  78. }
  79. return rv;
  80. }
  81. #if OPENSSL_API_COMPAT < 0x10100000L
  82. int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
  83. {
  84. if (key && md)
  85. HMAC_CTX_reset(ctx);
  86. return HMAC_Init_ex(ctx, key, len, md, NULL);
  87. }
  88. #endif
  89. int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
  90. {
  91. if (!ctx->md)
  92. return 0;
  93. return EVP_DigestUpdate(ctx->md_ctx, data, len);
  94. }
  95. int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
  96. {
  97. unsigned int i;
  98. unsigned char buf[EVP_MAX_MD_SIZE];
  99. if (!ctx->md)
  100. goto err;
  101. if (!EVP_DigestFinal_ex(ctx->md_ctx, buf, &i))
  102. goto err;
  103. if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->o_ctx))
  104. goto err;
  105. if (!EVP_DigestUpdate(ctx->md_ctx, buf, i))
  106. goto err;
  107. if (!EVP_DigestFinal_ex(ctx->md_ctx, md, len))
  108. goto err;
  109. return 1;
  110. err:
  111. return 0;
  112. }
  113. size_t HMAC_size(const HMAC_CTX *ctx)
  114. {
  115. int size = EVP_MD_size((ctx)->md);
  116. return (size < 0) ? 0 : size;
  117. }
  118. HMAC_CTX *HMAC_CTX_new(void)
  119. {
  120. HMAC_CTX *ctx = OPENSSL_zalloc(sizeof(HMAC_CTX));
  121. if (ctx != NULL) {
  122. if (!HMAC_CTX_reset(ctx)) {
  123. HMAC_CTX_free(ctx);
  124. return NULL;
  125. }
  126. }
  127. return ctx;
  128. }
  129. static void hmac_ctx_cleanup(HMAC_CTX *ctx)
  130. {
  131. EVP_MD_CTX_reset(ctx->i_ctx);
  132. EVP_MD_CTX_reset(ctx->o_ctx);
  133. EVP_MD_CTX_reset(ctx->md_ctx);
  134. ctx->md = NULL;
  135. }
  136. void HMAC_CTX_free(HMAC_CTX *ctx)
  137. {
  138. if (ctx != NULL) {
  139. hmac_ctx_cleanup(ctx);
  140. EVP_MD_CTX_free(ctx->i_ctx);
  141. EVP_MD_CTX_free(ctx->o_ctx);
  142. EVP_MD_CTX_free(ctx->md_ctx);
  143. OPENSSL_free(ctx);
  144. }
  145. }
  146. static int hmac_ctx_alloc_mds(HMAC_CTX *ctx)
  147. {
  148. if (ctx->i_ctx == NULL)
  149. ctx->i_ctx = EVP_MD_CTX_new();
  150. if (ctx->i_ctx == NULL)
  151. return 0;
  152. if (ctx->o_ctx == NULL)
  153. ctx->o_ctx = EVP_MD_CTX_new();
  154. if (ctx->o_ctx == NULL)
  155. return 0;
  156. if (ctx->md_ctx == NULL)
  157. ctx->md_ctx = EVP_MD_CTX_new();
  158. if (ctx->md_ctx == NULL)
  159. return 0;
  160. return 1;
  161. }
  162. int HMAC_CTX_reset(HMAC_CTX *ctx)
  163. {
  164. hmac_ctx_cleanup(ctx);
  165. if (!hmac_ctx_alloc_mds(ctx)) {
  166. hmac_ctx_cleanup(ctx);
  167. return 0;
  168. }
  169. return 1;
  170. }
  171. int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
  172. {
  173. if (!hmac_ctx_alloc_mds(dctx))
  174. goto err;
  175. if (!EVP_MD_CTX_copy_ex(dctx->i_ctx, sctx->i_ctx))
  176. goto err;
  177. if (!EVP_MD_CTX_copy_ex(dctx->o_ctx, sctx->o_ctx))
  178. goto err;
  179. if (!EVP_MD_CTX_copy_ex(dctx->md_ctx, sctx->md_ctx))
  180. goto err;
  181. dctx->md = sctx->md;
  182. return 1;
  183. err:
  184. hmac_ctx_cleanup(dctx);
  185. return 0;
  186. }
  187. unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
  188. const unsigned char *d, size_t n, unsigned char *md,
  189. unsigned int *md_len)
  190. {
  191. HMAC_CTX *c = NULL;
  192. static unsigned char m[EVP_MAX_MD_SIZE];
  193. static const unsigned char dummy_key[1] = {'\0'};
  194. if (md == NULL)
  195. md = m;
  196. if ((c = HMAC_CTX_new()) == NULL)
  197. goto err;
  198. /* For HMAC_Init_ex, NULL key signals reuse. */
  199. if (key == NULL && key_len == 0) {
  200. key = dummy_key;
  201. }
  202. if (!HMAC_Init_ex(c, key, key_len, evp_md, NULL))
  203. goto err;
  204. if (!HMAC_Update(c, d, n))
  205. goto err;
  206. if (!HMAC_Final(c, md, md_len))
  207. goto err;
  208. HMAC_CTX_free(c);
  209. return md;
  210. err:
  211. HMAC_CTX_free(c);
  212. return NULL;
  213. }
  214. void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
  215. {
  216. EVP_MD_CTX_set_flags(ctx->i_ctx, flags);
  217. EVP_MD_CTX_set_flags(ctx->o_ctx, flags);
  218. EVP_MD_CTX_set_flags(ctx->md_ctx, flags);
  219. }
  220. const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx)
  221. {
  222. return ctx->md;
  223. }