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