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
10 #include <openssl/err.h>
11 #include <openssl/evp.h>
12 #include "internal/evp_int.h"
15 /* MAC PKEY context structure */
21 * We know of two MAC types:
23 * 1. those who take a secret in raw form, i.e. raw data as a
24 * ASN1_OCTET_STRING embedded in a EVP_PKEY. So far, that's
25 * all of them but CMAC.
26 * 2. those who take a secret with associated cipher in very generic
27 * form, i.e. a complete EVP_MAC_CTX embedded in a PKEY. So far,
28 * only CMAC does this.
30 * (one might wonder why the second form isn't used for all)
32 #define MAC_TYPE_RAW 1 /* HMAC like MAC type (all but CMAC so far) */
33 #define MAC_TYPE_MAC 2 /* CMAC like MAC type (only CMAC known so far) */
36 /* The following is only used for MAC_TYPE_RAW implementations */
38 const EVP_MD *md; /* temp storage of MD */
39 ASN1_OCTET_STRING ktmp; /* temp storage for key */
43 static int pkey_mac_init(EVP_PKEY_CTX *ctx)
46 int nid = ctx->pmeth->pkey_id;
48 if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
49 EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
53 /* We're being smart and using the same base NIDs for PKEY and for MAC */
54 hctx->ctx = EVP_MAC_CTX_new_id(nid);
55 if (hctx->ctx == NULL) {
60 if (nid == EVP_PKEY_CMAC) {
61 hctx->type = MAC_TYPE_MAC;
63 hctx->type = MAC_TYPE_RAW;
64 hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING;
67 EVP_PKEY_CTX_set_data(ctx, hctx);
68 ctx->keygen_info_count = 0;
73 static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
75 static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
77 MAC_PKEY_CTX *sctx, *dctx;
79 sctx = EVP_PKEY_CTX_get_data(src);
80 if (sctx->ctx->data == NULL)
83 dctx = OPENSSL_zalloc(sizeof(*dctx));
85 EVPerr(EVP_F_PKEY_MAC_COPY, ERR_R_MALLOC_FAILURE);
89 EVP_PKEY_CTX_set_data(dst, dctx);
90 dst->keygen_info_count = 0;
92 dctx->ctx = EVP_MAC_CTX_dup(sctx->ctx);
93 if (dctx->ctx == NULL)
96 dctx->type = sctx->type;
100 dctx->raw_data.md = sctx->raw_data.md;
101 if (ASN1_STRING_get0_data(&sctx->raw_data.ktmp) != NULL &&
102 !ASN1_STRING_copy(&dctx->raw_data.ktmp, &sctx->raw_data.ktmp))
106 /* Nothing more to do */
109 /* This should be dead code */
114 pkey_mac_cleanup(dst);
118 static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
120 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
123 switch (hctx->type) {
125 OPENSSL_clear_free(hctx->raw_data.ktmp.data,
126 hctx->raw_data.ktmp.length);
129 EVP_MAC_CTX_free(hctx->ctx);
131 EVP_PKEY_CTX_set_data(ctx, NULL);
135 static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
137 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
138 int nid = ctx->pmeth->pkey_id;
140 switch (hctx->type) {
143 ASN1_OCTET_STRING *hkey = NULL;
145 if (!hctx->raw_data.ktmp.data)
147 hkey = ASN1_OCTET_STRING_dup(&hctx->raw_data.ktmp);
150 EVP_PKEY_assign(pkey, nid, hkey);
155 EVP_MAC_CTX *cmkey = EVP_MAC_CTX_dup(hctx->ctx);
159 EVP_PKEY_assign(pkey, nid, cmkey);
163 /* This should be dead code */
170 static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
172 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
174 if (!EVP_MAC_update(hctx->ctx, data, count))
179 static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
181 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
182 ASN1_OCTET_STRING *key = NULL;
185 * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that
186 * gets the key passed as an ASN.1 OCTET STRING, we set the key here,
187 * as this may be only time it's set during a DigestSign.
189 * MACs that pass around the key in form of EVP_MAC_CTX are setting
190 * the key through other mechanisms. (this is only CMAC for now)
193 hctx->type == MAC_TYPE_RAW
194 && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
197 if (EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))
198 != EVP_MAC_nid(EVP_MAC_CTX_mac(hctx->ctx)))
200 key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
205 /* Some MACs don't support this control... that's fine */
206 EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_FLAGS,
207 EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT));
209 EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
210 EVP_MD_CTX_set_update_fn(mctx, int_update);
213 rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, key->data,
218 static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
219 size_t *siglen, EVP_MD_CTX *mctx)
221 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
223 return EVP_MAC_final(hctx->ctx, sig, siglen);
226 static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
228 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
232 case EVP_PKEY_CTRL_CIPHER:
233 switch (hctx->type) {
235 return -2; /* The raw types don't support ciphers */
240 if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
242 || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_CIPHER,
244 || !(rv = EVP_MAC_init(hctx->ctx)))
249 /* This should be dead code */
254 case EVP_PKEY_CTRL_MD:
255 switch (hctx->type) {
257 hctx->raw_data.md = p2;
260 EVP_MAC_CTX *new_mac_ctx;
262 if (ctx->pkey == NULL)
264 new_mac_ctx = EVP_MAC_CTX_dup((EVP_MAC_CTX *)ctx->pkey
266 if (new_mac_ctx == NULL)
268 EVP_MAC_CTX_free(hctx->ctx);
269 hctx->ctx = new_mac_ctx;
273 /* This should be dead code */
278 case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
279 return EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_SIZE, (size_t)p1);
281 case EVP_PKEY_CTRL_SET_MAC_KEY:
282 switch (hctx->type) {
284 if ((!p2 && p1 > 0) || (p1 < -1))
286 if (!ASN1_OCTET_STRING_set(&hctx->raw_data.ktmp, p2, p1))
290 if (EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, p2, p1) <= 0)
294 /* This should be dead code */
299 case EVP_PKEY_CTRL_DIGESTINIT:
300 switch (hctx->type) {
302 /* Ensure that we have attached the implementation */
303 if (!EVP_MAC_init(hctx->ctx))
307 ASN1_OCTET_STRING *key =
308 (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
310 if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
312 || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_MD,
313 hctx->raw_data.md)) <= 0
314 || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY,
315 key->data, key->length)) <= 0)
320 return -2; /* The mac types don't support ciphers */
322 /* This should be dead code */
334 static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
335 const char *type, const char *value)
337 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
339 return EVP_MAC_ctrl_str(hctx->ctx, type, value);
342 const EVP_PKEY_METHOD cmac_pkey_meth = {
344 EVP_PKEY_FLAG_SIGCTX_CUSTOM,
360 pkey_mac_signctx_init,
375 const EVP_PKEY_METHOD hmac_pkey_meth = {
393 pkey_mac_signctx_init,
408 const EVP_PKEY_METHOD siphash_pkey_meth = {
410 EVP_PKEY_FLAG_SIGCTX_CUSTOM,
426 pkey_mac_signctx_init,
441 const EVP_PKEY_METHOD poly1305_pkey_meth = {
443 EVP_PKEY_FLAG_SIGCTX_CUSTOM,
459 pkey_mac_signctx_init,