Coverage Report

Created: 2024-11-21 07:03

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