]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/evp/exchange.c
Convert all {NAME}err() in crypto/ to their corresponding ERR_raise() call
[thirdparty/openssl.git] / crypto / evp / exchange.c
1 /*
2 * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
3 *
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
8 */
9
10 #include <openssl/crypto.h>
11 #include <openssl/evp.h>
12 #include <openssl/err.h>
13 #include "internal/refcount.h"
14 #include "crypto/evp.h"
15 #include "internal/provider.h"
16 #include "internal/numbers.h" /* includes SIZE_MAX */
17 #include "evp_local.h"
18
19 static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov)
20 {
21 EVP_KEYEXCH *exchange = OPENSSL_zalloc(sizeof(EVP_KEYEXCH));
22
23 if (exchange == NULL) {
24 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
25 return NULL;
26 }
27
28 exchange->lock = CRYPTO_THREAD_lock_new();
29 if (exchange->lock == NULL) {
30 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
31 OPENSSL_free(exchange);
32 return NULL;
33 }
34 exchange->prov = prov;
35 ossl_provider_up_ref(prov);
36 exchange->refcnt = 1;
37
38 return exchange;
39 }
40
41 static void *evp_keyexch_from_dispatch(int name_id,
42 const OSSL_DISPATCH *fns,
43 OSSL_PROVIDER *prov)
44 {
45 EVP_KEYEXCH *exchange = NULL;
46 int fncnt = 0, sparamfncnt = 0, gparamfncnt = 0;
47
48 if ((exchange = evp_keyexch_new(prov)) == NULL) {
49 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
50 goto err;
51 }
52
53 exchange->name_id = name_id;
54
55 for (; fns->function_id != 0; fns++) {
56 switch (fns->function_id) {
57 case OSSL_FUNC_KEYEXCH_NEWCTX:
58 if (exchange->newctx != NULL)
59 break;
60 exchange->newctx = OSSL_FUNC_keyexch_newctx(fns);
61 fncnt++;
62 break;
63 case OSSL_FUNC_KEYEXCH_INIT:
64 if (exchange->init != NULL)
65 break;
66 exchange->init = OSSL_FUNC_keyexch_init(fns);
67 fncnt++;
68 break;
69 case OSSL_FUNC_KEYEXCH_SET_PEER:
70 if (exchange->set_peer != NULL)
71 break;
72 exchange->set_peer = OSSL_FUNC_keyexch_set_peer(fns);
73 break;
74 case OSSL_FUNC_KEYEXCH_DERIVE:
75 if (exchange->derive != NULL)
76 break;
77 exchange->derive = OSSL_FUNC_keyexch_derive(fns);
78 fncnt++;
79 break;
80 case OSSL_FUNC_KEYEXCH_FREECTX:
81 if (exchange->freectx != NULL)
82 break;
83 exchange->freectx = OSSL_FUNC_keyexch_freectx(fns);
84 fncnt++;
85 break;
86 case OSSL_FUNC_KEYEXCH_DUPCTX:
87 if (exchange->dupctx != NULL)
88 break;
89 exchange->dupctx = OSSL_FUNC_keyexch_dupctx(fns);
90 break;
91 case OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS:
92 if (exchange->get_ctx_params != NULL)
93 break;
94 exchange->get_ctx_params = OSSL_FUNC_keyexch_get_ctx_params(fns);
95 gparamfncnt++;
96 break;
97 case OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS:
98 if (exchange->gettable_ctx_params != NULL)
99 break;
100 exchange->gettable_ctx_params
101 = OSSL_FUNC_keyexch_gettable_ctx_params(fns);
102 gparamfncnt++;
103 break;
104 case OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS:
105 if (exchange->set_ctx_params != NULL)
106 break;
107 exchange->set_ctx_params = OSSL_FUNC_keyexch_set_ctx_params(fns);
108 sparamfncnt++;
109 break;
110 case OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS:
111 if (exchange->settable_ctx_params != NULL)
112 break;
113 exchange->settable_ctx_params
114 = OSSL_FUNC_keyexch_settable_ctx_params(fns);
115 sparamfncnt++;
116 break;
117 }
118 }
119 if (fncnt != 4
120 || (gparamfncnt != 0 && gparamfncnt != 2)
121 || (sparamfncnt != 0 && sparamfncnt != 2)) {
122 /*
123 * In order to be a consistent set of functions we must have at least
124 * a complete set of "exchange" functions: init, derive, newctx,
125 * and freectx. The set_ctx_params and settable_ctx_params functions are
126 * optional, but if one of them is present then the other one must also
127 * be present. Same goes for get_ctx_params and gettable_ctx_params.
128 * The dupctx and set_peer functions are optional.
129 */
130 ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
131 goto err;
132 }
133
134 return exchange;
135
136 err:
137 EVP_KEYEXCH_free(exchange);
138 return NULL;
139 }
140
141 void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange)
142 {
143 if (exchange != NULL) {
144 int i;
145
146 CRYPTO_DOWN_REF(&exchange->refcnt, &i, exchange->lock);
147 if (i > 0)
148 return;
149 ossl_provider_free(exchange->prov);
150 CRYPTO_THREAD_lock_free(exchange->lock);
151 OPENSSL_free(exchange);
152 }
153 }
154
155 int EVP_KEYEXCH_up_ref(EVP_KEYEXCH *exchange)
156 {
157 int ref = 0;
158
159 CRYPTO_UP_REF(&exchange->refcnt, &ref, exchange->lock);
160 return 1;
161 }
162
163 OSSL_PROVIDER *EVP_KEYEXCH_provider(const EVP_KEYEXCH *exchange)
164 {
165 return exchange->prov;
166 }
167
168 EVP_KEYEXCH *EVP_KEYEXCH_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
169 const char *properties)
170 {
171 return evp_generic_fetch(ctx, OSSL_OP_KEYEXCH, algorithm, properties,
172 evp_keyexch_from_dispatch,
173 (int (*)(void *))EVP_KEYEXCH_up_ref,
174 (void (*)(void *))EVP_KEYEXCH_free);
175 }
176
177 int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
178 {
179 int ret;
180 void *provkey = NULL;
181 EVP_KEYEXCH *exchange = NULL;
182 EVP_KEYMGMT *tmp_keymgmt = NULL;
183 const char *supported_exch = NULL;
184
185 if (ctx == NULL) {
186 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
187 return -2;
188 }
189
190 evp_pkey_ctx_free_old_ops(ctx);
191 ctx->operation = EVP_PKEY_OP_DERIVE;
192
193 /*
194 * TODO when we stop falling back to legacy, this and the ERR_pop_to_mark()
195 * calls can be removed.
196 */
197 ERR_set_mark();
198
199 if (evp_pkey_ctx_is_legacy(ctx))
200 goto legacy;
201
202 /*
203 * Ensure that the key is provided, either natively, or as a cached export.
204 * If not, goto legacy
205 */
206 tmp_keymgmt = ctx->keymgmt;
207 if (ctx->pkey == NULL) {
208 /*
209 * Some algorithms (e.g. legacy KDFs) don't have a pkey - so we create
210 * a blank one.
211 */
212 EVP_PKEY *pkey = EVP_PKEY_new();
213
214 if (pkey == NULL || !EVP_PKEY_set_type_by_keymgmt(pkey, tmp_keymgmt)) {
215 ERR_clear_last_mark();
216 EVP_PKEY_free(pkey);
217 ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
218 goto err;
219 }
220 provkey = pkey->keydata = evp_keymgmt_newdata(tmp_keymgmt);
221 if (provkey == NULL)
222 EVP_PKEY_free(pkey);
223 else
224 ctx->pkey = pkey;
225 } else {
226 provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx,
227 &tmp_keymgmt, ctx->propquery);
228 }
229 if (provkey == NULL)
230 goto legacy;
231 if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
232 ERR_clear_last_mark();
233 ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
234 goto err;
235 }
236 EVP_KEYMGMT_free(ctx->keymgmt);
237 ctx->keymgmt = tmp_keymgmt;
238
239 if (ctx->keymgmt->query_operation_name != NULL)
240 supported_exch = ctx->keymgmt->query_operation_name(OSSL_OP_KEYEXCH);
241
242 /*
243 * If we didn't get a supported exch, assume there is one with the
244 * same name as the key type.
245 */
246 if (supported_exch == NULL)
247 supported_exch = ctx->keytype;
248
249 /*
250 * Because we cleared out old ops, we shouldn't need to worry about
251 * checking if exchange is already there.
252 */
253 exchange = EVP_KEYEXCH_fetch(ctx->libctx, supported_exch, ctx->propquery);
254
255 if (exchange == NULL
256 || (EVP_KEYMGMT_provider(ctx->keymgmt)
257 != EVP_KEYEXCH_provider(exchange))) {
258 /*
259 * We don't need to free ctx->keymgmt here, as it's not necessarily
260 * tied to this operation. It will be freed by EVP_PKEY_CTX_free().
261 */
262 EVP_KEYEXCH_free(exchange);
263 goto legacy;
264 }
265
266 /*
267 * TODO remove this when legacy is gone
268 * If we don't have the full support we need with provided methods,
269 * let's go see if legacy does.
270 */
271 ERR_pop_to_mark();
272
273 /* No more legacy from here down to legacy: */
274
275 ctx->op.kex.exchange = exchange;
276 ctx->op.kex.exchprovctx = exchange->newctx(ossl_provider_ctx(exchange->prov));
277 if (ctx->op.kex.exchprovctx == NULL) {
278 /* The provider key can stay in the cache */
279 ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
280 goto err;
281 }
282 ret = exchange->init(ctx->op.kex.exchprovctx, provkey);
283
284 return ret ? 1 : 0;
285 err:
286 evp_pkey_ctx_free_old_ops(ctx);
287 ctx->operation = EVP_PKEY_OP_UNDEFINED;
288 return 0;
289
290 legacy:
291 /*
292 * TODO remove this when legacy is gone
293 * If we don't have the full support we need with provided methods,
294 * let's go see if legacy does.
295 */
296 ERR_pop_to_mark();
297
298 #ifdef FIPS_MODULE
299 return 0;
300 #else
301 if (ctx->pmeth == NULL || ctx->pmeth->derive == NULL) {
302 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
303 return -2;
304 }
305
306 if (ctx->pmeth->derive_init == NULL)
307 return 1;
308 ret = ctx->pmeth->derive_init(ctx);
309 if (ret <= 0)
310 ctx->operation = EVP_PKEY_OP_UNDEFINED;
311 return ret;
312 #endif
313 }
314
315 int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
316 {
317 int ret = 0;
318 void *provkey = NULL;
319
320 if (ctx == NULL) {
321 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
322 return -2;
323 }
324
325 if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx) || ctx->op.kex.exchprovctx == NULL)
326 goto legacy;
327
328 if (ctx->op.kex.exchange->set_peer == NULL) {
329 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
330 return -2;
331 }
332
333 provkey = evp_pkey_export_to_provider(peer, ctx->libctx, &ctx->keymgmt,
334 ctx->propquery);
335 /*
336 * If making the key provided wasn't possible, legacy may be able to pick
337 * it up
338 */
339 if (provkey == NULL)
340 goto legacy;
341 return ctx->op.kex.exchange->set_peer(ctx->op.kex.exchprovctx, provkey);
342
343 legacy:
344 #ifdef FIPS_MODULE
345 return ret;
346 #else
347 /*
348 * TODO(3.0) investigate the case where the operation is deemed legacy,
349 * but the given peer key is provider only.
350 */
351 if (ctx->pmeth == NULL
352 || !(ctx->pmeth->derive != NULL
353 || ctx->pmeth->encrypt != NULL
354 || ctx->pmeth->decrypt != NULL)
355 || ctx->pmeth->ctrl == NULL) {
356 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
357 return -2;
358 }
359 if (ctx->operation != EVP_PKEY_OP_DERIVE
360 && ctx->operation != EVP_PKEY_OP_ENCRYPT
361 && ctx->operation != EVP_PKEY_OP_DECRYPT) {
362 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATON_NOT_INITIALIZED);
363 return -1;
364 }
365
366 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
367
368 if (ret <= 0)
369 return ret;
370
371 if (ret == 2)
372 return 1;
373
374 if (ctx->pkey == NULL) {
375 ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET);
376 return -1;
377 }
378
379 if (ctx->pkey->type != peer->type) {
380 ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
381 return -1;
382 }
383
384 /*
385 * For clarity. The error is if parameters in peer are
386 * present (!missing) but don't match. EVP_PKEY_parameters_eq may return
387 * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1
388 * (different key types) is impossible here because it is checked earlier.
389 * -2 is OK for us here, as well as 1, so we can check for 0 only.
390 */
391 if (!EVP_PKEY_missing_parameters(peer) &&
392 !EVP_PKEY_parameters_eq(ctx->pkey, peer)) {
393 ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_PARAMETERS);
394 return -1;
395 }
396
397 EVP_PKEY_free(ctx->peerkey);
398 ctx->peerkey = peer;
399
400 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
401
402 if (ret <= 0) {
403 ctx->peerkey = NULL;
404 return ret;
405 }
406
407 EVP_PKEY_up_ref(peer);
408 return 1;
409 #endif
410 }
411
412 int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
413 {
414 int ret;
415
416 if (ctx == NULL) {
417 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
418 return -2;
419 }
420
421 if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
422 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATON_NOT_INITIALIZED);
423 return -1;
424 }
425
426 if (ctx->op.kex.exchprovctx == NULL)
427 goto legacy;
428
429 ret = ctx->op.kex.exchange->derive(ctx->op.kex.exchprovctx, key, pkeylen,
430 SIZE_MAX);
431
432 return ret;
433 legacy:
434 if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->derive == NULL) {
435 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
436 return -2;
437 }
438
439 M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
440 return ctx->pmeth->derive(ctx, key, pkeylen);
441 }
442
443 int EVP_KEYEXCH_number(const EVP_KEYEXCH *keyexch)
444 {
445 return keyexch->name_id;
446 }
447
448 int EVP_KEYEXCH_is_a(const EVP_KEYEXCH *keyexch, const char *name)
449 {
450 return evp_is_a(keyexch->prov, keyexch->name_id, NULL, name);
451 }
452
453 void EVP_KEYEXCH_do_all_provided(OSSL_LIB_CTX *libctx,
454 void (*fn)(EVP_KEYEXCH *keyexch, void *arg),
455 void *arg)
456 {
457 evp_generic_do_all(libctx, OSSL_OP_KEYEXCH,
458 (void (*)(void *, void *))fn, arg,
459 evp_keyexch_from_dispatch,
460 (void (*)(void *))EVP_KEYEXCH_free);
461 }
462
463 void EVP_KEYEXCH_names_do_all(const EVP_KEYEXCH *keyexch,
464 void (*fn)(const char *name, void *data),
465 void *data)
466 {
467 if (keyexch->prov != NULL)
468 evp_names_do_all(keyexch->prov, keyexch->name_id, fn, data);
469 }
470
471 const OSSL_PARAM *EVP_KEYEXCH_gettable_ctx_params(const EVP_KEYEXCH *keyexch)
472 {
473 void *provctx;
474
475 if (keyexch == NULL || keyexch->gettable_ctx_params == NULL)
476 return NULL;
477
478 provctx = ossl_provider_ctx(EVP_KEYEXCH_provider(keyexch));
479 return keyexch->gettable_ctx_params(provctx);
480 }
481
482 const OSSL_PARAM *EVP_KEYEXCH_settable_ctx_params(const EVP_KEYEXCH *keyexch)
483 {
484 void *provctx;
485
486 if (keyexch == NULL || keyexch->settable_ctx_params == NULL)
487 return NULL;
488 provctx = ossl_provider_ctx(EVP_KEYEXCH_provider(keyexch));
489 return keyexch->settable_ctx_params(provctx);
490 }