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,