Coverage Report

Created: 2026-02-14 07:20

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-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
/* 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.7k
{
87
16.7k
    PROV_RSA_CTX *prsactx;
88
89
16.7k
    if (!ossl_prov_is_running())
90
0
        return NULL;
91
16.7k
    prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX));
92
16.7k
    if (prsactx == NULL)
93
0
        return NULL;
94
16.7k
    prsactx->libctx = PROV_LIBCTX_OF(provctx);
95
16.7k
    OSSL_FIPS_IND_INIT(prsactx)
96
97
16.7k
    return prsactx;
98
16.7k
}
99
100
static int rsa_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[],
101
    int operation, const char *desc)
102
11.5k
{
103
11.5k
    PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
104
11.5k
    int protect = 0;
105
106
11.5k
    if (!ossl_prov_is_running() || prsactx == NULL || vrsa == NULL)
107
0
        return 0;
108
109
11.5k
    if (!ossl_rsa_key_op_get_protect(vrsa, operation, &protect))
110
0
        return 0;
111
11.5k
    if (!RSA_up_ref(vrsa))
112
0
        return 0;
113
11.5k
    RSA_free(prsactx->rsa);
114
11.5k
    prsactx->rsa = vrsa;
115
11.5k
    prsactx->operation = operation;
116
11.5k
    prsactx->implicit_rejection = 1;
117
118
11.5k
    switch (RSA_test_flags(prsactx->rsa, RSA_FLAG_TYPE_MASK)) {
119
11.5k
    case RSA_FLAG_TYPE_RSA:
120
11.5k
        prsactx->pad_mode = RSA_PKCS1_PADDING;
121
11.5k
        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
11.5k
    }
127
128
11.5k
    OSSL_FIPS_IND_SET_APPROVED(prsactx)
129
11.5k
    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
11.5k
    return 1;
138
11.5k
}
139
140
static int rsa_encrypt_init(void *vprsactx, void *vrsa,
141
    const OSSL_PARAM params[])
142
6.26k
{
143
6.26k
    return rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_ENCRYPT,
144
6.26k
        "RSA Encrypt Init");
145
6.26k
}
146
147
static int rsa_decrypt_init(void *vprsactx, void *vrsa,
148
    const OSSL_PARAM params[])
149
10.4k
{
150
10.4k
    return rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_DECRYPT,
151
10.4k
        "RSA Decrypt Init");
152
10.4k
}
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
12.5k
{
157
12.5k
    PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
158
12.5k
    size_t len = RSA_size(prsactx->rsa);
159
12.5k
    int ret;
160
161
12.5k
    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
12.5k
    if (len == 0) {
177
8
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
178
8
        return 0;
179
8
    }
180
181
12.5k
    if (out == NULL) {
182
6.25k
        *outlen = len;
183
6.25k
        return 1;
184
6.25k
    }
185
186
6.25k
    if (outsize < len) {
187
0
        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
188
0
        return 0;
189
0
    }
190
191
6.25k
    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
6.25k
    } else {
220
6.25k
        ret = RSA_public_encrypt((int)inlen, in, out, prsactx->rsa,
221
6.25k
            prsactx->pad_mode);
222
6.25k
    }
223
    /* A ret value of 0 is not an error */
224
6.25k
    if (ret < 0)
225
734
        return ret;
226
5.52k
    *outlen = ret;
227
5.52k
    return 1;
228
6.25k
}
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
9.95k
{
233
9.95k
    PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
234
9.95k
    int ret;
235
9.95k
    int pad_mode;
236
9.95k
    size_t len = RSA_size(prsactx->rsa);
237
238
9.95k
    if (!ossl_prov_is_running())
239
0
        return 0;
240
241
9.95k
    if (prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) {
242
9.95k
        if (out == NULL) {
243
0
            *outlen = SSL_MAX_MASTER_KEY_LENGTH;
244
0
            return 1;
245
0
        }
246
9.95k
        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
9.95k
    } 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
9.95k
    if (prsactx->pad_mode == RSA_PKCS1_OAEP_PADDING
267
9.95k
        || prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) {
268
9.95k
        unsigned char *tbuf;
269
270
9.95k
        if ((tbuf = OPENSSL_malloc(len)) == NULL)
271
0
            return 0;
272
9.95k
        ret = RSA_private_decrypt((int)inlen, in, tbuf, prsactx->rsa,
273
9.95k
            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
9.95k
        if (ret != (int)len) {
279
36
            OPENSSL_free(tbuf);
280
36
            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_DECRYPT);
281
36
            return 0;
282
36
        }
283
9.91k
        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
9.91k
        } else {
299
            /* RSA_PKCS1_WITH_TLS_PADDING */
300
9.91k
            if (prsactx->client_version <= 0) {
301
27
                ERR_raise(ERR_LIB_PROV, PROV_R_BAD_TLS_CLIENT_VERSION);
302
27
                OPENSSL_free(tbuf);
303
27
                return 0;
304
27
            }
305
9.89k
            ret = ossl_rsa_padding_check_PKCS1_type_2_TLS(
306
9.89k
                prsactx->libctx, out, outsize, tbuf, len,
307
9.89k
                prsactx->client_version, prsactx->alt_version);
308
9.89k
        }
309
9.89k
        OPENSSL_free(tbuf);
310
9.89k
    } 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
9.89k
    *outlen = constant_time_select_s(constant_time_msb_s(ret), *outlen, ret);
318
9.89k
    ret = constant_time_select_int(constant_time_msb(ret), 0, 1);
319
9.89k
    return ret;
320
9.95k
}
321
322
static void rsa_freectx(void *vprsactx)
323
16.7k
{
324
16.7k
    PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
325
326
16.7k
    RSA_free(prsactx->rsa);
327
328
16.7k
    EVP_MD_free(prsactx->oaep_md);
329
16.7k
    EVP_MD_free(prsactx->mgf1_md);
330
16.7k
    OPENSSL_free(prsactx->oaep_label);
331
332
16.7k
    OPENSSL_free(prsactx);
333
16.7k
}
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
    if (dstctx->oaep_label != NULL
367
0
        && (dstctx->oaep_label = OPENSSL_memdup(dstctx->oaep_label, dstctx->oaep_labellen)) == NULL) {
368
0
        rsa_freectx(dstctx);
369
0
        return NULL;
370
0
    }
371
372
0
    return dstctx;
373
0
}
374
375
/* clang-format off */
376
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
377
#ifndef rsa_get_ctx_params_list
378
static const OSSL_PARAM rsa_get_ctx_params_list[] = {
379
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, NULL, 0),
380
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL, 0),
381
    OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL),
382
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, NULL, 0),
383
    OSSL_PARAM_octet_ptr(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, NULL, 0),
384
    OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, NULL),
385
    OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL),
386
    OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION, NULL),
387
# if defined(FIPS_MODULE)
388
    OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_FIPS_APPROVED_INDICATOR, NULL),
389
# endif
390
    OSSL_PARAM_END
391
};
392
#endif
393
394
#ifndef rsa_get_ctx_params_st
395
struct rsa_get_ctx_params_st {
396
    OSSL_PARAM *imrej;
397
# if defined(FIPS_MODULE)
398
    OSSL_PARAM *ind;
399
# endif
400
    OSSL_PARAM *label;
401
    OSSL_PARAM *mgf1;
402
    OSSL_PARAM *negver;
403
    OSSL_PARAM *oaep;
404
    OSSL_PARAM *pad;
405
    OSSL_PARAM *tlsver;
406
};
407
#endif
408
409
#ifndef rsa_get_ctx_params_decoder
410
static int rsa_get_ctx_params_decoder
411
    (const OSSL_PARAM *p, struct rsa_get_ctx_params_st *r)
412
0
{
413
0
    const char *s;
414
415
0
    memset(r, 0, sizeof(*r));
416
0
    if (p != NULL)
417
0
        for (; (s = p->key) != NULL; p++)
418
0
            switch(s[0]) {
419
0
            default:
420
0
                break;
421
0
            case 'd':
422
0
                if (ossl_likely(strcmp("igest", s + 1) == 0)) {
423
                    /* OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST */
424
0
                    if (ossl_unlikely(r->oaep != NULL)) {
425
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
426
0
                                       "param %s is repeated", s);
427
0
                        return 0;
428
0
                    }
429
0
                    r->oaep = (OSSL_PARAM *)p;
430
0
                }
431
0
                break;
432
0
            case 'f':
433
# if defined(FIPS_MODULE)
434
                if (ossl_likely(strcmp("ips-indicator", s + 1) == 0)) {
435
                    /* OSSL_ASYM_CIPHER_PARAM_FIPS_APPROVED_INDICATOR */
436
                    if (ossl_unlikely(r->ind != NULL)) {
437
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
438
                                       "param %s is repeated", s);
439
                        return 0;
440
                    }
441
                    r->ind = (OSSL_PARAM *)p;
442
                }
443
# endif
444
0
                break;
445
0
            case 'i':
446
0
                if (ossl_likely(strcmp("mplicit-rejection", s + 1) == 0)) {
447
                    /* OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION */
448
0
                    if (ossl_unlikely(r->imrej != NULL)) {
449
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
450
0
                                       "param %s is repeated", s);
451
0
                        return 0;
452
0
                    }
453
0
                    r->imrej = (OSSL_PARAM *)p;
454
0
                }
455
0
                break;
456
0
            case 'm':
457
0
                if (ossl_likely(strcmp("gf1-digest", s + 1) == 0)) {
458
                    /* OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST */
459
0
                    if (ossl_unlikely(r->mgf1 != NULL)) {
460
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
461
0
                                       "param %s is repeated", s);
462
0
                        return 0;
463
0
                    }
464
0
                    r->mgf1 = (OSSL_PARAM *)p;
465
0
                }
466
0
                break;
467
0
            case 'o':
468
0
                if (ossl_likely(strcmp("aep-label", s + 1) == 0)) {
469
                    /* OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL */
470
0
                    if (ossl_unlikely(r->label != NULL)) {
471
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
472
0
                                       "param %s is repeated", s);
473
0
                        return 0;
474
0
                    }
475
0
                    r->label = (OSSL_PARAM *)p;
476
0
                }
477
0
                break;
478
0
            case 'p':
479
0
                if (ossl_likely(strcmp("ad-mode", s + 1) == 0)) {
480
                    /* OSSL_ASYM_CIPHER_PARAM_PAD_MODE */
481
0
                    if (ossl_unlikely(r->pad != NULL)) {
482
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
483
0
                                       "param %s is repeated", s);
484
0
                        return 0;
485
0
                    }
486
0
                    r->pad = (OSSL_PARAM *)p;
487
0
                }
488
0
                break;
489
0
            case 't':
490
0
                switch(s[1]) {
491
0
                default:
492
0
                    break;
493
0
                case 'l':
494
0
                    switch(s[2]) {
495
0
                    default:
496
0
                        break;
497
0
                    case 's':
498
0
                        switch(s[3]) {
499
0
                        default:
500
0
                            break;
501
0
                        case '-':
502
0
                            switch(s[4]) {
503
0
                            default:
504
0
                                break;
505
0
                            case 'c':
506
0
                                if (ossl_likely(strcmp("lient-version", s + 5) == 0)) {
507
                                    /* OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION */
508
0
                                    if (ossl_unlikely(r->tlsver != NULL)) {
509
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
510
0
                                                       "param %s is repeated", s);
511
0
                                        return 0;
512
0
                                    }
513
0
                                    r->tlsver = (OSSL_PARAM *)p;
514
0
                                }
515
0
                                break;
516
0
                            case 'n':
517
0
                                if (ossl_likely(strcmp("egotiated-version", s + 5) == 0)) {
518
                                    /* OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION */
519
0
                                    if (ossl_unlikely(r->negver != NULL)) {
520
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
521
0
                                                       "param %s is repeated", s);
522
0
                                        return 0;
523
0
                                    }
524
0
                                    r->negver = (OSSL_PARAM *)p;
525
0
                                }
526
0
                            }
527
0
                        }
528
0
                    }
529
0
                }
530
0
            }
531
0
    return 1;
532
0
}
533
#endif
534
/* End of machine generated */
535
/* clang-format on */
536
537
static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params)
538
0
{
539
0
    PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
540
0
    struct rsa_get_ctx_params_st p;
541
542
0
    if (prsactx == NULL || !rsa_get_ctx_params_decoder(params, &p))
543
0
        return 0;
544
545
0
    if (p.pad != NULL) {
546
0
        if (p.pad->data_type != OSSL_PARAM_UTF8_STRING) {
547
            /* Support for legacy pad mode number */
548
0
            if (!OSSL_PARAM_set_int(p.pad, prsactx->pad_mode))
549
0
                return 0;
550
0
        } else {
551
0
            int i;
552
0
            const char *word = NULL;
553
554
0
            for (i = 0; padding_item[i].id != 0; i++) {
555
0
                if (prsactx->pad_mode == (int)padding_item[i].id) {
556
0
                    word = padding_item[i].ptr;
557
0
                    break;
558
0
                }
559
0
            }
560
561
0
            if (word != NULL) {
562
0
                if (!OSSL_PARAM_set_utf8_string(p.pad, word))
563
0
                    return 0;
564
0
            } else {
565
0
                ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
566
0
            }
567
0
        }
568
0
    }
569
570
0
    if (p.oaep != NULL && !OSSL_PARAM_set_utf8_string(p.oaep, prsactx->oaep_md == NULL ? "" : EVP_MD_get0_name(prsactx->oaep_md)))
571
0
        return 0;
572
573
0
    if (p.mgf1 != NULL) {
574
0
        EVP_MD *mgf1_md = prsactx->mgf1_md == NULL ? prsactx->oaep_md
575
0
                                                   : prsactx->mgf1_md;
576
577
0
        if (!OSSL_PARAM_set_utf8_string(p.mgf1, mgf1_md == NULL ? "" : EVP_MD_get0_name(mgf1_md)))
578
0
            return 0;
579
0
    }
580
581
0
    if (p.label != NULL
582
0
        && !OSSL_PARAM_set_octet_ptr(p.label, prsactx->oaep_label,
583
0
            prsactx->oaep_labellen))
584
0
        return 0;
585
586
0
    if (p.tlsver != NULL
587
0
        && !OSSL_PARAM_set_uint(p.tlsver, prsactx->client_version))
588
0
        return 0;
589
590
0
    if (p.negver != NULL
591
0
        && !OSSL_PARAM_set_uint(p.negver, prsactx->alt_version))
592
0
        return 0;
593
594
0
    if (p.imrej != NULL
595
0
        && !OSSL_PARAM_set_uint(p.imrej, prsactx->implicit_rejection))
596
0
        return 0;
597
598
0
    if (!OSSL_FIPS_IND_GET_CTX_FROM_PARAM(prsactx, p.ind))
599
0
        return 0;
600
601
0
    return 1;
602
0
}
603
604
static const OSSL_PARAM *rsa_gettable_ctx_params(ossl_unused void *vprsactx,
605
    ossl_unused void *provctx)
606
0
{
607
0
    return rsa_get_ctx_params_list;
608
0
}
609
610
/* clang-format off */
611
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
612
#ifndef rsa_set_ctx_params_list
613
static const OSSL_PARAM rsa_set_ctx_params_list[] = {
614
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, NULL, 0),
615
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS, NULL, 0),
616
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL, 0),
617
    OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL),
618
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, NULL, 0),
619
    OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS, NULL, 0),
620
    OSSL_PARAM_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, NULL, 0),
621
    OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, NULL),
622
    OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL),
623
    OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION, NULL),
624
# if defined(FIPS_MODULE)
625
    OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_FIPS_KEY_CHECK, NULL),
626
# endif
627
# if defined(FIPS_MODULE)
628
    OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_FIPS_RSA_PKCS15_PAD_DISABLED, NULL),
629
# endif
630
    OSSL_PARAM_END
631
};
632
#endif
633
634
#ifndef rsa_set_ctx_params_st
635
struct rsa_set_ctx_params_st {
636
    OSSL_PARAM *imrej;
637
# if defined(FIPS_MODULE)
638
    OSSL_PARAM *ind_k;
639
# endif
640
# if defined(FIPS_MODULE)
641
    OSSL_PARAM *ind_pad;
642
# endif
643
    OSSL_PARAM *label;
644
    OSSL_PARAM *mgf1;
645
    OSSL_PARAM *mgf1_pq;
646
    OSSL_PARAM *negver;
647
    OSSL_PARAM *oaep;
648
    OSSL_PARAM *oaep_pq;
649
    OSSL_PARAM *pad;
650
    OSSL_PARAM *tlsver;
651
};
652
#endif
653
654
#ifndef rsa_set_ctx_params_decoder
655
static int rsa_set_ctx_params_decoder
656
    (const OSSL_PARAM *p, struct rsa_set_ctx_params_st *r)
657
10.4k
{
658
10.4k
    const char *s;
659
660
10.4k
    memset(r, 0, sizeof(*r));
661
10.4k
    if (p != NULL)
662
13.0k
        for (; (s = p->key) != NULL; p++)
663
6.53k
            switch(s[0]) {
664
0
            default:
665
0
                break;
666
0
            case 'd':
667
0
                switch(s[1]) {
668
0
                default:
669
0
                    break;
670
0
                case 'i':
671
0
                    switch(s[2]) {
672
0
                    default:
673
0
                        break;
674
0
                    case 'g':
675
0
                        switch(s[3]) {
676
0
                        default:
677
0
                            break;
678
0
                        case 'e':
679
0
                            switch(s[4]) {
680
0
                            default:
681
0
                                break;
682
0
                            case 's':
683
0
                                switch(s[5]) {
684
0
                                default:
685
0
                                    break;
686
0
                                case 't':
687
0
                                    switch(s[6]) {
688
0
                                    default:
689
0
                                        break;
690
0
                                    case '-':
691
0
                                        if (ossl_likely(strcmp("props", s + 7) == 0)) {
692
                                            /* OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS */
693
0
                                            if (ossl_unlikely(r->oaep_pq != NULL)) {
694
0
                                                ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
695
0
                                                               "param %s is repeated", s);
696
0
                                                return 0;
697
0
                                            }
698
0
                                            r->oaep_pq = (OSSL_PARAM *)p;
699
0
                                        }
700
0
                                        break;
701
0
                                    case '\0':
702
0
                                        if (ossl_unlikely(r->oaep != NULL)) {
703
0
                                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
704
0
                                                           "param %s is repeated", s);
705
0
                                            return 0;
706
0
                                        }
707
0
                                        r->oaep = (OSSL_PARAM *)p;
708
0
                                    }
709
0
                                }
710
0
                            }
711
0
                        }
712
0
                    }
713
0
                }
714
0
                break;
715
0
            case 'i':
716
0
                if (ossl_likely(strcmp("mplicit-rejection", s + 1) == 0)) {
717
                    /* OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION */
718
0
                    if (ossl_unlikely(r->imrej != NULL)) {
719
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
720
0
                                       "param %s is repeated", s);
721
0
                        return 0;
722
0
                    }
723
0
                    r->imrej = (OSSL_PARAM *)p;
724
0
                }
725
0
                break;
726
0
            case 'k':
727
# if defined(FIPS_MODULE)
728
                if (ossl_likely(strcmp("ey-check", s + 1) == 0)) {
729
                    /* OSSL_ASYM_CIPHER_PARAM_FIPS_KEY_CHECK */
730
                    if (ossl_unlikely(r->ind_k != NULL)) {
731
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
732
                                       "param %s is repeated", s);
733
                        return 0;
734
                    }
735
                    r->ind_k = (OSSL_PARAM *)p;
736
                }
737
# endif
738
0
                break;
739
0
            case 'm':
740
0
                switch(s[1]) {
741
0
                default:
742
0
                    break;
743
0
                case 'g':
744
0
                    switch(s[2]) {
745
0
                    default:
746
0
                        break;
747
0
                    case 'f':
748
0
                        switch(s[3]) {
749
0
                        default:
750
0
                            break;
751
0
                        case '1':
752
0
                            switch(s[4]) {
753
0
                            default:
754
0
                                break;
755
0
                            case '-':
756
0
                                switch(s[5]) {
757
0
                                default:
758
0
                                    break;
759
0
                                case 'd':
760
0
                                    if (ossl_likely(strcmp("igest", s + 6) == 0)) {
761
                                        /* OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST */
762
0
                                        if (ossl_unlikely(r->mgf1 != NULL)) {
763
0
                                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
764
0
                                                           "param %s is repeated", s);
765
0
                                            return 0;
766
0
                                        }
767
0
                                        r->mgf1 = (OSSL_PARAM *)p;
768
0
                                    }
769
0
                                    break;
770
0
                                case 'p':
771
0
                                    if (ossl_likely(strcmp("roperties", s + 6) == 0)) {
772
                                        /* OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS */
773
0
                                        if (ossl_unlikely(r->mgf1_pq != NULL)) {
774
0
                                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
775
0
                                                           "param %s is repeated", s);
776
0
                                            return 0;
777
0
                                        }
778
0
                                        r->mgf1_pq = (OSSL_PARAM *)p;
779
0
                                    }
780
0
                                }
781
0
                            }
782
0
                        }
783
0
                    }
784
0
                }
785
0
                break;
786
0
            case 'o':
787
0
                if (ossl_likely(strcmp("aep-label", s + 1) == 0)) {
788
                    /* OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL */
789
0
                    if (ossl_unlikely(r->label != NULL)) {
790
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
791
0
                                       "param %s is repeated", s);
792
0
                        return 0;
793
0
                    }
794
0
                    r->label = (OSSL_PARAM *)p;
795
0
                }
796
0
                break;
797
3.26k
            case 'p':
798
3.26k
                if (ossl_likely(strcmp("ad-mode", s + 1) == 0)) {
799
                    /* OSSL_ASYM_CIPHER_PARAM_PAD_MODE */
800
3.26k
                    if (ossl_unlikely(r->pad != NULL)) {
801
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
802
0
                                       "param %s is repeated", s);
803
0
                        return 0;
804
0
                    }
805
3.26k
                    r->pad = (OSSL_PARAM *)p;
806
3.26k
                }
807
3.26k
                break;
808
3.26k
            case 'r':
809
# if defined(FIPS_MODULE)
810
                if (ossl_likely(strcmp("sa-pkcs15-pad-disabled", s + 1) == 0)) {
811
                    /* OSSL_ASYM_CIPHER_PARAM_FIPS_RSA_PKCS15_PAD_DISABLED */
812
                    if (ossl_unlikely(r->ind_pad != NULL)) {
813
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
814
                                       "param %s is repeated", s);
815
                        return 0;
816
                    }
817
                    r->ind_pad = (OSSL_PARAM *)p;
818
                }
819
# endif
820
0
                break;
821
3.26k
            case 't':
822
3.26k
                switch(s[1]) {
823
0
                default:
824
0
                    break;
825
3.26k
                case 'l':
826
3.26k
                    switch(s[2]) {
827
0
                    default:
828
0
                        break;
829
3.26k
                    case 's':
830
3.26k
                        switch(s[3]) {
831
0
                        default:
832
0
                            break;
833
3.26k
                        case '-':
834
3.26k
                            switch(s[4]) {
835
0
                            default:
836
0
                                break;
837
3.26k
                            case 'c':
838
3.26k
                                if (ossl_likely(strcmp("lient-version", s + 5) == 0)) {
839
                                    /* OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION */
840
3.26k
                                    if (ossl_unlikely(r->tlsver != NULL)) {
841
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
842
0
                                                       "param %s is repeated", s);
843
0
                                        return 0;
844
0
                                    }
845
3.26k
                                    r->tlsver = (OSSL_PARAM *)p;
846
3.26k
                                }
847
3.26k
                                break;
848
3.26k
                            case 'n':
849
0
                                if (ossl_likely(strcmp("egotiated-version", s + 5) == 0)) {
850
                                    /* OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION */
851
0
                                    if (ossl_unlikely(r->negver != NULL)) {
852
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
853
0
                                                       "param %s is repeated", s);
854
0
                                        return 0;
855
0
                                    }
856
0
                                    r->negver = (OSSL_PARAM *)p;
857
0
                                }
858
3.26k
                            }
859
3.26k
                        }
860
3.26k
                    }
861
3.26k
                }
862
6.53k
            }
863
10.4k
    return 1;
864
10.4k
}
865
#endif
866
/* End of machine generated */
867
/* clang-format on */
868
869
static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
870
10.4k
{
871
10.4k
    PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
872
10.4k
    struct rsa_set_ctx_params_st p;
873
10.4k
    char mdname[OSSL_MAX_NAME_SIZE];
874
10.4k
    char mdprops[OSSL_MAX_PROPQUERY_SIZE] = { '\0' };
875
10.4k
    char *str = NULL;
876
877
10.4k
    if (prsactx == NULL || !rsa_set_ctx_params_decoder(params, &p))
878
0
        return 0;
879
880
10.4k
    if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE0, p.ind_k))
881
0
        return 0;
882
10.4k
    if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE1, p.ind_pad))
883
0
        return 0;
884
885
10.4k
    if (p.oaep != NULL) {
886
0
        str = mdname;
887
0
        if (!OSSL_PARAM_get_utf8_string(p.oaep, &str, sizeof(mdname)))
888
0
            return 0;
889
890
0
        if (p.oaep_pq != NULL) {
891
0
            str = mdprops;
892
0
            if (!OSSL_PARAM_get_utf8_string(p.oaep_pq, &str, sizeof(mdprops)))
893
0
                return 0;
894
0
        }
895
896
0
        EVP_MD_free(prsactx->oaep_md);
897
0
        prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, mdname, mdprops);
898
899
0
        if (prsactx->oaep_md == NULL)
900
0
            return 0;
901
0
    }
902
903
10.4k
    if (p.pad != NULL) {
904
3.26k
        int pad_mode = 0;
905
906
3.26k
        if (p.pad->data_type != OSSL_PARAM_UTF8_STRING) {
907
            /* Support for legacy pad mode as a number */
908
3.26k
            if (!OSSL_PARAM_get_int(p.pad, &pad_mode))
909
0
                return 0;
910
3.26k
        } else {
911
0
            int i;
912
913
0
            if (p.pad->data == NULL)
914
0
                return 0;
915
916
0
            for (i = 0; padding_item[i].id != 0; i++) {
917
0
                if (strcmp(p.pad->data, padding_item[i].ptr) == 0) {
918
0
                    pad_mode = padding_item[i].id;
919
0
                    break;
920
0
                }
921
0
            }
922
0
        }
923
924
        /*
925
         * PSS padding is for signatures only so is not compatible with
926
         * asymmetric cipher use.
927
         */
928
3.26k
        if (pad_mode == RSA_PKCS1_PSS_PADDING)
929
0
            return 0;
930
3.26k
        if (pad_mode == RSA_PKCS1_OAEP_PADDING && prsactx->oaep_md == NULL) {
931
0
            prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, "SHA1", mdprops);
932
0
            if (prsactx->oaep_md == NULL)
933
0
                return 0;
934
0
        }
935
3.26k
        prsactx->pad_mode = pad_mode;
936
3.26k
    }
937
938
10.4k
    if (p.mgf1 != NULL) {
939
0
        str = mdname;
940
0
        if (!OSSL_PARAM_get_utf8_string(p.mgf1, &str, sizeof(mdname)))
941
0
            return 0;
942
943
0
        if (p.mgf1_pq != NULL) {
944
0
            str = mdprops;
945
0
            if (!OSSL_PARAM_get_utf8_string(p.mgf1_pq, &str, sizeof(mdprops)))
946
0
                return 0;
947
0
        } else {
948
0
            str = NULL;
949
0
        }
950
951
0
        EVP_MD_free(prsactx->mgf1_md);
952
0
        prsactx->mgf1_md = EVP_MD_fetch(prsactx->libctx, mdname, str);
953
954
0
        if (prsactx->mgf1_md == NULL)
955
0
            return 0;
956
0
    }
957
958
10.4k
    if (p.label != NULL) {
959
0
        void *tmp_label = NULL;
960
0
        size_t tmp_labellen;
961
962
0
        if (!OSSL_PARAM_get_octet_string(p.label, &tmp_label, 0, &tmp_labellen))
963
0
            return 0;
964
0
        OPENSSL_free(prsactx->oaep_label);
965
0
        prsactx->oaep_label = (unsigned char *)tmp_label;
966
0
        prsactx->oaep_labellen = tmp_labellen;
967
0
    }
968
969
10.4k
    if (p.tlsver != NULL) {
970
3.26k
        unsigned int client_version;
971
972
3.26k
        if (!OSSL_PARAM_get_uint(p.tlsver, &client_version))
973
0
            return 0;
974
3.26k
        prsactx->client_version = client_version;
975
3.26k
    }
976
977
10.4k
    if (p.negver != NULL) {
978
0
        unsigned int alt_version;
979
980
0
        if (!OSSL_PARAM_get_uint(p.negver, &alt_version))
981
0
            return 0;
982
0
        prsactx->alt_version = alt_version;
983
0
    }
984
985
10.4k
    if (p.imrej != NULL) {
986
0
        unsigned int implicit_rejection;
987
988
0
        if (!OSSL_PARAM_get_uint(p.imrej, &implicit_rejection))
989
0
            return 0;
990
0
        prsactx->implicit_rejection = implicit_rejection;
991
0
    }
992
10.4k
    return 1;
993
10.4k
}
994
995
static const OSSL_PARAM *rsa_settable_ctx_params(ossl_unused void *vprsactx,
996
    ossl_unused void *provctx)
997
10.5k
{
998
10.5k
    return rsa_set_ctx_params_list;
999
10.5k
}
1000
1001
const OSSL_DISPATCH ossl_rsa_asym_cipher_functions[] = {
1002
    { OSSL_FUNC_ASYM_CIPHER_NEWCTX, (void (*)(void))rsa_newctx },
1003
    { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, (void (*)(void))rsa_encrypt_init },
1004
    { OSSL_FUNC_ASYM_CIPHER_ENCRYPT, (void (*)(void))rsa_encrypt },
1005
    { OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT, (void (*)(void))rsa_decrypt_init },
1006
    { OSSL_FUNC_ASYM_CIPHER_DECRYPT, (void (*)(void))rsa_decrypt },
1007
    { OSSL_FUNC_ASYM_CIPHER_FREECTX, (void (*)(void))rsa_freectx },
1008
    { OSSL_FUNC_ASYM_CIPHER_DUPCTX, (void (*)(void))rsa_dupctx },
1009
    { OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS,
1010
        (void (*)(void))rsa_get_ctx_params },
1011
    { OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS,
1012
        (void (*)(void))rsa_gettable_ctx_params },
1013
    { OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS,
1014
        (void (*)(void))rsa_set_ctx_params },
1015
    { OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS,
1016
        (void (*)(void))rsa_settable_ctx_params },
1017
    OSSL_DISPATCH_END
1018
};