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_MALLOC_FAILURE); 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, 0); 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, int locking) 223 { 224 if (pk != NULL) { 225 if (locking && pk->lock != NULL && !CRYPTO_THREAD_write_lock(pk->lock)) 226 return 0; 227 sk_OP_CACHE_ELEM_pop_free(pk->operation_cache, op_cache_free); 228 pk->operation_cache = NULL; 229 if (locking && pk->lock != NULL) 230 CRYPTO_THREAD_unlock(pk->lock); 231 } 232 233 return 1; 234 } 235 236 OP_CACHE_ELEM *evp_keymgmt_util_find_operation_cache(EVP_PKEY *pk, 237 EVP_KEYMGMT *keymgmt, 238 int selection) 239 { 240 int i, end = sk_OP_CACHE_ELEM_num(pk->operation_cache); 241 OP_CACHE_ELEM *p; 242 243 /* 244 * A comparison and sk_P_CACHE_ELEM_find() are avoided to not cause 245 * problems when we've only a read lock. 246 * A keymgmt is a match if the |keymgmt| pointers are identical or if the 247 * provider and the name ID match 248 */ 249 for (i = 0; i < end; i++) { 250 p = sk_OP_CACHE_ELEM_value(pk->operation_cache, i); 251 if ((p->selection & selection) == selection 252 && (keymgmt == p->keymgmt 253 || (keymgmt->name_id == p->keymgmt->name_id 254 && keymgmt->prov == p->keymgmt->prov))) 255 return p; 256 } 257 return NULL; 258 } 259 260 int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, 261 void *keydata, int selection) 262 { 263 OP_CACHE_ELEM *p = NULL; 264 265 if (keydata != NULL) { 266 if (pk->operation_cache == NULL) { 267 pk->operation_cache = sk_OP_CACHE_ELEM_new_null(); 268 if (pk->operation_cache == NULL) 269 return 0; 270 } 271 272 p = OPENSSL_malloc(sizeof(*p)); 273 if (p == NULL) 274 return 0; 275 p->keydata = keydata; 276 p->keymgmt = keymgmt; 277 p->selection = selection; 278 279 if (!EVP_KEYMGMT_up_ref(keymgmt)) { 280 OPENSSL_free(p); 281 return 0; 282 } 283 284 if (!sk_OP_CACHE_ELEM_push(pk->operation_cache, p)) { 285 EVP_KEYMGMT_free(keymgmt); 286 OPENSSL_free(p); 287 return 0; 288 } 289 } 290 return 1; 291 } 292 293 void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk) 294 { 295 /* 296 * Cache information about the provider "origin" key. 297 * 298 * This services functions like EVP_PKEY_get_size, EVP_PKEY_get_bits, etc 299 */ 300 if (pk->keydata != NULL) { 301 int bits = 0; 302 int security_bits = 0; 303 int size = 0; 304 OSSL_PARAM params[4]; 305 306 params[0] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_BITS, &bits); 307 params[1] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_SECURITY_BITS, 308 &security_bits); 309 params[2] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_MAX_SIZE, &size); 310 params[3] = OSSL_PARAM_construct_end(); 311 if (evp_keymgmt_get_params(pk->keymgmt, pk->keydata, params)) { 312 pk->cache.size = size; 313 pk->cache.bits = bits; 314 pk->cache.security_bits = security_bits; 315 } 316 } 317 } 318 319 void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt, 320 int selection, const OSSL_PARAM params[]) 321 { 322 void *keydata = NULL; 323 324 if ((keydata = evp_keymgmt_newdata(keymgmt)) == NULL 325 || !evp_keymgmt_import(keymgmt, keydata, selection, params) 326 || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) { 327 evp_keymgmt_freedata(keymgmt, keydata); 328 keydata = NULL; 329 } 330 return keydata; 331 } 332 333 int evp_keymgmt_util_has(EVP_PKEY *pk, int selection) 334 { 335 /* Check if key is even assigned */ 336 if (pk->keymgmt == NULL) 337 return 0; 338 339 return evp_keymgmt_has(pk->keymgmt, pk->keydata, selection); 340 } 341 342 /* 343 * evp_keymgmt_util_match() doesn't just look at the provider side "origin", 344 * but also in the operation cache to see if there's any common keymgmt that 345 * supplies OP_keymgmt_match. 346 * 347 * evp_keymgmt_util_match() adheres to the return values that EVP_PKEY_eq() 348 * and EVP_PKEY_parameters_eq() return, i.e.: 349 * 350 * 1 same key 351 * 0 not same key 352 * -1 not same key type 353 * -2 unsupported operation 354 */ 355 int evp_keymgmt_util_match(EVP_PKEY *pk1, EVP_PKEY *pk2, int selection) 356 { 357 EVP_KEYMGMT *keymgmt1 = NULL, *keymgmt2 = NULL; 358 void *keydata1 = NULL, *keydata2 = NULL; 359 360 if (pk1 == NULL || pk2 == NULL) { 361 if (pk1 == NULL && pk2 == NULL) 362 return 1; 363 return 0; 364 } 365 366 keymgmt1 = pk1->keymgmt; 367 keydata1 = pk1->keydata; 368 keymgmt2 = pk2->keymgmt; 369 keydata2 = pk2->keydata; 370 371 if (keymgmt1 != keymgmt2) { 372 /* 373 * The condition for a successful cross export is that the 374 * keydata to be exported is NULL (typed, but otherwise empty 375 * EVP_PKEY), or that it was possible to export it with 376 * evp_keymgmt_util_export_to_provider(). 377 * 378 * We use |ok| to determine if it's ok to cross export one way, 379 * but also to determine if we should attempt a cross export 380 * the other way. There's no point doing it both ways. 381 */ 382 int ok = 0; 383 384 /* Complex case, where the keymgmt differ */ 385 if (keymgmt1 != NULL 386 && keymgmt2 != NULL 387 && !match_type(keymgmt1, keymgmt2)) { 388 ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES); 389 return -1; /* Not the same type */ 390 } 391 392 /* 393 * The key types are determined to match, so we try cross export, 394 * but only to keymgmt's that supply a matching function. 395 */ 396 if (keymgmt2 != NULL 397 && keymgmt2->match != NULL) { 398 void *tmp_keydata = NULL; 399 400 ok = 1; 401 if (keydata1 != NULL) { 402 tmp_keydata = 403 evp_keymgmt_util_export_to_provider(pk1, keymgmt2, 404 selection); 405 ok = (tmp_keydata != NULL); 406 } 407 if (ok) { 408 keymgmt1 = keymgmt2; 409 keydata1 = tmp_keydata; 410 } 411 } 412 /* 413 * If we've successfully cross exported one way, there's no point 414 * doing it the other way, hence the |!ok| check. 415 */ 416 if (!ok 417 && keymgmt1 != NULL 418 && keymgmt1->match != NULL) { 419 void *tmp_keydata = NULL; 420 421 ok = 1; 422 if (keydata2 != NULL) { 423 tmp_keydata = 424 evp_keymgmt_util_export_to_provider(pk2, keymgmt1, 425 selection); 426 ok = (tmp_keydata != NULL); 427 } 428 if (ok) { 429 keymgmt2 = keymgmt1; 430 keydata2 = tmp_keydata; 431 } 432 } 433 } 434 435 /* If we still don't have matching keymgmt implementations, we give up */ 436 if (keymgmt1 != keymgmt2) 437 return -2; 438 439 /* If both keydata are NULL, then they're the same key */ 440 if (keydata1 == NULL && keydata2 == NULL) 441 return 1; 442 /* If only one of the keydata is NULL, then they're different keys */ 443 if (keydata1 == NULL || keydata2 == NULL) 444 return 0; 445 /* If both keydata are non-NULL, we let the backend decide */ 446 return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection); 447 } 448 449 int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection) 450 { 451 /* Save copies of pointers we want to play with without affecting |to| */ 452 EVP_KEYMGMT *to_keymgmt = to->keymgmt; 453 void *to_keydata = to->keydata, *alloc_keydata = NULL; 454 455 /* An unassigned key can't be copied */ 456 if (from == NULL || from->keydata == NULL) 457 return 0; 458 459 /* 460 * If |to| is unassigned, ensure it gets the same KEYMGMT as |from|, 461 * Note that the final setting of KEYMGMT is done further down, with 462 * EVP_PKEY_set_type_by_keymgmt(); we don't want to do that prematurely. 463 */ 464 if (to_keymgmt == NULL) 465 to_keymgmt = from->keymgmt; 466 467 if (to_keymgmt == from->keymgmt && to_keymgmt->dup != NULL 468 && to_keydata == NULL) { 469 to_keydata = alloc_keydata = evp_keymgmt_dup(to_keymgmt, 470 from->keydata, 471 selection); 472 if (to_keydata == NULL) 473 return 0; 474 } else if (match_type(to_keymgmt, from->keymgmt)) { 475 struct evp_keymgmt_util_try_import_data_st import_data; 476 477 import_data.keymgmt = to_keymgmt; 478 import_data.keydata = to_keydata; 479 import_data.selection = selection; 480 481 if (!evp_keymgmt_util_export(from, selection, 482 &evp_keymgmt_util_try_import, 483 &import_data)) 484 return 0; 485 486 /* 487 * In case to_keydata was previously unallocated, 488 * evp_keymgmt_util_try_import() may have created it for us. 489 */ 490 if (to_keydata == NULL) 491 to_keydata = alloc_keydata = import_data.keydata; 492 } else { 493 ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES); 494 return 0; 495 } 496 497 /* 498 * We only need to set the |to| type when its |keymgmt| isn't set. 499 * We can then just set its |keydata| to what we have, which might 500 * be exactly what it had when entering this function. 501 * This is a bit different from using evp_keymgmt_util_assign_pkey(), 502 * which isn't as careful with |to|'s original |keymgmt|, since it's 503 * meant to forcibly reassign an EVP_PKEY no matter what, which is 504 * why we don't use that one here. 505 */ 506 if (to->keymgmt == NULL 507 && !EVP_PKEY_set_type_by_keymgmt(to, to_keymgmt)) { 508 evp_keymgmt_freedata(to_keymgmt, alloc_keydata); 509 return 0; 510 } 511 to->keydata = to_keydata; 512 evp_keymgmt_util_cache_keyinfo(to); 513 514 return 1; 515 } 516 517 void *evp_keymgmt_util_gen(EVP_PKEY *target, EVP_KEYMGMT *keymgmt, 518 void *genctx, OSSL_CALLBACK *cb, void *cbarg) 519 { 520 void *keydata = NULL; 521 522 if ((keydata = evp_keymgmt_gen(keymgmt, genctx, cb, cbarg)) == NULL 523 || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) { 524 evp_keymgmt_freedata(keymgmt, keydata); 525 keydata = NULL; 526 } 527 528 return keydata; 529 } 530 531 /* 532 * Returns the same numbers as EVP_PKEY_get_default_digest_name() 533 * When the string from the EVP_KEYMGMT implementation is "", we use 534 * SN_undef, since that corresponds to what EVP_PKEY_get_default_nid() 535 * returns for no digest. 536 */ 537 int evp_keymgmt_util_get_deflt_digest_name(EVP_KEYMGMT *keymgmt, 538 void *keydata, 539 char *mdname, size_t mdname_sz) 540 { 541 OSSL_PARAM params[3]; 542 char mddefault[100] = ""; 543 char mdmandatory[100] = ""; 544 char *result = NULL; 545 int rv = -2; 546 547 params[0] = 548 OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, 549 mddefault, sizeof(mddefault)); 550 params[1] = 551 OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, 552 mdmandatory, 553 sizeof(mdmandatory)); 554 params[2] = OSSL_PARAM_construct_end(); 555 556 if (!evp_keymgmt_get_params(keymgmt, keydata, params)) 557 return 0; 558 559 if (OSSL_PARAM_modified(params + 1)) { 560 if (params[1].return_size <= 1) /* Only a NUL byte */ 561 result = SN_undef; 562 else 563 result = mdmandatory; 564 rv = 2; 565 } else if (OSSL_PARAM_modified(params)) { 566 if (params[0].return_size <= 1) /* Only a NUL byte */ 567 result = SN_undef; 568 else 569 result = mddefault; 570 rv = 1; 571 } 572 if (rv > 0) 573 OPENSSL_strlcpy(mdname, result, mdname_sz); 574 return rv; 575 } 576 577 /* 578 * If |keymgmt| has the method function |query_operation_name|, use it to get 579 * the name of a supported operation identity. Otherwise, return the keytype, 580 * assuming that it works as a default operation name. 581 */ 582 const char *evp_keymgmt_util_query_operation_name(EVP_KEYMGMT *keymgmt, 583 int op_id) 584 { 585 const char *name = NULL; 586 587 if (keymgmt != NULL) { 588 if (keymgmt->query_operation_name != NULL) 589 name = keymgmt->query_operation_name(op_id); 590 if (name == NULL) 591 name = EVP_KEYMGMT_get0_name(keymgmt); 592 } 593 return name; 594 } 595