1 /* 2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (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 10 /* 11 * HMAC low level APIs are deprecated for public use, but still ok for internal 12 * use. 13 */ 14 #include "internal/deprecated.h" 15 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <string.h> 19 #include "internal/cryptlib.h" 20 #include <openssl/opensslconf.h> 21 #include <openssl/hmac.h> 22 #include <openssl/core_names.h> 23 #include "hmac_local.h" 24 25 int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, 26 const EVP_MD *md, ENGINE *impl) 27 { 28 int rv = 0, reset = 0; 29 int i, j; 30 unsigned char pad[HMAC_MAX_MD_CBLOCK_SIZE]; 31 unsigned int keytmp_length; 32 unsigned char keytmp[HMAC_MAX_MD_CBLOCK_SIZE]; 33 34 /* If we are changing MD then we must have a key */ 35 if (md != NULL && md != ctx->md && (key == NULL || len < 0)) 36 return 0; 37 38 if (md != NULL) 39 ctx->md = md; 40 else if (ctx->md != NULL) 41 md = ctx->md; 42 else 43 return 0; 44 45 /* 46 * The HMAC construction is not allowed to be used with the 47 * extendable-output functions (XOF) shake128 and shake256. 48 */ 49 if ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0) 50 return 0; 51 52 if (key != NULL) { 53 reset = 1; 54 55 j = EVP_MD_get_block_size(md); 56 if (!ossl_assert(j <= (int)sizeof(keytmp))) 57 return 0; 58 if (j < 0) 59 return 0; 60 if (j < len) { 61 if (!EVP_DigestInit_ex(ctx->md_ctx, md, impl) 62 || !EVP_DigestUpdate(ctx->md_ctx, key, len) 63 || !EVP_DigestFinal_ex(ctx->md_ctx, keytmp, 64 &keytmp_length)) 65 return 0; 66 } else { 67 if (len < 0 || len > (int)sizeof(keytmp)) 68 return 0; 69 memcpy(keytmp, key, len); 70 keytmp_length = len; 71 } 72 if (keytmp_length != HMAC_MAX_MD_CBLOCK_SIZE) 73 memset(&keytmp[keytmp_length], 0, 74 HMAC_MAX_MD_CBLOCK_SIZE - keytmp_length); 75 76 for (i = 0; i < HMAC_MAX_MD_CBLOCK_SIZE; i++) 77 pad[i] = 0x36 ^ keytmp[i]; 78 if (!EVP_DigestInit_ex(ctx->i_ctx, md, impl) 79 || !EVP_DigestUpdate(ctx->i_ctx, pad, 80 EVP_MD_get_block_size(md))) 81 goto err; 82 83 for (i = 0; i < HMAC_MAX_MD_CBLOCK_SIZE; i++) 84 pad[i] = 0x5c ^ keytmp[i]; 85 if (!EVP_DigestInit_ex(ctx->o_ctx, md, impl) 86 || !EVP_DigestUpdate(ctx->o_ctx, pad, 87 EVP_MD_get_block_size(md))) 88 goto err; 89 } 90 if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->i_ctx)) 91 goto err; 92 rv = 1; 93 err: 94 if (reset) { 95 OPENSSL_cleanse(keytmp, sizeof(keytmp)); 96 OPENSSL_cleanse(pad, sizeof(pad)); 97 } 98 return rv; 99 } 100 101 #ifndef OPENSSL_NO_DEPRECATED_1_1_0 102 int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md) 103 { 104 if (key && md) 105 HMAC_CTX_reset(ctx); 106 return HMAC_Init_ex(ctx, key, len, md, NULL); 107 } 108 #endif 109 110 int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) 111 { 112 if (!ctx->md) 113 return 0; 114 return EVP_DigestUpdate(ctx->md_ctx, data, len); 115 } 116 117 int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) 118 { 119 unsigned int i; 120 unsigned char buf[EVP_MAX_MD_SIZE]; 121 122 if (!ctx->md) 123 goto err; 124 125 if (!EVP_DigestFinal_ex(ctx->md_ctx, buf, &i)) 126 goto err; 127 if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->o_ctx)) 128 goto err; 129 if (!EVP_DigestUpdate(ctx->md_ctx, buf, i)) 130 goto err; 131 if (!EVP_DigestFinal_ex(ctx->md_ctx, md, len)) 132 goto err; 133 return 1; 134 err: 135 return 0; 136 } 137 138 size_t HMAC_size(const HMAC_CTX *ctx) 139 { 140 int size = EVP_MD_get_size((ctx)->md); 141 142 return (size < 0) ? 0 : size; 143 } 144 145 HMAC_CTX *HMAC_CTX_new(void) 146 { 147 HMAC_CTX *ctx = OPENSSL_zalloc(sizeof(HMAC_CTX)); 148 149 if (ctx != NULL) { 150 if (!HMAC_CTX_reset(ctx)) { 151 HMAC_CTX_free(ctx); 152 return NULL; 153 } 154 } 155 return ctx; 156 } 157 158 static void hmac_ctx_cleanup(HMAC_CTX *ctx) 159 { 160 EVP_MD_CTX_reset(ctx->i_ctx); 161 EVP_MD_CTX_reset(ctx->o_ctx); 162 EVP_MD_CTX_reset(ctx->md_ctx); 163 ctx->md = NULL; 164 } 165 166 void HMAC_CTX_free(HMAC_CTX *ctx) 167 { 168 if (ctx != NULL) { 169 hmac_ctx_cleanup(ctx); 170 EVP_MD_CTX_free(ctx->i_ctx); 171 EVP_MD_CTX_free(ctx->o_ctx); 172 EVP_MD_CTX_free(ctx->md_ctx); 173 OPENSSL_free(ctx); 174 } 175 } 176 177 static int hmac_ctx_alloc_mds(HMAC_CTX *ctx) 178 { 179 if (ctx->i_ctx == NULL) 180 ctx->i_ctx = EVP_MD_CTX_new(); 181 if (ctx->i_ctx == NULL) 182 return 0; 183 if (ctx->o_ctx == NULL) 184 ctx->o_ctx = EVP_MD_CTX_new(); 185 if (ctx->o_ctx == NULL) 186 return 0; 187 if (ctx->md_ctx == NULL) 188 ctx->md_ctx = EVP_MD_CTX_new(); 189 if (ctx->md_ctx == NULL) 190 return 0; 191 return 1; 192 } 193 194 int HMAC_CTX_reset(HMAC_CTX *ctx) 195 { 196 hmac_ctx_cleanup(ctx); 197 if (!hmac_ctx_alloc_mds(ctx)) { 198 hmac_ctx_cleanup(ctx); 199 return 0; 200 } 201 return 1; 202 } 203 204 int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx) 205 { 206 if (!hmac_ctx_alloc_mds(dctx)) 207 goto err; 208 if (!EVP_MD_CTX_copy_ex(dctx->i_ctx, sctx->i_ctx)) 209 goto err; 210 if (!EVP_MD_CTX_copy_ex(dctx->o_ctx, sctx->o_ctx)) 211 goto err; 212 if (!EVP_MD_CTX_copy_ex(dctx->md_ctx, sctx->md_ctx)) 213 goto err; 214 dctx->md = sctx->md; 215 return 1; 216 err: 217 hmac_ctx_cleanup(dctx); 218 return 0; 219 } 220 221 unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, 222 const unsigned char *data, size_t data_len, 223 unsigned char *md, unsigned int *md_len) 224 { 225 static unsigned char static_md[EVP_MAX_MD_SIZE]; 226 int size = EVP_MD_get_size(evp_md); 227 size_t temp_md_len = 0; 228 unsigned char *ret = NULL; 229 230 if (size >= 0) { 231 ret = EVP_Q_mac(NULL, "HMAC", NULL, EVP_MD_get0_name(evp_md), NULL, 232 key, key_len, data, data_len, 233 md == NULL ? static_md : md, size, &temp_md_len); 234 if (md_len != NULL) 235 *md_len = (unsigned int)temp_md_len; 236 } 237 return ret; 238 } 239 240 void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) 241 { 242 EVP_MD_CTX_set_flags(ctx->i_ctx, flags); 243 EVP_MD_CTX_set_flags(ctx->o_ctx, flags); 244 EVP_MD_CTX_set_flags(ctx->md_ctx, flags); 245 } 246 247 const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx) 248 { 249 return ctx->md; 250 } 251