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_CTX_new(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_CTX_dup(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_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_CTX_mac(hctx
->ctx
) : NULL
;
168 switch (hctx
->type
) {
170 OPENSSL_clear_free(hctx
->raw_data
.ktmp
.data
,
171 hctx
->raw_data
.ktmp
.length
);
174 EVP_MAC_CTX_free(hctx
->ctx
);
177 EVP_PKEY_CTX_set_data(ctx
, NULL
);
181 static int pkey_mac_keygen(EVP_PKEY_CTX
*ctx
, EVP_PKEY
*pkey
)
183 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
184 int nid
= ctx
->pmeth
->pkey_id
;
186 switch (hctx
->type
) {
189 ASN1_OCTET_STRING
*hkey
= NULL
;
191 if (!hctx
->raw_data
.ktmp
.data
)
193 hkey
= ASN1_OCTET_STRING_dup(&hctx
->raw_data
.ktmp
);
196 EVP_PKEY_assign(pkey
, nid
, hkey
);
203 if (hctx
->ctx
== NULL
) {
204 /* This actually means the fetch failed during the init call */
205 EVPerr(0, EVP_R_FETCH_FAILED
);
209 cmkey
= EVP_MAC_CTX_dup(hctx
->ctx
);
212 if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx
->ctx
)))
214 EVP_PKEY_assign(pkey
, nid
, cmkey
);
218 /* This should be dead code */
225 static int int_update(EVP_MD_CTX
*ctx
, const void *data
, size_t count
)
227 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx
));
229 if (!EVP_MAC_update(hctx
->ctx
, data
, count
))
234 static int pkey_mac_signctx_init(EVP_PKEY_CTX
*ctx
, EVP_MD_CTX
*mctx
)
236 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
237 ASN1_OCTET_STRING
*key
= NULL
;
240 * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that
241 * gets the key passed as an ASN.1 OCTET STRING, we set the key here,
242 * as this may be only time it's set during a DigestSign.
244 * MACs that pass around the key in form of EVP_MAC_CTX are setting
245 * the key through other mechanisms. (this is only CMAC for now)
248 hctx
->type
== MAC_TYPE_RAW
249 && (ctx
->pmeth
->flags
& EVP_PKEY_FLAG_SIGCTX_CUSTOM
) != 0;
251 if (hctx
->ctx
== NULL
) {
252 /* This actually means the fetch failed during the init call */
253 EVPerr(0, EVP_R_FETCH_FAILED
);
258 if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx
->ctx
),
259 OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx
)))))
261 key
= EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx
));
266 EVP_MD_CTX_set_flags(mctx
, EVP_MD_CTX_FLAG_NO_INIT
);
267 EVP_MD_CTX_set_update_fn(mctx
, int_update
);
269 /* Some MACs don't support this control... that's fine */
271 OSSL_PARAM params
[3];
273 int flags
= EVP_MD_CTX_test_flags(mctx
, ~EVP_MD_CTX_FLAG_NO_INIT
);
275 /* TODO(3.0) "flags" isn't quite right, i.e. a quick hack for now */
277 OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS
, &flags
);
280 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
281 key
->data
, key
->length
);
282 params
[params_n
++] = OSSL_PARAM_construct_end();
283 rv
= EVP_MAC_CTX_set_params(hctx
->ctx
, params
);
288 static int pkey_mac_signctx(EVP_PKEY_CTX
*ctx
, unsigned char *sig
,
289 size_t *siglen
, EVP_MD_CTX
*mctx
)
291 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
293 return EVP_MAC_final(hctx
->ctx
, sig
, siglen
, EVP_MAC_size(hctx
->ctx
));
296 static int pkey_mac_ctrl(EVP_PKEY_CTX
*ctx
, int type
, int p1
, void *p2
)
298 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
302 case EVP_PKEY_CTRL_CIPHER
:
303 switch (hctx
->type
) {
305 return -2; /* The raw types don't support ciphers */
308 OSSL_PARAM params
[3];
310 char *ciphname
= (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2
));
312 #ifndef OPENSSL_NO_ENGINE
313 if (ctx
->engine
!= NULL
) {
314 char *engid
= (char *)ENGINE_get_id(ctx
->engine
);
317 OSSL_PARAM_construct_utf8_string("engine", engid
, 0);
321 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER
,
323 params
[params_n
] = OSSL_PARAM_construct_end();
325 if (hctx
->ctx
== NULL
) {
327 * This actually means the fetch failed during the init call
329 EVPerr(0, EVP_R_FETCH_FAILED
);
333 if (!EVP_MAC_CTX_set_params(hctx
->ctx
, params
)
334 || !EVP_MAC_init(hctx
->ctx
))
339 /* This should be dead code */
344 case EVP_PKEY_CTRL_MD
:
345 switch (hctx
->type
) {
347 hctx
->raw_data
.md
= p2
;
350 EVP_MAC_CTX
*new_mac_ctx
;
352 if (ctx
->pkey
== NULL
)
354 new_mac_ctx
= EVP_MAC_CTX_dup(ctx
->pkey
->pkey
.ptr
);
355 if (new_mac_ctx
== NULL
)
357 EVP_MAC_CTX_free(hctx
->ctx
);
358 hctx
->ctx
= new_mac_ctx
;
362 /* This should be dead code */
367 case EVP_PKEY_CTRL_SET_DIGEST_SIZE
:
369 OSSL_PARAM params
[2] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
370 size_t size
= (size_t)p1
;
374 * We verify that the length is actually set by getting back
375 * the same parameter and checking that it matches what we
377 * TODO(3.0) when we have a more direct mechanism to check if
378 * a parameter was used, we must refactor this to use that.
382 OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE
, &size
);
384 if (hctx
->ctx
== NULL
) {
386 * This actually means the fetch failed during the init call
388 EVPerr(0, EVP_R_FETCH_FAILED
);
392 if (!EVP_MAC_CTX_set_params(hctx
->ctx
, params
))
396 OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE
, &verify
);
398 if (!EVP_MAC_CTX_get_params(hctx
->ctx
, params
))
402 * Since EVP_MAC_CTX_{get,set}_params() returned successfully,
403 * we can only assume that the size was ignored, i.e. this
404 * control is unsupported.
410 case EVP_PKEY_CTRL_SET_MAC_KEY
:
411 switch (hctx
->type
) {
413 if ((!p2
&& p1
> 0) || (p1
< -1))
415 if (!ASN1_OCTET_STRING_set(&hctx
->raw_data
.ktmp
, p2
, p1
))
420 OSSL_PARAM params
[2];
424 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
426 params
[params_n
] = OSSL_PARAM_construct_end();
428 if (hctx
->ctx
== NULL
) {
430 * This actually means the fetch failed during the init call
432 EVPerr(0, EVP_R_FETCH_FAILED
);
436 return EVP_MAC_CTX_set_params(hctx
->ctx
, params
);
440 /* This should be dead code */
445 case EVP_PKEY_CTRL_DIGESTINIT
:
446 switch (hctx
->type
) {
448 if (hctx
->ctx
== NULL
) {
449 /* This actually means the fetch failed during the init call */
450 EVPerr(0, EVP_R_FETCH_FAILED
);
454 /* Ensure that we have attached the implementation */
455 if (!EVP_MAC_init(hctx
->ctx
))
458 ASN1_OCTET_STRING
*key
=
459 (ASN1_OCTET_STRING
*)ctx
->pkey
->pkey
.ptr
;
460 OSSL_PARAM params
[4];
463 (char *)OBJ_nid2sn(EVP_MD_nid(hctx
->raw_data
.md
));
465 #ifndef OPENSSL_NO_ENGINE
466 if (ctx
->engine
!= NULL
) {
467 char *engid
= (char *)ENGINE_get_id(ctx
->engine
);
470 OSSL_PARAM_construct_utf8_string("engine", engid
, 0);
474 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST
,
477 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
478 key
->data
, key
->length
);
479 params
[params_n
] = OSSL_PARAM_construct_end();
481 return EVP_MAC_CTX_set_params(hctx
->ctx
, params
);
485 return -2; /* The mac types don't support ciphers */
487 /* This should be dead code */
499 static int pkey_mac_ctrl_str(EVP_PKEY_CTX
*ctx
,
500 const char *type
, const char *value
)
502 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
504 OSSL_PARAM params
[2];
508 EVPerr(0, EVP_R_NULL_MAC_PKEY_CTX
);
511 if (hctx
->ctx
== NULL
) {
512 /* This actually means the fetch failed during the init call */
513 EVPerr(0, EVP_R_FETCH_FAILED
);
516 mac
= EVP_MAC_CTX_mac(hctx
->ctx
);
519 * Translation of some control names that are equivalent to a single
522 * "md" and "digest" are the same thing, we use the single "digest"
524 * "digestsize" was a setting control in siphash, but naming wise,
525 * it's really the same as "size".
527 if (strcmp(type
, "md") == 0)
528 type
= OSSL_MAC_PARAM_DIGEST
;
529 else if (strcmp(type
, "digestsize") == 0)
530 type
= OSSL_MAC_PARAM_SIZE
;
532 if (!OSSL_PARAM_allocate_from_text(¶ms
[0],
533 EVP_MAC_settable_ctx_params(mac
),
534 type
, value
, strlen(value
) + 1, NULL
))
536 params
[1] = OSSL_PARAM_construct_end();
538 ok
= EVP_MAC_CTX_set_params(hctx
->ctx
, params
);
539 OPENSSL_free(params
[0].data
);
543 static const EVP_PKEY_METHOD cmac_pkey_meth
= {
545 EVP_PKEY_FLAG_SIGCTX_CUSTOM
,
561 pkey_mac_signctx_init
,
576 const EVP_PKEY_METHOD
*cmac_pkey_method(void)
578 return &cmac_pkey_meth
;
581 static const EVP_PKEY_METHOD hmac_pkey_meth
= {
599 pkey_mac_signctx_init
,
614 const EVP_PKEY_METHOD
*hmac_pkey_method(void)
616 return &hmac_pkey_meth
;
619 static const EVP_PKEY_METHOD siphash_pkey_meth
= {
621 EVP_PKEY_FLAG_SIGCTX_CUSTOM
,
637 pkey_mac_signctx_init
,
652 const EVP_PKEY_METHOD
*siphash_pkey_method(void)
654 return &siphash_pkey_meth
;
657 static const EVP_PKEY_METHOD poly1305_pkey_meth
= {
659 EVP_PKEY_FLAG_SIGCTX_CUSTOM
,
675 pkey_mac_signctx_init
,
690 const EVP_PKEY_METHOD
*poly1305_pkey_method(void)
692 return &poly1305_pkey_meth
;