Coverage Report

Created: 2026-10-28 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mbedtls/library/psa_crypto_rsa.c
Line
Count
Source
1
/*
2
 *  PSA RSA layer on top of Mbed TLS crypto
3
 */
4
/*
5
 *  Copyright The Mbed TLS Contributors
6
 *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7
 */
8
9
#include "common.h"
10
11
#if defined(MBEDTLS_PSA_CRYPTO_C)
12
13
#include <psa/crypto.h>
14
#include "psa/crypto_values.h"
15
#include "psa_crypto_core.h"
16
#include "psa_crypto_random_impl.h"
17
#include "psa_crypto_rsa.h"
18
#include "psa_crypto_hash.h"
19
#include "mbedtls/psa_util.h"
20
21
#include <stdlib.h>
22
#include <string.h>
23
#include "mbedtls/platform.h"
24
25
#include <mbedtls/rsa.h>
26
#include <mbedtls/error.h>
27
#include "rsa_internal.h"
28
#include "constant_time_internal.h"
29
30
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
31
    defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
32
    defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
33
    defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
34
    defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || \
35
    defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
36
    defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
37
38
/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
39
 * that are not a multiple of 8) well. For example, there is only
40
 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
41
 * way to return the exact bit size of a key.
42
 * To keep things simple, reject non-byte-aligned key sizes. */
43
static psa_status_t psa_check_rsa_key_byte_aligned(
44
    const mbedtls_rsa_context *rsa)
45
0
{
46
0
    mbedtls_mpi n;
47
0
    psa_status_t status;
48
0
    mbedtls_mpi_init(&n);
49
0
    status = mbedtls_to_psa_error(
50
0
        mbedtls_rsa_export(rsa, &n, NULL, NULL, NULL, NULL));
51
0
    if (status == PSA_SUCCESS) {
52
0
        if (mbedtls_mpi_bitlen(&n) % 8 != 0) {
53
0
            status = PSA_ERROR_NOT_SUPPORTED;
54
0
        }
55
0
    }
56
0
    mbedtls_mpi_free(&n);
57
0
    return status;
58
0
}
59
60
psa_status_t mbedtls_psa_rsa_load_representation(
61
    psa_key_type_t type, const uint8_t *data, size_t data_length,
62
    mbedtls_rsa_context **p_rsa)
63
0
{
64
0
    psa_status_t status;
65
0
    size_t bits;
66
67
0
    *p_rsa = mbedtls_calloc(1, sizeof(mbedtls_rsa_context));
68
0
    if (*p_rsa == NULL) {
69
0
        return PSA_ERROR_INSUFFICIENT_MEMORY;
70
0
    }
71
0
    mbedtls_rsa_init(*p_rsa);
72
73
    /* Parse the data. */
74
0
    if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
75
0
        status = mbedtls_to_psa_error(mbedtls_rsa_parse_key(*p_rsa, data, data_length));
76
0
    } else {
77
0
        status = mbedtls_to_psa_error(mbedtls_rsa_parse_pubkey(*p_rsa, data, data_length));
78
0
    }
79
0
    if (status != PSA_SUCCESS) {
80
0
        goto exit;
81
0
    }
82
83
    /* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS
84
     * supports non-byte-aligned key sizes, but not well. For example,
85
     * mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */
86
0
    bits = PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(*p_rsa));
87
0
    if (bits > PSA_VENDOR_RSA_MAX_KEY_BITS) {
88
0
        status = PSA_ERROR_NOT_SUPPORTED;
89
0
        goto exit;
90
0
    }
91
0
    status = psa_check_rsa_key_byte_aligned(*p_rsa);
92
0
    if (status != PSA_SUCCESS) {
93
0
        goto exit;
94
0
    }
95
96
0
exit:
97
0
    return status;
98
0
}
99
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
100
        * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
101
        * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
102
        * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
103
        * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) ||
104
        * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) ||
105
        * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
106
107
#if (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && \
108
    defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) || \
109
    defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
110
psa_status_t mbedtls_psa_rsa_import_key(
111
    const psa_key_attributes_t *attributes,
112
    const uint8_t *data, size_t data_length,
113
    uint8_t *key_buffer, size_t key_buffer_size,
114
    size_t *key_buffer_length, size_t *bits)
115
0
{
116
0
    psa_status_t status;
117
0
    mbedtls_rsa_context *rsa = NULL;
118
119
    /* Parse input */
120
0
    status = mbedtls_psa_rsa_load_representation(attributes->type,
121
0
                                                 data,
122
0
                                                 data_length,
123
0
                                                 &rsa);
124
0
    if (status != PSA_SUCCESS) {
125
0
        goto exit;
126
0
    }
127
128
0
    *bits = (psa_key_bits_t) PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(rsa));
129
130
    /* Re-export the data to PSA export format, such that we can store export
131
     * representation in the key slot. Export representation in case of RSA is
132
     * the smallest representation that's allowed as input, so a straight-up
133
     * allocation of the same size as the input buffer will be large enough. */
134
0
    status = mbedtls_psa_rsa_export_key(attributes->type,
135
0
                                        rsa,
136
0
                                        key_buffer,
137
0
                                        key_buffer_size,
138
0
                                        key_buffer_length);
139
0
exit:
140
    /* Always free the RSA object */
141
0
    mbedtls_rsa_free(rsa);
142
0
    mbedtls_free(rsa);
143
144
0
    return status;
145
0
}
146
#endif /* (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) &&
147
        *  defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) ||
148
        * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
149
150
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
151
    defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
152
psa_status_t mbedtls_psa_rsa_export_key(psa_key_type_t type,
153
                                        mbedtls_rsa_context *rsa,
154
                                        uint8_t *data,
155
                                        size_t data_size,
156
                                        size_t *data_length)
157
0
{
158
0
    int ret;
159
0
    uint8_t *end = data + data_size;
160
161
    /* PSA Crypto API defines the format of an RSA key as a DER-encoded
162
     * representation of the non-encrypted PKCS#1 RSAPrivateKey for a
163
     * private key and of the RFC3279 RSAPublicKey for a public key. */
164
0
    if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
165
0
        ret = mbedtls_rsa_write_key(rsa, data, &end);
166
0
    } else {
167
0
        ret = mbedtls_rsa_write_pubkey(rsa, data, &end);
168
0
    }
169
170
0
    if (ret < 0) {
171
        /* Clean up in case pk_write failed halfway through. */
172
0
        memset(data, 0, data_size);
173
0
        return mbedtls_to_psa_error(ret);
174
0
    }
175
176
    /* The mbedtls_pk_xxx functions write to the end of the buffer.
177
     * Move the data to the beginning and erase remaining data
178
     * at the original location. */
179
0
    if (2 * (size_t) ret <= data_size) {
180
0
        memcpy(data, data + data_size - ret, ret);
181
0
        memset(data + data_size - ret, 0, ret);
182
0
    } else if ((size_t) ret < data_size) {
183
0
        memmove(data, data + data_size - ret, ret);
184
0
        memset(data + ret, 0, data_size - ret);
185
0
    }
186
187
0
    *data_length = ret;
188
0
    return PSA_SUCCESS;
189
0
}
190
191
psa_status_t mbedtls_psa_rsa_export_public_key(
192
    const psa_key_attributes_t *attributes,
193
    const uint8_t *key_buffer, size_t key_buffer_size,
194
    uint8_t *data, size_t data_size, size_t *data_length)
195
0
{
196
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
197
0
    mbedtls_rsa_context *rsa = NULL;
198
199
0
    status = mbedtls_psa_rsa_load_representation(
200
0
        attributes->type, key_buffer, key_buffer_size, &rsa);
201
0
    if (status == PSA_SUCCESS) {
202
0
        status = mbedtls_psa_rsa_export_key(PSA_KEY_TYPE_RSA_PUBLIC_KEY,
203
0
                                            rsa,
204
0
                                            data,
205
0
                                            data_size,
206
0
                                            data_length);
207
0
    }
208
209
0
    mbedtls_rsa_free(rsa);
210
0
    mbedtls_free(rsa);
211
212
0
    return status;
213
0
}
214
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) ||
215
        * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
216
217
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
218
static psa_status_t psa_rsa_read_exponent(const uint8_t *e_bytes,
219
                                          size_t e_length,
220
                                          int *exponent)
221
0
{
222
0
    size_t i;
223
0
    uint32_t acc = 0;
224
225
    /* Mbed TLS encodes the public exponent as an int. For simplicity, only
226
     * support values that fit in a 32-bit integer, which is larger than
227
     * int on just about every platform anyway. */
228
0
    if (e_length > sizeof(acc)) {
229
0
        return PSA_ERROR_NOT_SUPPORTED;
230
0
    }
231
0
    for (i = 0; i < e_length; i++) {
232
0
        acc = (acc << 8) | e_bytes[i];
233
0
    }
234
0
    if (acc > INT_MAX) {
235
0
        return PSA_ERROR_NOT_SUPPORTED;
236
0
    }
237
0
    *exponent = acc;
238
0
    return PSA_SUCCESS;
239
0
}
240
241
psa_status_t mbedtls_psa_rsa_generate_key(
242
    const psa_key_attributes_t *attributes,
243
    const uint8_t *custom_data, size_t custom_data_length,
244
    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
245
0
{
246
0
    psa_status_t status;
247
0
    mbedtls_rsa_context rsa;
248
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
249
0
    int exponent = 65537;
250
251
0
    if (custom_data_length != 0) {
252
0
        status = psa_rsa_read_exponent(custom_data, custom_data_length,
253
0
                                       &exponent);
254
0
        if (status != PSA_SUCCESS) {
255
0
            return status;
256
0
        }
257
0
    }
258
259
0
    mbedtls_rsa_init(&rsa);
260
0
    ret = mbedtls_rsa_gen_key(&rsa,
261
0
                              mbedtls_psa_get_random,
262
0
                              MBEDTLS_PSA_RANDOM_STATE,
263
0
                              (unsigned int) attributes->bits,
264
0
                              exponent);
265
0
    if (ret != 0) {
266
0
        mbedtls_rsa_free(&rsa);
267
0
        return mbedtls_to_psa_error(ret);
268
0
    }
269
270
0
    status = mbedtls_psa_rsa_export_key(attributes->type,
271
0
                                        &rsa, key_buffer, key_buffer_size,
272
0
                                        key_buffer_length);
273
0
    mbedtls_rsa_free(&rsa);
274
275
0
    return status;
276
0
}
277
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */
278
279
/****************************************************************/
280
/* Sign/verify hashes */
281
/****************************************************************/
282
283
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
284
    defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
285
286
/* Decode the hash algorithm from alg and store the mbedtls encoding in
287
 * md_alg. Verify that the hash length is acceptable. */
288
static psa_status_t psa_rsa_decode_md_type(psa_algorithm_t alg,
289
                                           size_t hash_length,
290
                                           mbedtls_md_type_t *md_alg)
291
0
{
292
0
    psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
293
0
    *md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
294
295
    /* The Mbed TLS RSA module uses an unsigned int for hash length
296
     * parameters. Validate that it fits so that we don't risk an
297
     * overflow later. */
298
0
#if SIZE_MAX > UINT_MAX
299
0
    if (hash_length > UINT_MAX) {
300
0
        return PSA_ERROR_INVALID_ARGUMENT;
301
0
    }
302
0
#endif
303
304
    /* For signatures using a hash, the hash length must be correct. */
305
0
    if (alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
306
0
        if (*md_alg == MBEDTLS_MD_NONE) {
307
0
            return PSA_ERROR_NOT_SUPPORTED;
308
0
        }
309
0
        if (mbedtls_md_get_size_from_type(*md_alg) != hash_length) {
310
0
            return PSA_ERROR_INVALID_ARGUMENT;
311
0
        }
312
0
    }
313
314
0
    return PSA_SUCCESS;
315
0
}
316
317
psa_status_t mbedtls_psa_rsa_sign_hash(
318
    const psa_key_attributes_t *attributes,
319
    const uint8_t *key_buffer, size_t key_buffer_size,
320
    psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
321
    uint8_t *signature, size_t signature_size, size_t *signature_length)
322
0
{
323
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
324
0
    mbedtls_rsa_context *rsa = NULL;
325
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
326
0
    mbedtls_md_type_t md_alg;
327
328
0
    status = mbedtls_psa_rsa_load_representation(attributes->type,
329
0
                                                 key_buffer,
330
0
                                                 key_buffer_size,
331
0
                                                 &rsa);
332
0
    if (status != PSA_SUCCESS) {
333
0
        goto exit;
334
0
    }
335
336
0
    status = psa_rsa_decode_md_type(alg, hash_length, &md_alg);
337
0
    if (status != PSA_SUCCESS) {
338
0
        goto exit;
339
0
    }
340
341
0
    if (signature_size < mbedtls_rsa_get_len(rsa)) {
342
0
        status = PSA_ERROR_BUFFER_TOO_SMALL;
343
0
        goto exit;
344
0
    }
345
346
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
347
0
    if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
348
0
        ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V15,
349
0
                                      MBEDTLS_MD_NONE);
350
0
        if (ret == 0) {
351
0
            ret = mbedtls_rsa_pkcs1_sign(rsa,
352
0
                                         mbedtls_psa_get_random,
353
0
                                         MBEDTLS_PSA_RANDOM_STATE,
354
0
                                         md_alg,
355
0
                                         (unsigned int) hash_length,
356
0
                                         hash,
357
0
                                         signature);
358
0
        }
359
0
    } else
360
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
361
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
362
0
    if (PSA_ALG_IS_RSA_PSS(alg)) {
363
0
        ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
364
365
0
        if (ret == 0) {
366
0
            ret = mbedtls_rsa_rsassa_pss_sign(rsa,
367
0
                                              mbedtls_psa_get_random,
368
0
                                              MBEDTLS_PSA_RANDOM_STATE,
369
0
                                              MBEDTLS_MD_NONE,
370
0
                                              (unsigned int) hash_length,
371
0
                                              hash,
372
0
                                              signature);
373
0
        }
374
0
    } else
375
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
376
0
    {
377
0
        status = PSA_ERROR_INVALID_ARGUMENT;
378
0
        goto exit;
379
0
    }
380
381
0
    if (ret == 0) {
382
0
        *signature_length = mbedtls_rsa_get_len(rsa);
383
0
    }
384
0
    status = mbedtls_to_psa_error(ret);
385
386
0
exit:
387
0
    mbedtls_rsa_free(rsa);
388
0
    mbedtls_free(rsa);
389
390
0
    return status;
391
0
}
392
393
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
394
static int rsa_pss_expected_salt_len(psa_algorithm_t alg,
395
                                     const mbedtls_rsa_context *rsa,
396
                                     size_t hash_length)
397
0
{
398
0
    if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
399
0
        return MBEDTLS_RSA_SALT_LEN_ANY;
400
0
    }
401
    /* Otherwise: standard salt length, i.e. largest possible salt length
402
     * up to the hash length. */
403
0
    int klen = (int) mbedtls_rsa_get_len(rsa);   // known to fit
404
0
    int hlen = (int) hash_length; // known to fit
405
0
    int room = klen - 2 - hlen;
406
0
    if (room < 0) {
407
0
        return 0;  // there is no valid signature in this case anyway
408
0
    } else if (room > hlen) {
409
0
        return hlen;
410
0
    } else {
411
0
        return room;
412
0
    }
413
0
}
414
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
415
416
psa_status_t mbedtls_psa_rsa_verify_hash(
417
    const psa_key_attributes_t *attributes,
418
    const uint8_t *key_buffer, size_t key_buffer_size,
419
    psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
420
    const uint8_t *signature, size_t signature_length)
421
0
{
422
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
423
0
    mbedtls_rsa_context *rsa = NULL;
424
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
425
0
    mbedtls_md_type_t md_alg;
426
427
0
    status = mbedtls_psa_rsa_load_representation(attributes->type,
428
0
                                                 key_buffer,
429
0
                                                 key_buffer_size,
430
0
                                                 &rsa);
431
0
    if (status != PSA_SUCCESS) {
432
0
        goto exit;
433
0
    }
434
435
0
    status = psa_rsa_decode_md_type(alg, hash_length, &md_alg);
436
0
    if (status != PSA_SUCCESS) {
437
0
        goto exit;
438
0
    }
439
440
0
    if (signature_length != mbedtls_rsa_get_len(rsa)) {
441
0
        status = PSA_ERROR_INVALID_SIGNATURE;
442
0
        goto exit;
443
0
    }
444
445
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
446
0
    if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
447
0
        ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V15,
448
0
                                      MBEDTLS_MD_NONE);
449
0
        if (ret == 0) {
450
0
            ret = mbedtls_rsa_pkcs1_verify(rsa,
451
0
                                           md_alg,
452
0
                                           (unsigned int) hash_length,
453
0
                                           hash,
454
0
                                           signature);
455
0
        }
456
0
    } else
457
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
458
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
459
0
    if (PSA_ALG_IS_RSA_PSS(alg)) {
460
0
        ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
461
0
        if (ret == 0) {
462
0
            int slen = rsa_pss_expected_salt_len(alg, rsa, hash_length);
463
0
            ret = mbedtls_rsa_rsassa_pss_verify_ext(rsa,
464
0
                                                    md_alg,
465
0
                                                    (unsigned) hash_length,
466
0
                                                    hash,
467
0
                                                    md_alg,
468
0
                                                    slen,
469
0
                                                    signature);
470
0
        }
471
0
    } else
472
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
473
0
    {
474
0
        status = PSA_ERROR_INVALID_ARGUMENT;
475
0
        goto exit;
476
0
    }
477
478
    /* Mbed TLS distinguishes "invalid padding" from "valid padding but
479
     * the rest of the signature is invalid". This has little use in
480
     * practice and PSA doesn't report this distinction. */
481
0
    status = (ret == MBEDTLS_ERR_RSA_INVALID_PADDING) ?
482
0
             PSA_ERROR_INVALID_SIGNATURE :
483
0
             mbedtls_to_psa_error(ret);
484
485
0
exit:
486
0
    mbedtls_rsa_free(rsa);
487
0
    mbedtls_free(rsa);
488
489
0
    return status;
490
0
}
491
492
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
493
        * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
494
495
/****************************************************************/
496
/* Asymmetric cryptography */
497
/****************************************************************/
498
499
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
500
static int psa_rsa_oaep_set_padding_mode(psa_algorithm_t alg,
501
                                         mbedtls_rsa_context *rsa)
502
0
{
503
0
    psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH(alg);
504
0
    mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
505
506
    /* Just to get the error status right, as rsa_set_padding() doesn't
507
     * distinguish between "bad RSA algorithm" and "unknown hash". */
508
0
    if (mbedtls_md_info_from_type(md_alg) == NULL) {
509
0
        return PSA_ERROR_NOT_SUPPORTED;
510
0
    }
511
512
0
    return mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
513
0
}
514
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
515
516
psa_status_t mbedtls_psa_asymmetric_encrypt(const psa_key_attributes_t *attributes,
517
                                            const uint8_t *key_buffer,
518
                                            size_t key_buffer_size,
519
                                            psa_algorithm_t alg,
520
                                            const uint8_t *input,
521
                                            size_t input_length,
522
                                            const uint8_t *salt,
523
                                            size_t salt_length,
524
                                            uint8_t *output,
525
                                            size_t output_size,
526
                                            size_t *output_length)
527
0
{
528
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
529
0
    (void) key_buffer;
530
0
    (void) key_buffer_size;
531
0
    (void) input;
532
0
    (void) input_length;
533
0
    (void) salt;
534
0
    (void) salt_length;
535
0
    (void) output;
536
0
    (void) output_size;
537
0
    (void) output_length;
538
539
0
    if (PSA_KEY_TYPE_IS_RSA(attributes->type)) {
540
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
541
0
        defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
542
0
        mbedtls_rsa_context *rsa = NULL;
543
0
        status = mbedtls_psa_rsa_load_representation(attributes->type,
544
0
                                                     key_buffer,
545
0
                                                     key_buffer_size,
546
0
                                                     &rsa);
547
0
        if (status != PSA_SUCCESS) {
548
0
            goto rsa_exit;
549
0
        }
550
551
0
        if (output_size < mbedtls_rsa_get_len(rsa)) {
552
0
            status = PSA_ERROR_BUFFER_TOO_SMALL;
553
0
            goto rsa_exit;
554
0
        }
555
0
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
556
        * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
557
0
        if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
558
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
559
0
            status = mbedtls_to_psa_error(
560
0
                mbedtls_rsa_pkcs1_encrypt(rsa,
561
0
                                          mbedtls_psa_get_random,
562
0
                                          MBEDTLS_PSA_RANDOM_STATE,
563
0
                                          input_length,
564
0
                                          input,
565
0
                                          output));
566
#else
567
            status = PSA_ERROR_NOT_SUPPORTED;
568
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
569
0
        } else
570
0
        if (PSA_ALG_IS_RSA_OAEP(alg)) {
571
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
572
0
            status = mbedtls_to_psa_error(
573
0
                psa_rsa_oaep_set_padding_mode(alg, rsa));
574
0
            if (status != PSA_SUCCESS) {
575
0
                goto rsa_exit;
576
0
            }
577
578
0
            status = mbedtls_to_psa_error(
579
0
                mbedtls_rsa_rsaes_oaep_encrypt(rsa,
580
0
                                               mbedtls_psa_get_random,
581
0
                                               MBEDTLS_PSA_RANDOM_STATE,
582
0
                                               salt, salt_length,
583
0
                                               input_length,
584
0
                                               input,
585
0
                                               output));
586
#else
587
            status = PSA_ERROR_NOT_SUPPORTED;
588
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
589
0
        } else {
590
0
            status = PSA_ERROR_INVALID_ARGUMENT;
591
0
        }
592
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
593
0
        defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
594
0
rsa_exit:
595
0
        if (status == PSA_SUCCESS) {
596
0
            *output_length = mbedtls_rsa_get_len(rsa);
597
0
        }
598
599
0
        mbedtls_rsa_free(rsa);
600
0
        mbedtls_free(rsa);
601
0
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
602
        * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
603
0
    } else {
604
0
        status = PSA_ERROR_NOT_SUPPORTED;
605
0
    }
606
607
0
    return status;
608
0
}
609
610
psa_status_t mbedtls_psa_asymmetric_decrypt(const psa_key_attributes_t *attributes,
611
                                            const uint8_t *key_buffer,
612
                                            size_t key_buffer_size,
613
                                            psa_algorithm_t alg,
614
                                            const uint8_t *input,
615
                                            size_t input_length,
616
                                            const uint8_t *salt,
617
                                            size_t salt_length,
618
                                            uint8_t *output,
619
                                            size_t output_size,
620
                                            size_t *output_length)
621
0
{
622
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
623
0
    (void) key_buffer;
624
0
    (void) key_buffer_size;
625
0
    (void) input;
626
0
    (void) input_length;
627
0
    (void) salt;
628
0
    (void) salt_length;
629
0
    (void) output;
630
0
    (void) output_size;
631
0
    (void) output_length;
632
633
0
    *output_length = 0;
634
635
0
    if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
636
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
637
0
        defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
638
0
        mbedtls_rsa_context *rsa = NULL;
639
0
        status = mbedtls_psa_rsa_load_representation(attributes->type,
640
0
                                                     key_buffer,
641
0
                                                     key_buffer_size,
642
0
                                                     &rsa);
643
0
        if (status != PSA_SUCCESS) {
644
0
            goto rsa_exit;
645
0
        }
646
647
0
        if (input_length != mbedtls_rsa_get_len(rsa)) {
648
0
            status = PSA_ERROR_INVALID_ARGUMENT;
649
0
            goto rsa_exit;
650
0
        }
651
0
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
652
        * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
653
654
0
        if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
655
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
656
0
            int combined_ret = mbedtls_rsa_rsaes_pkcs1_v15_decrypt(
657
0
                rsa, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE,
658
0
                output_length, input, output, output_size);
659
660
            /* Translate error codes from legacy to PSA.
661
             * Success vs INVALID_PADDING vs OUTPUT_TOO_LARGE is sensitive
662
             * (padding oracle attack), so we take care to translate that
663
             * part in constant time.
664
             */
665
0
            int problem;
666
0
            int public_ret = mbedtls_rsa_decrypt_decompose_ret(
667
0
                MBEDTLS_ERR_RSA_INVALID_PADDING, PSA_ERROR_INVALID_PADDING,
668
0
                MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE, PSA_ERROR_BUFFER_TOO_SMALL,
669
0
                combined_ret, &problem);
670
0
            status = mbedtls_to_psa_error(public_ret);
671
0
            status |= problem;
672
#else
673
            status = PSA_ERROR_NOT_SUPPORTED;
674
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
675
0
        } else
676
0
        if (PSA_ALG_IS_RSA_OAEP(alg)) {
677
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
678
0
            status = mbedtls_to_psa_error(
679
0
                psa_rsa_oaep_set_padding_mode(alg, rsa));
680
0
            if (status != PSA_SUCCESS) {
681
0
                goto rsa_exit;
682
0
            }
683
684
0
            status = mbedtls_to_psa_error(
685
0
                mbedtls_rsa_rsaes_oaep_decrypt(rsa,
686
0
                                               mbedtls_psa_get_random,
687
0
                                               MBEDTLS_PSA_RANDOM_STATE,
688
0
                                               salt, salt_length,
689
0
                                               output_length,
690
0
                                               input,
691
0
                                               output,
692
0
                                               output_size));
693
#else
694
            status = PSA_ERROR_NOT_SUPPORTED;
695
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
696
0
        } else {
697
0
            status = PSA_ERROR_INVALID_ARGUMENT;
698
0
        }
699
700
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
701
0
        defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
702
0
rsa_exit:
703
0
        mbedtls_rsa_free(rsa);
704
0
        mbedtls_free(rsa);
705
0
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
706
        * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
707
0
    } else {
708
0
        status = PSA_ERROR_NOT_SUPPORTED;
709
0
    }
710
711
0
    return status;
712
0
}
713
714
#endif /* MBEDTLS_PSA_CRYPTO_C */