]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/hmac/hm_meth.c
Change EVP_MAC method from copy to dup
[thirdparty/openssl.git] / crypto / hmac / hm_meth.c
CommitLineData
6723f867
RL
1/*
2 * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
3 *
6f888e05 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
6723f867
RL
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#include <string.h>
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"
16
17/* local HMAC context structure */
18
19/* typedef EVP_MAC_IMPL */
20struct 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 */
25};
26
27static EVP_MAC_IMPL *hmac_new(void)
28{
29 EVP_MAC_IMPL *hctx;
30
31 if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL
32 || (hctx->ctx = HMAC_CTX_new()) == NULL) {
33 OPENSSL_free(hctx);
34 return NULL;
35 }
36
37 return hctx;
38}
39
40static void hmac_free(EVP_MAC_IMPL *hctx)
41{
42 if (hctx != NULL) {
43 HMAC_CTX_free(hctx->ctx);
44 OPENSSL_free(hctx);
45 }
46}
47
7ed66e26 48static EVP_MAC_IMPL *hmac_dup(const EVP_MAC_IMPL *hsrc)
6723f867 49{
7ed66e26
KR
50 EVP_MAC_IMPL *hdst;
51
52 hdst = hmac_new();
53 if (hdst == NULL)
54 return NULL;
55
56 if (!HMAC_CTX_copy(hdst->ctx, hsrc->ctx)) {
57 hmac_free(hdst);
58 return NULL;
59 }
6723f867
RL
60
61 hdst->tmpengine = hsrc->tmpengine;
62 hdst->tmpmd = hsrc->tmpmd;
7ed66e26
KR
63
64 return hdst;
6723f867
RL
65}
66
67static size_t hmac_size(EVP_MAC_IMPL *hctx)
68{
69 return HMAC_size(hctx->ctx);
70}
71
72static int hmac_init(EVP_MAC_IMPL *hctx)
73{
74 int rv = 1;
75
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;
81 hctx->tmpmd = NULL;
82 return rv;
83}
84
85static int hmac_update(EVP_MAC_IMPL *hctx, const unsigned char *data,
86 size_t datalen)
87{
88 return HMAC_Update(hctx->ctx, data, datalen);
89}
90
91static int hmac_final(EVP_MAC_IMPL *hctx, unsigned char *out)
92{
93 unsigned int hlen;
94
95 return HMAC_Final(hctx->ctx, out, &hlen);
96}
97
98static int hmac_ctrl(EVP_MAC_IMPL *hctx, int cmd, va_list args)
99{
100 switch (cmd) {
101 case EVP_MAC_CTRL_SET_FLAGS:
102 {
103 unsigned long flags = va_arg(args, unsigned long);
104
105 HMAC_CTX_set_flags(hctx->ctx, flags);
106 }
107 break;
108 case EVP_MAC_CTRL_SET_KEY:
109 {
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);
114
115 hctx->tmpengine = NULL;
116 hctx->tmpmd = NULL;
117 return rv;
118 }
119 break;
120 case EVP_MAC_CTRL_SET_MD:
121 hctx->tmpmd = va_arg(args, const EVP_MD *);
122 break;
123 case EVP_MAC_CTRL_SET_ENGINE:
124 hctx->tmpengine = va_arg(args, const ENGINE *);
125 break;
126 default:
127 return -2;
128
129 }
130 return 1;
131}
132
133static int hmac_ctrl_int(EVP_MAC_IMPL *hctx, int cmd, ...)
134{
135 int rv;
136 va_list args;
137
138 va_start(args, cmd);
139 rv = hmac_ctrl(hctx, cmd, args);
140 va_end(args);
141
142 return rv;
143}
144
145static int hmac_ctrl_str_cb(void *hctx, int cmd, void *buf, size_t buflen)
146{
147 return hmac_ctrl_int(hctx, cmd, buf, buflen);
148}
149
150static int hmac_ctrl_str(EVP_MAC_IMPL *hctx, const char *type,
151 const char *value)
152{
153 if (!value)
154 return 0;
155 if (strcmp(type, "digest") == 0) {
156 const EVP_MD *d = EVP_get_digestbyname(value);
157
158 if (d == NULL)
159 return 0;
160 return hmac_ctrl_int(hctx, EVP_MAC_CTRL_SET_MD, d);
161 }
162 if (strcmp(type, "key") == 0)
163 return EVP_str2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY,
164 value);
165 if (strcmp(type, "hexkey") == 0)
166 return EVP_hex2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY,
167 value);
168 return -2;
169}
170
171const EVP_MAC hmac_meth = {
172 EVP_MAC_HMAC,
173 hmac_new,
7ed66e26 174 hmac_dup,
6723f867
RL
175 hmac_free,
176 hmac_size,
177 hmac_init,
178 hmac_update,
179 hmac_final,
180 hmac_ctrl,
181 hmac_ctrl_str
182};