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