2 * Copyright 2018-2020 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/evp.h>
13 #include <openssl/engine.h>
14 #include <openssl/params.h>
15 #include <openssl/core_names.h>
16 #include "crypto/evp.h"
17 #include "evp_local.h"
19 /* MAC PKEY context structure */
25 * We know of two MAC types:
27 * 1. those who take a secret in raw form, i.e. raw data as a
28 * ASN1_OCTET_STRING embedded in a EVP_PKEY. So far, that's
29 * all of them but CMAC.
30 * 2. those who take a secret with associated cipher in very generic
31 * form, i.e. a complete EVP_MAC_CTX embedded in a PKEY. So far,
32 * only CMAC does this.
34 * (one might wonder why the second form isn't used for all)
36 #define MAC_TYPE_RAW 1 /* HMAC like MAC type (all but CMAC so far) */
37 #define MAC_TYPE_MAC 2 /* CMAC like MAC type (only CMAC known so far) */
40 /* The following is only used for MAC_TYPE_RAW implementations */
42 const EVP_MD *md; /* temp storage of MD */
43 ASN1_OCTET_STRING ktmp; /* temp storage for key */
47 static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
49 static int pkey_mac_init(EVP_PKEY_CTX *ctx)
52 /* We're being smart and using the same base NIDs for PKEY and for MAC */
53 int nid = ctx->pmeth->pkey_id;
57 mac = EVP_MAC_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propquery);
61 * mac == NULL may actually be ok in some situations. In an
62 * EVP_PKEY_new_mac_key() call a temporary EVP_PKEY_CTX is created with
63 * default libctx. We don't actually need the underlying MAC to be present
64 * to successfully set the key in that case. The resulting EVP_PKEY could
65 * then be used in some other libctx where the MAC *is* present
68 if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
69 EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
74 hctx->ctx = EVP_MAC_new_ctx(mac);
75 if (hctx->ctx == NULL) {
81 if (nid == EVP_PKEY_CMAC) {
82 hctx->type = MAC_TYPE_MAC;
84 hctx->type = MAC_TYPE_RAW;
85 hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING;
88 pkey_mac_cleanup(ctx);
89 EVP_PKEY_CTX_set_data(ctx, hctx);
90 ctx->keygen_info_count = 0;
95 static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
97 MAC_PKEY_CTX *sctx, *dctx;
99 sctx = EVP_PKEY_CTX_get_data(src);
101 if (sctx->ctx == NULL) {
102 /* This actually means the fetch failed during the init call */
103 EVPerr(0, EVP_R_FETCH_FAILED);
107 if (sctx->ctx->data == NULL)
110 dctx = OPENSSL_zalloc(sizeof(*dctx));
112 EVPerr(EVP_F_PKEY_MAC_COPY, ERR_R_MALLOC_FAILURE);
116 EVP_PKEY_CTX_set_data(dst, dctx);
117 dst->keygen_info_count = 0;
119 dctx->ctx = EVP_MAC_dup_ctx(sctx->ctx);
120 if (dctx->ctx == NULL)
124 * Normally, nothing special would be done with the MAC method. In
125 * this particular case, though, the MAC method was fetched internally
126 * by pkey_mac_init() above or by EVP_PKEY_new_CMAC_key() and passed
127 * via the EVP_MAC_CTX, so it is effectively like every new EVP_MAC_CTX
128 * fetches the MAC method anew in this case. Therefore, its reference
129 * count must be adjusted here.
131 if (!EVP_MAC_up_ref(EVP_MAC_get_ctx_mac(dctx->ctx)))
134 dctx->type = sctx->type;
136 switch (dctx->type) {
138 dctx->raw_data.md = sctx->raw_data.md;
139 if (ASN1_STRING_get0_data(&sctx->raw_data.ktmp) != NULL &&
140 !ASN1_STRING_copy(&dctx->raw_data.ktmp, &sctx->raw_data.ktmp))
144 /* Nothing more to do */
147 /* This should be dead code */
152 pkey_mac_cleanup(dst);
156 static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
159 * For the exact same reasons the MAC reference count is incremented
160 * in pkey_mac_copy() above, it must be explicitly freed here.
163 MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx);
166 EVP_MAC *mac = hctx->ctx != NULL ? EVP_MAC_get_ctx_mac(hctx->ctx)
169 switch (hctx->type) {
171 OPENSSL_clear_free(hctx->raw_data.ktmp.data,
172 hctx->raw_data.ktmp.length);
175 EVP_MAC_free_ctx(hctx->ctx);
178 EVP_PKEY_CTX_set_data(ctx, NULL);
182 static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
184 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
185 int nid = ctx->pmeth->pkey_id;
187 switch (hctx->type) {
190 ASN1_OCTET_STRING *hkey = NULL;
192 if (!hctx->raw_data.ktmp.data)
194 hkey = ASN1_OCTET_STRING_dup(&hctx->raw_data.ktmp);
197 EVP_PKEY_assign(pkey, nid, hkey);
204 if (hctx->ctx == NULL) {
205 /* This actually means the fetch failed during the init call */
206 EVPerr(0, EVP_R_FETCH_FAILED);
210 cmkey = EVP_MAC_dup_ctx(hctx->ctx);
213 if (!EVP_MAC_up_ref(EVP_MAC_get_ctx_mac(hctx->ctx)))
215 EVP_PKEY_assign(pkey, nid, cmkey);
219 /* This should be dead code */
226 static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
228 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
230 if (!EVP_MAC_update(hctx->ctx, data, count))
235 static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
237 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
238 ASN1_OCTET_STRING *key = NULL;
241 * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that
242 * gets the key passed as an ASN.1 OCTET STRING, we set the key here,
243 * as this may be only time it's set during a DigestSign.
245 * MACs that pass around the key in form of EVP_MAC_CTX are setting
246 * the key through other mechanisms. (this is only CMAC for now)
249 hctx->type == MAC_TYPE_RAW
250 && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
252 if (hctx->ctx == NULL) {
253 /* This actually means the fetch failed during the init call */
254 EVPerr(0, EVP_R_FETCH_FAILED);
259 if (!EVP_MAC_is_a(EVP_MAC_get_ctx_mac(hctx->ctx),
260 OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)))))
262 key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
267 EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
268 EVP_MD_CTX_set_update_fn(mctx, int_update);
270 /* Some MACs don't support this control... that's fine */
272 OSSL_PARAM params[3];
274 int flags = EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT);
276 /* TODO(3.0) "flags" isn't quite right, i.e. a quick hack for now */
278 OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &flags);
281 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
282 key->data, key->length);
283 params[params_n++] = OSSL_PARAM_construct_end();
284 rv = EVP_MAC_set_ctx_params(hctx->ctx, params);
289 static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
290 size_t *siglen, EVP_MD_CTX *mctx)
292 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
294 return EVP_MAC_final(hctx->ctx, sig, siglen, EVP_MAC_size(hctx->ctx));
297 static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
299 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
303 case EVP_PKEY_CTRL_CIPHER:
304 switch (hctx->type) {
306 return -2; /* The raw types don't support ciphers */
309 OSSL_PARAM params[3];
311 char *ciphname = (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2));
313 #ifndef OPENSSL_NO_ENGINE
314 if (ctx->engine != NULL) {
315 char *engid = (char *)ENGINE_get_id(ctx->engine);
318 OSSL_PARAM_construct_utf8_string("engine", engid, 0);
322 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
324 params[params_n] = OSSL_PARAM_construct_end();
326 if (hctx->ctx == NULL) {
328 * This actually means the fetch failed during the init call
330 EVPerr(0, EVP_R_FETCH_FAILED);
334 if (!EVP_MAC_set_ctx_params(hctx->ctx, params)
335 || !EVP_MAC_init(hctx->ctx))
340 /* This should be dead code */
345 case EVP_PKEY_CTRL_MD:
346 switch (hctx->type) {
348 hctx->raw_data.md = p2;
351 EVP_MAC_CTX *new_mac_ctx;
353 if (ctx->pkey == NULL)
355 new_mac_ctx = EVP_MAC_dup_ctx(ctx->pkey->pkey.ptr);
356 if (new_mac_ctx == NULL)
358 EVP_MAC_free_ctx(hctx->ctx);
359 hctx->ctx = new_mac_ctx;
363 /* This should be dead code */
368 case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
370 OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
371 size_t size = (size_t)p1;
375 * We verify that the length is actually set by getting back
376 * the same parameter and checking that it matches what we
378 * TODO(3.0) when we have a more direct mechanism to check if
379 * a parameter was used, we must refactor this to use that.
383 OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size);
385 if (hctx->ctx == NULL) {
387 * This actually means the fetch failed during the init call
389 EVPerr(0, EVP_R_FETCH_FAILED);
393 if (!EVP_MAC_set_ctx_params(hctx->ctx, params))
397 OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &verify);
399 if (!EVP_MAC_get_ctx_params(hctx->ctx, params))
403 * Since EVP_MAC_{get,set}_ctx_params() returned successfully,
404 * we can only assume that the size was ignored, i.e. this
405 * control is unsupported.
411 case EVP_PKEY_CTRL_SET_MAC_KEY:
412 switch (hctx->type) {
414 if ((!p2 && p1 > 0) || (p1 < -1))
416 if (!ASN1_OCTET_STRING_set(&hctx->raw_data.ktmp, p2, p1))
421 OSSL_PARAM params[2];
425 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
427 params[params_n] = OSSL_PARAM_construct_end();
429 if (hctx->ctx == NULL) {
431 * This actually means the fetch failed during the init call
433 EVPerr(0, EVP_R_FETCH_FAILED);
437 return EVP_MAC_set_ctx_params(hctx->ctx, params);
441 /* This should be dead code */
446 case EVP_PKEY_CTRL_DIGESTINIT:
447 switch (hctx->type) {
449 if (hctx->ctx == NULL) {
450 /* This actually means the fetch failed during the init call */
451 EVPerr(0, EVP_R_FETCH_FAILED);
455 /* Ensure that we have attached the implementation */
456 if (!EVP_MAC_init(hctx->ctx))
459 ASN1_OCTET_STRING *key =
460 (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
461 OSSL_PARAM params[4];
464 (char *)OBJ_nid2sn(EVP_MD_nid(hctx->raw_data.md));
466 #ifndef OPENSSL_NO_ENGINE
467 if (ctx->engine != NULL) {
468 char *engid = (char *)ENGINE_get_id(ctx->engine);
471 OSSL_PARAM_construct_utf8_string("engine", engid, 0);
475 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
478 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
479 key->data, key->length);
480 params[params_n] = OSSL_PARAM_construct_end();
482 return EVP_MAC_set_ctx_params(hctx->ctx, params);
486 return -2; /* The mac types don't support ciphers */
488 /* This should be dead code */
500 static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
501 const char *type, const char *value)
503 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
505 OSSL_PARAM params[2];
509 EVPerr(0, EVP_R_NULL_MAC_PKEY_CTX);
512 if (hctx->ctx == NULL) {
513 /* This actually means the fetch failed during the init call */
514 EVPerr(0, EVP_R_FETCH_FAILED);
517 mac = EVP_MAC_get_ctx_mac(hctx->ctx);
520 * Translation of some control names that are equivalent to a single
523 * "md" and "digest" are the same thing, we use the single "digest"
525 * "digestsize" was a setting control in siphash, but naming wise,
526 * it's really the same as "size".
528 if (strcmp(type, "md") == 0)
529 type = OSSL_MAC_PARAM_DIGEST;
530 else if (strcmp(type, "digestsize") == 0)
531 type = OSSL_MAC_PARAM_SIZE;
533 if (!OSSL_PARAM_allocate_from_text(¶ms[0],
534 EVP_MAC_settable_ctx_params(mac),
535 type, value, strlen(value) + 1, NULL))
537 params[1] = OSSL_PARAM_construct_end();
539 ok = EVP_MAC_set_ctx_params(hctx->ctx, params);
540 OPENSSL_free(params[0].data);
544 static const EVP_PKEY_METHOD cmac_pkey_meth = {
546 EVP_PKEY_FLAG_SIGCTX_CUSTOM,
562 pkey_mac_signctx_init,
577 const EVP_PKEY_METHOD *cmac_pkey_method(void)
579 return &cmac_pkey_meth;
582 static const EVP_PKEY_METHOD hmac_pkey_meth = {
600 pkey_mac_signctx_init,
615 const EVP_PKEY_METHOD *hmac_pkey_method(void)
617 return &hmac_pkey_meth;
620 static const EVP_PKEY_METHOD siphash_pkey_meth = {
622 EVP_PKEY_FLAG_SIGCTX_CUSTOM,
638 pkey_mac_signctx_init,
653 const EVP_PKEY_METHOD *siphash_pkey_method(void)
655 return &siphash_pkey_meth;
658 static const EVP_PKEY_METHOD poly1305_pkey_meth = {
660 EVP_PKEY_FLAG_SIGCTX_CUSTOM,
676 pkey_mac_signctx_init,
691 const EVP_PKEY_METHOD *poly1305_pkey_method(void)
693 return &poly1305_pkey_meth;