2 * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
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
11 #include <openssl/err.h>
12 #include <openssl/ossl_typ.h>
13 #include <openssl/asn1.h>
14 #include <openssl/hmac.h>
15 #include "internal/evp_int.h"
17 /* local HMAC context structure */
19 /* typedef EVP_MAC_IMPL */
20 struct evp_mac_impl_st {
21 /* tmpmd and tmpengine are set to NULL after a CMAC_Init call */
22 const EVP_MD *tmpmd; /* HMAC digest */
23 const ENGINE *tmpengine; /* HMAC digest engine */
24 HMAC_CTX *ctx; /* HMAC context */
27 static EVP_MAC_IMPL *hmac_new(void)
31 if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL
32 || (hctx->ctx = HMAC_CTX_new()) == NULL) {
40 static void hmac_free(EVP_MAC_IMPL *hctx)
43 HMAC_CTX_free(hctx->ctx);
48 static EVP_MAC_IMPL *hmac_dup(const EVP_MAC_IMPL *hsrc)
56 if (!HMAC_CTX_copy(hdst->ctx, hsrc->ctx)) {
61 hdst->tmpengine = hsrc->tmpengine;
62 hdst->tmpmd = hsrc->tmpmd;
67 static size_t hmac_size(EVP_MAC_IMPL *hctx)
69 return HMAC_size(hctx->ctx);
72 static int hmac_init(EVP_MAC_IMPL *hctx)
76 /* HMAC_Init_ex doesn't tolerate all zero params, so we must be careful */
77 if (hctx->tmpmd != NULL)
78 rv = HMAC_Init_ex(hctx->ctx, NULL, 0, hctx->tmpmd,
79 (ENGINE * )hctx->tmpengine);
80 hctx->tmpengine = NULL;
85 static int hmac_update(EVP_MAC_IMPL *hctx, const unsigned char *data,
88 return HMAC_Update(hctx->ctx, data, datalen);
91 static int hmac_final(EVP_MAC_IMPL *hctx, unsigned char *out)
95 return HMAC_Final(hctx->ctx, out, &hlen);
98 static int hmac_ctrl(EVP_MAC_IMPL *hctx, int cmd, va_list args)
101 case EVP_MAC_CTRL_SET_FLAGS:
103 unsigned long flags = va_arg(args, unsigned long);
105 HMAC_CTX_set_flags(hctx->ctx, flags);
108 case EVP_MAC_CTRL_SET_KEY:
110 const unsigned char *key = va_arg(args, const unsigned char *);
111 size_t keylen = va_arg(args, size_t);
112 int rv = HMAC_Init_ex(hctx->ctx, key, keylen, hctx->tmpmd,
113 (ENGINE *)hctx->tmpengine);
115 hctx->tmpengine = NULL;
120 case EVP_MAC_CTRL_SET_MD:
121 hctx->tmpmd = va_arg(args, const EVP_MD *);
123 case EVP_MAC_CTRL_SET_ENGINE:
124 hctx->tmpengine = va_arg(args, const ENGINE *);
133 static int hmac_ctrl_int(EVP_MAC_IMPL *hctx, int cmd, ...)
139 rv = hmac_ctrl(hctx, cmd, args);
145 static int hmac_ctrl_str_cb(void *hctx, int cmd, void *buf, size_t buflen)
147 return hmac_ctrl_int(hctx, cmd, buf, buflen);
150 static int hmac_ctrl_str(EVP_MAC_IMPL *hctx, const char *type,
155 if (strcmp(type, "digest") == 0) {
156 const EVP_MD *d = EVP_get_digestbyname(value);
160 return hmac_ctrl_int(hctx, EVP_MAC_CTRL_SET_MD, d);
162 if (strcmp(type, "key") == 0)
163 return EVP_str2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY,
165 if (strcmp(type, "hexkey") == 0)
166 return EVP_hex2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY,
171 const EVP_MAC hmac_meth = {