]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/evp/asymcipher.c
Rename the field 'provctx and data' to 'algctx' inside some objects containing
[thirdparty/openssl.git] / crypto / evp / asymcipher.c
1 /*
2 * Copyright 2006-2021 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 <stdio.h>
11 #include <stdlib.h>
12 #include <openssl/objects.h>
13 #include <openssl/evp.h>
14 #include "internal/cryptlib.h"
15 #include "internal/provider.h"
16 #include "internal/core.h"
17 #include "crypto/evp.h"
18 #include "evp_local.h"
19
20 static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation,
21 const OSSL_PARAM params[])
22 {
23 int ret = 0;
24 void *provkey = NULL;
25 EVP_ASYM_CIPHER *cipher = NULL;
26 EVP_KEYMGMT *tmp_keymgmt = NULL;
27 const char *supported_ciph = NULL;
28
29 if (ctx == NULL) {
30 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
31 return -2;
32 }
33
34 evp_pkey_ctx_free_old_ops(ctx);
35 ctx->operation = operation;
36
37 /*
38 * TODO when we stop falling back to legacy, this and the ERR_pop_to_mark()
39 * calls can be removed.
40 */
41 ERR_set_mark();
42
43 if (evp_pkey_ctx_is_legacy(ctx))
44 goto legacy;
45
46 /*
47 * Ensure that the key is provided, either natively, or as a cached export.
48 * If not, go legacy
49 */
50 tmp_keymgmt = ctx->keymgmt;
51 provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx,
52 &tmp_keymgmt, ctx->propquery);
53 if (provkey == NULL)
54 goto legacy;
55 if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
56 ERR_clear_last_mark();
57 ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
58 goto err;
59 }
60 EVP_KEYMGMT_free(ctx->keymgmt);
61 ctx->keymgmt = tmp_keymgmt;
62
63 if (ctx->keymgmt->query_operation_name != NULL)
64 supported_ciph =
65 ctx->keymgmt->query_operation_name(OSSL_OP_ASYM_CIPHER);
66
67 /*
68 * If we didn't get a supported ciph, assume there is one with the
69 * same name as the key type.
70 */
71 if (supported_ciph == NULL)
72 supported_ciph = ctx->keytype;
73
74 /*
75 * Because we cleared out old ops, we shouldn't need to worry about
76 * checking if cipher is already there.
77 */
78 cipher =
79 EVP_ASYM_CIPHER_fetch(ctx->libctx, supported_ciph, ctx->propquery);
80
81 if (cipher == NULL
82 || (EVP_KEYMGMT_provider(ctx->keymgmt)
83 != EVP_ASYM_CIPHER_provider(cipher))) {
84 /*
85 * We don't need to free ctx->keymgmt here, as it's not necessarily
86 * tied to this operation. It will be freed by EVP_PKEY_CTX_free().
87 */
88 EVP_ASYM_CIPHER_free(cipher);
89 goto legacy;
90 }
91
92 /*
93 * TODO remove this when legacy is gone
94 * If we don't have the full support we need with provided methods,
95 * let's go see if legacy does.
96 */
97 ERR_pop_to_mark();
98
99 /* No more legacy from here down to legacy: */
100
101 ctx->op.ciph.cipher = cipher;
102 ctx->op.ciph.algctx = cipher->newctx(ossl_provider_ctx(cipher->prov));
103 if (ctx->op.ciph.algctx == NULL) {
104 /* The provider key can stay in the cache */
105 ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
106 goto err;
107 }
108
109 switch (operation) {
110 case EVP_PKEY_OP_ENCRYPT:
111 if (cipher->encrypt_init == NULL) {
112 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
113 ret = -2;
114 goto err;
115 }
116 ret = cipher->encrypt_init(ctx->op.ciph.algctx, provkey, params);
117 break;
118 case EVP_PKEY_OP_DECRYPT:
119 if (cipher->decrypt_init == NULL) {
120 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
121 ret = -2;
122 goto err;
123 }
124 ret = cipher->decrypt_init(ctx->op.ciph.algctx, provkey, params);
125 break;
126 default:
127 ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
128 goto err;
129 }
130
131 if (ret <= 0)
132 goto err;
133 return 1;
134
135 legacy:
136 /*
137 * TODO remove this when legacy is gone
138 * If we don't have the full support we need with provided methods,
139 * let's go see if legacy does.
140 */
141 ERR_pop_to_mark();
142
143 if (ctx->pmeth == NULL || ctx->pmeth->encrypt == NULL) {
144 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
145 return -2;
146 }
147 switch(ctx->operation) {
148 case EVP_PKEY_OP_ENCRYPT:
149 if (ctx->pmeth->encrypt_init == NULL)
150 return 1;
151 ret = ctx->pmeth->encrypt_init(ctx);
152 break;
153 case EVP_PKEY_OP_DECRYPT:
154 if (ctx->pmeth->decrypt_init == NULL)
155 return 1;
156 ret = ctx->pmeth->decrypt_init(ctx);
157 break;
158 default:
159 ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
160 ret = -1;
161 }
162
163 err:
164 if (ret <= 0) {
165 evp_pkey_ctx_free_old_ops(ctx);
166 ctx->operation = EVP_PKEY_OP_UNDEFINED;
167 }
168 return ret;
169 }
170
171 int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
172 {
173 return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_ENCRYPT, NULL);
174 }
175
176 int EVP_PKEY_encrypt_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[])
177 {
178 return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_ENCRYPT, params);
179 }
180
181 int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
182 unsigned char *out, size_t *outlen,
183 const unsigned char *in, size_t inlen)
184 {
185 int ret;
186
187 if (ctx == NULL) {
188 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
189 return -2;
190 }
191
192 if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
193 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED);
194 return -1;
195 }
196
197 if (ctx->op.ciph.algctx == NULL)
198 goto legacy;
199
200 ret = ctx->op.ciph.cipher->encrypt(ctx->op.ciph.algctx, out, outlen,
201 (out == NULL ? 0 : *outlen), in, inlen);
202 return ret;
203
204 legacy:
205 if (ctx->pmeth == NULL || ctx->pmeth->encrypt == NULL) {
206 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
207 return -2;
208 }
209 M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
210 return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
211 }
212
213 int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
214 {
215 return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_DECRYPT, NULL);
216 }
217
218 int EVP_PKEY_decrypt_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[])
219 {
220 return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_DECRYPT, params);
221 }
222
223 int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
224 unsigned char *out, size_t *outlen,
225 const unsigned char *in, size_t inlen)
226 {
227 int ret;
228
229 if (ctx == NULL) {
230 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
231 return -2;
232 }
233
234 if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
235 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED);
236 return -1;
237 }
238
239 if (ctx->op.ciph.algctx == NULL)
240 goto legacy;
241
242 ret = ctx->op.ciph.cipher->decrypt(ctx->op.ciph.algctx, out, outlen,
243 (out == NULL ? 0 : *outlen), in, inlen);
244 return ret;
245
246 legacy:
247 if (ctx->pmeth == NULL || ctx->pmeth->decrypt == NULL) {
248 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
249 return -2;
250 }
251 M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
252 return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
253 }
254
255
256 static EVP_ASYM_CIPHER *evp_asym_cipher_new(OSSL_PROVIDER *prov)
257 {
258 EVP_ASYM_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_ASYM_CIPHER));
259
260 if (cipher == NULL) {
261 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
262 return NULL;
263 }
264
265 cipher->lock = CRYPTO_THREAD_lock_new();
266 if (cipher->lock == NULL) {
267 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
268 OPENSSL_free(cipher);
269 return NULL;
270 }
271 cipher->prov = prov;
272 ossl_provider_up_ref(prov);
273 cipher->refcnt = 1;
274
275 return cipher;
276 }
277
278 static void *evp_asym_cipher_from_algorithm(int name_id,
279 const OSSL_ALGORITHM *algodef,
280 OSSL_PROVIDER *prov)
281 {
282 const OSSL_DISPATCH *fns = algodef->implementation;
283 EVP_ASYM_CIPHER *cipher = NULL;
284 int ctxfncnt = 0, encfncnt = 0, decfncnt = 0;
285 int gparamfncnt = 0, sparamfncnt = 0;
286
287 if ((cipher = evp_asym_cipher_new(prov)) == NULL) {
288 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
289 goto err;
290 }
291
292 cipher->name_id = name_id;
293 if ((cipher->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
294 goto err;
295 cipher->description = algodef->algorithm_description;
296
297 for (; fns->function_id != 0; fns++) {
298 switch (fns->function_id) {
299 case OSSL_FUNC_ASYM_CIPHER_NEWCTX:
300 if (cipher->newctx != NULL)
301 break;
302 cipher->newctx = OSSL_FUNC_asym_cipher_newctx(fns);
303 ctxfncnt++;
304 break;
305 case OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT:
306 if (cipher->encrypt_init != NULL)
307 break;
308 cipher->encrypt_init = OSSL_FUNC_asym_cipher_encrypt_init(fns);
309 encfncnt++;
310 break;
311 case OSSL_FUNC_ASYM_CIPHER_ENCRYPT:
312 if (cipher->encrypt != NULL)
313 break;
314 cipher->encrypt = OSSL_FUNC_asym_cipher_encrypt(fns);
315 encfncnt++;
316 break;
317 case OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT:
318 if (cipher->decrypt_init != NULL)
319 break;
320 cipher->decrypt_init = OSSL_FUNC_asym_cipher_decrypt_init(fns);
321 decfncnt++;
322 break;
323 case OSSL_FUNC_ASYM_CIPHER_DECRYPT:
324 if (cipher->decrypt != NULL)
325 break;
326 cipher->decrypt = OSSL_FUNC_asym_cipher_decrypt(fns);
327 decfncnt++;
328 break;
329 case OSSL_FUNC_ASYM_CIPHER_FREECTX:
330 if (cipher->freectx != NULL)
331 break;
332 cipher->freectx = OSSL_FUNC_asym_cipher_freectx(fns);
333 ctxfncnt++;
334 break;
335 case OSSL_FUNC_ASYM_CIPHER_DUPCTX:
336 if (cipher->dupctx != NULL)
337 break;
338 cipher->dupctx = OSSL_FUNC_asym_cipher_dupctx(fns);
339 break;
340 case OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS:
341 if (cipher->get_ctx_params != NULL)
342 break;
343 cipher->get_ctx_params
344 = OSSL_FUNC_asym_cipher_get_ctx_params(fns);
345 gparamfncnt++;
346 break;
347 case OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS:
348 if (cipher->gettable_ctx_params != NULL)
349 break;
350 cipher->gettable_ctx_params
351 = OSSL_FUNC_asym_cipher_gettable_ctx_params(fns);
352 gparamfncnt++;
353 break;
354 case OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS:
355 if (cipher->set_ctx_params != NULL)
356 break;
357 cipher->set_ctx_params
358 = OSSL_FUNC_asym_cipher_set_ctx_params(fns);
359 sparamfncnt++;
360 break;
361 case OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS:
362 if (cipher->settable_ctx_params != NULL)
363 break;
364 cipher->settable_ctx_params
365 = OSSL_FUNC_asym_cipher_settable_ctx_params(fns);
366 sparamfncnt++;
367 break;
368 }
369 }
370 if (ctxfncnt != 2
371 || (encfncnt != 0 && encfncnt != 2)
372 || (decfncnt != 0 && decfncnt != 2)
373 || (encfncnt != 2 && decfncnt != 2)
374 || (gparamfncnt != 0 && gparamfncnt != 2)
375 || (sparamfncnt != 0 && sparamfncnt != 2)) {
376 /*
377 * In order to be a consistent set of functions we must have at least
378 * a set of context functions (newctx and freectx) as well as a pair of
379 * "cipher" functions: (encrypt_init, encrypt) or
380 * (decrypt_init decrypt). set_ctx_params and settable_ctx_params are
381 * optional, but if one of them is present then the other one must also
382 * be present. The same applies to get_ctx_params and
383 * gettable_ctx_params. The dupctx function is optional.
384 */
385 ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
386 goto err;
387 }
388
389 return cipher;
390 err:
391 EVP_ASYM_CIPHER_free(cipher);
392 return NULL;
393 }
394
395 void EVP_ASYM_CIPHER_free(EVP_ASYM_CIPHER *cipher)
396 {
397 int i;
398
399 if (cipher == NULL)
400 return;
401 CRYPTO_DOWN_REF(&cipher->refcnt, &i, cipher->lock);
402 if (i > 0)
403 return;
404 OPENSSL_free(cipher->type_name);
405 ossl_provider_free(cipher->prov);
406 CRYPTO_THREAD_lock_free(cipher->lock);
407 OPENSSL_free(cipher);
408 }
409
410 int EVP_ASYM_CIPHER_up_ref(EVP_ASYM_CIPHER *cipher)
411 {
412 int ref = 0;
413
414 CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock);
415 return 1;
416 }
417
418 OSSL_PROVIDER *EVP_ASYM_CIPHER_provider(const EVP_ASYM_CIPHER *cipher)
419 {
420 return cipher->prov;
421 }
422
423 EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
424 const char *properties)
425 {
426 return evp_generic_fetch(ctx, OSSL_OP_ASYM_CIPHER, algorithm, properties,
427 evp_asym_cipher_from_algorithm,
428 (int (*)(void *))EVP_ASYM_CIPHER_up_ref,
429 (void (*)(void *))EVP_ASYM_CIPHER_free);
430 }
431
432 int EVP_ASYM_CIPHER_is_a(const EVP_ASYM_CIPHER *cipher, const char *name)
433 {
434 return evp_is_a(cipher->prov, cipher->name_id, NULL, name);
435 }
436
437 int EVP_ASYM_CIPHER_number(const EVP_ASYM_CIPHER *cipher)
438 {
439 return cipher->name_id;
440 }
441
442 const char *EVP_ASYM_CIPHER_name(const EVP_ASYM_CIPHER *cipher)
443 {
444 return cipher->type_name;
445 }
446
447 const char *EVP_ASYM_CIPHER_description(const EVP_ASYM_CIPHER *cipher)
448 {
449 return cipher->description;
450 }
451
452 void EVP_ASYM_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx,
453 void (*fn)(EVP_ASYM_CIPHER *cipher,
454 void *arg),
455 void *arg)
456 {
457 evp_generic_do_all(libctx, OSSL_OP_ASYM_CIPHER,
458 (void (*)(void *, void *))fn, arg,
459 evp_asym_cipher_from_algorithm,
460 (void (*)(void *))EVP_ASYM_CIPHER_free);
461 }
462
463
464 int EVP_ASYM_CIPHER_names_do_all(const EVP_ASYM_CIPHER *cipher,
465 void (*fn)(const char *name, void *data),
466 void *data)
467 {
468 if (cipher->prov != NULL)
469 return evp_names_do_all(cipher->prov, cipher->name_id, fn, data);
470
471 return 1;
472 }
473
474 const OSSL_PARAM *EVP_ASYM_CIPHER_gettable_ctx_params(const EVP_ASYM_CIPHER *cip)
475 {
476 void *provctx;
477
478 if (cip == NULL || cip->gettable_ctx_params == NULL)
479 return NULL;
480
481 provctx = ossl_provider_ctx(EVP_ASYM_CIPHER_provider(cip));
482 return cip->gettable_ctx_params(NULL, provctx);
483 }
484
485 const OSSL_PARAM *EVP_ASYM_CIPHER_settable_ctx_params(const EVP_ASYM_CIPHER *cip)
486 {
487 void *provctx;
488
489 if (cip == NULL || cip->settable_ctx_params == NULL)
490 return NULL;
491
492 provctx = ossl_provider_ctx(EVP_ASYM_CIPHER_provider(cip));
493 return cip->settable_ctx_params(NULL, provctx);
494 }