/src/openssl30/crypto/hmac/hmac.c
| Line | Count | Source (jump to first uncovered line) | 
| 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 | 36.9k | { | 
| 28 | 36.9k |     int rv = 0, reset = 0; | 
| 29 | 36.9k |     int i, j; | 
| 30 | 36.9k |     unsigned char pad[HMAC_MAX_MD_CBLOCK_SIZE]; | 
| 31 | 36.9k |     unsigned int keytmp_length; | 
| 32 | 36.9k |     unsigned char keytmp[HMAC_MAX_MD_CBLOCK_SIZE]; | 
| 33 |  |  | 
| 34 |  |     /* If we are changing MD then we must have a key */ | 
| 35 | 36.9k |     if (md != NULL && md != ctx->md && (key == NULL || len < 0)) | 
| 36 | 0 |         return 0; | 
| 37 |  |  | 
| 38 | 36.9k |     if (md != NULL) | 
| 39 | 36.9k |         ctx->md = md; | 
| 40 | 0 |     else if (ctx->md != NULL) | 
| 41 | 0 |         md = ctx->md; | 
| 42 | 0 |     else | 
| 43 | 0 |         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 | 36.9k |     if ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0) | 
| 50 | 0 |         return 0; | 
| 51 |  |  | 
| 52 | 36.9k |     if (key != NULL) { | 
| 53 | 36.9k |         reset = 1; | 
| 54 |  |  | 
| 55 | 36.9k |         j = EVP_MD_get_block_size(md); | 
| 56 | 36.9k |         if (!ossl_assert(j <= (int)sizeof(keytmp))) | 
| 57 | 0 |             return 0; | 
| 58 | 36.9k |         if (j < 0) | 
| 59 | 0 |             return 0; | 
| 60 | 36.9k |         if (j < len) { | 
| 61 | 1.48k |             if (!EVP_DigestInit_ex(ctx->md_ctx, md, impl) | 
| 62 | 1.48k |                     || !EVP_DigestUpdate(ctx->md_ctx, key, len) | 
| 63 | 1.48k |                     || !EVP_DigestFinal_ex(ctx->md_ctx, keytmp, | 
| 64 | 1.48k |                                            &keytmp_length)) | 
| 65 | 0 |                 return 0; | 
| 66 | 35.4k |         } else { | 
| 67 | 35.4k |             if (len < 0 || len > (int)sizeof(keytmp)) | 
| 68 | 0 |                 return 0; | 
| 69 | 35.4k |             memcpy(keytmp, key, len); | 
| 70 | 35.4k |             keytmp_length = len; | 
| 71 | 35.4k |         } | 
| 72 | 36.9k |         if (keytmp_length != HMAC_MAX_MD_CBLOCK_SIZE) | 
| 73 | 36.9k |             memset(&keytmp[keytmp_length], 0, | 
| 74 | 36.9k |                    HMAC_MAX_MD_CBLOCK_SIZE - keytmp_length); | 
| 75 |  |  | 
| 76 | 5.35M |         for (i = 0; i < HMAC_MAX_MD_CBLOCK_SIZE; i++) | 
| 77 | 5.31M |             pad[i] = 0x36 ^ keytmp[i]; | 
| 78 | 36.9k |         if (!EVP_DigestInit_ex(ctx->i_ctx, md, impl) | 
| 79 | 36.9k |                 || !EVP_DigestUpdate(ctx->i_ctx, pad, | 
| 80 | 36.9k |                                      EVP_MD_get_block_size(md))) | 
| 81 | 0 |             goto err; | 
| 82 |  |  | 
| 83 | 5.35M |         for (i = 0; i < HMAC_MAX_MD_CBLOCK_SIZE; i++) | 
| 84 | 5.31M |             pad[i] = 0x5c ^ keytmp[i]; | 
| 85 | 36.9k |         if (!EVP_DigestInit_ex(ctx->o_ctx, md, impl) | 
| 86 | 36.9k |                 || !EVP_DigestUpdate(ctx->o_ctx, pad, | 
| 87 | 36.9k |                                      EVP_MD_get_block_size(md))) | 
| 88 | 0 |             goto err; | 
| 89 | 36.9k |     } | 
| 90 | 36.9k |     if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->i_ctx)) | 
| 91 | 0 |         goto err; | 
| 92 | 36.9k |     rv = 1; | 
| 93 | 36.9k |  err: | 
| 94 | 36.9k |     if (reset) { | 
| 95 | 36.9k |         OPENSSL_cleanse(keytmp, sizeof(keytmp)); | 
| 96 | 36.9k |         OPENSSL_cleanse(pad, sizeof(pad)); | 
| 97 | 36.9k |     } | 
| 98 | 36.9k |     return rv; | 
| 99 | 36.9k | } | 
| 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 | 0 | { | 
| 104 | 0 |     if (key && md) | 
| 105 | 0 |         HMAC_CTX_reset(ctx); | 
| 106 | 0 |     return HMAC_Init_ex(ctx, key, len, md, NULL); | 
| 107 | 0 | } | 
| 108 |  | #endif | 
| 109 |  |  | 
| 110 |  | int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) | 
| 111 | 264k | { | 
| 112 | 264k |     if (!ctx->md) | 
| 113 | 0 |         return 0; | 
| 114 | 264k |     return EVP_DigestUpdate(ctx->md_ctx, data, len); | 
| 115 | 264k | } | 
| 116 |  |  | 
| 117 |  | int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) | 
| 118 | 186k | { | 
| 119 | 186k |     unsigned int i; | 
| 120 | 186k |     unsigned char buf[EVP_MAX_MD_SIZE]; | 
| 121 |  |  | 
| 122 | 186k |     if (!ctx->md) | 
| 123 | 0 |         goto err; | 
| 124 |  |  | 
| 125 | 186k |     if (!EVP_DigestFinal_ex(ctx->md_ctx, buf, &i)) | 
| 126 | 0 |         goto err; | 
| 127 | 186k |     if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->o_ctx)) | 
| 128 | 0 |         goto err; | 
| 129 | 186k |     if (!EVP_DigestUpdate(ctx->md_ctx, buf, i)) | 
| 130 | 0 |         goto err; | 
| 131 | 186k |     if (!EVP_DigestFinal_ex(ctx->md_ctx, md, len)) | 
| 132 | 0 |         goto err; | 
| 133 | 186k |     return 1; | 
| 134 | 0 |  err: | 
| 135 | 0 |     return 0; | 
| 136 | 186k | } | 
| 137 |  |  | 
| 138 |  | size_t HMAC_size(const HMAC_CTX *ctx) | 
| 139 | 126k | { | 
| 140 | 126k |     int size = EVP_MD_get_size((ctx)->md); | 
| 141 |  |  | 
| 142 | 126k |     return (size < 0) ? 0 : size; | 
| 143 | 126k | } | 
| 144 |  |  | 
| 145 |  | HMAC_CTX *HMAC_CTX_new(void) | 
| 146 | 299k | { | 
| 147 | 299k |     HMAC_CTX *ctx = OPENSSL_zalloc(sizeof(HMAC_CTX)); | 
| 148 |  |  | 
| 149 | 299k |     if (ctx != NULL) { | 
| 150 | 299k |         if (!HMAC_CTX_reset(ctx)) { | 
| 151 | 0 |             HMAC_CTX_free(ctx); | 
| 152 | 0 |             return NULL; | 
| 153 | 0 |         } | 
| 154 | 299k |     } | 
| 155 | 299k |     return ctx; | 
| 156 | 299k | } | 
| 157 |  |  | 
| 158 |  | static void hmac_ctx_cleanup(HMAC_CTX *ctx) | 
| 159 | 598k | { | 
| 160 | 598k |     EVP_MD_CTX_reset(ctx->i_ctx); | 
| 161 | 598k |     EVP_MD_CTX_reset(ctx->o_ctx); | 
| 162 | 598k |     EVP_MD_CTX_reset(ctx->md_ctx); | 
| 163 | 598k |     ctx->md = NULL; | 
| 164 | 598k | } | 
| 165 |  |  | 
| 166 |  | void HMAC_CTX_free(HMAC_CTX *ctx) | 
| 167 | 300k | { | 
| 168 | 300k |     if (ctx != NULL) { | 
| 169 | 299k |         hmac_ctx_cleanup(ctx); | 
| 170 | 299k |         EVP_MD_CTX_free(ctx->i_ctx); | 
| 171 | 299k |         EVP_MD_CTX_free(ctx->o_ctx); | 
| 172 | 299k |         EVP_MD_CTX_free(ctx->md_ctx); | 
| 173 | 299k |         OPENSSL_free(ctx); | 
| 174 | 299k |     } | 
| 175 | 300k | } | 
| 176 |  |  | 
| 177 |  | static int hmac_ctx_alloc_mds(HMAC_CTX *ctx) | 
| 178 | 538k | { | 
| 179 | 538k |     if (ctx->i_ctx == NULL) | 
| 180 | 299k |         ctx->i_ctx = EVP_MD_CTX_new(); | 
| 181 | 538k |     if (ctx->i_ctx == NULL) | 
| 182 | 0 |         return 0; | 
| 183 | 538k |     if (ctx->o_ctx == NULL) | 
| 184 | 299k |         ctx->o_ctx = EVP_MD_CTX_new(); | 
| 185 | 538k |     if (ctx->o_ctx == NULL) | 
| 186 | 0 |         return 0; | 
| 187 | 538k |     if (ctx->md_ctx == NULL) | 
| 188 | 299k |         ctx->md_ctx = EVP_MD_CTX_new(); | 
| 189 | 538k |     if (ctx->md_ctx == NULL) | 
| 190 | 0 |         return 0; | 
| 191 | 538k |     return 1; | 
| 192 | 538k | } | 
| 193 |  |  | 
| 194 |  | int HMAC_CTX_reset(HMAC_CTX *ctx) | 
| 195 | 299k | { | 
| 196 | 299k |     hmac_ctx_cleanup(ctx); | 
| 197 | 299k |     if (!hmac_ctx_alloc_mds(ctx)) { | 
| 198 | 0 |         hmac_ctx_cleanup(ctx); | 
| 199 | 0 |         return 0; | 
| 200 | 0 |     } | 
| 201 | 299k |     return 1; | 
| 202 | 299k | } | 
| 203 |  |  | 
| 204 |  | int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx) | 
| 205 | 238k | { | 
| 206 | 238k |     if (!hmac_ctx_alloc_mds(dctx)) | 
| 207 | 0 |         goto err; | 
| 208 | 238k |     if (!EVP_MD_CTX_copy_ex(dctx->i_ctx, sctx->i_ctx)) | 
| 209 | 0 |         goto err; | 
| 210 | 238k |     if (!EVP_MD_CTX_copy_ex(dctx->o_ctx, sctx->o_ctx)) | 
| 211 | 0 |         goto err; | 
| 212 | 238k |     if (!EVP_MD_CTX_copy_ex(dctx->md_ctx, sctx->md_ctx)) | 
| 213 | 0 |         goto err; | 
| 214 | 238k |     dctx->md = sctx->md; | 
| 215 | 238k |     return 1; | 
| 216 | 0 |  err: | 
| 217 | 0 |     hmac_ctx_cleanup(dctx); | 
| 218 | 0 |     return 0; | 
| 219 | 238k | } | 
| 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 | 10.8k | { | 
| 242 | 10.8k |     EVP_MD_CTX_set_flags(ctx->i_ctx, flags); | 
| 243 | 10.8k |     EVP_MD_CTX_set_flags(ctx->o_ctx, flags); | 
| 244 | 10.8k |     EVP_MD_CTX_set_flags(ctx->md_ctx, flags); | 
| 245 | 10.8k | } | 
| 246 |  |  | 
| 247 |  | const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx) | 
| 248 | 0 | { | 
| 249 | 0 |     return ctx->md; | 
| 250 | 0 | } |