1 /* 2 * Copyright 2006-2025 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 void evp_asym_cipher_free(void *data) 21 { 22 EVP_ASYM_CIPHER_free(data); 23 } 24 25 static int evp_asym_cipher_up_ref(void *data) 26 { 27 return EVP_ASYM_CIPHER_up_ref(data); 28 } 29 30 static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation, 31 const OSSL_PARAM params[]) 32 { 33 int ret = 0; 34 void *provkey = NULL; 35 EVP_ASYM_CIPHER *cipher = NULL; 36 const char *desc; 37 EVP_KEYMGMT *tmp_keymgmt = NULL; 38 const OSSL_PROVIDER *tmp_prov = NULL; 39 const char *supported_ciph = NULL; 40 int iter; 41 42 if (ctx == NULL) { 43 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 44 return -2; 45 } 46 47 evp_pkey_ctx_free_old_ops(ctx); 48 ctx->operation = operation; 49 50 ERR_set_mark(); 51 52 if (evp_pkey_ctx_is_legacy(ctx)) 53 goto legacy; 54 55 if (ctx->pkey == NULL) { 56 ERR_clear_last_mark(); 57 ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET); 58 goto err; 59 } 60 61 /* 62 * Try to derive the supported asym cipher from |ctx->keymgmt|. 63 */ 64 if (!ossl_assert(ctx->pkey->keymgmt == NULL 65 || ctx->pkey->keymgmt == ctx->keymgmt)) { 66 ERR_clear_last_mark(); 67 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); 68 goto err; 69 } 70 supported_ciph 71 = evp_keymgmt_util_query_operation_name(ctx->keymgmt, 72 OSSL_OP_ASYM_CIPHER); 73 if (supported_ciph == NULL) { 74 ERR_clear_last_mark(); 75 ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); 76 goto err; 77 } 78 79 /* 80 * We perform two iterations: 81 * 82 * 1. Do the normal asym cipher fetch, using the fetching data given by 83 * the EVP_PKEY_CTX. 84 * 2. Do the provider specific asym cipher fetch, from the same provider 85 * as |ctx->keymgmt| 86 * 87 * We then try to fetch the keymgmt from the same provider as the 88 * asym cipher, and try to export |ctx->pkey| to that keymgmt (when 89 * this keymgmt happens to be the same as |ctx->keymgmt|, the export 90 * is a no-op, but we call it anyway to not complicate the code even 91 * more). 92 * If the export call succeeds (returns a non-NULL provider key pointer), 93 * we're done and can perform the operation itself. If not, we perform 94 * the second iteration, or jump to legacy. 95 */ 96 for (iter = 1, provkey = NULL; iter < 3 && provkey == NULL; iter++) { 97 EVP_KEYMGMT *tmp_keymgmt_tofree; 98 99 /* 100 * If we're on the second iteration, free the results from the first. 101 * They are NULL on the first iteration, so no need to check what 102 * iteration we're on. 103 */ 104 EVP_ASYM_CIPHER_free(cipher); 105 EVP_KEYMGMT_free(tmp_keymgmt); 106 107 switch (iter) { 108 case 1: 109 cipher = EVP_ASYM_CIPHER_fetch(ctx->libctx, supported_ciph, 110 ctx->propquery); 111 if (cipher != NULL) 112 tmp_prov = EVP_ASYM_CIPHER_get0_provider(cipher); 113 break; 114 case 2: 115 tmp_prov = EVP_KEYMGMT_get0_provider(ctx->keymgmt); 116 cipher = 117 evp_asym_cipher_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, 118 supported_ciph, ctx->propquery); 119 if (cipher == NULL) 120 goto legacy; 121 break; 122 } 123 if (cipher == NULL) 124 continue; 125 126 /* 127 * Ensure that the key is provided, either natively, or as a cached 128 * export. We start by fetching the keymgmt with the same name as 129 * |ctx->pkey|, but from the provider of the asym cipher method, using 130 * the same property query as when fetching the asym cipher method. 131 * With the keymgmt we found (if we did), we try to export |ctx->pkey| 132 * to it (evp_pkey_export_to_provider() is smart enough to only actually 133 * export it if |tmp_keymgmt| is different from |ctx->pkey|'s keymgmt) 134 */ 135 tmp_keymgmt_tofree = tmp_keymgmt 136 = evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, 137 EVP_KEYMGMT_get0_name(ctx->keymgmt), 138 ctx->propquery); 139 if (tmp_keymgmt != NULL) 140 provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx, 141 &tmp_keymgmt, ctx->propquery); 142 if (tmp_keymgmt == NULL) 143 EVP_KEYMGMT_free(tmp_keymgmt_tofree); 144 } 145 146 if (provkey == NULL) { 147 EVP_ASYM_CIPHER_free(cipher); 148 goto legacy; 149 } 150 151 ERR_pop_to_mark(); 152 153 /* No more legacy from here down to legacy: */ 154 155 ctx->op.ciph.cipher = cipher; 156 ctx->op.ciph.algctx = cipher->newctx(ossl_provider_ctx(cipher->prov)); 157 if (ctx->op.ciph.algctx == NULL) { 158 /* The provider key can stay in the cache */ 159 ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); 160 goto err; 161 } 162 163 desc = cipher->description != NULL ? cipher->description : ""; 164 switch (operation) { 165 case EVP_PKEY_OP_ENCRYPT: 166 if (cipher->encrypt_init == NULL) { 167 ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED, 168 "%s encrypt_init:%s", cipher->type_name, desc); 169 ret = -2; 170 goto err; 171 } 172 ret = cipher->encrypt_init(ctx->op.ciph.algctx, provkey, params); 173 break; 174 case EVP_PKEY_OP_DECRYPT: 175 if (cipher->decrypt_init == NULL) { 176 ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED, 177 "%s decrypt_init:%s", cipher->type_name, desc); 178 ret = -2; 179 goto err; 180 } 181 ret = cipher->decrypt_init(ctx->op.ciph.algctx, provkey, params); 182 break; 183 default: 184 ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); 185 goto err; 186 } 187 188 if (ret <= 0) 189 goto err; 190 EVP_KEYMGMT_free(tmp_keymgmt); 191 return 1; 192 193 legacy: 194 /* 195 * If we don't have the full support we need with provided methods, 196 * let's go see if legacy does. 197 */ 198 ERR_pop_to_mark(); 199 EVP_KEYMGMT_free(tmp_keymgmt); 200 tmp_keymgmt = NULL; 201 202 if (ctx->pmeth == NULL || ctx->pmeth->encrypt == NULL) { 203 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 204 return -2; 205 } 206 switch (ctx->operation) { 207 case EVP_PKEY_OP_ENCRYPT: 208 if (ctx->pmeth->encrypt_init == NULL) 209 return 1; 210 ret = ctx->pmeth->encrypt_init(ctx); 211 break; 212 case EVP_PKEY_OP_DECRYPT: 213 if (ctx->pmeth->decrypt_init == NULL) 214 return 1; 215 ret = ctx->pmeth->decrypt_init(ctx); 216 break; 217 default: 218 ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); 219 ret = -1; 220 } 221 222 err: 223 if (ret <= 0) { 224 evp_pkey_ctx_free_old_ops(ctx); 225 ctx->operation = EVP_PKEY_OP_UNDEFINED; 226 } 227 EVP_KEYMGMT_free(tmp_keymgmt); 228 return ret; 229 } 230 231 int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) 232 { 233 return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_ENCRYPT, NULL); 234 } 235 236 int EVP_PKEY_encrypt_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) 237 { 238 return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_ENCRYPT, params); 239 } 240 241 int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, 242 unsigned char *out, size_t *outlen, 243 const unsigned char *in, size_t inlen) 244 { 245 EVP_ASYM_CIPHER *cipher; 246 const char *desc; 247 int ret; 248 249 if (ctx == NULL) { 250 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 251 return -2; 252 } 253 254 if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { 255 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); 256 return -1; 257 } 258 259 if (ctx->op.ciph.algctx == NULL) 260 goto legacy; 261 262 cipher = ctx->op.ciph.cipher; 263 desc = cipher->description != NULL ? cipher->description : ""; 264 ret = cipher->encrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen); 265 if (ret <= 0) 266 ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE, 267 "%s encrypt:%s", cipher->type_name, desc); 268 return ret; 269 270 legacy: 271 if (ctx->pmeth == NULL || ctx->pmeth->encrypt == NULL) { 272 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 273 return -2; 274 } 275 M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT) 276 return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); 277 } 278 279 int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) 280 { 281 return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_DECRYPT, NULL); 282 } 283 284 int EVP_PKEY_decrypt_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) 285 { 286 return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_DECRYPT, params); 287 } 288 289 int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, 290 unsigned char *out, size_t *outlen, 291 const unsigned char *in, size_t inlen) 292 { 293 EVP_ASYM_CIPHER *cipher; 294 const char *desc; 295 int ret; 296 297 if (ctx == NULL) { 298 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 299 return -2; 300 } 301 302 if (ctx->operation != EVP_PKEY_OP_DECRYPT) { 303 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); 304 return -1; 305 } 306 307 if (ctx->op.ciph.algctx == NULL) 308 goto legacy; 309 310 cipher = ctx->op.ciph.cipher; 311 desc = cipher->description != NULL ? cipher->description : ""; 312 ret = cipher->decrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen); 313 if (ret <= 0) 314 ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE, 315 "%s decrypt:%s", cipher->type_name, desc); 316 317 return ret; 318 319 legacy: 320 if (ctx->pmeth == NULL || ctx->pmeth->decrypt == NULL) { 321 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 322 return -2; 323 } 324 M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) 325 return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); 326 } 327 328 /* decrypt to new buffer of dynamic size, checking any pre-determined size */ 329 int evp_pkey_decrypt_alloc(EVP_PKEY_CTX *ctx, unsigned char **outp, 330 size_t *outlenp, size_t expected_outlen, 331 const unsigned char *in, size_t inlen) 332 { 333 if (EVP_PKEY_decrypt(ctx, NULL, outlenp, in, inlen) <= 0 334 || (*outp = OPENSSL_malloc(*outlenp)) == NULL) 335 return -1; 336 if (EVP_PKEY_decrypt(ctx, *outp, outlenp, in, inlen) <= 0 337 || *outlenp == 0 338 || (expected_outlen != 0 && *outlenp != expected_outlen)) { 339 ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); 340 OPENSSL_clear_free(*outp, *outlenp); 341 *outp = NULL; 342 return 0; 343 } 344 return 1; 345 } 346 347 static EVP_ASYM_CIPHER *evp_asym_cipher_new(OSSL_PROVIDER *prov) 348 { 349 EVP_ASYM_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_ASYM_CIPHER)); 350 351 if (cipher == NULL) 352 return NULL; 353 354 if (!CRYPTO_NEW_REF(&cipher->refcnt, 1) 355 || !ossl_provider_up_ref(prov)) { 356 CRYPTO_FREE_REF(&cipher->refcnt); 357 OPENSSL_free(cipher); 358 return NULL; 359 } 360 cipher->prov = prov; 361 362 return cipher; 363 } 364 365 static void *evp_asym_cipher_from_algorithm(int name_id, 366 const OSSL_ALGORITHM *algodef, 367 OSSL_PROVIDER *prov) 368 { 369 const OSSL_DISPATCH *fns = algodef->implementation; 370 EVP_ASYM_CIPHER *cipher = NULL; 371 int ctxfncnt = 0, encfncnt = 0, decfncnt = 0; 372 int gparamfncnt = 0, sparamfncnt = 0; 373 374 if ((cipher = evp_asym_cipher_new(prov)) == NULL) { 375 ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); 376 goto err; 377 } 378 379 cipher->name_id = name_id; 380 if ((cipher->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) 381 goto err; 382 cipher->description = algodef->algorithm_description; 383 384 for (; fns->function_id != 0; fns++) { 385 switch (fns->function_id) { 386 case OSSL_FUNC_ASYM_CIPHER_NEWCTX: 387 if (cipher->newctx != NULL) 388 break; 389 cipher->newctx = OSSL_FUNC_asym_cipher_newctx(fns); 390 ctxfncnt++; 391 break; 392 case OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT: 393 if (cipher->encrypt_init != NULL) 394 break; 395 cipher->encrypt_init = OSSL_FUNC_asym_cipher_encrypt_init(fns); 396 encfncnt++; 397 break; 398 case OSSL_FUNC_ASYM_CIPHER_ENCRYPT: 399 if (cipher->encrypt != NULL) 400 break; 401 cipher->encrypt = OSSL_FUNC_asym_cipher_encrypt(fns); 402 encfncnt++; 403 break; 404 case OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT: 405 if (cipher->decrypt_init != NULL) 406 break; 407 cipher->decrypt_init = OSSL_FUNC_asym_cipher_decrypt_init(fns); 408 decfncnt++; 409 break; 410 case OSSL_FUNC_ASYM_CIPHER_DECRYPT: 411 if (cipher->decrypt != NULL) 412 break; 413 cipher->decrypt = OSSL_FUNC_asym_cipher_decrypt(fns); 414 decfncnt++; 415 break; 416 case OSSL_FUNC_ASYM_CIPHER_FREECTX: 417 if (cipher->freectx != NULL) 418 break; 419 cipher->freectx = OSSL_FUNC_asym_cipher_freectx(fns); 420 ctxfncnt++; 421 break; 422 case OSSL_FUNC_ASYM_CIPHER_DUPCTX: 423 if (cipher->dupctx != NULL) 424 break; 425 cipher->dupctx = OSSL_FUNC_asym_cipher_dupctx(fns); 426 break; 427 case OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS: 428 if (cipher->get_ctx_params != NULL) 429 break; 430 cipher->get_ctx_params 431 = OSSL_FUNC_asym_cipher_get_ctx_params(fns); 432 gparamfncnt++; 433 break; 434 case OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS: 435 if (cipher->gettable_ctx_params != NULL) 436 break; 437 cipher->gettable_ctx_params 438 = OSSL_FUNC_asym_cipher_gettable_ctx_params(fns); 439 gparamfncnt++; 440 break; 441 case OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS: 442 if (cipher->set_ctx_params != NULL) 443 break; 444 cipher->set_ctx_params 445 = OSSL_FUNC_asym_cipher_set_ctx_params(fns); 446 sparamfncnt++; 447 break; 448 case OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS: 449 if (cipher->settable_ctx_params != NULL) 450 break; 451 cipher->settable_ctx_params 452 = OSSL_FUNC_asym_cipher_settable_ctx_params(fns); 453 sparamfncnt++; 454 break; 455 } 456 } 457 if (ctxfncnt != 2 458 || (encfncnt != 0 && encfncnt != 2) 459 || (decfncnt != 0 && decfncnt != 2) 460 || (encfncnt != 2 && decfncnt != 2) 461 || (gparamfncnt != 0 && gparamfncnt != 2) 462 || (sparamfncnt != 0 && sparamfncnt != 2)) { 463 /* 464 * In order to be a consistent set of functions we must have at least 465 * a set of context functions (newctx and freectx) as well as a pair of 466 * "cipher" functions: (encrypt_init, encrypt) or 467 * (decrypt_init decrypt). set_ctx_params and settable_ctx_params are 468 * optional, but if one of them is present then the other one must also 469 * be present. The same applies to get_ctx_params and 470 * gettable_ctx_params. The dupctx function is optional. 471 */ 472 ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); 473 goto err; 474 } 475 476 return cipher; 477 err: 478 EVP_ASYM_CIPHER_free(cipher); 479 return NULL; 480 } 481 482 void EVP_ASYM_CIPHER_free(EVP_ASYM_CIPHER *cipher) 483 { 484 int i; 485 486 if (cipher == NULL) 487 return; 488 CRYPTO_DOWN_REF(&cipher->refcnt, &i); 489 if (i > 0) 490 return; 491 OPENSSL_free(cipher->type_name); 492 ossl_provider_free(cipher->prov); 493 CRYPTO_FREE_REF(&cipher->refcnt); 494 OPENSSL_free(cipher); 495 } 496 497 int EVP_ASYM_CIPHER_up_ref(EVP_ASYM_CIPHER *cipher) 498 { 499 int ref = 0; 500 501 CRYPTO_UP_REF(&cipher->refcnt, &ref); 502 return 1; 503 } 504 505 OSSL_PROVIDER *EVP_ASYM_CIPHER_get0_provider(const EVP_ASYM_CIPHER *cipher) 506 { 507 return cipher->prov; 508 } 509 510 EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, 511 const char *properties) 512 { 513 return evp_generic_fetch(ctx, OSSL_OP_ASYM_CIPHER, algorithm, properties, 514 evp_asym_cipher_from_algorithm, 515 evp_asym_cipher_up_ref, 516 evp_asym_cipher_free); 517 } 518 519 EVP_ASYM_CIPHER *evp_asym_cipher_fetch_from_prov(OSSL_PROVIDER *prov, 520 const char *algorithm, 521 const char *properties) 522 { 523 return evp_generic_fetch_from_prov(prov, OSSL_OP_ASYM_CIPHER, 524 algorithm, properties, 525 evp_asym_cipher_from_algorithm, 526 evp_asym_cipher_up_ref, 527 evp_asym_cipher_free); 528 } 529 530 int EVP_ASYM_CIPHER_is_a(const EVP_ASYM_CIPHER *cipher, const char *name) 531 { 532 return evp_is_a(cipher->prov, cipher->name_id, NULL, name); 533 } 534 535 int evp_asym_cipher_get_number(const EVP_ASYM_CIPHER *cipher) 536 { 537 return cipher->name_id; 538 } 539 540 const char *EVP_ASYM_CIPHER_get0_name(const EVP_ASYM_CIPHER *cipher) 541 { 542 return cipher->type_name; 543 } 544 545 const char *EVP_ASYM_CIPHER_get0_description(const EVP_ASYM_CIPHER *cipher) 546 { 547 return cipher->description; 548 } 549 550 void EVP_ASYM_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx, 551 void (*fn)(EVP_ASYM_CIPHER *cipher, 552 void *arg), 553 void *arg) 554 { 555 evp_generic_do_all(libctx, OSSL_OP_ASYM_CIPHER, 556 (void (*)(void *, void *))fn, arg, 557 evp_asym_cipher_from_algorithm, 558 evp_asym_cipher_up_ref, 559 evp_asym_cipher_free); 560 } 561 562 563 int EVP_ASYM_CIPHER_names_do_all(const EVP_ASYM_CIPHER *cipher, 564 void (*fn)(const char *name, void *data), 565 void *data) 566 { 567 if (cipher->prov != NULL) 568 return evp_names_do_all(cipher->prov, cipher->name_id, fn, data); 569 570 return 1; 571 } 572 573 const OSSL_PARAM *EVP_ASYM_CIPHER_gettable_ctx_params(const EVP_ASYM_CIPHER *cip) 574 { 575 void *provctx; 576 577 if (cip == NULL || cip->gettable_ctx_params == NULL) 578 return NULL; 579 580 provctx = ossl_provider_ctx(EVP_ASYM_CIPHER_get0_provider(cip)); 581 return cip->gettable_ctx_params(NULL, provctx); 582 } 583 584 const OSSL_PARAM *EVP_ASYM_CIPHER_settable_ctx_params(const EVP_ASYM_CIPHER *cip) 585 { 586 void *provctx; 587 588 if (cip == NULL || cip->settable_ctx_params == NULL) 589 return NULL; 590 591 provctx = ossl_provider_ctx(EVP_ASYM_CIPHER_get0_provider(cip)); 592 return cip->settable_ctx_params(NULL, provctx); 593 } 594