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