1 /* 2 * Copyright 2019-2024 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/core_names.h> 11 #include "internal/cryptlib.h" 12 #include "internal/nelem.h" 13 #include "crypto/evp.h" 14 #include "internal/core.h" 15 #include "internal/provider.h" 16 #include "evp_local.h" 17 18 /* 19 * match_type() checks if two EVP_KEYMGMT are matching key types. This 20 * function assumes that the caller has made all the necessary NULL checks. 21 */ 22 static int match_type(const EVP_KEYMGMT *keymgmt1, const EVP_KEYMGMT *keymgmt2) 23 { 24 const char *name2 = EVP_KEYMGMT_get0_name(keymgmt2); 25 26 return EVP_KEYMGMT_is_a(keymgmt1, name2); 27 } 28 29 int evp_keymgmt_util_try_import(const OSSL_PARAM params[], void *arg) 30 { 31 struct evp_keymgmt_util_try_import_data_st *data = arg; 32 int delete_on_error = 0; 33 34 /* Just in time creation of keydata */ 35 if (data->keydata == NULL) { 36 if ((data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) { 37 ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); 38 return 0; 39 } 40 delete_on_error = 1; 41 } 42 43 /* 44 * It's fine if there was no data to transfer, we just end up with an 45 * empty destination key. 46 */ 47 if (params[0].key == NULL) 48 return 1; 49 50 if (evp_keymgmt_import(data->keymgmt, data->keydata, data->selection, 51 params)) 52 return 1; 53 if (delete_on_error) { 54 evp_keymgmt_freedata(data->keymgmt, data->keydata); 55 data->keydata = NULL; 56 } 57 return 0; 58 } 59 60 int evp_keymgmt_util_assign_pkey(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt, 61 void *keydata) 62 { 63 if (pkey == NULL || keymgmt == NULL || keydata == NULL 64 || !EVP_PKEY_set_type_by_keymgmt(pkey, keymgmt)) { 65 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); 66 return 0; 67 } 68 pkey->keydata = keydata; 69 evp_keymgmt_util_cache_keyinfo(pkey); 70 return 1; 71 } 72 73 EVP_PKEY *evp_keymgmt_util_make_pkey(EVP_KEYMGMT *keymgmt, void *keydata) 74 { 75 EVP_PKEY *pkey = NULL; 76 77 if (keymgmt == NULL 78 || keydata == NULL 79 || (pkey = EVP_PKEY_new()) == NULL 80 || !evp_keymgmt_util_assign_pkey(pkey, keymgmt, keydata)) { 81 EVP_PKEY_free(pkey); 82 return NULL; 83 } 84 return pkey; 85 } 86 87 int evp_keymgmt_util_export(const EVP_PKEY *pk, int selection, 88 OSSL_CALLBACK *export_cb, void *export_cbarg) 89 { 90 if (pk == NULL || export_cb == NULL) 91 return 0; 92 return evp_keymgmt_export(pk->keymgmt, pk->keydata, selection, 93 export_cb, export_cbarg); 94 } 95 96 void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, 97 int selection) 98 { 99 struct evp_keymgmt_util_try_import_data_st import_data; 100 OP_CACHE_ELEM *op; 101 102 /* Export to where? */ 103 if (keymgmt == NULL) 104 return NULL; 105 106 /* If we have an unassigned key, give up */ 107 if (pk->keydata == NULL) 108 return NULL; 109 110 /* 111 * If |keymgmt| matches the "origin" |keymgmt|, there is no more to do. 112 * The "origin" is determined by the |keymgmt| pointers being identical 113 * or when the provider and the name ID match. The latter case handles the 114 * situation where the fetch cache is flushed and a "new" key manager is 115 * created. 116 */ 117 if (pk->keymgmt == keymgmt 118 || (pk->keymgmt->name_id == keymgmt->name_id 119 && pk->keymgmt->prov == keymgmt->prov)) 120 return pk->keydata; 121 122 if (!CRYPTO_THREAD_read_lock(pk->lock)) 123 return NULL; 124 /* 125 * If the provider native "origin" hasn't changed since last time, we 126 * try to find our keymgmt in the operation cache. If it has changed 127 * and our keymgmt isn't found, we will clear the cache further down. 128 */ 129 if (pk->dirty_cnt == pk->dirty_cnt_copy) { 130 /* If this key is already exported to |keymgmt|, no more to do */ 131 op = evp_keymgmt_util_find_operation_cache(pk, keymgmt, selection); 132 if (op != NULL && op->keymgmt != NULL) { 133 void *ret = op->keydata; 134 135 CRYPTO_THREAD_unlock(pk->lock); 136 return ret; 137 } 138 } 139 CRYPTO_THREAD_unlock(pk->lock); 140 141 /* If the "origin" |keymgmt| doesn't support exporting, give up */ 142 if (pk->keymgmt->export == NULL) 143 return NULL; 144 145 /* 146 * Make sure that the type of the keymgmt to export to matches the type 147 * of the "origin" 148 */ 149 if (!ossl_assert(match_type(pk->keymgmt, keymgmt))) 150 return NULL; 151 152 /* 153 * We look at the already cached provider keys, and import from the 154 * first that supports it (i.e. use its export function), and export 155 * the imported data to the new provider. 156 */ 157 158 /* Setup for the export callback */ 159 import_data.keydata = NULL; /* evp_keymgmt_util_try_import will create it */ 160 import_data.keymgmt = keymgmt; 161 import_data.selection = selection; 162 163 /* 164 * The export function calls the callback (evp_keymgmt_util_try_import), 165 * which does the import for us. If successful, we're done. 166 */ 167 if (!evp_keymgmt_util_export(pk, selection, 168 &evp_keymgmt_util_try_import, &import_data)) 169 /* If there was an error, bail out */ 170 return NULL; 171 172 if (!CRYPTO_THREAD_write_lock(pk->lock)) { 173 evp_keymgmt_freedata(keymgmt, import_data.keydata); 174 return NULL; 175 } 176 /* Check to make sure some other thread didn't get there first */ 177 op = evp_keymgmt_util_find_operation_cache(pk, keymgmt, selection); 178 if (op != NULL && op->keydata != NULL) { 179 void *ret = op->keydata; 180 181 CRYPTO_THREAD_unlock(pk->lock); 182 183 /* 184 * Another thread seemms to have already exported this so we abandon 185 * all the work we just did. 186 */ 187 evp_keymgmt_freedata(keymgmt, import_data.keydata); 188 189 return ret; 190 } 191 192 /* 193 * If the dirty counter changed since last time, then clear the 194 * operation cache. In that case, we know that |i| is zero. 195 */ 196 if (pk->dirty_cnt != pk->dirty_cnt_copy) 197 evp_keymgmt_util_clear_operation_cache(pk); 198 199 /* Add the new export to the operation cache */ 200 if (!evp_keymgmt_util_cache_keydata(pk, keymgmt, import_data.keydata, 201 selection)) { 202 CRYPTO_THREAD_unlock(pk->lock); 203 evp_keymgmt_freedata(keymgmt, import_data.keydata); 204 return NULL; 205 } 206 207 /* Synchronize the dirty count */ 208 pk->dirty_cnt_copy = pk->dirty_cnt; 209 210 CRYPTO_THREAD_unlock(pk->lock); 211 212 return import_data.keydata; 213 } 214 215 static void op_cache_free(OP_CACHE_ELEM *e) 216 { 217 evp_keymgmt_freedata(e->keymgmt, e->keydata); 218 EVP_KEYMGMT_free(e->keymgmt); 219 OPENSSL_free(e); 220 } 221 222 int evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk) 223 { 224 if (pk != NULL) { 225 sk_OP_CACHE_ELEM_pop_free(pk->operation_cache, op_cache_free); 226 pk->operation_cache = NULL; 227 } 228 229 return 1; 230 } 231 232 OP_CACHE_ELEM *evp_keymgmt_util_find_operation_cache(EVP_PKEY *pk, 233 EVP_KEYMGMT *keymgmt, 234 int selection) 235 { 236 int i, end = sk_OP_CACHE_ELEM_num(pk->operation_cache); 237 OP_CACHE_ELEM *p; 238 239 /* 240 * A comparison and sk_P_CACHE_ELEM_find() are avoided to not cause 241 * problems when we've only a read lock. 242 * A keymgmt is a match if the |keymgmt| pointers are identical or if the 243 * provider and the name ID match 244 */ 245 for (i = 0; i < end; i++) { 246 p = sk_OP_CACHE_ELEM_value(pk->operation_cache, i); 247 if ((p->selection & selection) == selection 248 && (keymgmt == p->keymgmt 249 || (keymgmt->name_id == p->keymgmt->name_id 250 && keymgmt->prov == p->keymgmt->prov))) 251 return p; 252 } 253 return NULL; 254 } 255 256 int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, 257 void *keydata, int selection) 258 { 259 OP_CACHE_ELEM *p = NULL; 260 261 if (keydata != NULL) { 262 if (pk->operation_cache == NULL) { 263 pk->operation_cache = sk_OP_CACHE_ELEM_new_null(); 264 if (pk->operation_cache == NULL) 265 return 0; 266 } 267 268 p = OPENSSL_malloc(sizeof(*p)); 269 if (p == NULL) 270 return 0; 271 p->keydata = keydata; 272 p->keymgmt = keymgmt; 273 p->selection = selection; 274 275 if (!EVP_KEYMGMT_up_ref(keymgmt)) { 276 OPENSSL_free(p); 277 return 0; 278 } 279 280 if (!sk_OP_CACHE_ELEM_push(pk->operation_cache, p)) { 281 EVP_KEYMGMT_free(keymgmt); 282 OPENSSL_free(p); 283 return 0; 284 } 285 } 286 return 1; 287 } 288 289 void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk) 290 { 291 /* 292 * Cache information about the provider "origin" key. 293 * 294 * This services functions like EVP_PKEY_get_size, EVP_PKEY_get_bits, etc 295 */ 296 if (pk->keydata != NULL) { 297 int bits = 0; 298 int security_bits = 0; 299 int size = 0; 300 OSSL_PARAM params[4]; 301 302 params[0] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_BITS, &bits); 303 params[1] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_SECURITY_BITS, 304 &security_bits); 305 params[2] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_MAX_SIZE, &size); 306 params[3] = OSSL_PARAM_construct_end(); 307 if (evp_keymgmt_get_params(pk->keymgmt, pk->keydata, params)) { 308 pk->cache.size = size; 309 pk->cache.bits = bits; 310 pk->cache.security_bits = security_bits; 311 } 312 } 313 } 314 315 void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt, 316 int selection, const OSSL_PARAM params[]) 317 { 318 void *keydata = NULL; 319 320 if ((keydata = evp_keymgmt_newdata(keymgmt)) == NULL 321 || !evp_keymgmt_import(keymgmt, keydata, selection, params) 322 || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) { 323 evp_keymgmt_freedata(keymgmt, keydata); 324 keydata = NULL; 325 } 326 return keydata; 327 } 328 329 int evp_keymgmt_util_has(EVP_PKEY *pk, int selection) 330 { 331 /* Check if key is even assigned */ 332 if (pk->keymgmt == NULL) 333 return 0; 334 335 return evp_keymgmt_has(pk->keymgmt, pk->keydata, selection); 336 } 337 338 /* 339 * evp_keymgmt_util_match() doesn't just look at the provider side "origin", 340 * but also in the operation cache to see if there's any common keymgmt that 341 * supplies OP_keymgmt_match. 342 * 343 * evp_keymgmt_util_match() adheres to the return values that EVP_PKEY_eq() 344 * and EVP_PKEY_parameters_eq() return, i.e.: 345 * 346 * 1 same key 347 * 0 not same key 348 * -1 not same key type 349 * -2 unsupported operation 350 */ 351 int evp_keymgmt_util_match(EVP_PKEY *pk1, EVP_PKEY *pk2, int selection) 352 { 353 EVP_KEYMGMT *keymgmt1 = NULL, *keymgmt2 = NULL; 354 void *keydata1 = NULL, *keydata2 = NULL; 355 356 if (pk1 == NULL || pk2 == NULL) { 357 if (pk1 == NULL && pk2 == NULL) 358 return 1; 359 return 0; 360 } 361 362 keymgmt1 = pk1->keymgmt; 363 keydata1 = pk1->keydata; 364 keymgmt2 = pk2->keymgmt; 365 keydata2 = pk2->keydata; 366 367 if (keymgmt1 != keymgmt2) { 368 /* 369 * The condition for a successful cross export is that the 370 * keydata to be exported is NULL (typed, but otherwise empty 371 * EVP_PKEY), or that it was possible to export it with 372 * evp_keymgmt_util_export_to_provider(). 373 * 374 * We use |ok| to determine if it's ok to cross export one way, 375 * but also to determine if we should attempt a cross export 376 * the other way. There's no point doing it both ways. 377 */ 378 int ok = 0; 379 380 /* Complex case, where the keymgmt differ */ 381 if (keymgmt1 != NULL 382 && keymgmt2 != NULL 383 && !match_type(keymgmt1, keymgmt2)) { 384 ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES); 385 return -1; /* Not the same type */ 386 } 387 388 /* 389 * The key types are determined to match, so we try cross export, 390 * but only to keymgmt's that supply a matching function. 391 */ 392 if (keymgmt2 != NULL 393 && keymgmt2->match != NULL) { 394 void *tmp_keydata = NULL; 395 396 ok = 1; 397 if (keydata1 != NULL) { 398 tmp_keydata = 399 evp_keymgmt_util_export_to_provider(pk1, keymgmt2, 400 selection); 401 ok = (tmp_keydata != NULL); 402 } 403 if (ok) { 404 keymgmt1 = keymgmt2; 405 keydata1 = tmp_keydata; 406 } 407 } 408 /* 409 * If we've successfully cross exported one way, there's no point 410 * doing it the other way, hence the |!ok| check. 411 */ 412 if (!ok 413 && keymgmt1 != NULL 414 && keymgmt1->match != NULL) { 415 void *tmp_keydata = NULL; 416 417 ok = 1; 418 if (keydata2 != NULL) { 419 tmp_keydata = 420 evp_keymgmt_util_export_to_provider(pk2, keymgmt1, 421 selection); 422 ok = (tmp_keydata != NULL); 423 } 424 if (ok) { 425 keymgmt2 = keymgmt1; 426 keydata2 = tmp_keydata; 427 } 428 } 429 } 430 431 /* If we still don't have matching keymgmt implementations, we give up */ 432 if (keymgmt1 != keymgmt2) 433 return -2; 434 435 /* If both keydata are NULL, then they're the same key */ 436 if (keydata1 == NULL && keydata2 == NULL) 437 return 1; 438 /* If only one of the keydata is NULL, then they're different keys */ 439 if (keydata1 == NULL || keydata2 == NULL) 440 return 0; 441 /* If both keydata are non-NULL, we let the backend decide */ 442 return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection); 443 } 444 445 int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection) 446 { 447 /* Save copies of pointers we want to play with without affecting |to| */ 448 EVP_KEYMGMT *to_keymgmt = to->keymgmt; 449 void *to_keydata = to->keydata, *alloc_keydata = NULL; 450 451 /* An unassigned key can't be copied */ 452 if (from == NULL || from->keydata == NULL) 453 return 0; 454 455 /* 456 * If |to| is unassigned, ensure it gets the same KEYMGMT as |from|, 457 * Note that the final setting of KEYMGMT is done further down, with 458 * EVP_PKEY_set_type_by_keymgmt(); we don't want to do that prematurely. 459 */ 460 if (to_keymgmt == NULL) 461 to_keymgmt = from->keymgmt; 462 463 if (to_keymgmt == from->keymgmt && to_keymgmt->dup != NULL 464 && to_keydata == NULL) { 465 to_keydata = alloc_keydata = evp_keymgmt_dup(to_keymgmt, 466 from->keydata, 467 selection); 468 if (to_keydata == NULL) 469 return 0; 470 } else if (match_type(to_keymgmt, from->keymgmt)) { 471 struct evp_keymgmt_util_try_import_data_st import_data; 472 473 import_data.keymgmt = to_keymgmt; 474 import_data.keydata = to_keydata; 475 import_data.selection = selection; 476 477 if (!evp_keymgmt_util_export(from, selection, 478 &evp_keymgmt_util_try_import, 479 &import_data)) 480 return 0; 481 482 /* 483 * In case to_keydata was previously unallocated, 484 * evp_keymgmt_util_try_import() may have created it for us. 485 */ 486 if (to_keydata == NULL) 487 to_keydata = alloc_keydata = import_data.keydata; 488 } else { 489 ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES); 490 return 0; 491 } 492 493 /* 494 * We only need to set the |to| type when its |keymgmt| isn't set. 495 * We can then just set its |keydata| to what we have, which might 496 * be exactly what it had when entering this function. 497 * This is a bit different from using evp_keymgmt_util_assign_pkey(), 498 * which isn't as careful with |to|'s original |keymgmt|, since it's 499 * meant to forcibly reassign an EVP_PKEY no matter what, which is 500 * why we don't use that one here. 501 */ 502 if (to->keymgmt == NULL 503 && !EVP_PKEY_set_type_by_keymgmt(to, to_keymgmt)) { 504 evp_keymgmt_freedata(to_keymgmt, alloc_keydata); 505 return 0; 506 } 507 to->keydata = to_keydata; 508 evp_keymgmt_util_cache_keyinfo(to); 509 510 return 1; 511 } 512 513 void *evp_keymgmt_util_gen(EVP_PKEY *target, EVP_KEYMGMT *keymgmt, 514 void *genctx, OSSL_CALLBACK *cb, void *cbarg) 515 { 516 void *keydata = NULL; 517 518 if ((keydata = evp_keymgmt_gen(keymgmt, genctx, cb, cbarg)) == NULL 519 || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) { 520 evp_keymgmt_freedata(keymgmt, keydata); 521 keydata = NULL; 522 } 523 524 return keydata; 525 } 526 527 /* 528 * Returns the same numbers as EVP_PKEY_get_default_digest_name() 529 * When the string from the EVP_KEYMGMT implementation is "", we use 530 * SN_undef, since that corresponds to what EVP_PKEY_get_default_nid() 531 * returns for no digest. 532 */ 533 int evp_keymgmt_util_get_deflt_digest_name(EVP_KEYMGMT *keymgmt, 534 void *keydata, 535 char *mdname, size_t mdname_sz) 536 { 537 OSSL_PARAM params[3]; 538 char mddefault[100] = ""; 539 char mdmandatory[100] = ""; 540 char *result = NULL; 541 int rv = -2; 542 543 params[0] = 544 OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, 545 mddefault, sizeof(mddefault)); 546 params[1] = 547 OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, 548 mdmandatory, 549 sizeof(mdmandatory)); 550 params[2] = OSSL_PARAM_construct_end(); 551 552 if (!evp_keymgmt_get_params(keymgmt, keydata, params)) 553 return 0; 554 555 if (OSSL_PARAM_modified(params + 1)) { 556 if (params[1].return_size <= 1) /* Only a NUL byte */ 557 result = SN_undef; 558 else 559 result = mdmandatory; 560 rv = 2; 561 } else if (OSSL_PARAM_modified(params)) { 562 if (params[0].return_size <= 1) /* Only a NUL byte */ 563 result = SN_undef; 564 else 565 result = mddefault; 566 rv = 1; 567 } 568 if (rv > 0) 569 OPENSSL_strlcpy(mdname, result, mdname_sz); 570 return rv; 571 } 572 573 /* 574 * If |keymgmt| has the method function |query_operation_name|, use it to get 575 * the name of a supported operation identity. Otherwise, return the keytype, 576 * assuming that it works as a default operation name. 577 */ 578 const char *evp_keymgmt_util_query_operation_name(EVP_KEYMGMT *keymgmt, 579 int op_id) 580 { 581 const char *name = NULL; 582 583 if (keymgmt != NULL) { 584 if (keymgmt->query_operation_name != NULL) 585 name = keymgmt->query_operation_name(op_id); 586 if (name == NULL) 587 name = EVP_KEYMGMT_get0_name(keymgmt); 588 } 589 return name; 590 } 591