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
10 /* We need to use some engine deprecated APIs */
11 #define OPENSSL_SUPPRESS_DEPRECATED
14 #include <openssl/err.h>
15 #include <openssl/evp.h>
16 #include <openssl/engine.h>
17 #include <openssl/params.h>
18 #include <openssl/core_names.h>
19 #include "crypto/evp.h"
20 #include "evp_local.h"
22 /* MAC PKEY context structure */
28 * We know of two MAC types:
30 * 1. those who take a secret in raw form, i.e. raw data as a
31 * ASN1_OCTET_STRING embedded in a EVP_PKEY. So far, that's
32 * all of them but CMAC.
33 * 2. those who take a secret with associated cipher in very generic
34 * form, i.e. a complete EVP_MAC_CTX embedded in a PKEY. So far,
35 * only CMAC does this.
37 * (one might wonder why the second form isn't used for all)
39 #define MAC_TYPE_RAW 1 /* HMAC like MAC type (all but CMAC so far) */
40 #define MAC_TYPE_MAC 2 /* CMAC like MAC type (only CMAC known so far) */
43 /* The following is only used for MAC_TYPE_RAW implementations */
45 const EVP_MD *md; /* temp storage of MD */
46 ASN1_OCTET_STRING ktmp; /* temp storage for key */
50 static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
52 static int pkey_mac_init(EVP_PKEY_CTX *ctx)
55 /* We're being smart and using the same base NIDs for PKEY and for MAC */
56 int nid = ctx->pmeth->pkey_id;
60 mac = EVP_MAC_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propquery);
64 * mac == NULL may actually be ok in some situations. In an
65 * EVP_PKEY_new_mac_key() call a temporary EVP_PKEY_CTX is created with
66 * default libctx. We don't actually need the underlying MAC to be present
67 * to successfully set the key in that case. The resulting EVP_PKEY could
68 * then be used in some other libctx where the MAC *is* present
71 if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
72 EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
77 hctx->ctx = EVP_MAC_CTX_new(mac);
78 if (hctx->ctx == NULL) {
84 if (nid == EVP_PKEY_CMAC) {
85 hctx->type = MAC_TYPE_MAC;
87 hctx->type = MAC_TYPE_RAW;
88 hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING;
91 pkey_mac_cleanup(ctx);
92 EVP_PKEY_CTX_set_data(ctx, hctx);
93 ctx->keygen_info_count = 0;
98 static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
100 MAC_PKEY_CTX *sctx, *dctx;
102 sctx = EVP_PKEY_CTX_get_data(src);
104 if (sctx->ctx == NULL) {
105 /* This actually means the fetch failed during the init call */
106 EVPerr(0, EVP_R_FETCH_FAILED);
110 if (sctx->ctx->data == NULL)
113 dctx = OPENSSL_zalloc(sizeof(*dctx));
115 EVPerr(EVP_F_PKEY_MAC_COPY, ERR_R_MALLOC_FAILURE);
119 EVP_PKEY_CTX_set_data(dst, dctx);
120 dst->keygen_info_count = 0;
122 dctx->ctx = EVP_MAC_CTX_dup(sctx->ctx);
123 if (dctx->ctx == NULL)
127 * Normally, nothing special would be done with the MAC method. In
128 * this particular case, though, the MAC method was fetched internally
129 * by pkey_mac_init() above or by EVP_PKEY_new_CMAC_key() and passed
130 * via the EVP_MAC_CTX, so it is effectively like every new EVP_MAC_CTX
131 * fetches the MAC method anew in this case. Therefore, its reference
132 * count must be adjusted here.
134 if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(dctx->ctx)))
137 dctx->type = sctx->type;
139 switch (dctx->type) {
141 dctx->raw_data.md = sctx->raw_data.md;
142 if (ASN1_STRING_get0_data(&sctx->raw_data.ktmp) != NULL &&
143 !ASN1_STRING_copy(&dctx->raw_data.ktmp, &sctx->raw_data.ktmp))
147 /* Nothing more to do */
150 /* This should be dead code */
155 pkey_mac_cleanup(dst);
159 static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
162 * For the exact same reasons the MAC reference count is incremented
163 * in pkey_mac_copy() above, it must be explicitly freed here.
166 MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx);
169 EVP_MAC *mac = hctx->ctx != NULL ? EVP_MAC_CTX_mac(hctx->ctx) : NULL;
171 switch (hctx->type) {
173 OPENSSL_clear_free(hctx->raw_data.ktmp.data,
174 hctx->raw_data.ktmp.length);
177 EVP_MAC_CTX_free(hctx->ctx);
180 EVP_PKEY_CTX_set_data(ctx, NULL);
184 static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
186 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
187 int nid = ctx->pmeth->pkey_id;
189 switch (hctx->type) {
192 ASN1_OCTET_STRING *hkey = NULL;
194 if (!hctx->raw_data.ktmp.data)
196 hkey = ASN1_OCTET_STRING_dup(&hctx->raw_data.ktmp);
199 EVP_PKEY_assign(pkey, nid, hkey);
206 if (hctx->ctx == NULL) {
207 /* This actually means the fetch failed during the init call */
208 EVPerr(0, EVP_R_FETCH_FAILED);
212 cmkey = EVP_MAC_CTX_dup(hctx->ctx);
215 if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx)))
217 EVP_PKEY_assign(pkey, nid, cmkey);
221 /* This should be dead code */
228 static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
230 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
232 if (!EVP_MAC_update(hctx->ctx, data, count))
237 static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
239 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
240 ASN1_OCTET_STRING *key = NULL;
243 * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that
244 * gets the key passed as an ASN.1 OCTET STRING, we set the key here,
245 * as this may be only time it's set during a DigestSign.
247 * MACs that pass around the key in form of EVP_MAC_CTX are setting
248 * the key through other mechanisms. (this is only CMAC for now)
251 hctx->type == MAC_TYPE_RAW
252 && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
254 if (hctx->ctx == NULL) {
255 /* This actually means the fetch failed during the init call */
256 EVPerr(0, EVP_R_FETCH_FAILED);
261 if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx),
262 OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)))))
264 key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
269 EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
270 EVP_MD_CTX_set_update_fn(mctx, int_update);
272 /* Some MACs don't support this control... that's fine */
274 OSSL_PARAM params[3];
276 int flags = EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT);
278 /* TODO(3.0) "flags" isn't quite right, i.e. a quick hack for now */
280 OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &flags);
283 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
284 key->data, key->length);
285 params[params_n++] = OSSL_PARAM_construct_end();
286 rv = EVP_MAC_CTX_set_params(hctx->ctx, params);
291 static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
292 size_t *siglen, EVP_MD_CTX *mctx)
294 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
296 return EVP_MAC_final(hctx->ctx, sig, siglen, EVP_MAC_size(hctx->ctx));
299 static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
301 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
305 case EVP_PKEY_CTRL_CIPHER:
306 switch (hctx->type) {
308 return -2; /* The raw types don't support ciphers */
311 OSSL_PARAM params[3];
313 char *ciphname = (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2));
315 #ifndef OPENSSL_NO_ENGINE
316 if (ctx->engine != NULL) {
317 char *engid = (char *)ENGINE_get_id(ctx->engine);
320 OSSL_PARAM_construct_utf8_string("engine", engid, 0);
324 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
326 params[params_n] = OSSL_PARAM_construct_end();
328 if (hctx->ctx == NULL) {
330 * This actually means the fetch failed during the init call
332 EVPerr(0, EVP_R_FETCH_FAILED);
336 if (!EVP_MAC_CTX_set_params(hctx->ctx, params)
337 || !EVP_MAC_init(hctx->ctx))
342 /* This should be dead code */
347 case EVP_PKEY_CTRL_MD:
348 switch (hctx->type) {
350 hctx->raw_data.md = p2;
353 EVP_MAC_CTX *new_mac_ctx;
355 if (ctx->pkey == NULL)
357 new_mac_ctx = EVP_MAC_CTX_dup(ctx->pkey->pkey.ptr);
358 if (new_mac_ctx == NULL)
360 EVP_MAC_CTX_free(hctx->ctx);
361 hctx->ctx = new_mac_ctx;
365 /* This should be dead code */
370 case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
372 OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
373 size_t size = (size_t)p1;
377 * We verify that the length is actually set by getting back
378 * the same parameter and checking that it matches what we
380 * TODO(3.0) when we have a more direct mechanism to check if
381 * a parameter was used, we must refactor this to use that.
385 OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size);
387 if (hctx->ctx == NULL) {
389 * This actually means the fetch failed during the init call
391 EVPerr(0, EVP_R_FETCH_FAILED);
395 if (!EVP_MAC_CTX_set_params(hctx->ctx, params))
399 OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &verify);
401 if (!EVP_MAC_CTX_get_params(hctx->ctx, params))
405 * Since EVP_MAC_{get,set}_ctx_params() returned successfully,
406 * we can only assume that the size was ignored, i.e. this
407 * control is unsupported.
413 case EVP_PKEY_CTRL_SET_MAC_KEY:
414 switch (hctx->type) {
416 if ((!p2 && p1 > 0) || (p1 < -1))
418 if (!ASN1_OCTET_STRING_set(&hctx->raw_data.ktmp, p2, p1))
423 OSSL_PARAM params[2];
427 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
429 params[params_n] = OSSL_PARAM_construct_end();
431 if (hctx->ctx == NULL) {
433 * This actually means the fetch failed during the init call
435 EVPerr(0, EVP_R_FETCH_FAILED);
439 return EVP_MAC_CTX_set_params(hctx->ctx, params);
443 /* This should be dead code */
448 case EVP_PKEY_CTRL_DIGESTINIT:
449 switch (hctx->type) {
451 if (hctx->ctx == NULL) {
452 /* This actually means the fetch failed during the init call */
453 EVPerr(0, EVP_R_FETCH_FAILED);
457 /* Ensure that we have attached the implementation */
458 if (!EVP_MAC_init(hctx->ctx))
461 ASN1_OCTET_STRING *key =
462 (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
463 OSSL_PARAM params[4];
466 (char *)OBJ_nid2sn(EVP_MD_nid(hctx->raw_data.md));
468 #ifndef OPENSSL_NO_ENGINE
469 if (ctx->engine != NULL) {
470 char *engid = (char *)ENGINE_get_id(ctx->engine);
473 OSSL_PARAM_construct_utf8_string("engine", engid, 0);
477 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
480 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
481 key->data, key->length);
482 params[params_n] = OSSL_PARAM_construct_end();
484 return EVP_MAC_CTX_set_params(hctx->ctx, params);
488 return -2; /* The mac types don't support ciphers */
490 /* This should be dead code */
502 static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
503 const char *type, const char *value)
505 MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
507 OSSL_PARAM params[2];
511 EVPerr(0, EVP_R_NULL_MAC_PKEY_CTX);
514 if (hctx->ctx == NULL) {
515 /* This actually means the fetch failed during the init call */
516 EVPerr(0, EVP_R_FETCH_FAILED);
519 mac = EVP_MAC_CTX_mac(hctx->ctx);
522 * Translation of some control names that are equivalent to a single
525 * "md" and "digest" are the same thing, we use the single "digest"
527 * "digestsize" was a setting control in siphash, but naming wise,
528 * it's really the same as "size".
530 if (strcmp(type, "md") == 0)
531 type = OSSL_MAC_PARAM_DIGEST;
532 else if (strcmp(type, "digestsize") == 0)
533 type = OSSL_MAC_PARAM_SIZE;
535 if (!OSSL_PARAM_allocate_from_text(¶ms[0],
536 EVP_MAC_settable_ctx_params(mac),
537 type, value, strlen(value) + 1, NULL))
539 params[1] = OSSL_PARAM_construct_end();
541 ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
542 OPENSSL_free(params[0].data);
546 static const EVP_PKEY_METHOD cmac_pkey_meth = {
548 EVP_PKEY_FLAG_SIGCTX_CUSTOM,
564 pkey_mac_signctx_init,
579 const EVP_PKEY_METHOD *cmac_pkey_method(void)
581 return &cmac_pkey_meth;
584 static const EVP_PKEY_METHOD hmac_pkey_meth = {
602 pkey_mac_signctx_init,
617 const EVP_PKEY_METHOD *hmac_pkey_method(void)
619 return &hmac_pkey_meth;
622 static const EVP_PKEY_METHOD siphash_pkey_meth = {
624 EVP_PKEY_FLAG_SIGCTX_CUSTOM,
640 pkey_mac_signctx_init,
655 const EVP_PKEY_METHOD *siphash_pkey_method(void)
657 return &siphash_pkey_meth;
660 static const EVP_PKEY_METHOD poly1305_pkey_meth = {
662 EVP_PKEY_FLAG_SIGCTX_CUSTOM,
678 pkey_mac_signctx_init,
693 const EVP_PKEY_METHOD *poly1305_pkey_method(void)
695 return &poly1305_pkey_meth;