2 * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (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"
14 /* MAC PKEY context structure */
20 * We know of two MAC types:
22 * 1. those who take a secret in raw form, i.e. raw data as a
23 * ASN1_OCTET_STRING embedded in a EVP_PKEY. So far, that's
24 * all of them but CMAC.
25 * 2. those who take a secret with associated cipher in very generic
26 * form, i.e. a complete EVP_MAC_CTX embedded in a PKEY. So far,
27 * only CMAC does this.
29 * (one might wonder why the second form isn't used for all)
31 #define MAC_TYPE_RAW 1 /* HMAC like MAC type (all but CMAC so far) */
32 #define MAC_TYPE_MAC 2 /* CMAC like MAC type (only CMAC known so far) */
35 /* The following is only used for MAC_TYPE_RAW implementations */
37 const EVP_MD
*md
; /* temp storage of MD */
38 ASN1_OCTET_STRING ktmp
; /* temp storage for key */
42 static int pkey_mac_init(EVP_PKEY_CTX
*ctx
)
45 int nid
= ctx
->pmeth
->pkey_id
;
47 if ((hctx
= OPENSSL_zalloc(sizeof(*hctx
))) == NULL
) {
48 EVPerr(EVP_F_PKEY_MAC_INIT
, ERR_R_MALLOC_FAILURE
);
52 /* We're being smart and using the same base NIDs for PKEY and for MAC */
53 hctx
->ctx
= EVP_MAC_CTX_new_id(nid
);
54 if (hctx
->ctx
== NULL
) {
59 if (nid
== EVP_PKEY_CMAC
) {
60 hctx
->type
= MAC_TYPE_MAC
;
62 hctx
->type
= MAC_TYPE_RAW
;
63 hctx
->raw_data
.ktmp
.type
= V_ASN1_OCTET_STRING
;
66 EVP_PKEY_CTX_set_data(ctx
, hctx
);
67 ctx
->keygen_info_count
= 0;
72 static void pkey_mac_cleanup(EVP_PKEY_CTX
*ctx
);
74 static int pkey_mac_copy(EVP_PKEY_CTX
*dst
, EVP_PKEY_CTX
*src
)
76 MAC_PKEY_CTX
*sctx
, *dctx
;
78 if (!pkey_mac_init(dst
))
81 sctx
= EVP_PKEY_CTX_get_data(src
);
82 dctx
= EVP_PKEY_CTX_get_data(dst
);
84 if (!EVP_MAC_CTX_copy(dctx
->ctx
, sctx
->ctx
))
89 dctx
->raw_data
.md
= sctx
->raw_data
.md
;
90 if (ASN1_STRING_get0_data(&sctx
->raw_data
.ktmp
) != NULL
&&
91 !ASN1_STRING_copy(&dctx
->raw_data
.ktmp
, &sctx
->raw_data
.ktmp
))
95 /* Nothing more to do */
98 /* This should be dead code */
103 pkey_mac_cleanup (dst
);
107 static void pkey_mac_cleanup(EVP_PKEY_CTX
*ctx
)
109 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
112 switch (hctx
->type
) {
114 OPENSSL_clear_free(hctx
->raw_data
.ktmp
.data
,
115 hctx
->raw_data
.ktmp
.length
);
118 EVP_MAC_CTX_free(hctx
->ctx
);
120 EVP_PKEY_CTX_set_data(ctx
, NULL
);
124 static int pkey_mac_keygen(EVP_PKEY_CTX
*ctx
, EVP_PKEY
*pkey
)
126 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
127 int nid
= ctx
->pmeth
->pkey_id
;
129 switch (hctx
->type
) {
132 ASN1_OCTET_STRING
*hkey
= NULL
;
134 if (!hctx
->raw_data
.ktmp
.data
)
136 hkey
= ASN1_OCTET_STRING_dup(&hctx
->raw_data
.ktmp
);
139 EVP_PKEY_assign(pkey
, nid
, hkey
);
144 EVP_MAC_CTX
*cmkey
= EVP_MAC_CTX_new_id(nid
);
148 if (!EVP_MAC_CTX_copy(cmkey
, hctx
->ctx
)) {
149 EVP_MAC_CTX_free(cmkey
);
152 EVP_PKEY_assign(pkey
, nid
, cmkey
);
156 /* This should be dead code */
163 static int int_update(EVP_MD_CTX
*ctx
, const void *data
, size_t count
)
165 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx
));
167 if (!EVP_MAC_update(hctx
->ctx
, data
, count
))
172 static int pkey_mac_signctx_init(EVP_PKEY_CTX
*ctx
, EVP_MD_CTX
*mctx
)
174 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
175 ASN1_OCTET_STRING
*key
= NULL
;
178 * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that
179 * gets the key passed as an ASN.1 OCTET STRING, we set the key here,
180 * as this may be only time it's set during a DigestSign.
182 * MACs that pass around the key in form of EVP_MAC_CTX are setting
183 * the key through other mechanisms. (this is only CMAC for now)
186 hctx
->type
== MAC_TYPE_RAW
187 && (ctx
->pmeth
->flags
& EVP_PKEY_FLAG_SIGCTX_CUSTOM
) != 0;
190 if (EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx
))
191 != EVP_MAC_nid(EVP_MAC_CTX_mac(hctx
->ctx
)))
193 key
= EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx
));
198 /* Some MACs don't support this control... that's fine */
199 EVP_MAC_ctrl(hctx
->ctx
, EVP_MAC_CTRL_SET_FLAGS
,
200 EVP_MD_CTX_test_flags(mctx
, ~EVP_MD_CTX_FLAG_NO_INIT
));
202 EVP_MD_CTX_set_flags(mctx
, EVP_MD_CTX_FLAG_NO_INIT
);
203 EVP_MD_CTX_set_update_fn(mctx
, int_update
);
206 rv
= EVP_MAC_ctrl(hctx
->ctx
, EVP_MAC_CTRL_SET_KEY
, key
->data
,
211 static int pkey_mac_signctx(EVP_PKEY_CTX
*ctx
, unsigned char *sig
,
212 size_t *siglen
, EVP_MD_CTX
*mctx
)
214 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
216 return EVP_MAC_final(hctx
->ctx
, sig
, siglen
);
219 static int pkey_mac_ctrl(EVP_PKEY_CTX
*ctx
, int type
, int p1
, void *p2
)
221 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
225 case EVP_PKEY_CTRL_CIPHER
:
226 switch (hctx
->type
) {
228 return -2; /* The raw types don't support ciphers */
233 if ((rv
= EVP_MAC_ctrl(hctx
->ctx
, EVP_MAC_CTRL_SET_ENGINE
,
235 || (rv
= EVP_MAC_ctrl(hctx
->ctx
, EVP_MAC_CTRL_SET_CIPHER
,
237 || !(rv
= EVP_MAC_init(hctx
->ctx
)))
242 /* This should be dead code */
247 case EVP_PKEY_CTRL_MD
:
248 switch (hctx
->type
) {
250 hctx
->raw_data
.md
= p2
;
253 if (ctx
->pkey
!= NULL
254 && !EVP_MAC_CTX_copy(hctx
->ctx
,
255 (EVP_MAC_CTX
*)ctx
->pkey
->pkey
.ptr
))
257 if (!EVP_MAC_init(hctx
->ctx
))
261 /* This should be dead code */
266 case EVP_PKEY_CTRL_SET_DIGEST_SIZE
:
267 return EVP_MAC_ctrl(hctx
->ctx
, EVP_MAC_CTRL_SET_SIZE
, (size_t)p1
);
269 case EVP_PKEY_CTRL_SET_MAC_KEY
:
270 switch (hctx
->type
) {
272 if ((!p2
&& p1
> 0) || (p1
< -1))
274 if (!ASN1_OCTET_STRING_set(&hctx
->raw_data
.ktmp
, p2
, p1
))
278 if (!EVP_MAC_ctrl(hctx
->ctx
, EVP_MAC_CTRL_SET_KEY
, p2
, p1
))
282 /* This should be dead code */
287 case EVP_PKEY_CTRL_DIGESTINIT
:
288 switch (hctx
->type
) {
290 /* Ensure that we have attached the implementation */
291 if (!EVP_MAC_init(hctx
->ctx
))
295 ASN1_OCTET_STRING
*key
=
296 (ASN1_OCTET_STRING
*)ctx
->pkey
->pkey
.ptr
;
298 if ((rv
= EVP_MAC_ctrl(hctx
->ctx
, EVP_MAC_CTRL_SET_ENGINE
,
300 || (rv
= EVP_MAC_ctrl(hctx
->ctx
, EVP_MAC_CTRL_SET_MD
,
301 hctx
->raw_data
.md
)) < 0
302 || (rv
= EVP_MAC_ctrl(hctx
->ctx
, EVP_MAC_CTRL_SET_KEY
,
303 key
->data
, key
->length
)) < 0)
308 return -2; /* The mac types don't support ciphers */
310 /* This should be dead code */
322 static int pkey_mac_ctrl_str(EVP_PKEY_CTX
*ctx
,
323 const char *type
, const char *value
)
325 MAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
327 return EVP_MAC_ctrl_str(hctx
->ctx
, type
, value
);
331 * When this is actually used, the following will be replaced with real
332 * EVP_PKEY_METHODs, all exactly the same apart from the type and possibly
336 extern const EVP_PKEY_METHOD FAKE_pkey_meth
;
337 const EVP_PKEY_METHOD FAKE_pkey_meth
= {
338 20870442 /* EVP_PKEY_FAKE, a beast times 31337 (you do the math) */,
339 EVP_PKEY_FLAG_SIGCTX_CUSTOM
,
355 pkey_mac_signctx_init
,