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 ERR_set_mark(); 265 ret = cipher->encrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen); 266 if (ret <= 0 && ERR_count_to_mark() == 0) 267 ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE, 268 "%s encrypt:%s", cipher->type_name, desc); 269 ERR_clear_last_mark(); 270 return ret; 271 272 legacy: 273 if (ctx->pmeth == NULL || ctx->pmeth->encrypt == NULL) { 274 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 275 return -2; 276 } 277 M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT) 278 return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); 279 } 280 281 int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) 282 { 283 return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_DECRYPT, NULL); 284 } 285 286 int EVP_PKEY_decrypt_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) 287 { 288 return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_DECRYPT, params); 289 } 290 291 int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, 292 unsigned char *out, size_t *outlen, 293 const unsigned char *in, size_t inlen) 294 { 295 EVP_ASYM_CIPHER *cipher; 296 const char *desc; 297 int ret; 298 299 if (ctx == NULL) { 300 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 301 return -2; 302 } 303 304 if (ctx->operation != EVP_PKEY_OP_DECRYPT) { 305 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); 306 return -1; 307 } 308 309 if (ctx->op.ciph.algctx == NULL) 310 goto legacy; 311 312 cipher = ctx->op.ciph.cipher; 313 desc = cipher->description != NULL ? cipher->description : ""; 314 ERR_set_mark(); 315 ret = cipher->decrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen); 316 if (ret <= 0 && ERR_count_to_mark() == 0) 317 ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE, 318 "%s decrypt:%s", cipher->type_name, desc); 319 ERR_clear_last_mark(); 320 321 return ret; 322 323 legacy: 324 if (ctx->pmeth == NULL || ctx->pmeth->decrypt == NULL) { 325 ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 326 return -2; 327 } 328 M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) 329 return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); 330 } 331 332 /* decrypt to new buffer of dynamic size, checking any pre-determined size */ 333 int evp_pkey_decrypt_alloc(EVP_PKEY_CTX *ctx, unsigned char **outp, 334 size_t *outlenp, size_t expected_outlen, 335 const unsigned char *in, size_t inlen) 336 { 337 if (EVP_PKEY_decrypt(ctx, NULL, outlenp, in, inlen) <= 0 338 || (*outp = OPENSSL_malloc(*outlenp)) == NULL) 339 return -1; 340 if (EVP_PKEY_decrypt(ctx, *outp, outlenp, in, inlen) <= 0 341 || *outlenp == 0 342 || (expected_outlen != 0 && *outlenp != expected_outlen)) { 343 ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); 344 OPENSSL_clear_free(*outp, *outlenp); 345 *outp = NULL; 346 return 0; 347 } 348 return 1; 349 } 350 351 static EVP_ASYM_CIPHER *evp_asym_cipher_new(OSSL_PROVIDER *prov) 352 { 353 EVP_ASYM_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_ASYM_CIPHER)); 354 355 if (cipher == NULL) 356 return NULL; 357 358 if (!CRYPTO_NEW_REF(&cipher->refcnt, 1) 359 || !ossl_provider_up_ref(prov)) { 360 CRYPTO_FREE_REF(&cipher->refcnt); 361 OPENSSL_free(cipher); 362 return NULL; 363 } 364 cipher->prov = prov; 365 366 return cipher; 367 } 368 369 static void *evp_asym_cipher_from_algorithm(int name_id, 370 const OSSL_ALGORITHM *algodef, 371 OSSL_PROVIDER *prov) 372 { 373 const OSSL_DISPATCH *fns = algodef->implementation; 374 EVP_ASYM_CIPHER *cipher = NULL; 375 int ctxfncnt = 0, encfncnt = 0, decfncnt = 0; 376 int gparamfncnt = 0, sparamfncnt = 0; 377 378 if ((cipher = evp_asym_cipher_new(prov)) == NULL) { 379 ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); 380 goto err; 381 } 382 383 cipher->name_id = name_id; 384 if ((cipher->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) 385 goto err; 386 cipher->description = algodef->algorithm_description; 387 388 for (; fns->function_id != 0; fns++) { 389 switch (fns->function_id) { 390 case OSSL_FUNC_ASYM_CIPHER_NEWCTX: 391 if (cipher->newctx != NULL) 392 break; 393 cipher->newctx = OSSL_FUNC_asym_cipher_newctx(fns); 394 ctxfncnt++; 395 break; 396 case OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT: 397 if (cipher->encrypt_init != NULL) 398 break; 399 cipher->encrypt_init = OSSL_FUNC_asym_cipher_encrypt_init(fns); 400 encfncnt++; 401 break; 402 case OSSL_FUNC_ASYM_CIPHER_ENCRYPT: 403 if (cipher->encrypt != NULL) 404 break; 405 cipher->encrypt = OSSL_FUNC_asym_cipher_encrypt(fns); 406 encfncnt++; 407 break; 408 case OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT: 409 if (cipher->decrypt_init != NULL) 410 break; 411 cipher->decrypt_init = OSSL_FUNC_asym_cipher_decrypt_init(fns); 412 decfncnt++; 413 break; 414 case OSSL_FUNC_ASYM_CIPHER_DECRYPT: 415 if (cipher->decrypt != NULL) 416 break; 417 cipher->decrypt = OSSL_FUNC_asym_cipher_decrypt(fns); 418 decfncnt++; 419 break; 420 case OSSL_FUNC_ASYM_CIPHER_FREECTX: 421 if (cipher->freectx != NULL) 422 break; 423 cipher->freectx = OSSL_FUNC_asym_cipher_freectx(fns); 424 ctxfncnt++; 425 break; 426 case OSSL_FUNC_ASYM_CIPHER_DUPCTX: 427 if (cipher->dupctx != NULL) 428 break; 429 cipher->dupctx = OSSL_FUNC_asym_cipher_dupctx(fns); 430 break; 431 case OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS: 432 if (cipher->get_ctx_params != NULL) 433 break; 434 cipher->get_ctx_params 435 = OSSL_FUNC_asym_cipher_get_ctx_params(fns); 436 gparamfncnt++; 437 break; 438 case OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS: 439 if (cipher->gettable_ctx_params != NULL) 440 break; 441 cipher->gettable_ctx_params 442 = OSSL_FUNC_asym_cipher_gettable_ctx_params(fns); 443 gparamfncnt++; 444 break; 445 case OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS: 446 if (cipher->set_ctx_params != NULL) 447 break; 448 cipher->set_ctx_params 449 = OSSL_FUNC_asym_cipher_set_ctx_params(fns); 450 sparamfncnt++; 451 break; 452 case OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS: 453 if (cipher->settable_ctx_params != NULL) 454 break; 455 cipher->settable_ctx_params 456 = OSSL_FUNC_asym_cipher_settable_ctx_params(fns); 457 sparamfncnt++; 458 break; 459 } 460 } 461 if (ctxfncnt != 2 462 || (encfncnt != 0 && encfncnt != 2) 463 || (decfncnt != 0 && decfncnt != 2) 464 || (encfncnt != 2 && decfncnt != 2) 465 || (gparamfncnt != 0 && gparamfncnt != 2) 466 || (sparamfncnt != 0 && sparamfncnt != 2)) { 467 /* 468 * In order to be a consistent set of functions we must have at least 469 * a set of context functions (newctx and freectx) as well as a pair of 470 * "cipher" functions: (encrypt_init, encrypt) or 471 * (decrypt_init decrypt). set_ctx_params and settable_ctx_params are 472 * optional, but if one of them is present then the other one must also 473 * be present. The same applies to get_ctx_params and 474 * gettable_ctx_params. The dupctx function is optional. 475 */ 476 ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); 477 goto err; 478 } 479 480 return cipher; 481 err: 482 EVP_ASYM_CIPHER_free(cipher); 483 return NULL; 484 } 485 486 void EVP_ASYM_CIPHER_free(EVP_ASYM_CIPHER *cipher) 487 { 488 int i; 489 490 if (cipher == NULL) 491 return; 492 CRYPTO_DOWN_REF(&cipher->refcnt, &i); 493 if (i > 0) 494 return; 495 OPENSSL_free(cipher->type_name); 496 ossl_provider_free(cipher->prov); 497 CRYPTO_FREE_REF(&cipher->refcnt); 498 OPENSSL_free(cipher); 499 } 500 501 int EVP_ASYM_CIPHER_up_ref(EVP_ASYM_CIPHER *cipher) 502 { 503 int ref = 0; 504 505 CRYPTO_UP_REF(&cipher->refcnt, &ref); 506 return 1; 507 } 508 509 OSSL_PROVIDER *EVP_ASYM_CIPHER_get0_provider(const EVP_ASYM_CIPHER *cipher) 510 { 511 return cipher->prov; 512 } 513 514 EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, 515 const char *properties) 516 { 517 return evp_generic_fetch(ctx, OSSL_OP_ASYM_CIPHER, algorithm, properties, 518 evp_asym_cipher_from_algorithm, 519 evp_asym_cipher_up_ref, 520 evp_asym_cipher_free); 521 } 522 523 EVP_ASYM_CIPHER *evp_asym_cipher_fetch_from_prov(OSSL_PROVIDER *prov, 524 const char *algorithm, 525 const char *properties) 526 { 527 return evp_generic_fetch_from_prov(prov, OSSL_OP_ASYM_CIPHER, 528 algorithm, properties, 529 evp_asym_cipher_from_algorithm, 530 evp_asym_cipher_up_ref, 531 evp_asym_cipher_free); 532 } 533 534 int EVP_ASYM_CIPHER_is_a(const EVP_ASYM_CIPHER *cipher, const char *name) 535 { 536 return evp_is_a(cipher->prov, cipher->name_id, NULL, name); 537 } 538 539 int evp_asym_cipher_get_number(const EVP_ASYM_CIPHER *cipher) 540 { 541 return cipher->name_id; 542 } 543 544 const char *EVP_ASYM_CIPHER_get0_name(const EVP_ASYM_CIPHER *cipher) 545 { 546 return cipher->type_name; 547 } 548 549 const char *EVP_ASYM_CIPHER_get0_description(const EVP_ASYM_CIPHER *cipher) 550 { 551 return cipher->description; 552 } 553 554 void EVP_ASYM_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx, 555 void (*fn)(EVP_ASYM_CIPHER *cipher, 556 void *arg), 557 void *arg) 558 { 559 evp_generic_do_all(libctx, OSSL_OP_ASYM_CIPHER, 560 (void (*)(void *, void *))fn, arg, 561 evp_asym_cipher_from_algorithm, 562 evp_asym_cipher_up_ref, 563 evp_asym_cipher_free); 564 } 565 566 567 int EVP_ASYM_CIPHER_names_do_all(const EVP_ASYM_CIPHER *cipher, 568 void (*fn)(const char *name, void *data), 569 void *data) 570 { 571 if (cipher->prov != NULL) 572 return evp_names_do_all(cipher->prov, cipher->name_id, fn, data); 573 574 return 1; 575 } 576 577 const OSSL_PARAM *EVP_ASYM_CIPHER_gettable_ctx_params(const EVP_ASYM_CIPHER *cip) 578 { 579 void *provctx; 580 581 if (cip == NULL || cip->gettable_ctx_params == NULL) 582 return NULL; 583 584 provctx = ossl_provider_ctx(EVP_ASYM_CIPHER_get0_provider(cip)); 585 return cip->gettable_ctx_params(NULL, provctx); 586 } 587 588 const OSSL_PARAM *EVP_ASYM_CIPHER_settable_ctx_params(const EVP_ASYM_CIPHER *cip) 589 { 590 void *provctx; 591 592 if (cip == NULL || cip->settable_ctx_params == NULL) 593 return NULL; 594 595 provctx = ossl_provider_ctx(EVP_ASYM_CIPHER_get0_provider(cip)); 596 return cip->settable_ctx_params(NULL, provctx); 597 } 598