Coverage Report

Created: 2025-12-31 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl36/providers/implementations/asymciphers/rsa_enc.c
Line
Count
Source
1
/*
2
 * Copyright 2019-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
/* clang-format off */
10
11
/* clang-format on */
12
13
/*
14
 * RSA low level APIs are deprecated for public use, but still ok for
15
 * internal use.
16
 */
17
#include "internal/deprecated.h"
18
19
#include <openssl/crypto.h>
20
#include <openssl/evp.h>
21
#include <openssl/core_dispatch.h>
22
#include <openssl/core_names.h>
23
#include <openssl/rsa.h>
24
#include <openssl/params.h>
25
#include <openssl/err.h>
26
#include <openssl/proverr.h>
27
/* Just for SSL_MAX_MASTER_KEY_LENGTH */
28
#include <openssl/prov_ssl.h>
29
#include "internal/constant_time.h"
30
#include "internal/cryptlib.h"
31
#include "internal/sizes.h"
32
#include "crypto/rsa.h"
33
#include "prov/provider_ctx.h"
34
#include "prov/implementations.h"
35
#include "prov/providercommon.h"
36
#include "prov/securitycheck.h"
37
#include <stdlib.h>
38
39
static OSSL_FUNC_asym_cipher_newctx_fn rsa_newctx;
40
static OSSL_FUNC_asym_cipher_encrypt_init_fn rsa_encrypt_init;
41
static OSSL_FUNC_asym_cipher_encrypt_fn rsa_encrypt;
42
static OSSL_FUNC_asym_cipher_decrypt_init_fn rsa_decrypt_init;
43
static OSSL_FUNC_asym_cipher_decrypt_fn rsa_decrypt;
44
static OSSL_FUNC_asym_cipher_freectx_fn rsa_freectx;
45
static OSSL_FUNC_asym_cipher_dupctx_fn rsa_dupctx;
46
static OSSL_FUNC_asym_cipher_get_ctx_params_fn rsa_get_ctx_params;
47
static OSSL_FUNC_asym_cipher_gettable_ctx_params_fn rsa_gettable_ctx_params;
48
static OSSL_FUNC_asym_cipher_set_ctx_params_fn rsa_set_ctx_params;
49
static OSSL_FUNC_asym_cipher_settable_ctx_params_fn rsa_settable_ctx_params;
50
51
static OSSL_ITEM padding_item[] = {
52
    { RSA_PKCS1_PADDING, OSSL_PKEY_RSA_PAD_MODE_PKCSV15 },
53
    { RSA_NO_PADDING, OSSL_PKEY_RSA_PAD_MODE_NONE },
54
    { RSA_PKCS1_OAEP_PADDING, OSSL_PKEY_RSA_PAD_MODE_OAEP }, /* Correct spelling first */
55
    { RSA_PKCS1_OAEP_PADDING, "oeap" },
56
    { 0, NULL }
57
};
58
59
/*
60
 * What's passed as an actual key is defined by the KEYMGMT interface.
61
 * We happen to know that our KEYMGMT simply passes RSA structures, so
62
 * we use that here too.
63
 */
64
65
typedef struct {
66
    OSSL_LIB_CTX *libctx;
67
    RSA *rsa;
68
    int pad_mode;
69
    int operation;
70
    /* OAEP message digest */
71
    EVP_MD *oaep_md;
72
    /* message digest for MGF1 */
73
    EVP_MD *mgf1_md;
74
    /* OAEP label */
75
    unsigned char *oaep_label;
76
    size_t oaep_labellen;
77
    /* TLS padding */
78
    unsigned int client_version;
79
    unsigned int alt_version;
80
    /* PKCS#1 v1.5 decryption mode */
81
    unsigned int implicit_rejection;
82
    OSSL_FIPS_IND_DECLARE
83
} PROV_RSA_CTX;
84
85
static void *rsa_newctx(void *provctx)
86
16.9k
{
87
16.9k
    PROV_RSA_CTX *prsactx;
88
89
16.9k
    if (!ossl_prov_is_running())
90
0
        return NULL;
91
16.9k
    prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX));
92
16.9k
    if (prsactx == NULL)
93
0
        return NULL;
94
16.9k
    prsactx->libctx = PROV_LIBCTX_OF(provctx);
95
16.9k
    OSSL_FIPS_IND_INIT(prsactx)
96
97
16.9k
    return prsactx;
98
16.9k
}
99
100
static int rsa_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[],
101
    int operation, const char *desc)
102
12.3k
{
103
12.3k
    PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
104
12.3k
    int protect = 0;
105
106
12.3k
    if (!ossl_prov_is_running() || prsactx == NULL || vrsa == NULL)
107
0
        return 0;
108
109
12.3k
    if (!ossl_rsa_key_op_get_protect(vrsa, operation, &protect))
110
0
        return 0;
111
12.3k
    if (!RSA_up_ref(vrsa))
112
0
        return 0;
113
12.3k
    RSA_free(prsactx->rsa);
114
12.3k
    prsactx->rsa = vrsa;
115
12.3k
    prsactx->operation = operation;
116
12.3k
    prsactx->implicit_rejection = 1;
117
118
12.3k
    switch (RSA_test_flags(prsactx->rsa, RSA_FLAG_TYPE_MASK)) {
119
12.3k
    case RSA_FLAG_TYPE_RSA:
120
12.3k
        prsactx->pad_mode = RSA_PKCS1_PADDING;
121
12.3k
        break;
122
0
    default:
123
        /* This should not happen due to the check above */
124
0
        ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
125
0
        return 0;
126
12.3k
    }
127
128
12.3k
    OSSL_FIPS_IND_SET_APPROVED(prsactx)
129
12.3k
    if (!rsa_set_ctx_params(prsactx, params))
130
0
        return 0;
131
#ifdef FIPS_MODULE
132
    if (!ossl_fips_ind_rsa_key_check(OSSL_FIPS_IND_GET(prsactx),
133
            OSSL_FIPS_IND_SETTABLE0, prsactx->libctx,
134
            prsactx->rsa, desc, protect))
135
        return 0;
136
#endif
137
12.3k
    return 1;
138
12.3k
}
139
140
static int rsa_encrypt_init(void *vprsactx, void *vrsa,
141
    const OSSL_PARAM params[])
142
5.52k
{
143
5.52k
    return rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_ENCRYPT,
144
5.52k
        "RSA Encrypt Init");
145
5.52k
}
146
147
static int rsa_decrypt_init(void *vprsactx, void *vrsa,
148
    const OSSL_PARAM params[])
149
11.3k
{
150
11.3k
    return rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_DECRYPT,
151
11.3k
        "RSA Decrypt Init");
152
11.3k
}
153
154
static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen,
155
    size_t outsize, const unsigned char *in, size_t inlen)
156
11.0k
{
157
11.0k
    PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
158
11.0k
    size_t len = RSA_size(prsactx->rsa);
159
11.0k
    int ret;
160
161
11.0k
    if (!ossl_prov_is_running())
162
0
        return 0;
163
164
#ifdef FIPS_MODULE
165
    if ((prsactx->pad_mode == RSA_PKCS1_PADDING
166
            || prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING)
167
        && !OSSL_FIPS_IND_ON_UNAPPROVED(prsactx, OSSL_FIPS_IND_SETTABLE1,
168
            prsactx->libctx, "RSA Encrypt",
169
            "PKCS#1 v1.5 padding",
170
            ossl_fips_config_rsa_pkcs15_padding_disabled)) {
171
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE);
172
        return 0;
173
    }
174
#endif
175
176
11.0k
    if (len == 0) {
177
8
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
178
8
        return 0;
179
8
    }
180
181
11.0k
    if (out == NULL) {
182
5.52k
        *outlen = len;
183
5.52k
        return 1;
184
5.52k
    }
185
186
5.52k
    if (outsize < len) {
187
0
        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
188
0
        return 0;
189
0
    }
190
191
5.52k
    if (prsactx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
192
0
        int rsasize = RSA_size(prsactx->rsa);
193
0
        unsigned char *tbuf;
194
195
0
        if ((tbuf = OPENSSL_malloc(rsasize)) == NULL)
196
0
            return 0;
197
0
        if (prsactx->oaep_md == NULL) {
198
0
            prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, "SHA-1", NULL);
199
0
            if (prsactx->oaep_md == NULL) {
200
0
                OPENSSL_free(tbuf);
201
0
                ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
202
0
                return 0;
203
0
            }
204
0
        }
205
0
        ret = ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(prsactx->libctx, tbuf,
206
0
            rsasize, in, (int)inlen,
207
0
            prsactx->oaep_label,
208
0
            (int)prsactx->oaep_labellen,
209
0
            prsactx->oaep_md,
210
0
            prsactx->mgf1_md);
211
212
0
        if (!ret) {
213
0
            OPENSSL_free(tbuf);
214
0
            return 0;
215
0
        }
216
0
        ret = RSA_public_encrypt(rsasize, tbuf, out, prsactx->rsa,
217
0
            RSA_NO_PADDING);
218
0
        OPENSSL_free(tbuf);
219
5.52k
    } else {
220
5.52k
        ret = RSA_public_encrypt((int)inlen, in, out, prsactx->rsa,
221
5.52k
            prsactx->pad_mode);
222
5.52k
    }
223
    /* A ret value of 0 is not an error */
224
5.52k
    if (ret < 0)
225
720
        return ret;
226
4.80k
    *outlen = ret;
227
4.80k
    return 1;
228
5.52k
}
229
230
static int rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen,
231
    size_t outsize, const unsigned char *in, size_t inlen)
232
10.7k
{
233
10.7k
    PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
234
10.7k
    int ret;
235
10.7k
    int pad_mode;
236
10.7k
    size_t len = RSA_size(prsactx->rsa);
237
238
10.7k
    if (!ossl_prov_is_running())
239
0
        return 0;
240
241
10.7k
    if (prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) {
242
10.7k
        if (out == NULL) {
243
0
            *outlen = SSL_MAX_MASTER_KEY_LENGTH;
244
0
            return 1;
245
0
        }
246
10.7k
        if (outsize < SSL_MAX_MASTER_KEY_LENGTH) {
247
0
            ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH);
248
0
            return 0;
249
0
        }
250
10.7k
    } else {
251
0
        if (out == NULL) {
252
0
            if (len == 0) {
253
0
                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
254
0
                return 0;
255
0
            }
256
0
            *outlen = len;
257
0
            return 1;
258
0
        }
259
260
0
        if (outsize < len) {
261
0
            ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH);
262
0
            return 0;
263
0
        }
264
0
    }
265
266
10.7k
    if (prsactx->pad_mode == RSA_PKCS1_OAEP_PADDING
267
10.7k
        || prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) {
268
10.7k
        unsigned char *tbuf;
269
270
10.7k
        if ((tbuf = OPENSSL_malloc(len)) == NULL)
271
0
            return 0;
272
10.7k
        ret = RSA_private_decrypt((int)inlen, in, tbuf, prsactx->rsa,
273
10.7k
            RSA_NO_PADDING);
274
        /*
275
         * With no padding then, on success ret should be len, otherwise an
276
         * error occurred (non-constant time)
277
         */
278
10.7k
        if (ret != (int)len) {
279
27
            OPENSSL_free(tbuf);
280
27
            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_DECRYPT);
281
27
            return 0;
282
27
        }
283
10.7k
        if (prsactx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
284
0
            if (prsactx->oaep_md == NULL) {
285
0
                prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, "SHA-1", NULL);
286
0
                if (prsactx->oaep_md == NULL) {
287
0
                    OPENSSL_free(tbuf);
288
0
                    ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
289
0
                    return 0;
290
0
                }
291
0
            }
292
0
            ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, (int)outsize, tbuf,
293
0
                (int)len, (int)len,
294
0
                prsactx->oaep_label,
295
0
                (int)prsactx->oaep_labellen,
296
0
                prsactx->oaep_md,
297
0
                prsactx->mgf1_md);
298
10.7k
        } else {
299
            /* RSA_PKCS1_WITH_TLS_PADDING */
300
10.7k
            if (prsactx->client_version <= 0) {
301
21
                ERR_raise(ERR_LIB_PROV, PROV_R_BAD_TLS_CLIENT_VERSION);
302
21
                OPENSSL_free(tbuf);
303
21
                return 0;
304
21
            }
305
10.7k
            ret = ossl_rsa_padding_check_PKCS1_type_2_TLS(
306
10.7k
                prsactx->libctx, out, outsize, tbuf, len,
307
10.7k
                prsactx->client_version, prsactx->alt_version);
308
10.7k
        }
309
10.7k
        OPENSSL_free(tbuf);
310
10.7k
    } else {
311
0
        if ((prsactx->implicit_rejection == 0) && (prsactx->pad_mode == RSA_PKCS1_PADDING))
312
0
            pad_mode = RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING;
313
0
        else
314
0
            pad_mode = prsactx->pad_mode;
315
0
        ret = RSA_private_decrypt((int)inlen, in, out, prsactx->rsa, pad_mode);
316
0
    }
317
10.7k
    *outlen = constant_time_select_s(constant_time_msb_s(ret), *outlen, ret);
318
10.7k
    ret = constant_time_select_int(constant_time_msb(ret), 0, 1);
319
10.7k
    return ret;
320
10.7k
}
321
322
static void rsa_freectx(void *vprsactx)
323
16.9k
{
324
16.9k
    PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
325
326
16.9k
    RSA_free(prsactx->rsa);
327
328
16.9k
    EVP_MD_free(prsactx->oaep_md);
329
16.9k
    EVP_MD_free(prsactx->mgf1_md);
330
16.9k
    OPENSSL_free(prsactx->oaep_label);
331
332
16.9k
    OPENSSL_free(prsactx);
333
16.9k
}
334
335
static void *rsa_dupctx(void *vprsactx)
336
0
{
337
0
    PROV_RSA_CTX *srcctx = (PROV_RSA_CTX *)vprsactx;
338
0
    PROV_RSA_CTX *dstctx;
339
340
0
    if (!ossl_prov_is_running())
341
0
        return NULL;
342
343
0
    dstctx = OPENSSL_zalloc(sizeof(*srcctx));
344
0
    if (dstctx == NULL)
345
0
        return NULL;
346
347
0
    *dstctx = *srcctx;
348
0
    if (dstctx->rsa != NULL && !RSA_up_ref(dstctx->rsa)) {
349
0
        OPENSSL_free(dstctx);
350
0
        return NULL;
351
0
    }
352
353
0
    if (dstctx->oaep_md != NULL && !EVP_MD_up_ref(dstctx->oaep_md)) {
354
0
        RSA_free(dstctx->rsa);
355
0
        OPENSSL_free(dstctx);
356
0
        return NULL;
357
0
    }
358
359
0
    if (dstctx->mgf1_md != NULL && !EVP_MD_up_ref(dstctx->mgf1_md)) {
360
0
        RSA_free(dstctx->rsa);
361
0
        EVP_MD_free(dstctx->oaep_md);
362
0
        OPENSSL_free(dstctx);
363
0
        return NULL;
364
0
    }
365
366
0
    return dstctx;
367
0
}
368
369
/* clang-format off */
370
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
371
#ifndef rsa_get_ctx_params_list
372
static const OSSL_PARAM rsa_get_ctx_params_list[] = {
373
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, NULL, 0),
374
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL, 0),
375
    OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL),
376
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, NULL, 0),
377
    OSSL_PARAM_octet_ptr(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, NULL, 0),
378
    OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, NULL),
379
    OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL),
380
    OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION, NULL),
381
# if defined(FIPS_MODULE)
382
    OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_FIPS_APPROVED_INDICATOR, NULL),
383
# endif
384
    OSSL_PARAM_END
385
};
386
#endif
387
388
#ifndef rsa_get_ctx_params_st
389
struct rsa_get_ctx_params_st {
390
    OSSL_PARAM *imrej;
391
# if defined(FIPS_MODULE)
392
    OSSL_PARAM *ind;
393
# endif
394
    OSSL_PARAM *label;
395
    OSSL_PARAM *mgf1;
396
    OSSL_PARAM *negver;
397
    OSSL_PARAM *oaep;
398
    OSSL_PARAM *pad;
399
    OSSL_PARAM *tlsver;
400
};
401
#endif
402
403
#ifndef rsa_get_ctx_params_decoder
404
static int rsa_get_ctx_params_decoder
405
    (const OSSL_PARAM *p, struct rsa_get_ctx_params_st *r)
406
0
{
407
0
    const char *s;
408
409
0
    memset(r, 0, sizeof(*r));
410
0
    if (p != NULL)
411
0
        for (; (s = p->key) != NULL; p++)
412
0
            switch(s[0]) {
413
0
            default:
414
0
                break;
415
0
            case 'd':
416
0
                if (ossl_likely(strcmp("igest", s + 1) == 0)) {
417
                    /* OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST */
418
0
                    if (ossl_unlikely(r->oaep != NULL)) {
419
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
420
0
                                       "param %s is repeated", s);
421
0
                        return 0;
422
0
                    }
423
0
                    r->oaep = (OSSL_PARAM *)p;
424
0
                }
425
0
                break;
426
0
            case 'f':
427
# if defined(FIPS_MODULE)
428
                if (ossl_likely(strcmp("ips-indicator", s + 1) == 0)) {
429
                    /* OSSL_ASYM_CIPHER_PARAM_FIPS_APPROVED_INDICATOR */
430
                    if (ossl_unlikely(r->ind != NULL)) {
431
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
432
                                       "param %s is repeated", s);
433
                        return 0;
434
                    }
435
                    r->ind = (OSSL_PARAM *)p;
436
                }
437
# endif
438
0
                break;
439
0
            case 'i':
440
0
                if (ossl_likely(strcmp("mplicit-rejection", s + 1) == 0)) {
441
                    /* OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION */
442
0
                    if (ossl_unlikely(r->imrej != NULL)) {
443
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
444
0
                                       "param %s is repeated", s);
445
0
                        return 0;
446
0
                    }
447
0
                    r->imrej = (OSSL_PARAM *)p;
448
0
                }
449
0
                break;
450
0
            case 'm':
451
0
                if (ossl_likely(strcmp("gf1-digest", s + 1) == 0)) {
452
                    /* OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST */
453
0
                    if (ossl_unlikely(r->mgf1 != NULL)) {
454
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
455
0
                                       "param %s is repeated", s);
456
0
                        return 0;
457
0
                    }
458
0
                    r->mgf1 = (OSSL_PARAM *)p;
459
0
                }
460
0
                break;
461
0
            case 'o':
462
0
                if (ossl_likely(strcmp("aep-label", s + 1) == 0)) {
463
                    /* OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL */
464
0
                    if (ossl_unlikely(r->label != NULL)) {
465
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
466
0
                                       "param %s is repeated", s);
467
0
                        return 0;
468
0
                    }
469
0
                    r->label = (OSSL_PARAM *)p;
470
0
                }
471
0
                break;
472
0
            case 'p':
473
0
                if (ossl_likely(strcmp("ad-mode", s + 1) == 0)) {
474
                    /* OSSL_ASYM_CIPHER_PARAM_PAD_MODE */
475
0
                    if (ossl_unlikely(r->pad != NULL)) {
476
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
477
0
                                       "param %s is repeated", s);
478
0
                        return 0;
479
0
                    }
480
0
                    r->pad = (OSSL_PARAM *)p;
481
0
                }
482
0
                break;
483
0
            case 't':
484
0
                switch(s[1]) {
485
0
                default:
486
0
                    break;
487
0
                case 'l':
488
0
                    switch(s[2]) {
489
0
                    default:
490
0
                        break;
491
0
                    case 's':
492
0
                        switch(s[3]) {
493
0
                        default:
494
0
                            break;
495
0
                        case '-':
496
0
                            switch(s[4]) {
497
0
                            default:
498
0
                                break;
499
0
                            case 'c':
500
0
                                if (ossl_likely(strcmp("lient-version", s + 5) == 0)) {
501
                                    /* OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION */
502
0
                                    if (ossl_unlikely(r->tlsver != NULL)) {
503
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
504
0
                                                       "param %s is repeated", s);
505
0
                                        return 0;
506
0
                                    }
507
0
                                    r->tlsver = (OSSL_PARAM *)p;
508
0
                                }
509
0
                                break;
510
0
                            case 'n':
511
0
                                if (ossl_likely(strcmp("egotiated-version", s + 5) == 0)) {
512
                                    /* OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION */
513
0
                                    if (ossl_unlikely(r->negver != NULL)) {
514
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
515
0
                                                       "param %s is repeated", s);
516
0
                                        return 0;
517
0
                                    }
518
0
                                    r->negver = (OSSL_PARAM *)p;
519
0
                                }
520
0
                            }
521
0
                        }
522
0
                    }
523
0
                }
524
0
            }
525
0
    return 1;
526
0
}
527
#endif
528
/* End of machine generated */
529
/* clang-format on */
530
531
static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params)
532
0
{
533
0
    PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
534
0
    struct rsa_get_ctx_params_st p;
535
536
0
    if (prsactx == NULL || !rsa_get_ctx_params_decoder(params, &p))
537
0
        return 0;
538
539
0
    if (p.pad != NULL) {
540
0
        if (p.pad->data_type != OSSL_PARAM_UTF8_STRING) {
541
            /* Support for legacy pad mode number */
542
0
            if (!OSSL_PARAM_set_int(p.pad, prsactx->pad_mode))
543
0
                return 0;
544
0
        } else {
545
0
            int i;
546
0
            const char *word = NULL;
547
548
0
            for (i = 0; padding_item[i].id != 0; i++) {
549
0
                if (prsactx->pad_mode == (int)padding_item[i].id) {
550
0
                    word = padding_item[i].ptr;
551
0
                    break;
552
0
                }
553
0
            }
554
555
0
            if (word != NULL) {
556
0
                if (!OSSL_PARAM_set_utf8_string(p.pad, word))
557
0
                    return 0;
558
0
            } else {
559
0
                ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
560
0
            }
561
0
        }
562
0
    }
563
564
0
    if (p.oaep != NULL && !OSSL_PARAM_set_utf8_string(p.oaep, prsactx->oaep_md == NULL ? "" : EVP_MD_get0_name(prsactx->oaep_md)))
565
0
        return 0;
566
567
0
    if (p.mgf1 != NULL) {
568
0
        EVP_MD *mgf1_md = prsactx->mgf1_md == NULL ? prsactx->oaep_md
569
0
                                                   : prsactx->mgf1_md;
570
571
0
        if (!OSSL_PARAM_set_utf8_string(p.mgf1, mgf1_md == NULL ? "" : EVP_MD_get0_name(mgf1_md)))
572
0
            return 0;
573
0
    }
574
575
0
    if (p.label != NULL
576
0
        && !OSSL_PARAM_set_octet_ptr(p.label, prsactx->oaep_label,
577
0
            prsactx->oaep_labellen))
578
0
        return 0;
579
580
0
    if (p.tlsver != NULL
581
0
        && !OSSL_PARAM_set_uint(p.tlsver, prsactx->client_version))
582
0
        return 0;
583
584
0
    if (p.negver != NULL
585
0
        && !OSSL_PARAM_set_uint(p.negver, prsactx->alt_version))
586
0
        return 0;
587
588
0
    if (p.imrej != NULL
589
0
        && !OSSL_PARAM_set_uint(p.imrej, prsactx->implicit_rejection))
590
0
        return 0;
591
592
0
    if (!OSSL_FIPS_IND_GET_CTX_FROM_PARAM(prsactx, p.ind))
593
0
        return 0;
594
595
0
    return 1;
596
0
}
597
598
static const OSSL_PARAM *rsa_gettable_ctx_params(ossl_unused void *vprsactx,
599
    ossl_unused void *provctx)
600
0
{
601
0
    return rsa_get_ctx_params_list;
602
0
}
603
604
/* clang-format off */
605
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
606
#ifndef rsa_set_ctx_params_list
607
static const OSSL_PARAM rsa_set_ctx_params_list[] = {
608
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, NULL, 0),
609
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS, NULL, 0),
610
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL, 0),
611
    OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL),
612
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, NULL, 0),
613
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS, NULL, 0),
614
    OSSL_PARAM_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, NULL, 0),
615
    OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, NULL),
616
    OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL),
617
    OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION, NULL),
618
# if defined(FIPS_MODULE)
619
    OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_FIPS_KEY_CHECK, NULL),
620
# endif
621
# if defined(FIPS_MODULE)
622
    OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_FIPS_RSA_PKCS15_PAD_DISABLED, NULL),
623
# endif
624
    OSSL_PARAM_END
625
};
626
#endif
627
628
#ifndef rsa_set_ctx_params_st
629
struct rsa_set_ctx_params_st {
630
    OSSL_PARAM *imrej;
631
# if defined(FIPS_MODULE)
632
    OSSL_PARAM *ind_k;
633
# endif
634
# if defined(FIPS_MODULE)
635
    OSSL_PARAM *ind_pad;
636
# endif
637
    OSSL_PARAM *label;
638
    OSSL_PARAM *mgf1;
639
    OSSL_PARAM *mgf1_pq;
640
    OSSL_PARAM *negver;
641
    OSSL_PARAM *oaep;
642
    OSSL_PARAM *oaep_pq;
643
    OSSL_PARAM *pad;
644
    OSSL_PARAM *tlsver;
645
};
646
#endif
647
648
#ifndef rsa_set_ctx_params_decoder
649
static int rsa_set_ctx_params_decoder
650
    (const OSSL_PARAM *p, struct rsa_set_ctx_params_st *r)
651
13.3k
{
652
13.3k
    const char *s;
653
654
13.3k
    memset(r, 0, sizeof(*r));
655
13.3k
    if (p != NULL)
656
16.7k
        for (; (s = p->key) != NULL; p++)
657
8.36k
            switch(s[0]) {
658
0
            default:
659
0
                break;
660
0
            case 'd':
661
0
                switch(s[1]) {
662
0
                default:
663
0
                    break;
664
0
                case 'i':
665
0
                    switch(s[2]) {
666
0
                    default:
667
0
                        break;
668
0
                    case 'g':
669
0
                        switch(s[3]) {
670
0
                        default:
671
0
                            break;
672
0
                        case 'e':
673
0
                            switch(s[4]) {
674
0
                            default:
675
0
                                break;
676
0
                            case 's':
677
0
                                switch(s[5]) {
678
0
                                default:
679
0
                                    break;
680
0
                                case 't':
681
0
                                    switch(s[6]) {
682
0
                                    default:
683
0
                                        break;
684
0
                                    case '-':
685
0
                                        if (ossl_likely(strcmp("props", s + 7) == 0)) {
686
                                            /* OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS */
687
0
                                            if (ossl_unlikely(r->oaep_pq != NULL)) {
688
0
                                                ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
689
0
                                                               "param %s is repeated", s);
690
0
                                                return 0;
691
0
                                            }
692
0
                                            r->oaep_pq = (OSSL_PARAM *)p;
693
0
                                        }
694
0
                                        break;
695
0
                                    case '\0':
696
0
                                        if (ossl_unlikely(r->oaep != NULL)) {
697
0
                                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
698
0
                                                           "param %s is repeated", s);
699
0
                                            return 0;
700
0
                                        }
701
0
                                        r->oaep = (OSSL_PARAM *)p;
702
0
                                    }
703
0
                                }
704
0
                            }
705
0
                        }
706
0
                    }
707
0
                }
708
0
                break;
709
0
            case 'i':
710
0
                if (ossl_likely(strcmp("mplicit-rejection", s + 1) == 0)) {
711
                    /* OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION */
712
0
                    if (ossl_unlikely(r->imrej != NULL)) {
713
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
714
0
                                       "param %s is repeated", s);
715
0
                        return 0;
716
0
                    }
717
0
                    r->imrej = (OSSL_PARAM *)p;
718
0
                }
719
0
                break;
720
0
            case 'k':
721
# if defined(FIPS_MODULE)
722
                if (ossl_likely(strcmp("ey-check", s + 1) == 0)) {
723
                    /* OSSL_ASYM_CIPHER_PARAM_FIPS_KEY_CHECK */
724
                    if (ossl_unlikely(r->ind_k != NULL)) {
725
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
726
                                       "param %s is repeated", s);
727
                        return 0;
728
                    }
729
                    r->ind_k = (OSSL_PARAM *)p;
730
                }
731
# endif
732
0
                break;
733
0
            case 'm':
734
0
                switch(s[1]) {
735
0
                default:
736
0
                    break;
737
0
                case 'g':
738
0
                    switch(s[2]) {
739
0
                    default:
740
0
                        break;
741
0
                    case 'f':
742
0
                        switch(s[3]) {
743
0
                        default:
744
0
                            break;
745
0
                        case '1':
746
0
                            switch(s[4]) {
747
0
                            default:
748
0
                                break;
749
0
                            case '-':
750
0
                                switch(s[5]) {
751
0
                                default:
752
0
                                    break;
753
0
                                case 'd':
754
0
                                    if (ossl_likely(strcmp("igest", s + 6) == 0)) {
755
                                        /* OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST */
756
0
                                        if (ossl_unlikely(r->mgf1 != NULL)) {
757
0
                                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
758
0
                                                           "param %s is repeated", s);
759
0
                                            return 0;
760
0
                                        }
761
0
                                        r->mgf1 = (OSSL_PARAM *)p;
762
0
                                    }
763
0
                                    break;
764
0
                                case 'p':
765
0
                                    if (ossl_likely(strcmp("roperties", s + 6) == 0)) {
766
                                        /* OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS */
767
0
                                        if (ossl_unlikely(r->mgf1_pq != NULL)) {
768
0
                                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
769
0
                                                           "param %s is repeated", s);
770
0
                                            return 0;
771
0
                                        }
772
0
                                        r->mgf1_pq = (OSSL_PARAM *)p;
773
0
                                    }
774
0
                                }
775
0
                            }
776
0
                        }
777
0
                    }
778
0
                }
779
0
                break;
780
0
            case 'o':
781
0
                if (ossl_likely(strcmp("aep-label", s + 1) == 0)) {
782
                    /* OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL */
783
0
                    if (ossl_unlikely(r->label != NULL)) {
784
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
785
0
                                       "param %s is repeated", s);
786
0
                        return 0;
787
0
                    }
788
0
                    r->label = (OSSL_PARAM *)p;
789
0
                }
790
0
                break;
791
4.18k
            case 'p':
792
4.18k
                if (ossl_likely(strcmp("ad-mode", s + 1) == 0)) {
793
                    /* OSSL_ASYM_CIPHER_PARAM_PAD_MODE */
794
4.18k
                    if (ossl_unlikely(r->pad != NULL)) {
795
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
796
0
                                       "param %s is repeated", s);
797
0
                        return 0;
798
0
                    }
799
4.18k
                    r->pad = (OSSL_PARAM *)p;
800
4.18k
                }
801
4.18k
                break;
802
4.18k
            case 'r':
803
# if defined(FIPS_MODULE)
804
                if (ossl_likely(strcmp("sa-pkcs15-pad-disabled", s + 1) == 0)) {
805
                    /* OSSL_ASYM_CIPHER_PARAM_FIPS_RSA_PKCS15_PAD_DISABLED */
806
                    if (ossl_unlikely(r->ind_pad != NULL)) {
807
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
808
                                       "param %s is repeated", s);
809
                        return 0;
810
                    }
811
                    r->ind_pad = (OSSL_PARAM *)p;
812
                }
813
# endif
814
0
                break;
815
4.18k
            case 't':
816
4.18k
                switch(s[1]) {
817
0
                default:
818
0
                    break;
819
4.18k
                case 'l':
820
4.18k
                    switch(s[2]) {
821
0
                    default:
822
0
                        break;
823
4.18k
                    case 's':
824
4.18k
                        switch(s[3]) {
825
0
                        default:
826
0
                            break;
827
4.18k
                        case '-':
828
4.18k
                            switch(s[4]) {
829
0
                            default:
830
0
                                break;
831
4.18k
                            case 'c':
832
4.18k
                                if (ossl_likely(strcmp("lient-version", s + 5) == 0)) {
833
                                    /* OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION */
834
4.18k
                                    if (ossl_unlikely(r->tlsver != NULL)) {
835
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
836
0
                                                       "param %s is repeated", s);
837
0
                                        return 0;
838
0
                                    }
839
4.18k
                                    r->tlsver = (OSSL_PARAM *)p;
840
4.18k
                                }
841
4.18k
                                break;
842
4.18k
                            case 'n':
843
0
                                if (ossl_likely(strcmp("egotiated-version", s + 5) == 0)) {
844
                                    /* OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION */
845
0
                                    if (ossl_unlikely(r->negver != NULL)) {
846
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
847
0
                                                       "param %s is repeated", s);
848
0
                                        return 0;
849
0
                                    }
850
0
                                    r->negver = (OSSL_PARAM *)p;
851
0
                                }
852
4.18k
                            }
853
4.18k
                        }
854
4.18k
                    }
855
4.18k
                }
856
8.36k
            }
857
13.3k
    return 1;
858
13.3k
}
859
#endif
860
/* End of machine generated */
861
/* clang-format on */
862
863
static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
864
13.3k
{
865
13.3k
    PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
866
13.3k
    struct rsa_set_ctx_params_st p;
867
13.3k
    char mdname[OSSL_MAX_NAME_SIZE];
868
13.3k
    char mdprops[OSSL_MAX_PROPQUERY_SIZE] = { '\0' };
869
13.3k
    char *str = NULL;
870
871
13.3k
    if (prsactx == NULL || !rsa_set_ctx_params_decoder(params, &p))
872
0
        return 0;
873
874
13.3k
    if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE0, p.ind_k))
875
0
        return 0;
876
13.3k
    if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE1, p.ind_pad))
877
0
        return 0;
878
879
13.3k
    if (p.oaep != NULL) {
880
0
        str = mdname;
881
0
        if (!OSSL_PARAM_get_utf8_string(p.oaep, &str, sizeof(mdname)))
882
0
            return 0;
883
884
0
        if (p.oaep_pq != NULL) {
885
0
            str = mdprops;
886
0
            if (!OSSL_PARAM_get_utf8_string(p.oaep_pq, &str, sizeof(mdprops)))
887
0
                return 0;
888
0
        }
889
890
0
        EVP_MD_free(prsactx->oaep_md);
891
0
        prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, mdname, mdprops);
892
893
0
        if (prsactx->oaep_md == NULL)
894
0
            return 0;
895
0
    }
896
897
13.3k
    if (p.pad != NULL) {
898
4.18k
        int pad_mode = 0;
899
900
4.18k
        if (p.pad->data_type != OSSL_PARAM_UTF8_STRING) {
901
            /* Support for legacy pad mode as a number */
902
4.18k
            if (!OSSL_PARAM_get_int(p.pad, &pad_mode))
903
0
                return 0;
904
4.18k
        } else {
905
0
            int i;
906
907
0
            if (p.pad->data == NULL)
908
0
                return 0;
909
910
0
            for (i = 0; padding_item[i].id != 0; i++) {
911
0
                if (strcmp(p.pad->data, padding_item[i].ptr) == 0) {
912
0
                    pad_mode = padding_item[i].id;
913
0
                    break;
914
0
                }
915
0
            }
916
0
        }
917
918
        /*
919
         * PSS padding is for signatures only so is not compatible with
920
         * asymmetric cipher use.
921
         */
922
4.18k
        if (pad_mode == RSA_PKCS1_PSS_PADDING)
923
0
            return 0;
924
4.18k
        if (pad_mode == RSA_PKCS1_OAEP_PADDING && prsactx->oaep_md == NULL) {
925
0
            prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, "SHA1", mdprops);
926
0
            if (prsactx->oaep_md == NULL)
927
0
                return 0;
928
0
        }
929
4.18k
        prsactx->pad_mode = pad_mode;
930
4.18k
    }
931
932
13.3k
    if (p.mgf1 != NULL) {
933
0
        str = mdname;
934
0
        if (!OSSL_PARAM_get_utf8_string(p.mgf1, &str, sizeof(mdname)))
935
0
            return 0;
936
937
0
        if (p.mgf1_pq != NULL) {
938
0
            str = mdprops;
939
0
            if (!OSSL_PARAM_get_utf8_string(p.mgf1_pq, &str, sizeof(mdprops)))
940
0
                return 0;
941
0
        } else {
942
0
            str = NULL;
943
0
        }
944
945
0
        EVP_MD_free(prsactx->mgf1_md);
946
0
        prsactx->mgf1_md = EVP_MD_fetch(prsactx->libctx, mdname, str);
947
948
0
        if (prsactx->mgf1_md == NULL)
949
0
            return 0;
950
0
    }
951
952
13.3k
    if (p.label != NULL) {
953
0
        void *tmp_label = NULL;
954
0
        size_t tmp_labellen;
955
956
0
        if (!OSSL_PARAM_get_octet_string(p.label, &tmp_label, 0, &tmp_labellen))
957
0
            return 0;
958
0
        OPENSSL_free(prsactx->oaep_label);
959
0
        prsactx->oaep_label = (unsigned char *)tmp_label;
960
0
        prsactx->oaep_labellen = tmp_labellen;
961
0
    }
962
963
13.3k
    if (p.tlsver != NULL) {
964
4.18k
        unsigned int client_version;
965
966
4.18k
        if (!OSSL_PARAM_get_uint(p.tlsver, &client_version))
967
0
            return 0;
968
4.18k
        prsactx->client_version = client_version;
969
4.18k
    }
970
971
13.3k
    if (p.negver != NULL) {
972
0
        unsigned int alt_version;
973
974
0
        if (!OSSL_PARAM_get_uint(p.negver, &alt_version))
975
0
            return 0;
976
0
        prsactx->alt_version = alt_version;
977
0
    }
978
979
13.3k
    if (p.imrej != NULL) {
980
0
        unsigned int implicit_rejection;
981
982
0
        if (!OSSL_PARAM_get_uint(p.imrej, &implicit_rejection))
983
0
            return 0;
984
0
        prsactx->implicit_rejection = implicit_rejection;
985
0
    }
986
13.3k
    return 1;
987
13.3k
}
988
989
static const OSSL_PARAM *rsa_settable_ctx_params(ossl_unused void *vprsactx,
990
    ossl_unused void *provctx)
991
11.4k
{
992
11.4k
    return rsa_set_ctx_params_list;
993
11.4k
}
994
995
const OSSL_DISPATCH ossl_rsa_asym_cipher_functions[] = {
996
    { OSSL_FUNC_ASYM_CIPHER_NEWCTX, (void (*)(void))rsa_newctx },
997
    { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, (void (*)(void))rsa_encrypt_init },
998
    { OSSL_FUNC_ASYM_CIPHER_ENCRYPT, (void (*)(void))rsa_encrypt },
999
    { OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT, (void (*)(void))rsa_decrypt_init },
1000
    { OSSL_FUNC_ASYM_CIPHER_DECRYPT, (void (*)(void))rsa_decrypt },
1001
    { OSSL_FUNC_ASYM_CIPHER_FREECTX, (void (*)(void))rsa_freectx },
1002
    { OSSL_FUNC_ASYM_CIPHER_DUPCTX, (void (*)(void))rsa_dupctx },
1003
    { OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS,
1004
        (void (*)(void))rsa_get_ctx_params },
1005
    { OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS,
1006
        (void (*)(void))rsa_gettable_ctx_params },
1007
    { OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS,
1008
        (void (*)(void))rsa_set_ctx_params },
1009
    { OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS,
1010
        (void (*)(void))rsa_settable_ctx_params },
1011
    OSSL_DISPATCH_END
1012
};