1 /* 2 * Copyright 2019-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 <openssl/crypto.h> 11 #include <openssl/core_dispatch.h> 12 #include <openssl/evp.h> 13 #include <openssl/err.h> 14 #include "internal/provider.h" 15 #include "internal/refcount.h" 16 #include "internal/core.h" 17 #include "crypto/evp.h" 18 #include "evp_local.h" 19 20 static void evp_keymgmt_free(void *data) 21 { 22 EVP_KEYMGMT_free(data); 23 } 24 25 static int evp_keymgmt_up_ref(void *data) 26 { 27 return EVP_KEYMGMT_up_ref(data); 28 } 29 30 static void *keymgmt_new(void) 31 { 32 EVP_KEYMGMT *keymgmt = NULL; 33 34 if ((keymgmt = OPENSSL_zalloc(sizeof(*keymgmt))) == NULL) 35 return NULL; 36 if (!CRYPTO_NEW_REF(&keymgmt->refcnt, 1)) { 37 EVP_KEYMGMT_free(keymgmt); 38 return NULL; 39 } 40 return keymgmt; 41 } 42 43 #ifndef FIPS_MODULE 44 static void help_get_legacy_alg_type_from_keymgmt(const char *keytype, 45 void *arg) 46 { 47 int *type = arg; 48 49 if (*type == NID_undef) 50 *type = evp_pkey_name2type(keytype); 51 } 52 53 static int get_legacy_alg_type_from_keymgmt(const EVP_KEYMGMT *keymgmt) 54 { 55 int type = NID_undef; 56 57 EVP_KEYMGMT_names_do_all(keymgmt, help_get_legacy_alg_type_from_keymgmt, 58 &type); 59 return type; 60 } 61 #endif 62 63 static void *keymgmt_from_algorithm(int name_id, 64 const OSSL_ALGORITHM *algodef, 65 OSSL_PROVIDER *prov) 66 { 67 const OSSL_DISPATCH *fns = algodef->implementation; 68 EVP_KEYMGMT *keymgmt = NULL; 69 int setparamfncnt = 0, getparamfncnt = 0; 70 int setgenparamfncnt = 0; 71 int importfncnt = 0, exportfncnt = 0; 72 int importtypesfncnt = 0, exporttypesfncnt = 0; 73 int getgenparamfncnt = 0; 74 75 if ((keymgmt = keymgmt_new()) == NULL) 76 return NULL; 77 78 keymgmt->name_id = name_id; 79 if ((keymgmt->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { 80 EVP_KEYMGMT_free(keymgmt); 81 return NULL; 82 } 83 keymgmt->description = algodef->algorithm_description; 84 85 for (; fns->function_id != 0; fns++) { 86 switch (fns->function_id) { 87 case OSSL_FUNC_KEYMGMT_NEW: 88 if (keymgmt->new == NULL) 89 keymgmt->new = OSSL_FUNC_keymgmt_new(fns); 90 break; 91 case OSSL_FUNC_KEYMGMT_GEN_INIT: 92 if (keymgmt->gen_init == NULL) 93 keymgmt->gen_init = OSSL_FUNC_keymgmt_gen_init(fns); 94 break; 95 case OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE: 96 if (keymgmt->gen_set_template == NULL) 97 keymgmt->gen_set_template = OSSL_FUNC_keymgmt_gen_set_template(fns); 98 break; 99 case OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS: 100 if (keymgmt->gen_set_params == NULL) { 101 setgenparamfncnt++; 102 keymgmt->gen_set_params = OSSL_FUNC_keymgmt_gen_set_params(fns); 103 } 104 break; 105 case OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS: 106 if (keymgmt->gen_settable_params == NULL) { 107 setgenparamfncnt++; 108 keymgmt->gen_settable_params = OSSL_FUNC_keymgmt_gen_settable_params(fns); 109 } 110 break; 111 case OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS: 112 if (keymgmt->gen_get_params == NULL) { 113 getgenparamfncnt++; 114 keymgmt->gen_get_params = OSSL_FUNC_keymgmt_gen_get_params(fns); 115 } 116 break; 117 case OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS: 118 if (keymgmt->gen_gettable_params == NULL) { 119 getgenparamfncnt++; 120 keymgmt->gen_gettable_params = OSSL_FUNC_keymgmt_gen_gettable_params(fns); 121 } 122 break; 123 case OSSL_FUNC_KEYMGMT_GEN: 124 if (keymgmt->gen == NULL) 125 keymgmt->gen = OSSL_FUNC_keymgmt_gen(fns); 126 break; 127 case OSSL_FUNC_KEYMGMT_GEN_CLEANUP: 128 if (keymgmt->gen_cleanup == NULL) 129 keymgmt->gen_cleanup = OSSL_FUNC_keymgmt_gen_cleanup(fns); 130 break; 131 case OSSL_FUNC_KEYMGMT_FREE: 132 if (keymgmt->free == NULL) 133 keymgmt->free = OSSL_FUNC_keymgmt_free(fns); 134 break; 135 case OSSL_FUNC_KEYMGMT_LOAD: 136 if (keymgmt->load == NULL) 137 keymgmt->load = OSSL_FUNC_keymgmt_load(fns); 138 break; 139 case OSSL_FUNC_KEYMGMT_GET_PARAMS: 140 if (keymgmt->get_params == NULL) { 141 getparamfncnt++; 142 keymgmt->get_params = OSSL_FUNC_keymgmt_get_params(fns); 143 } 144 break; 145 case OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS: 146 if (keymgmt->gettable_params == NULL) { 147 getparamfncnt++; 148 keymgmt->gettable_params = OSSL_FUNC_keymgmt_gettable_params(fns); 149 } 150 break; 151 case OSSL_FUNC_KEYMGMT_SET_PARAMS: 152 if (keymgmt->set_params == NULL) { 153 setparamfncnt++; 154 keymgmt->set_params = OSSL_FUNC_keymgmt_set_params(fns); 155 } 156 break; 157 case OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS: 158 if (keymgmt->settable_params == NULL) { 159 setparamfncnt++; 160 keymgmt->settable_params = OSSL_FUNC_keymgmt_settable_params(fns); 161 } 162 break; 163 case OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME: 164 if (keymgmt->query_operation_name == NULL) 165 keymgmt->query_operation_name = OSSL_FUNC_keymgmt_query_operation_name(fns); 166 break; 167 case OSSL_FUNC_KEYMGMT_HAS: 168 if (keymgmt->has == NULL) 169 keymgmt->has = OSSL_FUNC_keymgmt_has(fns); 170 break; 171 case OSSL_FUNC_KEYMGMT_DUP: 172 if (keymgmt->dup == NULL) 173 keymgmt->dup = OSSL_FUNC_keymgmt_dup(fns); 174 break; 175 case OSSL_FUNC_KEYMGMT_VALIDATE: 176 if (keymgmt->validate == NULL) 177 keymgmt->validate = OSSL_FUNC_keymgmt_validate(fns); 178 break; 179 case OSSL_FUNC_KEYMGMT_MATCH: 180 if (keymgmt->match == NULL) 181 keymgmt->match = OSSL_FUNC_keymgmt_match(fns); 182 break; 183 case OSSL_FUNC_KEYMGMT_IMPORT: 184 if (keymgmt->import == NULL) { 185 importfncnt++; 186 keymgmt->import = OSSL_FUNC_keymgmt_import(fns); 187 } 188 break; 189 case OSSL_FUNC_KEYMGMT_IMPORT_TYPES: 190 if (keymgmt->import_types == NULL) { 191 if (importtypesfncnt == 0) 192 importfncnt++; 193 importtypesfncnt++; 194 keymgmt->import_types = OSSL_FUNC_keymgmt_import_types(fns); 195 } 196 break; 197 case OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX: 198 if (keymgmt->import_types_ex == NULL) { 199 if (importtypesfncnt == 0) 200 importfncnt++; 201 importtypesfncnt++; 202 keymgmt->import_types_ex = OSSL_FUNC_keymgmt_import_types_ex(fns); 203 } 204 break; 205 case OSSL_FUNC_KEYMGMT_EXPORT: 206 if (keymgmt->export == NULL) { 207 exportfncnt++; 208 keymgmt->export = OSSL_FUNC_keymgmt_export(fns); 209 } 210 break; 211 case OSSL_FUNC_KEYMGMT_EXPORT_TYPES: 212 if (keymgmt->export_types == NULL) { 213 if (exporttypesfncnt == 0) 214 exportfncnt++; 215 exporttypesfncnt++; 216 keymgmt->export_types = OSSL_FUNC_keymgmt_export_types(fns); 217 } 218 break; 219 case OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX: 220 if (keymgmt->export_types_ex == NULL) { 221 if (exporttypesfncnt == 0) 222 exportfncnt++; 223 exporttypesfncnt++; 224 keymgmt->export_types_ex = OSSL_FUNC_keymgmt_export_types_ex(fns); 225 } 226 break; 227 } 228 } 229 /* 230 * Try to check that the method is sensible. 231 * At least one constructor and the destructor are MANDATORY 232 * The functions 'has' is MANDATORY 233 * It makes no sense being able to free stuff if you can't create it. 234 * It makes no sense providing OSSL_PARAM descriptors for import and 235 * export if you can't import or export. 236 */ 237 if (keymgmt->free == NULL 238 || (keymgmt->new == NULL 239 && keymgmt->gen == NULL 240 && keymgmt->load == NULL) 241 || keymgmt->has == NULL 242 || (getparamfncnt != 0 && getparamfncnt != 2) 243 || (setparamfncnt != 0 && setparamfncnt != 2) 244 || (setgenparamfncnt != 0 && setgenparamfncnt != 2) 245 || (getgenparamfncnt != 0 && getgenparamfncnt != 2) 246 || (importfncnt != 0 && importfncnt != 2) 247 || (exportfncnt != 0 && exportfncnt != 2) 248 || (keymgmt->gen != NULL 249 && (keymgmt->gen_init == NULL 250 || keymgmt->gen_cleanup == NULL))) { 251 EVP_KEYMGMT_free(keymgmt); 252 ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); 253 return NULL; 254 } 255 keymgmt->prov = prov; 256 if (prov != NULL) 257 ossl_provider_up_ref(prov); 258 259 #ifndef FIPS_MODULE 260 keymgmt->legacy_alg = get_legacy_alg_type_from_keymgmt(keymgmt); 261 #endif 262 263 return keymgmt; 264 } 265 266 EVP_KEYMGMT *evp_keymgmt_fetch_from_prov(OSSL_PROVIDER *prov, 267 const char *name, 268 const char *properties) 269 { 270 return evp_generic_fetch_from_prov(prov, OSSL_OP_KEYMGMT, 271 name, properties, 272 keymgmt_from_algorithm, 273 evp_keymgmt_up_ref, 274 evp_keymgmt_free); 275 } 276 277 EVP_KEYMGMT *EVP_KEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, 278 const char *properties) 279 { 280 return evp_generic_fetch(ctx, OSSL_OP_KEYMGMT, algorithm, properties, 281 keymgmt_from_algorithm, 282 evp_keymgmt_up_ref, 283 evp_keymgmt_free); 284 } 285 286 int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt) 287 { 288 int ref = 0; 289 290 CRYPTO_UP_REF(&keymgmt->refcnt, &ref); 291 return 1; 292 } 293 294 void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt) 295 { 296 int ref = 0; 297 298 if (keymgmt == NULL) 299 return; 300 301 CRYPTO_DOWN_REF(&keymgmt->refcnt, &ref); 302 if (ref > 0) 303 return; 304 OPENSSL_free(keymgmt->type_name); 305 ossl_provider_free(keymgmt->prov); 306 CRYPTO_FREE_REF(&keymgmt->refcnt); 307 OPENSSL_free(keymgmt); 308 } 309 310 const OSSL_PROVIDER *EVP_KEYMGMT_get0_provider(const EVP_KEYMGMT *keymgmt) 311 { 312 return keymgmt->prov; 313 } 314 315 int evp_keymgmt_get_number(const EVP_KEYMGMT *keymgmt) 316 { 317 return keymgmt->name_id; 318 } 319 320 int evp_keymgmt_get_legacy_alg(const EVP_KEYMGMT *keymgmt) 321 { 322 return keymgmt->legacy_alg; 323 } 324 325 const char *EVP_KEYMGMT_get0_description(const EVP_KEYMGMT *keymgmt) 326 { 327 return keymgmt->description; 328 } 329 330 const char *EVP_KEYMGMT_get0_name(const EVP_KEYMGMT *keymgmt) 331 { 332 return keymgmt->type_name; 333 } 334 335 int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name) 336 { 337 return keymgmt != NULL 338 && evp_is_a(keymgmt->prov, keymgmt->name_id, NULL, name); 339 } 340 341 void EVP_KEYMGMT_do_all_provided(OSSL_LIB_CTX *libctx, 342 void (*fn)(EVP_KEYMGMT *keymgmt, void *arg), 343 void *arg) 344 { 345 evp_generic_do_all(libctx, OSSL_OP_KEYMGMT, 346 (void (*)(void *, void *))fn, arg, 347 keymgmt_from_algorithm, 348 evp_keymgmt_up_ref, 349 evp_keymgmt_free); 350 } 351 352 int EVP_KEYMGMT_names_do_all(const EVP_KEYMGMT *keymgmt, 353 void (*fn)(const char *name, void *data), 354 void *data) 355 { 356 if (keymgmt->prov != NULL) 357 return evp_names_do_all(keymgmt->prov, keymgmt->name_id, fn, data); 358 359 return 1; 360 } 361 362 /* 363 * Internal API that interfaces with the method function pointers 364 */ 365 void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt) 366 { 367 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); 368 369 /* 370 * 'new' is currently mandatory on its own, but when new 371 * constructors appear, it won't be quite as mandatory, 372 * so we have a check for future cases. 373 */ 374 if (keymgmt->new == NULL) 375 return NULL; 376 return keymgmt->new(provctx); 377 } 378 379 void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keydata) 380 { 381 /* This is mandatory, no need to check for its presence */ 382 keymgmt->free(keydata); 383 } 384 385 void *evp_keymgmt_gen_init(const EVP_KEYMGMT *keymgmt, int selection, 386 const OSSL_PARAM params[]) 387 { 388 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); 389 390 if (keymgmt->gen_init == NULL) 391 return NULL; 392 return keymgmt->gen_init(provctx, selection, params); 393 } 394 395 int evp_keymgmt_gen_set_template(const EVP_KEYMGMT *keymgmt, void *genctx, 396 void *templ) 397 { 398 /* 399 * It's arguable if we actually should return success in this case, as 400 * it allows the caller to set a template key, which is then ignored. 401 * However, this is how the legacy methods (EVP_PKEY_METHOD) operate, 402 * so we do this in the interest of backward compatibility. 403 */ 404 if (keymgmt->gen_set_template == NULL) 405 return 1; 406 return keymgmt->gen_set_template(genctx, templ); 407 } 408 409 int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx, 410 const OSSL_PARAM params[]) 411 { 412 if (keymgmt->gen_set_params == NULL) 413 return 0; 414 return keymgmt->gen_set_params(genctx, params); 415 } 416 417 const OSSL_PARAM *EVP_KEYMGMT_gen_settable_params(const EVP_KEYMGMT *keymgmt) 418 { 419 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); 420 421 if (keymgmt->gen_settable_params == NULL) 422 return NULL; 423 return keymgmt->gen_settable_params(NULL, provctx); 424 } 425 426 int evp_keymgmt_gen_get_params(const EVP_KEYMGMT *keymgmt, void *genctx, 427 OSSL_PARAM params[]) 428 { 429 if (keymgmt->gen_get_params == NULL) 430 return 0; 431 return keymgmt->gen_get_params(genctx, params); 432 } 433 434 const OSSL_PARAM *EVP_KEYMGMT_gen_gettable_params(const EVP_KEYMGMT *keymgmt) 435 { 436 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); 437 438 if (keymgmt->gen_gettable_params == NULL) 439 return NULL; 440 return keymgmt->gen_gettable_params(NULL, provctx); 441 } 442 443 void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx, 444 OSSL_CALLBACK *cb, void *cbarg) 445 { 446 void *ret; 447 const char *desc = keymgmt->description != NULL ? keymgmt->description : ""; 448 449 if (keymgmt->gen == NULL) { 450 ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_KEYMGMT_NOT_SUPPORTED, 451 "%s key generation:%s", keymgmt->type_name, desc); 452 return NULL; 453 } 454 455 ERR_set_mark(); 456 ret = keymgmt->gen(genctx, cb, cbarg); 457 if (ret == NULL && ERR_count_to_mark() == 0) 458 ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_KEYMGMT_FAILURE, 459 "%s key generation:%s", keymgmt->type_name, desc); 460 ERR_clear_last_mark(); 461 return ret; 462 } 463 464 void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx) 465 { 466 if (keymgmt->gen_cleanup != NULL) 467 keymgmt->gen_cleanup(genctx); 468 } 469 470 int evp_keymgmt_has_load(const EVP_KEYMGMT *keymgmt) 471 { 472 return keymgmt != NULL && keymgmt->load != NULL; 473 } 474 475 void *evp_keymgmt_load(const EVP_KEYMGMT *keymgmt, 476 const void *objref, size_t objref_sz) 477 { 478 if (evp_keymgmt_has_load(keymgmt)) 479 return keymgmt->load(objref, objref_sz); 480 return NULL; 481 } 482 483 int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, void *keydata, 484 OSSL_PARAM params[]) 485 { 486 if (keymgmt->get_params == NULL) 487 return 1; 488 return keymgmt->get_params(keydata, params); 489 } 490 491 const OSSL_PARAM *EVP_KEYMGMT_gettable_params(const EVP_KEYMGMT *keymgmt) 492 { 493 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); 494 495 if (keymgmt->gettable_params == NULL) 496 return NULL; 497 return keymgmt->gettable_params(provctx); 498 } 499 500 int evp_keymgmt_set_params(const EVP_KEYMGMT *keymgmt, void *keydata, 501 const OSSL_PARAM params[]) 502 { 503 if (keymgmt->set_params == NULL) 504 return 1; 505 return keymgmt->set_params(keydata, params); 506 } 507 508 const OSSL_PARAM *EVP_KEYMGMT_settable_params(const EVP_KEYMGMT *keymgmt) 509 { 510 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); 511 512 if (keymgmt->settable_params == NULL) 513 return NULL; 514 return keymgmt->settable_params(provctx); 515 } 516 517 int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keydata, int selection) 518 { 519 /* This is mandatory, no need to check for its presence */ 520 return keymgmt->has(keydata, selection); 521 } 522 523 int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata, 524 int selection, int checktype) 525 { 526 /* We assume valid if the implementation doesn't have a function */ 527 if (keymgmt->validate == NULL) 528 return 1; 529 return keymgmt->validate(keydata, selection, checktype); 530 } 531 532 int evp_keymgmt_match(const EVP_KEYMGMT *keymgmt, 533 const void *keydata1, const void *keydata2, 534 int selection) 535 { 536 /* We assume no match if the implementation doesn't have a function */ 537 if (keymgmt->match == NULL) 538 return 0; 539 return keymgmt->match(keydata1, keydata2, selection); 540 } 541 542 int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata, 543 int selection, const OSSL_PARAM params[]) 544 { 545 if (keymgmt->import == NULL) 546 return 0; 547 return keymgmt->import(keydata, selection, params); 548 } 549 550 const OSSL_PARAM *evp_keymgmt_import_types(const EVP_KEYMGMT *keymgmt, 551 int selection) 552 { 553 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); 554 555 if (keymgmt->import_types_ex != NULL) 556 return keymgmt->import_types_ex(provctx, selection); 557 if (keymgmt->import_types == NULL) 558 return NULL; 559 return keymgmt->import_types(selection); 560 } 561 562 int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata, 563 int selection, OSSL_CALLBACK *param_cb, void *cbarg) 564 { 565 if (keymgmt->export == NULL) 566 return 0; 567 return keymgmt->export(keydata, selection, param_cb, cbarg); 568 } 569 570 const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt, 571 int selection) 572 { 573 void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); 574 575 if (keymgmt->export_types_ex != NULL) 576 return keymgmt->export_types_ex(provctx, selection); 577 if (keymgmt->export_types == NULL) 578 return NULL; 579 return keymgmt->export_types(selection); 580 } 581 582 void *evp_keymgmt_dup(const EVP_KEYMGMT *keymgmt, const void *keydata_from, 583 int selection) 584 { 585 /* We assume no dup if the implementation doesn't have a function */ 586 if (keymgmt->dup == NULL) 587 return NULL; 588 return keymgmt->dup(keydata_from, selection); 589 } 590