blob: f1b9809d8bc1f5a85672736ee9d3091e9a0bf87d [file] [log] [blame]
Ronald Cron00b7bfc2020-11-25 15:25:26 +01001/*
2 * PSA RSA layer on top of Mbed TLS crypto
3 */
4/*
5 * Copyright The Mbed TLS Contributors
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21#include "common.h"
22
23#if defined(MBEDTLS_PSA_CRYPTO_C)
24
25#include <psa/crypto.h>
Przemyslaw Stekiel234f3182021-12-09 11:13:58 +010026#include "psa/crypto_values.h"
Ronald Cron00b7bfc2020-11-25 15:25:26 +010027#include "psa_crypto_core.h"
Ronald Cron9e18fc12020-11-05 17:36:40 +010028#include "psa_crypto_random_impl.h"
Ronald Cron00b7bfc2020-11-25 15:25:26 +010029#include "psa_crypto_rsa.h"
Steven Cooreman5f88e772021-03-15 11:07:12 +010030#include "psa_crypto_hash.h"
Ronald Cron00b7bfc2020-11-25 15:25:26 +010031
32#include <stdlib.h>
33#include <string.h>
34#include "mbedtls/platform.h"
Ronald Cron00b7bfc2020-11-25 15:25:26 +010035
36#include <mbedtls/rsa.h>
37#include <mbedtls/error.h>
38#include <mbedtls/pk.h>
Dave Rodgman3b5e6f02021-04-06 17:58:16 +010039#include "pk_wrap.h"
Manuel Pégourié-Gonnard47728842022-07-18 13:00:40 +020040#include "hash_info.h"
Ronald Cron00b7bfc2020-11-25 15:25:26 +010041
42#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
Ronald Cron00b7bfc2020-11-25 15:25:26 +010043 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
Ronald Cron0266cfe2021-03-13 18:50:11 +010044 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
45 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
46 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
47 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Ronald Cron00b7bfc2020-11-25 15:25:26 +010048
49/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
50 * that are not a multiple of 8) well. For example, there is only
51 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
52 * way to return the exact bit size of a key.
53 * To keep things simple, reject non-byte-aligned key sizes. */
54static psa_status_t psa_check_rsa_key_byte_aligned(
55 const mbedtls_rsa_context *rsa )
56{
57 mbedtls_mpi n;
58 psa_status_t status;
59 mbedtls_mpi_init( &n );
60 status = mbedtls_to_psa_error(
61 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
62 if( status == PSA_SUCCESS )
63 {
64 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
65 status = PSA_ERROR_NOT_SUPPORTED;
66 }
67 mbedtls_mpi_free( &n );
68 return( status );
69}
70
71psa_status_t mbedtls_psa_rsa_load_representation(
72 psa_key_type_t type, const uint8_t *data, size_t data_length,
73 mbedtls_rsa_context **p_rsa )
74{
75 psa_status_t status;
76 mbedtls_pk_context ctx;
77 size_t bits;
78 mbedtls_pk_init( &ctx );
79
80 /* Parse the data. */
81 if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
82 status = mbedtls_to_psa_error(
Manuel Pégourié-Gonnard84dea012021-06-15 11:29:26 +020083 mbedtls_pk_parse_key( &ctx, data, data_length, NULL, 0,
84 mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ) );
Ronald Cron00b7bfc2020-11-25 15:25:26 +010085 else
86 status = mbedtls_to_psa_error(
87 mbedtls_pk_parse_public_key( &ctx, data, data_length ) );
88 if( status != PSA_SUCCESS )
89 goto exit;
90
91 /* We have something that the pkparse module recognizes. If it is a
92 * valid RSA key, store it. */
93 if( mbedtls_pk_get_type( &ctx ) != MBEDTLS_PK_RSA )
94 {
95 status = PSA_ERROR_INVALID_ARGUMENT;
96 goto exit;
97 }
98
99 /* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS
100 * supports non-byte-aligned key sizes, but not well. For example,
101 * mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */
102 bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( mbedtls_pk_rsa( ctx ) ) );
103 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
104 {
105 status = PSA_ERROR_NOT_SUPPORTED;
106 goto exit;
107 }
108 status = psa_check_rsa_key_byte_aligned( mbedtls_pk_rsa( ctx ) );
109 if( status != PSA_SUCCESS )
110 goto exit;
111
112 /* Copy out the pointer to the RSA context, and reset the PK context
113 * such that pk_free doesn't free the RSA context we just grabbed. */
114 *p_rsa = mbedtls_pk_rsa( ctx );
115 ctx.pk_info = NULL;
116
117exit:
118 mbedtls_pk_free( &ctx );
119 return( status );
120}
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100121#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100122 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
Ronald Cron0266cfe2021-03-13 18:50:11 +0100123 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
124 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
125 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
126 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100127
Ronald Cron0266cfe2021-03-13 18:50:11 +0100128#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
129 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Ronald Cronabf2aef2020-11-27 18:13:44 +0100130
Ronald Cron0266cfe2021-03-13 18:50:11 +0100131psa_status_t mbedtls_psa_rsa_import_key(
Ronald Cronabf2aef2020-11-27 18:13:44 +0100132 const psa_key_attributes_t *attributes,
133 const uint8_t *data, size_t data_length,
134 uint8_t *key_buffer, size_t key_buffer_size,
135 size_t *key_buffer_length, size_t *bits )
136{
137 psa_status_t status;
138 mbedtls_rsa_context *rsa = NULL;
139
140 /* Parse input */
141 status = mbedtls_psa_rsa_load_representation( attributes->core.type,
142 data,
143 data_length,
144 &rsa );
145 if( status != PSA_SUCCESS )
146 goto exit;
147
148 *bits = (psa_key_bits_t) PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( rsa ) );
149
150 /* Re-export the data to PSA export format, such that we can store export
151 * representation in the key slot. Export representation in case of RSA is
152 * the smallest representation that's allowed as input, so a straight-up
153 * allocation of the same size as the input buffer will be large enough. */
154 status = mbedtls_psa_rsa_export_key( attributes->core.type,
155 rsa,
156 key_buffer,
157 key_buffer_size,
158 key_buffer_length );
159exit:
160 /* Always free the RSA object */
161 mbedtls_rsa_free( rsa );
162 mbedtls_free( rsa );
163
164 return( status );
165}
166
Ronald Crone5ca3d82020-11-26 16:36:16 +0100167psa_status_t mbedtls_psa_rsa_export_key( psa_key_type_t type,
168 mbedtls_rsa_context *rsa,
169 uint8_t *data,
170 size_t data_size,
171 size_t *data_length )
172{
173#if defined(MBEDTLS_PK_WRITE_C)
174 int ret;
175 mbedtls_pk_context pk;
176 uint8_t *pos = data + data_size;
177
178 mbedtls_pk_init( &pk );
179 pk.pk_info = &mbedtls_rsa_info;
180 pk.pk_ctx = rsa;
181
182 /* PSA Crypto API defines the format of an RSA key as a DER-encoded
183 * representation of the non-encrypted PKCS#1 RSAPrivateKey for a
184 * private key and of the RFC3279 RSAPublicKey for a public key. */
185 if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
186 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
187 else
188 ret = mbedtls_pk_write_pubkey( &pos, data, &pk );
189
190 if( ret < 0 )
191 {
192 /* Clean up in case pk_write failed halfway through. */
193 memset( data, 0, data_size );
194 return( mbedtls_to_psa_error( ret ) );
195 }
196
197 /* The mbedtls_pk_xxx functions write to the end of the buffer.
198 * Move the data to the beginning and erase remaining data
199 * at the original location. */
200 if( 2 * (size_t) ret <= data_size )
201 {
202 memcpy( data, data + data_size - ret, ret );
203 memset( data + data_size - ret, 0, ret );
204 }
205 else if( (size_t) ret < data_size )
206 {
207 memmove( data, data + data_size - ret, ret );
208 memset( data + ret, 0, data_size - ret );
209 }
210
211 *data_length = ret;
212 return( PSA_SUCCESS );
213#else
214 (void) type;
215 (void) rsa;
216 (void) data;
217 (void) data_size;
218 (void) data_length;
219 return( PSA_ERROR_NOT_SUPPORTED );
220#endif /* MBEDTLS_PK_WRITE_C */
221}
222
Ronald Cron0266cfe2021-03-13 18:50:11 +0100223psa_status_t mbedtls_psa_rsa_export_public_key(
Ronald Crone5ca3d82020-11-26 16:36:16 +0100224 const psa_key_attributes_t *attributes,
225 const uint8_t *key_buffer, size_t key_buffer_size,
226 uint8_t *data, size_t data_size, size_t *data_length )
227{
228 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
229 mbedtls_rsa_context *rsa = NULL;
230
231 status = mbedtls_psa_rsa_load_representation(
232 attributes->core.type, key_buffer, key_buffer_size, &rsa );
233 if( status != PSA_SUCCESS )
234 return( status );
235
236 status = mbedtls_psa_rsa_export_key( PSA_KEY_TYPE_RSA_PUBLIC_KEY,
237 rsa,
238 data,
239 data_size,
240 data_length );
241
242 mbedtls_rsa_free( rsa );
243 mbedtls_free( rsa );
244
245 return( status );
246}
Ronald Cron0266cfe2021-03-13 18:50:11 +0100247#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
248 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Ronald Cronf1057d32020-11-26 19:19:10 +0100249
Ronald Cron0266cfe2021-03-13 18:50:11 +0100250#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) && \
Jaeden Amero424fa932021-05-14 08:34:32 +0100251 defined(MBEDTLS_GENPRIME)
Ronald Cron2365fde2021-02-08 09:52:24 +0100252static psa_status_t psa_rsa_read_exponent( const uint8_t *domain_parameters,
Ronald Cron9e18fc12020-11-05 17:36:40 +0100253 size_t domain_parameters_size,
254 int *exponent )
255{
256 size_t i;
257 uint32_t acc = 0;
258
259 if( domain_parameters_size == 0 )
260 {
261 *exponent = 65537;
262 return( PSA_SUCCESS );
263 }
264
265 /* Mbed TLS encodes the public exponent as an int. For simplicity, only
266 * support values that fit in a 32-bit integer, which is larger than
267 * int on just about every platform anyway. */
268 if( domain_parameters_size > sizeof( acc ) )
269 return( PSA_ERROR_NOT_SUPPORTED );
270 for( i = 0; i < domain_parameters_size; i++ )
271 acc = ( acc << 8 ) | domain_parameters[i];
272 if( acc > INT_MAX )
273 return( PSA_ERROR_NOT_SUPPORTED );
274 *exponent = acc;
275 return( PSA_SUCCESS );
276}
277
Ronald Cron0266cfe2021-03-13 18:50:11 +0100278psa_status_t mbedtls_psa_rsa_generate_key(
Ronald Cron9e18fc12020-11-05 17:36:40 +0100279 const psa_key_attributes_t *attributes,
280 uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
281{
282 psa_status_t status;
283 mbedtls_rsa_context rsa;
284 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
285 int exponent;
286
Ronald Cron2365fde2021-02-08 09:52:24 +0100287 status = psa_rsa_read_exponent( attributes->domain_parameters,
Ronald Cron9e18fc12020-11-05 17:36:40 +0100288 attributes->domain_parameters_size,
289 &exponent );
290 if( status != PSA_SUCCESS )
291 return( status );
292
Ronald Cronc1905a12021-06-05 11:11:14 +0200293 mbedtls_rsa_init( &rsa );
Ronald Cron9e18fc12020-11-05 17:36:40 +0100294 ret = mbedtls_rsa_gen_key( &rsa,
295 mbedtls_psa_get_random,
296 MBEDTLS_PSA_RANDOM_STATE,
297 (unsigned int)attributes->core.bits,
298 exponent );
299 if( ret != 0 )
300 return( mbedtls_to_psa_error( ret ) );
301
302 status = mbedtls_psa_rsa_export_key( attributes->core.type,
303 &rsa, key_buffer, key_buffer_size,
304 key_buffer_length );
305 mbedtls_rsa_free( &rsa );
306
307 return( status );
308}
Ronald Cron0266cfe2021-03-13 18:50:11 +0100309#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR)
Jaeden Amero424fa932021-05-14 08:34:32 +0100310 * defined(MBEDTLS_GENPRIME) */
Ronald Cron9e18fc12020-11-05 17:36:40 +0100311
Ronald Cron7bdbca32020-12-09 13:34:54 +0100312/****************************************************************/
313/* Sign/verify hashes */
314/****************************************************************/
315
Ronald Cron0266cfe2021-03-13 18:50:11 +0100316#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
317 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Ronald Cron7bdbca32020-12-09 13:34:54 +0100318
319/* Decode the hash algorithm from alg and store the mbedtls encoding in
320 * md_alg. Verify that the hash length is acceptable. */
321static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
322 size_t hash_length,
323 mbedtls_md_type_t *md_alg )
324{
325 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Manuel Pégourié-Gonnard130fa4d2022-07-18 15:12:48 +0200326 *md_alg = mbedtls_hash_info_md_from_psa( hash_alg );
Ronald Cron7bdbca32020-12-09 13:34:54 +0100327
328 /* The Mbed TLS RSA module uses an unsigned int for hash length
329 * parameters. Validate that it fits so that we don't risk an
330 * overflow later. */
331#if SIZE_MAX > UINT_MAX
332 if( hash_length > UINT_MAX )
333 return( PSA_ERROR_INVALID_ARGUMENT );
334#endif
335
Janos Follath0af093b2021-06-07 14:34:10 +0100336 /* For signatures using a hash, the hash length must be correct. */
337 if( alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Ronald Cron7bdbca32020-12-09 13:34:54 +0100338 {
Manuel Pégourié-Gonnard3f477892022-07-05 11:30:31 +0200339 if( *md_alg == MBEDTLS_MD_NONE )
Ronald Cron7bdbca32020-12-09 13:34:54 +0100340 return( PSA_ERROR_NOT_SUPPORTED );
Manuel Pégourié-Gonnard47728842022-07-18 13:00:40 +0200341 if( mbedtls_hash_info_get_size( *md_alg ) != hash_length )
Ronald Cron7bdbca32020-12-09 13:34:54 +0100342 return( PSA_ERROR_INVALID_ARGUMENT );
343 }
Ronald Cron7bdbca32020-12-09 13:34:54 +0100344
345 return( PSA_SUCCESS );
346}
347
Ronald Cron0266cfe2021-03-13 18:50:11 +0100348psa_status_t mbedtls_psa_rsa_sign_hash(
Ronald Cron7bdbca32020-12-09 13:34:54 +0100349 const psa_key_attributes_t *attributes,
350 const uint8_t *key_buffer, size_t key_buffer_size,
351 psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
352 uint8_t *signature, size_t signature_size, size_t *signature_length )
353{
354 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
355 mbedtls_rsa_context *rsa = NULL;
356 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
357 mbedtls_md_type_t md_alg;
358
359 status = mbedtls_psa_rsa_load_representation( attributes->core.type,
360 key_buffer,
361 key_buffer_size,
362 &rsa );
363 if( status != PSA_SUCCESS )
364 return( status );
365
366 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
367 if( status != PSA_SUCCESS )
368 goto exit;
369
370 if( signature_size < mbedtls_rsa_get_len( rsa ) )
371 {
372 status = PSA_ERROR_BUFFER_TOO_SMALL;
373 goto exit;
374 }
375
Ronald Cron0266cfe2021-03-13 18:50:11 +0100376#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Ronald Cron7bdbca32020-12-09 13:34:54 +0100377 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
378 {
Ronald Cronea7631b2021-06-03 18:51:59 +0200379 ret = mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
380 MBEDTLS_MD_NONE );
381 if( ret == 0 )
382 {
383 ret = mbedtls_rsa_pkcs1_sign( rsa,
384 mbedtls_psa_get_random,
385 MBEDTLS_PSA_RANDOM_STATE,
386 md_alg,
387 (unsigned int) hash_length,
388 hash,
389 signature );
390 }
Ronald Cron7bdbca32020-12-09 13:34:54 +0100391 }
392 else
Ronald Cron0266cfe2021-03-13 18:50:11 +0100393#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
394#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Ronald Cron7bdbca32020-12-09 13:34:54 +0100395 if( PSA_ALG_IS_RSA_PSS( alg ) )
396 {
Ronald Cronea7631b2021-06-03 18:51:59 +0200397 ret = mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
398
399 if( ret == 0 )
400 {
401 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
402 mbedtls_psa_get_random,
403 MBEDTLS_PSA_RANDOM_STATE,
404 MBEDTLS_MD_NONE,
405 (unsigned int) hash_length,
406 hash,
407 signature );
408 }
Ronald Cron7bdbca32020-12-09 13:34:54 +0100409 }
410 else
Ronald Cron0266cfe2021-03-13 18:50:11 +0100411#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Ronald Cron7bdbca32020-12-09 13:34:54 +0100412 {
413 status = PSA_ERROR_INVALID_ARGUMENT;
414 goto exit;
415 }
416
417 if( ret == 0 )
418 *signature_length = mbedtls_rsa_get_len( rsa );
419 status = mbedtls_to_psa_error( ret );
420
421exit:
422 mbedtls_rsa_free( rsa );
423 mbedtls_free( rsa );
424
425 return( status );
426}
427
Ronald Cron0266cfe2021-03-13 18:50:11 +0100428#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Gilles Peskineb9b817e2021-10-04 22:15:05 +0200429static int rsa_pss_expected_salt_len( psa_algorithm_t alg,
430 const mbedtls_rsa_context *rsa,
431 size_t hash_length )
432{
433 if( PSA_ALG_IS_RSA_PSS_ANY_SALT( alg ) )
434 return( MBEDTLS_RSA_SALT_LEN_ANY );
435 /* Otherwise: standard salt length, i.e. largest possible salt length
436 * up to the hash length. */
Gilles Peskinef6892de2021-10-08 16:28:32 +0200437 int klen = (int) mbedtls_rsa_get_len( rsa ); // known to fit
Gilles Peskineb9b817e2021-10-04 22:15:05 +0200438 int hlen = (int) hash_length; // known to fit
439 int room = klen - 2 - hlen;
440 if( room < 0 )
441 return( 0 ); // there is no valid signature in this case anyway
442 else if( room > hlen )
443 return( hlen );
444 else
445 return( room );
446}
Ronald Cron0266cfe2021-03-13 18:50:11 +0100447#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Gilles Peskineb9b817e2021-10-04 22:15:05 +0200448
Ronald Cron0266cfe2021-03-13 18:50:11 +0100449psa_status_t mbedtls_psa_rsa_verify_hash(
Ronald Cron7bdbca32020-12-09 13:34:54 +0100450 const psa_key_attributes_t *attributes,
451 const uint8_t *key_buffer, size_t key_buffer_size,
452 psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
453 const uint8_t *signature, size_t signature_length )
454{
455 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
456 mbedtls_rsa_context *rsa = NULL;
457 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
458 mbedtls_md_type_t md_alg;
459
460 status = mbedtls_psa_rsa_load_representation( attributes->core.type,
461 key_buffer,
462 key_buffer_size,
463 &rsa );
464 if( status != PSA_SUCCESS )
465 goto exit;
466
467 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
468 if( status != PSA_SUCCESS )
469 goto exit;
470
471 if( signature_length != mbedtls_rsa_get_len( rsa ) )
472 {
473 status = PSA_ERROR_INVALID_SIGNATURE;
474 goto exit;
475 }
476
Ronald Cron0266cfe2021-03-13 18:50:11 +0100477#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
Ronald Cron7bdbca32020-12-09 13:34:54 +0100478 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
479 {
Ronald Cronea7631b2021-06-03 18:51:59 +0200480 ret = mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
481 MBEDTLS_MD_NONE );
482 if( ret == 0 )
483 {
484 ret = mbedtls_rsa_pkcs1_verify( rsa,
485 md_alg,
486 (unsigned int) hash_length,
487 hash,
488 signature );
489 }
Ronald Cron7bdbca32020-12-09 13:34:54 +0100490 }
491 else
Ronald Cron0266cfe2021-03-13 18:50:11 +0100492#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
493#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
Ronald Cron7bdbca32020-12-09 13:34:54 +0100494 if( PSA_ALG_IS_RSA_PSS( alg ) )
495 {
Ronald Cronea7631b2021-06-03 18:51:59 +0200496 ret = mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
497 if( ret == 0 )
498 {
Gilles Peskineb9b817e2021-10-04 22:15:05 +0200499 int slen = rsa_pss_expected_salt_len( alg, rsa, hash_length );
500 ret = mbedtls_rsa_rsassa_pss_verify_ext( rsa,
501 md_alg,
502 (unsigned) hash_length,
503 hash,
504 md_alg,
505 slen,
506 signature );
Ronald Cronea7631b2021-06-03 18:51:59 +0200507 }
Ronald Cron7bdbca32020-12-09 13:34:54 +0100508 }
509 else
Ronald Cron0266cfe2021-03-13 18:50:11 +0100510#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
Ronald Cron7bdbca32020-12-09 13:34:54 +0100511 {
512 status = PSA_ERROR_INVALID_ARGUMENT;
513 goto exit;
514 }
515
516 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
517 * the rest of the signature is invalid". This has little use in
518 * practice and PSA doesn't report this distinction. */
519 status = ( ret == MBEDTLS_ERR_RSA_INVALID_PADDING ) ?
520 PSA_ERROR_INVALID_SIGNATURE :
521 mbedtls_to_psa_error( ret );
522
523exit:
524 mbedtls_rsa_free( rsa );
525 mbedtls_free( rsa );
526
527 return( status );
528}
529
Ronald Crond2fb8542020-12-09 15:18:01 +0100530#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
531 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
532
Przemyslaw Stekiel234f3182021-12-09 11:13:58 +0100533/****************************************************************/
534/* Asymmetric cryptography */
535/****************************************************************/
536
537#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
538static int psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
539 mbedtls_rsa_context *rsa )
540{
541 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
Manuel Pégourié-Gonnardd82a9ed2022-07-18 15:21:37 +0200542 mbedtls_md_type_t md_alg = mbedtls_hash_info_md_from_psa( hash_alg );
Przemyslaw Stekiel234f3182021-12-09 11:13:58 +0100543
544 return( mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg ) );
545}
546#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
547
548psa_status_t mbedtls_psa_asymmetric_encrypt( const psa_key_attributes_t *attributes,
549 const uint8_t *key_buffer,
550 size_t key_buffer_size,
551 psa_algorithm_t alg,
552 const uint8_t *input,
553 size_t input_length,
554 const uint8_t *salt,
555 size_t salt_length,
556 uint8_t *output,
557 size_t output_size,
558 size_t *output_length )
559{
560 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
561 (void) key_buffer;
562 (void) key_buffer_size;
563 (void) input;
564 (void) input_length;
565 (void) salt;
566 (void) salt_length;
567 (void) output;
568 (void) output_size;
569 (void) output_length;
570
571 if( PSA_KEY_TYPE_IS_RSA( attributes->core.type ) )
572 {
573#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
574 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
575 mbedtls_rsa_context *rsa = NULL;
576 status = mbedtls_psa_rsa_load_representation( attributes->core.type,
577 key_buffer,
578 key_buffer_size,
579 &rsa );
580 if( status != PSA_SUCCESS )
581 goto rsa_exit;
582
583 if( output_size < mbedtls_rsa_get_len( rsa ) )
584 {
585 status = PSA_ERROR_BUFFER_TOO_SMALL;
586 goto rsa_exit;
587 }
588#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
589 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
590 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
591 {
592#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
593 status = mbedtls_to_psa_error(
594 mbedtls_rsa_pkcs1_encrypt( rsa,
595 mbedtls_psa_get_random,
596 MBEDTLS_PSA_RANDOM_STATE,
597 input_length,
598 input,
599 output ) );
600#else
601 status = PSA_ERROR_NOT_SUPPORTED;
602#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
603 }
604 else
605 if( PSA_ALG_IS_RSA_OAEP( alg ) )
606 {
607#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
608 status = mbedtls_to_psa_error(
609 psa_rsa_oaep_set_padding_mode( alg, rsa ) );
610 if( status != PSA_SUCCESS )
611 goto rsa_exit;
612
613 status = mbedtls_to_psa_error(
614 mbedtls_rsa_rsaes_oaep_encrypt( rsa,
615 mbedtls_psa_get_random,
616 MBEDTLS_PSA_RANDOM_STATE,
617 salt, salt_length,
618 input_length,
619 input,
620 output ) );
621#else
622 status = PSA_ERROR_NOT_SUPPORTED;
623#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
624 }
625 else
626 {
627 status = PSA_ERROR_INVALID_ARGUMENT;
628 }
629#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
630 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
631rsa_exit:
632 if( status == PSA_SUCCESS )
633 *output_length = mbedtls_rsa_get_len( rsa );
634
635 mbedtls_rsa_free( rsa );
636 mbedtls_free( rsa );
637#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
638 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
639 }
640 else
641 {
642 status = PSA_ERROR_NOT_SUPPORTED;
643 }
644
645 return status;
646}
647
Przemyslaw Stekiel2ecfd572021-12-13 09:08:05 +0100648psa_status_t mbedtls_psa_asymmetric_decrypt( const psa_key_attributes_t *attributes,
649 const uint8_t *key_buffer,
650 size_t key_buffer_size,
651 psa_algorithm_t alg,
652 const uint8_t *input,
653 size_t input_length,
654 const uint8_t *salt,
655 size_t salt_length,
656 uint8_t *output,
657 size_t output_size,
658 size_t *output_length )
659{
660 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
661 (void) key_buffer;
662 (void) key_buffer_size;
663 (void) input;
664 (void) input_length;
665 (void) salt;
666 (void) salt_length;
667 (void) output;
668 (void) output_size;
669 (void) output_length;
670
671 *output_length = 0;
672
673 if( attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
674 {
675#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
676 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
677 mbedtls_rsa_context *rsa = NULL;
678 status = mbedtls_psa_rsa_load_representation( attributes->core.type,
679 key_buffer,
680 key_buffer_size,
681 &rsa );
682 if( status != PSA_SUCCESS )
683 goto rsa_exit;
684
685 if( input_length != mbedtls_rsa_get_len( rsa ) )
686 {
687 status = PSA_ERROR_INVALID_ARGUMENT;
688 goto rsa_exit;
689 }
690#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
691 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
692
693 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
694 {
695#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
696 status = mbedtls_to_psa_error(
697 mbedtls_rsa_pkcs1_decrypt( rsa,
698 mbedtls_psa_get_random,
699 MBEDTLS_PSA_RANDOM_STATE,
700 output_length,
701 input,
702 output,
703 output_size ) );
704#else
705 status = PSA_ERROR_NOT_SUPPORTED;
706#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
707 }
708 else
709 if( PSA_ALG_IS_RSA_OAEP( alg ) )
710 {
711#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
712 status = mbedtls_to_psa_error(
713 psa_rsa_oaep_set_padding_mode( alg, rsa ) );
714 if( status != PSA_SUCCESS )
715 goto rsa_exit;
716
717 status = mbedtls_to_psa_error(
718 mbedtls_rsa_rsaes_oaep_decrypt( rsa,
719 mbedtls_psa_get_random,
720 MBEDTLS_PSA_RANDOM_STATE,
721 salt, salt_length,
722 output_length,
723 input,
724 output,
725 output_size ) );
726#else
727 status = PSA_ERROR_NOT_SUPPORTED;
728#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
729 }
730 else
731 {
732 status = PSA_ERROR_INVALID_ARGUMENT;
733 }
734
735#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
736 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
737rsa_exit:
738 mbedtls_rsa_free( rsa );
739 mbedtls_free( rsa );
740#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
741 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
742 }
743 else
744 {
745 status = PSA_ERROR_NOT_SUPPORTED;
746 }
747
748 return status;
749}
750
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100751#endif /* MBEDTLS_PSA_CRYPTO_C */