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