1 /* 2 * Copyright 2019-2023 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 /* 11 * RSA low level APIs are deprecated for public use, but still ok for 12 * internal use. 13 */ 14 #include "internal/deprecated.h" 15 16 #include <openssl/crypto.h> 17 #include <openssl/evp.h> 18 #include <openssl/core_dispatch.h> 19 #include <openssl/core_names.h> 20 #include <openssl/rsa.h> 21 #include <openssl/params.h> 22 #include <openssl/err.h> 23 #include <openssl/proverr.h> 24 /* Just for SSL_MAX_MASTER_KEY_LENGTH */ 25 #include <openssl/prov_ssl.h> 26 #include "internal/constant_time.h" 27 #include "internal/sizes.h" 28 #include "crypto/rsa.h" 29 #include "prov/provider_ctx.h" 30 #include "prov/implementations.h" 31 #include "prov/providercommon.h" 32 #include "prov/securitycheck.h" 33 34 #include <stdlib.h> 35 36 static OSSL_FUNC_asym_cipher_newctx_fn rsa_newctx; 37 static OSSL_FUNC_asym_cipher_encrypt_init_fn rsa_encrypt_init; 38 static OSSL_FUNC_asym_cipher_encrypt_fn rsa_encrypt; 39 static OSSL_FUNC_asym_cipher_decrypt_init_fn rsa_decrypt_init; 40 static OSSL_FUNC_asym_cipher_decrypt_fn rsa_decrypt; 41 static OSSL_FUNC_asym_cipher_freectx_fn rsa_freectx; 42 static OSSL_FUNC_asym_cipher_dupctx_fn rsa_dupctx; 43 static OSSL_FUNC_asym_cipher_get_ctx_params_fn rsa_get_ctx_params; 44 static OSSL_FUNC_asym_cipher_gettable_ctx_params_fn rsa_gettable_ctx_params; 45 static OSSL_FUNC_asym_cipher_set_ctx_params_fn rsa_set_ctx_params; 46 static OSSL_FUNC_asym_cipher_settable_ctx_params_fn rsa_settable_ctx_params; 47 48 static OSSL_ITEM padding_item[] = { 49 { RSA_PKCS1_PADDING, OSSL_PKEY_RSA_PAD_MODE_PKCSV15 }, 50 { RSA_NO_PADDING, OSSL_PKEY_RSA_PAD_MODE_NONE }, 51 { RSA_PKCS1_OAEP_PADDING, OSSL_PKEY_RSA_PAD_MODE_OAEP }, /* Correct spelling first */ 52 { RSA_PKCS1_OAEP_PADDING, "oeap" }, 53 { RSA_X931_PADDING, OSSL_PKEY_RSA_PAD_MODE_X931 }, 54 { 0, NULL } 55 }; 56 57 /* 58 * What's passed as an actual key is defined by the KEYMGMT interface. 59 * We happen to know that our KEYMGMT simply passes RSA structures, so 60 * we use that here too. 61 */ 62 63 typedef struct { 64 OSSL_LIB_CTX *libctx; 65 RSA *rsa; 66 int pad_mode; 67 int operation; 68 /* OAEP message digest */ 69 EVP_MD *oaep_md; 70 /* message digest for MGF1 */ 71 EVP_MD *mgf1_md; 72 /* OAEP label */ 73 unsigned char *oaep_label; 74 size_t oaep_labellen; 75 /* TLS padding */ 76 unsigned int client_version; 77 unsigned int alt_version; 78 } PROV_RSA_CTX; 79 80 static void *rsa_newctx(void *provctx) 81 { 82 PROV_RSA_CTX *prsactx; 83 84 if (!ossl_prov_is_running()) 85 return NULL; 86 prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX)); 87 if (prsactx == NULL) 88 return NULL; 89 prsactx->libctx = PROV_LIBCTX_OF(provctx); 90 91 return prsactx; 92 } 93 94 static int rsa_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[], 95 int operation) 96 { 97 PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 98 99 if (!ossl_prov_is_running() || prsactx == NULL || vrsa == NULL) 100 return 0; 101 102 if (!ossl_rsa_check_key(prsactx->libctx, vrsa, operation)) 103 return 0; 104 105 if (!RSA_up_ref(vrsa)) 106 return 0; 107 RSA_free(prsactx->rsa); 108 prsactx->rsa = vrsa; 109 prsactx->operation = operation; 110 111 switch (RSA_test_flags(prsactx->rsa, RSA_FLAG_TYPE_MASK)) { 112 case RSA_FLAG_TYPE_RSA: 113 prsactx->pad_mode = RSA_PKCS1_PADDING; 114 break; 115 default: 116 /* This should not happen due to the check above */ 117 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 118 return 0; 119 } 120 return rsa_set_ctx_params(prsactx, params); 121 } 122 123 static int rsa_encrypt_init(void *vprsactx, void *vrsa, 124 const OSSL_PARAM params[]) 125 { 126 return rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_ENCRYPT); 127 } 128 129 static int rsa_decrypt_init(void *vprsactx, void *vrsa, 130 const OSSL_PARAM params[]) 131 { 132 return rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_DECRYPT); 133 } 134 135 static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen, 136 size_t outsize, const unsigned char *in, size_t inlen) 137 { 138 PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 139 int ret; 140 141 if (!ossl_prov_is_running()) 142 return 0; 143 144 if (out == NULL) { 145 size_t len = RSA_size(prsactx->rsa); 146 147 if (len == 0) { 148 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); 149 return 0; 150 } 151 *outlen = len; 152 return 1; 153 } 154 155 if (prsactx->pad_mode == RSA_PKCS1_OAEP_PADDING) { 156 int rsasize = RSA_size(prsactx->rsa); 157 unsigned char *tbuf; 158 159 if ((tbuf = OPENSSL_malloc(rsasize)) == NULL) { 160 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 161 return 0; 162 } 163 if (prsactx->oaep_md == NULL) { 164 prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, "SHA-1", NULL); 165 if (prsactx->oaep_md == NULL) { 166 OPENSSL_free(tbuf); 167 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 168 return 0; 169 } 170 } 171 ret = 172 ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(prsactx->libctx, tbuf, 173 rsasize, in, inlen, 174 prsactx->oaep_label, 175 prsactx->oaep_labellen, 176 prsactx->oaep_md, 177 prsactx->mgf1_md); 178 179 if (!ret) { 180 OPENSSL_free(tbuf); 181 return 0; 182 } 183 ret = RSA_public_encrypt(rsasize, tbuf, out, prsactx->rsa, 184 RSA_NO_PADDING); 185 OPENSSL_free(tbuf); 186 } else { 187 ret = RSA_public_encrypt(inlen, in, out, prsactx->rsa, 188 prsactx->pad_mode); 189 } 190 /* A ret value of 0 is not an error */ 191 if (ret < 0) 192 return ret; 193 *outlen = ret; 194 return 1; 195 } 196 197 static int rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, 198 size_t outsize, const unsigned char *in, size_t inlen) 199 { 200 PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 201 int ret; 202 size_t len = RSA_size(prsactx->rsa); 203 204 if (!ossl_prov_is_running()) 205 return 0; 206 207 if (prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) { 208 if (out == NULL) { 209 *outlen = SSL_MAX_MASTER_KEY_LENGTH; 210 return 1; 211 } 212 if (outsize < SSL_MAX_MASTER_KEY_LENGTH) { 213 ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH); 214 return 0; 215 } 216 } else { 217 if (out == NULL) { 218 if (len == 0) { 219 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); 220 return 0; 221 } 222 *outlen = len; 223 return 1; 224 } 225 226 if (outsize < len) { 227 ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH); 228 return 0; 229 } 230 } 231 232 if (prsactx->pad_mode == RSA_PKCS1_OAEP_PADDING 233 || prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) { 234 unsigned char *tbuf; 235 236 if ((tbuf = OPENSSL_malloc(len)) == NULL) { 237 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 238 return 0; 239 } 240 ret = RSA_private_decrypt(inlen, in, tbuf, prsactx->rsa, 241 RSA_NO_PADDING); 242 /* 243 * With no padding then, on success ret should be len, otherwise an 244 * error occurred (non-constant time) 245 */ 246 if (ret != (int)len) { 247 OPENSSL_free(tbuf); 248 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_DECRYPT); 249 return 0; 250 } 251 if (prsactx->pad_mode == RSA_PKCS1_OAEP_PADDING) { 252 if (prsactx->oaep_md == NULL) { 253 prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, "SHA-1", NULL); 254 if (prsactx->oaep_md == NULL) { 255 OPENSSL_free(tbuf); 256 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 257 return 0; 258 } 259 } 260 ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, outsize, tbuf, 261 len, len, 262 prsactx->oaep_label, 263 prsactx->oaep_labellen, 264 prsactx->oaep_md, 265 prsactx->mgf1_md); 266 } else { 267 /* RSA_PKCS1_WITH_TLS_PADDING */ 268 if (prsactx->client_version <= 0) { 269 ERR_raise(ERR_LIB_PROV, PROV_R_BAD_TLS_CLIENT_VERSION); 270 OPENSSL_free(tbuf); 271 return 0; 272 } 273 ret = ossl_rsa_padding_check_PKCS1_type_2_TLS( 274 prsactx->libctx, out, outsize, tbuf, len, 275 prsactx->client_version, prsactx->alt_version); 276 } 277 OPENSSL_free(tbuf); 278 } else { 279 ret = RSA_private_decrypt(inlen, in, out, prsactx->rsa, 280 prsactx->pad_mode); 281 } 282 *outlen = constant_time_select_s(constant_time_msb_s(ret), *outlen, ret); 283 ret = constant_time_select_int(constant_time_msb(ret), 0, 1); 284 return ret; 285 } 286 287 static void rsa_freectx(void *vprsactx) 288 { 289 PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 290 291 RSA_free(prsactx->rsa); 292 293 EVP_MD_free(prsactx->oaep_md); 294 EVP_MD_free(prsactx->mgf1_md); 295 OPENSSL_free(prsactx->oaep_label); 296 297 OPENSSL_free(prsactx); 298 } 299 300 static void *rsa_dupctx(void *vprsactx) 301 { 302 PROV_RSA_CTX *srcctx = (PROV_RSA_CTX *)vprsactx; 303 PROV_RSA_CTX *dstctx; 304 305 if (!ossl_prov_is_running()) 306 return NULL; 307 308 dstctx = OPENSSL_zalloc(sizeof(*srcctx)); 309 if (dstctx == NULL) 310 return NULL; 311 312 *dstctx = *srcctx; 313 if (dstctx->rsa != NULL && !RSA_up_ref(dstctx->rsa)) { 314 OPENSSL_free(dstctx); 315 return NULL; 316 } 317 318 if (dstctx->oaep_md != NULL && !EVP_MD_up_ref(dstctx->oaep_md)) { 319 RSA_free(dstctx->rsa); 320 OPENSSL_free(dstctx); 321 return NULL; 322 } 323 324 if (dstctx->mgf1_md != NULL && !EVP_MD_up_ref(dstctx->mgf1_md)) { 325 RSA_free(dstctx->rsa); 326 EVP_MD_free(dstctx->oaep_md); 327 OPENSSL_free(dstctx); 328 return NULL; 329 } 330 331 return dstctx; 332 } 333 334 static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) 335 { 336 PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 337 OSSL_PARAM *p; 338 339 if (prsactx == NULL) 340 return 0; 341 342 p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_PAD_MODE); 343 if (p != NULL) 344 switch (p->data_type) { 345 case OSSL_PARAM_INTEGER: /* Support for legacy pad mode number */ 346 if (!OSSL_PARAM_set_int(p, prsactx->pad_mode)) 347 return 0; 348 break; 349 case OSSL_PARAM_UTF8_STRING: 350 { 351 int i; 352 const char *word = NULL; 353 354 for (i = 0; padding_item[i].id != 0; i++) { 355 if (prsactx->pad_mode == (int)padding_item[i].id) { 356 word = padding_item[i].ptr; 357 break; 358 } 359 } 360 361 if (word != NULL) { 362 if (!OSSL_PARAM_set_utf8_string(p, word)) 363 return 0; 364 } else { 365 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 366 } 367 } 368 break; 369 default: 370 return 0; 371 } 372 373 p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST); 374 if (p != NULL && !OSSL_PARAM_set_utf8_string(p, prsactx->oaep_md == NULL 375 ? "" 376 : EVP_MD_get0_name(prsactx->oaep_md))) 377 return 0; 378 379 p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST); 380 if (p != NULL) { 381 EVP_MD *mgf1_md = prsactx->mgf1_md == NULL ? prsactx->oaep_md 382 : prsactx->mgf1_md; 383 384 if (!OSSL_PARAM_set_utf8_string(p, mgf1_md == NULL 385 ? "" 386 : EVP_MD_get0_name(mgf1_md))) 387 return 0; 388 } 389 390 p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL); 391 if (p != NULL && 392 !OSSL_PARAM_set_octet_ptr(p, prsactx->oaep_label, 393 prsactx->oaep_labellen)) 394 return 0; 395 396 p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION); 397 if (p != NULL && !OSSL_PARAM_set_uint(p, prsactx->client_version)) 398 return 0; 399 400 p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION); 401 if (p != NULL && !OSSL_PARAM_set_uint(p, prsactx->alt_version)) 402 return 0; 403 404 return 1; 405 } 406 407 static const OSSL_PARAM known_gettable_ctx_params[] = { 408 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, NULL, 0), 409 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL, 0), 410 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, NULL, 0), 411 OSSL_PARAM_DEFN(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, OSSL_PARAM_OCTET_PTR, 412 NULL, 0), 413 OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, NULL), 414 OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL), 415 OSSL_PARAM_END 416 }; 417 418 static const OSSL_PARAM *rsa_gettable_ctx_params(ossl_unused void *vprsactx, 419 ossl_unused void *provctx) 420 { 421 return known_gettable_ctx_params; 422 } 423 424 static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) 425 { 426 PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 427 const OSSL_PARAM *p; 428 char mdname[OSSL_MAX_NAME_SIZE]; 429 char mdprops[OSSL_MAX_PROPQUERY_SIZE] = { '\0' }; 430 char *str = NULL; 431 432 if (prsactx == NULL) 433 return 0; 434 if (params == NULL) 435 return 1; 436 437 p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST); 438 if (p != NULL) { 439 str = mdname; 440 if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdname))) 441 return 0; 442 443 p = OSSL_PARAM_locate_const(params, 444 OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS); 445 if (p != NULL) { 446 str = mdprops; 447 if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops))) 448 return 0; 449 } 450 451 EVP_MD_free(prsactx->oaep_md); 452 prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, mdname, mdprops); 453 454 if (prsactx->oaep_md == NULL) 455 return 0; 456 } 457 458 p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_PAD_MODE); 459 if (p != NULL) { 460 int pad_mode = 0; 461 462 switch (p->data_type) { 463 case OSSL_PARAM_INTEGER: /* Support for legacy pad mode number */ 464 if (!OSSL_PARAM_get_int(p, &pad_mode)) 465 return 0; 466 break; 467 case OSSL_PARAM_UTF8_STRING: 468 { 469 int i; 470 471 if (p->data == NULL) 472 return 0; 473 474 for (i = 0; padding_item[i].id != 0; i++) { 475 if (strcmp(p->data, padding_item[i].ptr) == 0) { 476 pad_mode = padding_item[i].id; 477 break; 478 } 479 } 480 } 481 break; 482 default: 483 return 0; 484 } 485 486 /* 487 * PSS padding is for signatures only so is not compatible with 488 * asymmetric cipher use. 489 */ 490 if (pad_mode == RSA_PKCS1_PSS_PADDING) 491 return 0; 492 if (pad_mode == RSA_PKCS1_OAEP_PADDING && prsactx->oaep_md == NULL) { 493 prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, "SHA1", mdprops); 494 if (prsactx->oaep_md == NULL) 495 return 0; 496 } 497 prsactx->pad_mode = pad_mode; 498 } 499 500 p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST); 501 if (p != NULL) { 502 str = mdname; 503 if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdname))) 504 return 0; 505 506 p = OSSL_PARAM_locate_const(params, 507 OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS); 508 if (p != NULL) { 509 str = mdprops; 510 if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops))) 511 return 0; 512 } else { 513 str = NULL; 514 } 515 516 EVP_MD_free(prsactx->mgf1_md); 517 prsactx->mgf1_md = EVP_MD_fetch(prsactx->libctx, mdname, str); 518 519 if (prsactx->mgf1_md == NULL) 520 return 0; 521 } 522 523 p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL); 524 if (p != NULL) { 525 void *tmp_label = NULL; 526 size_t tmp_labellen; 527 528 if (!OSSL_PARAM_get_octet_string(p, &tmp_label, 0, &tmp_labellen)) 529 return 0; 530 OPENSSL_free(prsactx->oaep_label); 531 prsactx->oaep_label = (unsigned char *)tmp_label; 532 prsactx->oaep_labellen = tmp_labellen; 533 } 534 535 p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION); 536 if (p != NULL) { 537 unsigned int client_version; 538 539 if (!OSSL_PARAM_get_uint(p, &client_version)) 540 return 0; 541 prsactx->client_version = client_version; 542 } 543 544 p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION); 545 if (p != NULL) { 546 unsigned int alt_version; 547 548 if (!OSSL_PARAM_get_uint(p, &alt_version)) 549 return 0; 550 prsactx->alt_version = alt_version; 551 } 552 553 return 1; 554 } 555 556 static const OSSL_PARAM known_settable_ctx_params[] = { 557 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, NULL, 0), 558 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS, NULL, 0), 559 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL, 0), 560 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, NULL, 0), 561 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS, NULL, 0), 562 OSSL_PARAM_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, NULL, 0), 563 OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, NULL), 564 OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL), 565 OSSL_PARAM_END 566 }; 567 568 static const OSSL_PARAM *rsa_settable_ctx_params(ossl_unused void *vprsactx, 569 ossl_unused void *provctx) 570 { 571 return known_settable_ctx_params; 572 } 573 574 const OSSL_DISPATCH ossl_rsa_asym_cipher_functions[] = { 575 { OSSL_FUNC_ASYM_CIPHER_NEWCTX, (void (*)(void))rsa_newctx }, 576 { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, (void (*)(void))rsa_encrypt_init }, 577 { OSSL_FUNC_ASYM_CIPHER_ENCRYPT, (void (*)(void))rsa_encrypt }, 578 { OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT, (void (*)(void))rsa_decrypt_init }, 579 { OSSL_FUNC_ASYM_CIPHER_DECRYPT, (void (*)(void))rsa_decrypt }, 580 { OSSL_FUNC_ASYM_CIPHER_FREECTX, (void (*)(void))rsa_freectx }, 581 { OSSL_FUNC_ASYM_CIPHER_DUPCTX, (void (*)(void))rsa_dupctx }, 582 { OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS, 583 (void (*)(void))rsa_get_ctx_params }, 584 { OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS, 585 (void (*)(void))rsa_gettable_ctx_params }, 586 { OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS, 587 (void (*)(void))rsa_set_ctx_params }, 588 { OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS, 589 (void (*)(void))rsa_settable_ctx_params }, 590 { 0, NULL } 591 }; 592