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
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 "internal/evp_int.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
;
54 EVP_MAC
*mac
= EVP_MAC_fetch(NULL
, OBJ_nid2sn(nid
), NULL
);
56 if ((hctx
= OPENSSL_zalloc(sizeof(*hctx
))) == NULL
) {
57 EVPerr(EVP_F_PKEY_MAC_INIT
, ERR_R_MALLOC_FAILURE
);
61 hctx
->ctx
= EVP_MAC_CTX_new(mac
);
62 if (hctx
->ctx
== NULL
) {
67 if (nid
== EVP_PKEY_CMAC
) {
68 hctx
->type
= MAC_TYPE_MAC
;
70 hctx
->type
= MAC_TYPE_RAW
;
71 hctx
->raw_data
.ktmp
.type
= V_ASN1_OCTET_STRING
;
74 pkey_mac_cleanup(ctx
);
75 EVP_PKEY_CTX_set_data(ctx
, hctx
);
76 ctx
->keygen_info_count
= 0;
81 static int pkey_mac_copy(EVP_PKEY_CTX
*dst
, const EVP_PKEY_CTX
*src
)
83 MAC_PKEY_CTX
*sctx
, *dctx
;
85 sctx
= EVP_PKEY_CTX_get_data(src
);
86 if (sctx
->ctx
->data
== NULL
)
89 dctx
= OPENSSL_zalloc(sizeof(*dctx
));
91 EVPerr(EVP_F_PKEY_MAC_COPY
, ERR_R_MALLOC_FAILURE
);
95 EVP_PKEY_CTX_set_data(dst
, dctx
);
96 dst
->keygen_info_count
= 0;
98 dctx
->ctx
= EVP_MAC_CTX_dup(sctx
->ctx
);
99 if (dctx
->ctx
== NULL
)
103 * Normally, nothing special would be done with the MAC method. In
104 * this particular case, though, the MAC method was fetched internally
105 * by pkey_mac_init() above or by EVP_PKEY_new_CMAC_key() and passed
106 * via the EVP_MAC_CTX, so it is effectively like every new EVP_MAC_CTX
107 * fetches the MAC method anew in this case. Therefore, its reference
108 * count must be adjusted here.
110 if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(dctx
->ctx
)))
113 dctx
->type
= sctx
->type
;
115 switch (dctx
->type
) {
117 dctx
->raw_data
.md
= sctx
->raw_data
.md
;
118 if (ASN1_STRING_get0_data(&sctx
->raw_data
.ktmp
) != NULL
&&
119 !ASN1_STRING_copy(&dctx
->raw_data
.ktmp
, &sctx
->raw_data
.ktmp
))
123 /* Nothing more to do */
126 /* This should be dead code */
131 pkey_mac_cleanup(dst
);
135 static void pkey_mac_cleanup(EVP_PKEY_CTX
*ctx
)
138 * For the exact same reasons the MAC reference count is incremented
139 * in pkey_mac_copy() above, it must be explicitly freed here.
142 MAC_PKEY_CTX
*hctx
= ctx
== NULL
? NULL
: EVP_PKEY_CTX_get_data(ctx
);
145 EVP_MAC
*mac
= EVP_MAC_CTX_mac(hctx
->ctx
);
147 switch (hctx
->type
) {
149 OPENSSL_clear_free(hctx
->raw_data
.ktmp
.data
,
150 hctx
->raw_data
.ktmp
.length
);
153 EVP_MAC_CTX_free(hctx
->ctx
);
156 EVP_PKEY_CTX_set_data(ctx
, NULL
);
160 static int pkey_mac_keygen(EVP_PKEY_CTX
*ctx
, EVP_PKEY
*pkey
)
162 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
163 int nid
= ctx
->pmeth
->pkey_id
;
165 switch (hctx
->type
) {
168 ASN1_OCTET_STRING
*hkey
= NULL
;
170 if (!hctx
->raw_data
.ktmp
.data
)
172 hkey
= ASN1_OCTET_STRING_dup(&hctx
->raw_data
.ktmp
);
175 EVP_PKEY_assign(pkey
, nid
, hkey
);
180 EVP_MAC_CTX
*cmkey
= EVP_MAC_CTX_dup(hctx
->ctx
);
184 if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx
->ctx
)))
186 EVP_PKEY_assign(pkey
, nid
, cmkey
);
190 /* This should be dead code */
197 static int int_update(EVP_MD_CTX
*ctx
, const void *data
, size_t count
)
199 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx
));
201 if (!EVP_MAC_update(hctx
->ctx
, data
, count
))
206 static int pkey_mac_signctx_init(EVP_PKEY_CTX
*ctx
, EVP_MD_CTX
*mctx
)
208 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
209 ASN1_OCTET_STRING
*key
= NULL
;
212 * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that
213 * gets the key passed as an ASN.1 OCTET STRING, we set the key here,
214 * as this may be only time it's set during a DigestSign.
216 * MACs that pass around the key in form of EVP_MAC_CTX are setting
217 * the key through other mechanisms. (this is only CMAC for now)
220 hctx
->type
== MAC_TYPE_RAW
221 && (ctx
->pmeth
->flags
& EVP_PKEY_FLAG_SIGCTX_CUSTOM
) != 0;
224 if (strcmp(OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx
))),
225 EVP_MAC_name(EVP_MAC_CTX_mac(hctx
->ctx
))) != 0)
227 key
= EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx
));
232 EVP_MD_CTX_set_flags(mctx
, EVP_MD_CTX_FLAG_NO_INIT
);
233 EVP_MD_CTX_set_update_fn(mctx
, int_update
);
235 /* Some MACs don't support this control... that's fine */
237 OSSL_PARAM params
[3];
239 int flags
= EVP_MD_CTX_test_flags(mctx
, ~EVP_MD_CTX_FLAG_NO_INIT
);
241 /* TODO(3.0) "flags" isn't quite right, i.e. a quick hack for now */
243 OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS
, &flags
);
246 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
247 key
->data
, key
->length
);
248 params
[params_n
++] = OSSL_PARAM_construct_end();
249 rv
= EVP_MAC_CTX_set_params(hctx
->ctx
, params
);
254 static int pkey_mac_signctx(EVP_PKEY_CTX
*ctx
, unsigned char *sig
,
255 size_t *siglen
, EVP_MD_CTX
*mctx
)
257 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
259 return EVP_MAC_final(hctx
->ctx
, sig
, siglen
, EVP_MAC_size(hctx
->ctx
));
262 static int pkey_mac_ctrl(EVP_PKEY_CTX
*ctx
, int type
, int p1
, void *p2
)
264 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
268 case EVP_PKEY_CTRL_CIPHER
:
269 switch (hctx
->type
) {
271 return -2; /* The raw types don't support ciphers */
274 OSSL_PARAM params
[3];
276 char *ciphname
= (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2
));
277 char *engineid
= (char *)ENGINE_get_id(ctx
->engine
);
280 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE
,
282 strlen(engineid
) + 1);
284 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM
,
286 strlen(ciphname
) + 1);
287 params
[params_n
] = OSSL_PARAM_construct_end();
289 if (!EVP_MAC_CTX_set_params(hctx
->ctx
, params
)
290 || !EVP_MAC_init(hctx
->ctx
))
295 /* This should be dead code */
300 case EVP_PKEY_CTRL_MD
:
301 switch (hctx
->type
) {
303 hctx
->raw_data
.md
= p2
;
306 EVP_MAC_CTX
*new_mac_ctx
;
308 if (ctx
->pkey
== NULL
)
310 new_mac_ctx
= EVP_MAC_CTX_dup((EVP_MAC_CTX
*)ctx
->pkey
312 if (new_mac_ctx
== NULL
)
314 EVP_MAC_CTX_free(hctx
->ctx
);
315 hctx
->ctx
= new_mac_ctx
;
319 /* This should be dead code */
324 case EVP_PKEY_CTRL_SET_DIGEST_SIZE
:
326 OSSL_PARAM params
[2] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
327 size_t size
= (size_t)p1
;
331 * We verify that the length is actually set by getting back
332 * the same parameter and checking that it matches what we
334 * TODO(3.0) when we have a more direct mechanism to check if
335 * a parameter was used, we must refactor this to use that.
339 OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_OUTLEN
, &size
);
341 if (!EVP_MAC_CTX_set_params(hctx
->ctx
, params
))
345 OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_OUTLEN
, &verify
);
347 if (!EVP_MAC_CTX_get_params(hctx
->ctx
, params
))
351 * Since EVP_MAC_CTX_{get,set}_params() returned successfully,
352 * we can only assume that the size was ignored, i.e. this
353 * control is unsupported.
359 case EVP_PKEY_CTRL_SET_MAC_KEY
:
360 switch (hctx
->type
) {
362 if ((!p2
&& p1
> 0) || (p1
< -1))
364 if (!ASN1_OCTET_STRING_set(&hctx
->raw_data
.ktmp
, p2
, p1
))
369 OSSL_PARAM params
[2];
373 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
375 params
[params_n
] = OSSL_PARAM_construct_end();
377 return EVP_MAC_CTX_set_params(hctx
->ctx
, params
);
381 /* This should be dead code */
386 case EVP_PKEY_CTRL_DIGESTINIT
:
387 switch (hctx
->type
) {
389 /* Ensure that we have attached the implementation */
390 if (!EVP_MAC_init(hctx
->ctx
))
393 ASN1_OCTET_STRING
*key
=
394 (ASN1_OCTET_STRING
*)ctx
->pkey
->pkey
.ptr
;
395 OSSL_PARAM params
[4];
398 (char *)OBJ_nid2sn(EVP_MD_nid(hctx
->raw_data
.md
));
399 char *engineid
= ctx
->engine
== NULL
400 ? NULL
: (char *)ENGINE_get_id(ctx
->engine
);
402 if (engineid
!= NULL
) {
403 size_t engineid_l
= strlen(engineid
) + 1;
405 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE
,
410 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM
,
414 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
415 key
->data
, key
->length
);
416 params
[params_n
] = OSSL_PARAM_construct_end();
418 return EVP_MAC_CTX_set_params(hctx
->ctx
, params
);
422 return -2; /* The mac types don't support ciphers */
424 /* This should be dead code */
436 static int pkey_mac_ctrl_str(EVP_PKEY_CTX
*ctx
,
437 const char *type
, const char *value
)
439 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
440 const EVP_MAC
*mac
= EVP_MAC_CTX_mac(hctx
->ctx
);
441 OSSL_PARAM params
[2];
444 if (!OSSL_PARAM_allocate_from_text(¶ms
[0],
445 EVP_MAC_CTX_settable_params(mac
),
446 type
, value
, strlen(value
) + 1))
448 params
[1] = OSSL_PARAM_construct_end();
449 ok
= EVP_MAC_CTX_set_params(hctx
->ctx
, params
);
450 OPENSSL_free(params
[0].data
);
454 const EVP_PKEY_METHOD cmac_pkey_meth
= {
456 EVP_PKEY_FLAG_SIGCTX_CUSTOM
,
472 pkey_mac_signctx_init
,
487 const EVP_PKEY_METHOD hmac_pkey_meth
= {
505 pkey_mac_signctx_init
,
520 const EVP_PKEY_METHOD siphash_pkey_meth
= {
522 EVP_PKEY_FLAG_SIGCTX_CUSTOM
,
538 pkey_mac_signctx_init
,
553 const EVP_PKEY_METHOD poly1305_pkey_meth
= {
555 EVP_PKEY_FLAG_SIGCTX_CUSTOM
,
571 pkey_mac_signctx_init
,