2 * Copyright 2019-2021 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 #include <openssl/crypto.h>
11 #include <openssl/evp.h>
12 #include <openssl/err.h>
13 #include "internal/refcount.h"
14 #include "internal/provider.h"
15 #include "internal/core.h"
16 #include "internal/numbers.h" /* includes SIZE_MAX */
17 #include "crypto/evp.h"
18 #include "evp_local.h"
20 static EVP_KEYEXCH
*evp_keyexch_new(OSSL_PROVIDER
*prov
)
22 EVP_KEYEXCH
*exchange
= OPENSSL_zalloc(sizeof(EVP_KEYEXCH
));
24 if (exchange
== NULL
) {
25 ERR_raise(ERR_LIB_EVP
, ERR_R_MALLOC_FAILURE
);
29 exchange
->lock
= CRYPTO_THREAD_lock_new();
30 if (exchange
->lock
== NULL
) {
31 ERR_raise(ERR_LIB_EVP
, ERR_R_MALLOC_FAILURE
);
32 OPENSSL_free(exchange
);
35 exchange
->prov
= prov
;
36 ossl_provider_up_ref(prov
);
42 static void *evp_keyexch_from_algorithm(int name_id
,
43 const OSSL_ALGORITHM
*algodef
,
46 const OSSL_DISPATCH
*fns
= algodef
->implementation
;
47 EVP_KEYEXCH
*exchange
= NULL
;
48 int fncnt
= 0, sparamfncnt
= 0, gparamfncnt
= 0;
50 if ((exchange
= evp_keyexch_new(prov
)) == NULL
) {
51 ERR_raise(ERR_LIB_EVP
, ERR_R_MALLOC_FAILURE
);
55 exchange
->name_id
= name_id
;
56 if ((exchange
->type_name
= ossl_algorithm_get1_first_name(algodef
)) == NULL
)
58 exchange
->description
= algodef
->algorithm_description
;
60 for (; fns
->function_id
!= 0; fns
++) {
61 switch (fns
->function_id
) {
62 case OSSL_FUNC_KEYEXCH_NEWCTX
:
63 if (exchange
->newctx
!= NULL
)
65 exchange
->newctx
= OSSL_FUNC_keyexch_newctx(fns
);
68 case OSSL_FUNC_KEYEXCH_INIT
:
69 if (exchange
->init
!= NULL
)
71 exchange
->init
= OSSL_FUNC_keyexch_init(fns
);
74 case OSSL_FUNC_KEYEXCH_SET_PEER
:
75 if (exchange
->set_peer
!= NULL
)
77 exchange
->set_peer
= OSSL_FUNC_keyexch_set_peer(fns
);
79 case OSSL_FUNC_KEYEXCH_DERIVE
:
80 if (exchange
->derive
!= NULL
)
82 exchange
->derive
= OSSL_FUNC_keyexch_derive(fns
);
85 case OSSL_FUNC_KEYEXCH_FREECTX
:
86 if (exchange
->freectx
!= NULL
)
88 exchange
->freectx
= OSSL_FUNC_keyexch_freectx(fns
);
91 case OSSL_FUNC_KEYEXCH_DUPCTX
:
92 if (exchange
->dupctx
!= NULL
)
94 exchange
->dupctx
= OSSL_FUNC_keyexch_dupctx(fns
);
96 case OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS
:
97 if (exchange
->get_ctx_params
!= NULL
)
99 exchange
->get_ctx_params
= OSSL_FUNC_keyexch_get_ctx_params(fns
);
102 case OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS
:
103 if (exchange
->gettable_ctx_params
!= NULL
)
105 exchange
->gettable_ctx_params
106 = OSSL_FUNC_keyexch_gettable_ctx_params(fns
);
109 case OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS
:
110 if (exchange
->set_ctx_params
!= NULL
)
112 exchange
->set_ctx_params
= OSSL_FUNC_keyexch_set_ctx_params(fns
);
115 case OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS
:
116 if (exchange
->settable_ctx_params
!= NULL
)
118 exchange
->settable_ctx_params
119 = OSSL_FUNC_keyexch_settable_ctx_params(fns
);
125 || (gparamfncnt
!= 0 && gparamfncnt
!= 2)
126 || (sparamfncnt
!= 0 && sparamfncnt
!= 2)) {
128 * In order to be a consistent set of functions we must have at least
129 * a complete set of "exchange" functions: init, derive, newctx,
130 * and freectx. The set_ctx_params and settable_ctx_params functions are
131 * optional, but if one of them is present then the other one must also
132 * be present. Same goes for get_ctx_params and gettable_ctx_params.
133 * The dupctx and set_peer functions are optional.
135 ERR_raise(ERR_LIB_EVP
, EVP_R_INVALID_PROVIDER_FUNCTIONS
);
142 EVP_KEYEXCH_free(exchange
);
146 void EVP_KEYEXCH_free(EVP_KEYEXCH
*exchange
)
150 if (exchange
== NULL
)
152 CRYPTO_DOWN_REF(&exchange
->refcnt
, &i
, exchange
->lock
);
155 OPENSSL_free(exchange
->type_name
);
156 ossl_provider_free(exchange
->prov
);
157 CRYPTO_THREAD_lock_free(exchange
->lock
);
158 OPENSSL_free(exchange
);
161 int EVP_KEYEXCH_up_ref(EVP_KEYEXCH
*exchange
)
165 CRYPTO_UP_REF(&exchange
->refcnt
, &ref
, exchange
->lock
);
169 OSSL_PROVIDER
*EVP_KEYEXCH_get0_provider(const EVP_KEYEXCH
*exchange
)
171 return exchange
->prov
;
174 EVP_KEYEXCH
*EVP_KEYEXCH_fetch(OSSL_LIB_CTX
*ctx
, const char *algorithm
,
175 const char *properties
)
177 return evp_generic_fetch(ctx
, OSSL_OP_KEYEXCH
, algorithm
, properties
,
178 evp_keyexch_from_algorithm
,
179 (int (*)(void *))EVP_KEYEXCH_up_ref
,
180 (void (*)(void *))EVP_KEYEXCH_free
);
183 int EVP_PKEY_derive_init(EVP_PKEY_CTX
*ctx
)
185 return EVP_PKEY_derive_init_ex(ctx
, NULL
);
188 int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX
*ctx
, const OSSL_PARAM params
[])
191 void *provkey
= NULL
;
192 EVP_KEYEXCH
*exchange
= NULL
;
193 EVP_KEYMGMT
*tmp_keymgmt
= NULL
;
194 const char *supported_exch
= NULL
;
197 ERR_raise(ERR_LIB_EVP
, ERR_R_PASSED_NULL_PARAMETER
);
201 evp_pkey_ctx_free_old_ops(ctx
);
202 ctx
->operation
= EVP_PKEY_OP_DERIVE
;
206 if (evp_pkey_ctx_is_legacy(ctx
))
210 * Ensure that the key is provided, either natively, or as a cached export.
211 * If not, goto legacy
213 tmp_keymgmt
= ctx
->keymgmt
;
214 if (ctx
->pkey
== NULL
) {
216 * Some algorithms (e.g. legacy KDFs) don't have a pkey - so we create
219 EVP_PKEY
*pkey
= EVP_PKEY_new();
221 if (pkey
== NULL
|| !EVP_PKEY_set_type_by_keymgmt(pkey
, tmp_keymgmt
)) {
222 ERR_clear_last_mark();
224 ERR_raise(ERR_LIB_EVP
, EVP_R_INITIALIZATION_ERROR
);
227 provkey
= pkey
->keydata
= evp_keymgmt_newdata(tmp_keymgmt
);
233 provkey
= evp_pkey_export_to_provider(ctx
->pkey
, ctx
->libctx
,
234 &tmp_keymgmt
, ctx
->propquery
);
238 if (!EVP_KEYMGMT_up_ref(tmp_keymgmt
)) {
239 ERR_clear_last_mark();
240 ERR_raise(ERR_LIB_EVP
, EVP_R_INITIALIZATION_ERROR
);
243 EVP_KEYMGMT_free(ctx
->keymgmt
);
244 ctx
->keymgmt
= tmp_keymgmt
;
246 if (ctx
->keymgmt
->query_operation_name
!= NULL
)
247 supported_exch
= ctx
->keymgmt
->query_operation_name(OSSL_OP_KEYEXCH
);
250 * If we didn't get a supported exch, assume there is one with the
251 * same name as the key type.
253 if (supported_exch
== NULL
)
254 supported_exch
= ctx
->keytype
;
257 * Because we cleared out old ops, we shouldn't need to worry about
258 * checking if exchange is already there.
260 exchange
= EVP_KEYEXCH_fetch(ctx
->libctx
, supported_exch
, ctx
->propquery
);
263 || (EVP_KEYMGMT_get0_provider(ctx
->keymgmt
)
264 != EVP_KEYEXCH_get0_provider(exchange
))) {
266 * We don't need to free ctx->keymgmt here, as it's not necessarily
267 * tied to this operation. It will be freed by EVP_PKEY_CTX_free().
269 EVP_KEYEXCH_free(exchange
);
274 * If we don't have the full support we need with provided methods,
275 * let's go see if legacy does.
279 /* No more legacy from here down to legacy: */
281 ctx
->op
.kex
.exchange
= exchange
;
282 ctx
->op
.kex
.algctx
= exchange
->newctx(ossl_provider_ctx(exchange
->prov
));
283 if (ctx
->op
.kex
.algctx
== NULL
) {
284 /* The provider key can stay in the cache */
285 ERR_raise(ERR_LIB_EVP
, EVP_R_INITIALIZATION_ERROR
);
288 ret
= exchange
->init(ctx
->op
.kex
.algctx
, provkey
, params
);
292 evp_pkey_ctx_free_old_ops(ctx
);
293 ctx
->operation
= EVP_PKEY_OP_UNDEFINED
;
298 * If we don't have the full support we need with provided methods,
299 * let's go see if legacy does.
306 if (ctx
->pmeth
== NULL
|| ctx
->pmeth
->derive
== NULL
) {
307 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
);
311 if (ctx
->pmeth
->derive_init
== NULL
)
313 ret
= ctx
->pmeth
->derive_init(ctx
);
315 ctx
->operation
= EVP_PKEY_OP_UNDEFINED
;
320 int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX
*ctx
, EVP_PKEY
*peer
,
324 void *provkey
= NULL
;
325 EVP_PKEY_CTX
*check_ctx
= NULL
;
328 ERR_raise(ERR_LIB_EVP
, ERR_R_PASSED_NULL_PARAMETER
);
332 if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx
) || ctx
->op
.kex
.algctx
== NULL
)
335 if (ctx
->op
.kex
.exchange
->set_peer
== NULL
) {
336 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
);
341 check_ctx
= EVP_PKEY_CTX_new_from_pkey(ctx
->libctx
, peer
, ctx
->propquery
);
342 if (check_ctx
== NULL
)
344 check
= EVP_PKEY_public_check(check_ctx
);
345 EVP_PKEY_CTX_free(check_ctx
);
350 provkey
= evp_pkey_export_to_provider(peer
, ctx
->libctx
, &ctx
->keymgmt
,
353 * If making the key provided wasn't possible, legacy may be able to pick
358 return ctx
->op
.kex
.exchange
->set_peer(ctx
->op
.kex
.algctx
, provkey
);
364 if (ctx
->pmeth
== NULL
365 || !(ctx
->pmeth
->derive
!= NULL
366 || ctx
->pmeth
->encrypt
!= NULL
367 || ctx
->pmeth
->decrypt
!= NULL
)
368 || ctx
->pmeth
->ctrl
== NULL
) {
369 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
);
372 if (ctx
->operation
!= EVP_PKEY_OP_DERIVE
373 && ctx
->operation
!= EVP_PKEY_OP_ENCRYPT
374 && ctx
->operation
!= EVP_PKEY_OP_DECRYPT
) {
375 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_INITIALIZED
);
379 ret
= ctx
->pmeth
->ctrl(ctx
, EVP_PKEY_CTRL_PEER_KEY
, 0, peer
);
387 if (ctx
->pkey
== NULL
) {
388 ERR_raise(ERR_LIB_EVP
, EVP_R_NO_KEY_SET
);
392 if (ctx
->pkey
->type
!= peer
->type
) {
393 ERR_raise(ERR_LIB_EVP
, EVP_R_DIFFERENT_KEY_TYPES
);
398 * For clarity. The error is if parameters in peer are
399 * present (!missing) but don't match. EVP_PKEY_parameters_eq may return
400 * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1
401 * (different key types) is impossible here because it is checked earlier.
402 * -2 is OK for us here, as well as 1, so we can check for 0 only.
404 if (!EVP_PKEY_missing_parameters(peer
) &&
405 !EVP_PKEY_parameters_eq(ctx
->pkey
, peer
)) {
406 ERR_raise(ERR_LIB_EVP
, EVP_R_DIFFERENT_PARAMETERS
);
410 EVP_PKEY_free(ctx
->peerkey
);
413 ret
= ctx
->pmeth
->ctrl(ctx
, EVP_PKEY_CTRL_PEER_KEY
, 1, peer
);
420 EVP_PKEY_up_ref(peer
);
425 int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX
*ctx
, EVP_PKEY
*peer
)
427 return EVP_PKEY_derive_set_peer_ex(ctx
, peer
, 1);
430 int EVP_PKEY_derive(EVP_PKEY_CTX
*ctx
, unsigned char *key
, size_t *pkeylen
)
434 if (ctx
== NULL
|| pkeylen
== NULL
) {
435 ERR_raise(ERR_LIB_EVP
, ERR_R_PASSED_NULL_PARAMETER
);
439 if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx
)) {
440 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_INITIALIZED
);
444 if (ctx
->op
.kex
.algctx
== NULL
)
447 ret
= ctx
->op
.kex
.exchange
->derive(ctx
->op
.kex
.algctx
, key
, pkeylen
,
448 key
!= NULL
? *pkeylen
: 0);
452 if (ctx
->pmeth
== NULL
|| ctx
->pmeth
->derive
== NULL
) {
453 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
);
457 M_check_autoarg(ctx
, key
, pkeylen
, EVP_F_EVP_PKEY_DERIVE
)
458 return ctx
->pmeth
->derive(ctx
, key
, pkeylen
);
461 int evp_keyexch_get_number(const EVP_KEYEXCH
*keyexch
)
463 return keyexch
->name_id
;
466 const char *EVP_KEYEXCH_get0_name(const EVP_KEYEXCH
*keyexch
)
468 return keyexch
->type_name
;
471 const char *EVP_KEYEXCH_get0_description(const EVP_KEYEXCH
*keyexch
)
473 return keyexch
->description
;
476 int EVP_KEYEXCH_is_a(const EVP_KEYEXCH
*keyexch
, const char *name
)
478 return evp_is_a(keyexch
->prov
, keyexch
->name_id
, NULL
, name
);
481 void EVP_KEYEXCH_do_all_provided(OSSL_LIB_CTX
*libctx
,
482 void (*fn
)(EVP_KEYEXCH
*keyexch
, void *arg
),
485 evp_generic_do_all(libctx
, OSSL_OP_KEYEXCH
,
486 (void (*)(void *, void *))fn
, arg
,
487 evp_keyexch_from_algorithm
,
488 (int (*)(void *))EVP_KEYEXCH_up_ref
,
489 (void (*)(void *))EVP_KEYEXCH_free
);
492 int EVP_KEYEXCH_names_do_all(const EVP_KEYEXCH
*keyexch
,
493 void (*fn
)(const char *name
, void *data
),
496 if (keyexch
->prov
!= NULL
)
497 return evp_names_do_all(keyexch
->prov
, keyexch
->name_id
, fn
, data
);
502 const OSSL_PARAM
*EVP_KEYEXCH_gettable_ctx_params(const EVP_KEYEXCH
*keyexch
)
506 if (keyexch
== NULL
|| keyexch
->gettable_ctx_params
== NULL
)
509 provctx
= ossl_provider_ctx(EVP_KEYEXCH_get0_provider(keyexch
));
510 return keyexch
->gettable_ctx_params(NULL
, provctx
);
513 const OSSL_PARAM
*EVP_KEYEXCH_settable_ctx_params(const EVP_KEYEXCH
*keyexch
)
517 if (keyexch
== NULL
|| keyexch
->settable_ctx_params
== NULL
)
519 provctx
= ossl_provider_ctx(EVP_KEYEXCH_get0_provider(keyexch
));
520 return keyexch
->settable_ctx_params(NULL
, provctx
);