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 int hmac_copy(EVP_MAC_IMPL *hdst, EVP_MAC_IMPL *hsrc)
50 if (!HMAC_CTX_copy(hdst->ctx, hsrc->ctx))
53 hdst->tmpengine = hsrc->tmpengine;
54 hdst->tmpmd = hsrc->tmpmd;
58 static size_t hmac_size(EVP_MAC_IMPL *hctx)
60 return HMAC_size(hctx->ctx);
63 static int hmac_init(EVP_MAC_IMPL *hctx)
67 /* HMAC_Init_ex doesn't tolerate all zero params, so we must be careful */
68 if (hctx->tmpmd != NULL)
69 rv = HMAC_Init_ex(hctx->ctx, NULL, 0, hctx->tmpmd,
70 (ENGINE * )hctx->tmpengine);
71 hctx->tmpengine = NULL;
76 static int hmac_update(EVP_MAC_IMPL *hctx, const unsigned char *data,
79 return HMAC_Update(hctx->ctx, data, datalen);
82 static int hmac_final(EVP_MAC_IMPL *hctx, unsigned char *out)
86 return HMAC_Final(hctx->ctx, out, &hlen);
89 static int hmac_ctrl(EVP_MAC_IMPL *hctx, int cmd, va_list args)
92 case EVP_MAC_CTRL_SET_FLAGS:
94 unsigned long flags = va_arg(args, unsigned long);
96 HMAC_CTX_set_flags(hctx->ctx, flags);
99 case EVP_MAC_CTRL_SET_KEY:
101 const unsigned char *key = va_arg(args, const unsigned char *);
102 size_t keylen = va_arg(args, size_t);
103 int rv = HMAC_Init_ex(hctx->ctx, key, keylen, hctx->tmpmd,
104 (ENGINE *)hctx->tmpengine);
106 hctx->tmpengine = NULL;
111 case EVP_MAC_CTRL_SET_MD:
112 hctx->tmpmd = va_arg(args, const EVP_MD *);
114 case EVP_MAC_CTRL_SET_ENGINE:
115 hctx->tmpengine = va_arg(args, const ENGINE *);
124 static int hmac_ctrl_int(EVP_MAC_IMPL *hctx, int cmd, ...)
130 rv = hmac_ctrl(hctx, cmd, args);
136 static int hmac_ctrl_str_cb(void *hctx, int cmd, void *buf, size_t buflen)
138 return hmac_ctrl_int(hctx, cmd, buf, buflen);
141 static int hmac_ctrl_str(EVP_MAC_IMPL *hctx, const char *type,
146 if (strcmp(type, "digest") == 0) {
147 const EVP_MD *d = EVP_get_digestbyname(value);
151 return hmac_ctrl_int(hctx, EVP_MAC_CTRL_SET_MD, d);
153 if (strcmp(type, "key") == 0)
154 return EVP_str2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY,
156 if (strcmp(type, "hexkey") == 0)
157 return EVP_hex2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY,
162 const EVP_MAC hmac_meth = {