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_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
;
205 * TODO when we stop falling back to legacy, this and the ERR_pop_to_mark()
206 * calls can be removed.
210 if (evp_pkey_ctx_is_legacy(ctx
))
214 * Ensure that the key is provided, either natively, or as a cached export.
215 * If not, goto legacy
217 tmp_keymgmt
= ctx
->keymgmt
;
218 if (ctx
->pkey
== NULL
) {
220 * Some algorithms (e.g. legacy KDFs) don't have a pkey - so we create
223 EVP_PKEY
*pkey
= EVP_PKEY_new();
225 if (pkey
== NULL
|| !EVP_PKEY_set_type_by_keymgmt(pkey
, tmp_keymgmt
)) {
226 ERR_clear_last_mark();
228 ERR_raise(ERR_LIB_EVP
, EVP_R_INITIALIZATION_ERROR
);
231 provkey
= pkey
->keydata
= evp_keymgmt_newdata(tmp_keymgmt
);
237 provkey
= evp_pkey_export_to_provider(ctx
->pkey
, ctx
->libctx
,
238 &tmp_keymgmt
, ctx
->propquery
);
242 if (!EVP_KEYMGMT_up_ref(tmp_keymgmt
)) {
243 ERR_clear_last_mark();
244 ERR_raise(ERR_LIB_EVP
, EVP_R_INITIALIZATION_ERROR
);
247 EVP_KEYMGMT_free(ctx
->keymgmt
);
248 ctx
->keymgmt
= tmp_keymgmt
;
250 if (ctx
->keymgmt
->query_operation_name
!= NULL
)
251 supported_exch
= ctx
->keymgmt
->query_operation_name(OSSL_OP_KEYEXCH
);
254 * If we didn't get a supported exch, assume there is one with the
255 * same name as the key type.
257 if (supported_exch
== NULL
)
258 supported_exch
= ctx
->keytype
;
261 * Because we cleared out old ops, we shouldn't need to worry about
262 * checking if exchange is already there.
264 exchange
= EVP_KEYEXCH_fetch(ctx
->libctx
, supported_exch
, ctx
->propquery
);
267 || (EVP_KEYMGMT_provider(ctx
->keymgmt
)
268 != EVP_KEYEXCH_provider(exchange
))) {
270 * We don't need to free ctx->keymgmt here, as it's not necessarily
271 * tied to this operation. It will be freed by EVP_PKEY_CTX_free().
273 EVP_KEYEXCH_free(exchange
);
278 * TODO remove this when legacy is gone
279 * If we don't have the full support we need with provided methods,
280 * let's go see if legacy does.
284 /* No more legacy from here down to legacy: */
286 ctx
->op
.kex
.exchange
= exchange
;
287 ctx
->op
.kex
.algctx
= exchange
->newctx(ossl_provider_ctx(exchange
->prov
));
288 if (ctx
->op
.kex
.algctx
== NULL
) {
289 /* The provider key can stay in the cache */
290 ERR_raise(ERR_LIB_EVP
, EVP_R_INITIALIZATION_ERROR
);
293 ret
= exchange
->init(ctx
->op
.kex
.algctx
, provkey
, params
);
297 evp_pkey_ctx_free_old_ops(ctx
);
298 ctx
->operation
= EVP_PKEY_OP_UNDEFINED
;
303 * TODO remove this when legacy is gone
304 * If we don't have the full support we need with provided methods,
305 * let's go see if legacy does.
312 if (ctx
->pmeth
== NULL
|| ctx
->pmeth
->derive
== NULL
) {
313 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
);
317 if (ctx
->pmeth
->derive_init
== NULL
)
319 ret
= ctx
->pmeth
->derive_init(ctx
);
321 ctx
->operation
= EVP_PKEY_OP_UNDEFINED
;
326 int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX
*ctx
, EVP_PKEY
*peer
,
330 void *provkey
= NULL
;
331 EVP_PKEY_CTX
*check_ctx
= NULL
;
334 ERR_raise(ERR_LIB_EVP
, ERR_R_PASSED_NULL_PARAMETER
);
338 if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx
) || ctx
->op
.kex
.algctx
== NULL
)
341 if (ctx
->op
.kex
.exchange
->set_peer
== NULL
) {
342 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
);
347 check_ctx
= EVP_PKEY_CTX_new_from_pkey(ctx
->libctx
, peer
, ctx
->propquery
);
348 if (check_ctx
== NULL
)
350 check
= EVP_PKEY_public_check(check_ctx
);
351 EVP_PKEY_CTX_free(check_ctx
);
356 provkey
= evp_pkey_export_to_provider(peer
, ctx
->libctx
, &ctx
->keymgmt
,
359 * If making the key provided wasn't possible, legacy may be able to pick
364 return ctx
->op
.kex
.exchange
->set_peer(ctx
->op
.kex
.algctx
, provkey
);
370 if (ctx
->pmeth
== NULL
371 || !(ctx
->pmeth
->derive
!= NULL
372 || ctx
->pmeth
->encrypt
!= NULL
373 || ctx
->pmeth
->decrypt
!= NULL
)
374 || ctx
->pmeth
->ctrl
== NULL
) {
375 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
);
378 if (ctx
->operation
!= EVP_PKEY_OP_DERIVE
379 && ctx
->operation
!= EVP_PKEY_OP_ENCRYPT
380 && ctx
->operation
!= EVP_PKEY_OP_DECRYPT
) {
381 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_INITIALIZED
);
385 ret
= ctx
->pmeth
->ctrl(ctx
, EVP_PKEY_CTRL_PEER_KEY
, 0, peer
);
393 if (ctx
->pkey
== NULL
) {
394 ERR_raise(ERR_LIB_EVP
, EVP_R_NO_KEY_SET
);
398 if (ctx
->pkey
->type
!= peer
->type
) {
399 ERR_raise(ERR_LIB_EVP
, EVP_R_DIFFERENT_KEY_TYPES
);
404 * For clarity. The error is if parameters in peer are
405 * present (!missing) but don't match. EVP_PKEY_parameters_eq may return
406 * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1
407 * (different key types) is impossible here because it is checked earlier.
408 * -2 is OK for us here, as well as 1, so we can check for 0 only.
410 if (!EVP_PKEY_missing_parameters(peer
) &&
411 !EVP_PKEY_parameters_eq(ctx
->pkey
, peer
)) {
412 ERR_raise(ERR_LIB_EVP
, EVP_R_DIFFERENT_PARAMETERS
);
416 EVP_PKEY_free(ctx
->peerkey
);
419 ret
= ctx
->pmeth
->ctrl(ctx
, EVP_PKEY_CTRL_PEER_KEY
, 1, peer
);
426 EVP_PKEY_up_ref(peer
);
431 int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX
*ctx
, EVP_PKEY
*peer
)
433 return EVP_PKEY_derive_set_peer_ex(ctx
, peer
, 1);
436 int EVP_PKEY_derive(EVP_PKEY_CTX
*ctx
, unsigned char *key
, size_t *pkeylen
)
440 if (ctx
== NULL
|| pkeylen
== NULL
) {
441 ERR_raise(ERR_LIB_EVP
, ERR_R_PASSED_NULL_PARAMETER
);
445 if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx
)) {
446 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_INITIALIZED
);
450 if (ctx
->op
.kex
.algctx
== NULL
)
453 ret
= ctx
->op
.kex
.exchange
->derive(ctx
->op
.kex
.algctx
, key
, pkeylen
,
454 key
!= NULL
? *pkeylen
: 0);
458 if (ctx
->pmeth
== NULL
|| ctx
->pmeth
->derive
== NULL
) {
459 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
);
463 M_check_autoarg(ctx
, key
, pkeylen
, EVP_F_EVP_PKEY_DERIVE
)
464 return ctx
->pmeth
->derive(ctx
, key
, pkeylen
);
467 int EVP_KEYEXCH_number(const EVP_KEYEXCH
*keyexch
)
469 return keyexch
->name_id
;
472 const char *EVP_KEYEXCH_name(const EVP_KEYEXCH
*keyexch
)
474 return keyexch
->type_name
;
477 const char *EVP_KEYEXCH_description(const EVP_KEYEXCH
*keyexch
)
479 return keyexch
->description
;
482 int EVP_KEYEXCH_is_a(const EVP_KEYEXCH
*keyexch
, const char *name
)
484 return evp_is_a(keyexch
->prov
, keyexch
->name_id
, NULL
, name
);
487 void EVP_KEYEXCH_do_all_provided(OSSL_LIB_CTX
*libctx
,
488 void (*fn
)(EVP_KEYEXCH
*keyexch
, void *arg
),
491 evp_generic_do_all(libctx
, OSSL_OP_KEYEXCH
,
492 (void (*)(void *, void *))fn
, arg
,
493 evp_keyexch_from_algorithm
,
494 (void (*)(void *))EVP_KEYEXCH_free
);
497 int EVP_KEYEXCH_names_do_all(const EVP_KEYEXCH
*keyexch
,
498 void (*fn
)(const char *name
, void *data
),
501 if (keyexch
->prov
!= NULL
)
502 return evp_names_do_all(keyexch
->prov
, keyexch
->name_id
, fn
, data
);
507 const OSSL_PARAM
*EVP_KEYEXCH_gettable_ctx_params(const EVP_KEYEXCH
*keyexch
)
511 if (keyexch
== NULL
|| keyexch
->gettable_ctx_params
== NULL
)
514 provctx
= ossl_provider_ctx(EVP_KEYEXCH_provider(keyexch
));
515 return keyexch
->gettable_ctx_params(NULL
, provctx
);
518 const OSSL_PARAM
*EVP_KEYEXCH_settable_ctx_params(const EVP_KEYEXCH
*keyexch
)
522 if (keyexch
== NULL
|| keyexch
->settable_ctx_params
== NULL
)
524 provctx
= ossl_provider_ctx(EVP_KEYEXCH_provider(keyexch
));
525 return keyexch
->settable_ctx_params(NULL
, provctx
);