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