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