blob: aae1d056a110371632ee02c621e6398924cf25c9 [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>
26#include "psa_crypto_core.h"
27#include "psa_crypto_rsa.h"
28
29#include <stdlib.h>
30#include <string.h>
31#include "mbedtls/platform.h"
32#if !defined(MBEDTLS_PLATFORM_C)
33#define mbedtls_calloc calloc
34#define mbedtls_free free
35#endif
36
37#include <mbedtls/rsa.h>
38#include <mbedtls/error.h>
39#include <mbedtls/pk.h>
40#include <mbedtls/pk_internal.h>
41
Ronald Cronf1057d32020-11-26 19:19:10 +010042#if ( defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
43 ( defined(PSA_CRYPTO_DRIVER_TEST) && \
44 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) ) )
45#define BUILTIN_KEY_TYPE_RSA_KEY_PAIR 1
46#endif
47
48#if ( defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) || \
49 ( defined(PSA_CRYPTO_DRIVER_TEST) && \
50 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY) ) )
51#define BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1
52#endif
53
Ronald Cron00b7bfc2020-11-25 15:25:26 +010054#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
55 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
56 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
57 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
Ronald Cronf1057d32020-11-26 19:19:10 +010058 defined(BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
59 defined(BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Ronald Cron00b7bfc2020-11-25 15:25:26 +010060
61/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
62 * that are not a multiple of 8) well. For example, there is only
63 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
64 * way to return the exact bit size of a key.
65 * To keep things simple, reject non-byte-aligned key sizes. */
66static psa_status_t psa_check_rsa_key_byte_aligned(
67 const mbedtls_rsa_context *rsa )
68{
69 mbedtls_mpi n;
70 psa_status_t status;
71 mbedtls_mpi_init( &n );
72 status = mbedtls_to_psa_error(
73 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
74 if( status == PSA_SUCCESS )
75 {
76 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
77 status = PSA_ERROR_NOT_SUPPORTED;
78 }
79 mbedtls_mpi_free( &n );
80 return( status );
81}
82
83psa_status_t mbedtls_psa_rsa_load_representation(
84 psa_key_type_t type, const uint8_t *data, size_t data_length,
85 mbedtls_rsa_context **p_rsa )
86{
87 psa_status_t status;
88 mbedtls_pk_context ctx;
89 size_t bits;
90 mbedtls_pk_init( &ctx );
91
92 /* Parse the data. */
93 if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
94 status = mbedtls_to_psa_error(
95 mbedtls_pk_parse_key( &ctx, data, data_length, NULL, 0 ) );
96 else
97 status = mbedtls_to_psa_error(
98 mbedtls_pk_parse_public_key( &ctx, data, data_length ) );
99 if( status != PSA_SUCCESS )
100 goto exit;
101
102 /* We have something that the pkparse module recognizes. If it is a
103 * valid RSA key, store it. */
104 if( mbedtls_pk_get_type( &ctx ) != MBEDTLS_PK_RSA )
105 {
106 status = PSA_ERROR_INVALID_ARGUMENT;
107 goto exit;
108 }
109
110 /* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS
111 * supports non-byte-aligned key sizes, but not well. For example,
112 * mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */
113 bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( mbedtls_pk_rsa( ctx ) ) );
114 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
115 {
116 status = PSA_ERROR_NOT_SUPPORTED;
117 goto exit;
118 }
119 status = psa_check_rsa_key_byte_aligned( mbedtls_pk_rsa( ctx ) );
120 if( status != PSA_SUCCESS )
121 goto exit;
122
123 /* Copy out the pointer to the RSA context, and reset the PK context
124 * such that pk_free doesn't free the RSA context we just grabbed. */
125 *p_rsa = mbedtls_pk_rsa( ctx );
126 ctx.pk_info = NULL;
127
128exit:
129 mbedtls_pk_free( &ctx );
130 return( status );
131}
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100132#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
133 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
134 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
135 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
Ronald Cronf1057d32020-11-26 19:19:10 +0100136 * defined(BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
137 * defined(BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100138
Ronald Cronf1057d32020-11-26 19:19:10 +0100139#if defined(BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
140 defined(BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Ronald Cronabf2aef2020-11-27 18:13:44 +0100141
Ronald Cron784fb322020-11-30 13:55:05 +0100142static psa_status_t rsa_import_key(
Ronald Cronabf2aef2020-11-27 18:13:44 +0100143 const psa_key_attributes_t *attributes,
144 const uint8_t *data, size_t data_length,
145 uint8_t *key_buffer, size_t key_buffer_size,
146 size_t *key_buffer_length, size_t *bits )
147{
148 psa_status_t status;
149 mbedtls_rsa_context *rsa = NULL;
150
151 /* Parse input */
152 status = mbedtls_psa_rsa_load_representation( attributes->core.type,
153 data,
154 data_length,
155 &rsa );
156 if( status != PSA_SUCCESS )
157 goto exit;
158
159 *bits = (psa_key_bits_t) PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( rsa ) );
160
161 /* Re-export the data to PSA export format, such that we can store export
162 * representation in the key slot. Export representation in case of RSA is
163 * the smallest representation that's allowed as input, so a straight-up
164 * allocation of the same size as the input buffer will be large enough. */
165 status = mbedtls_psa_rsa_export_key( attributes->core.type,
166 rsa,
167 key_buffer,
168 key_buffer_size,
169 key_buffer_length );
170exit:
171 /* Always free the RSA object */
172 mbedtls_rsa_free( rsa );
173 mbedtls_free( rsa );
174
175 return( status );
176}
177
Ronald Crone5ca3d82020-11-26 16:36:16 +0100178psa_status_t mbedtls_psa_rsa_export_key( psa_key_type_t type,
179 mbedtls_rsa_context *rsa,
180 uint8_t *data,
181 size_t data_size,
182 size_t *data_length )
183{
184#if defined(MBEDTLS_PK_WRITE_C)
185 int ret;
186 mbedtls_pk_context pk;
187 uint8_t *pos = data + data_size;
188
189 mbedtls_pk_init( &pk );
190 pk.pk_info = &mbedtls_rsa_info;
191 pk.pk_ctx = rsa;
192
193 /* PSA Crypto API defines the format of an RSA key as a DER-encoded
194 * representation of the non-encrypted PKCS#1 RSAPrivateKey for a
195 * private key and of the RFC3279 RSAPublicKey for a public key. */
196 if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
197 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
198 else
199 ret = mbedtls_pk_write_pubkey( &pos, data, &pk );
200
201 if( ret < 0 )
202 {
203 /* Clean up in case pk_write failed halfway through. */
204 memset( data, 0, data_size );
205 return( mbedtls_to_psa_error( ret ) );
206 }
207
208 /* The mbedtls_pk_xxx functions write to the end of the buffer.
209 * Move the data to the beginning and erase remaining data
210 * at the original location. */
211 if( 2 * (size_t) ret <= data_size )
212 {
213 memcpy( data, data + data_size - ret, ret );
214 memset( data + data_size - ret, 0, ret );
215 }
216 else if( (size_t) ret < data_size )
217 {
218 memmove( data, data + data_size - ret, ret );
219 memset( data + ret, 0, data_size - ret );
220 }
221
222 *data_length = ret;
223 return( PSA_SUCCESS );
224#else
225 (void) type;
226 (void) rsa;
227 (void) data;
228 (void) data_size;
229 (void) data_length;
230 return( PSA_ERROR_NOT_SUPPORTED );
231#endif /* MBEDTLS_PK_WRITE_C */
232}
233
Ronald Cronf1057d32020-11-26 19:19:10 +0100234static psa_status_t rsa_export_public_key(
Ronald Crone5ca3d82020-11-26 16:36:16 +0100235 const psa_key_attributes_t *attributes,
236 const uint8_t *key_buffer, size_t key_buffer_size,
237 uint8_t *data, size_t data_size, size_t *data_length )
238{
239 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
240 mbedtls_rsa_context *rsa = NULL;
241
242 status = mbedtls_psa_rsa_load_representation(
243 attributes->core.type, key_buffer, key_buffer_size, &rsa );
244 if( status != PSA_SUCCESS )
245 return( status );
246
247 status = mbedtls_psa_rsa_export_key( PSA_KEY_TYPE_RSA_PUBLIC_KEY,
248 rsa,
249 data,
250 data_size,
251 data_length );
252
253 mbedtls_rsa_free( rsa );
254 mbedtls_free( rsa );
255
256 return( status );
257}
Ronald Cronf1057d32020-11-26 19:19:10 +0100258#endif /* defined(BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
259 * defined(BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
260
261#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
262 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
263
Ronald Cron784fb322020-11-30 13:55:05 +0100264psa_status_t mbedtls_psa_rsa_import_key(
265 const psa_key_attributes_t *attributes,
266 const uint8_t *data, size_t data_length,
267 uint8_t *key_buffer, size_t key_buffer_size,
268 size_t *key_buffer_length, size_t *bits )
269{
270 return( rsa_import_key( attributes, data, data_length,
271 key_buffer, key_buffer_size,
272 key_buffer_length, bits ) );
273}
274
Ronald Cronf1057d32020-11-26 19:19:10 +0100275psa_status_t mbedtls_psa_rsa_export_public_key(
276 const psa_key_attributes_t *attributes,
277 const uint8_t *key_buffer, size_t key_buffer_size,
278 uint8_t *data, size_t data_size, size_t *data_length )
279{
280 return( rsa_export_public_key( attributes, key_buffer, key_buffer_size,
281 data, data_size, data_length ) );
282}
283
Ronald Crone5ca3d82020-11-26 16:36:16 +0100284#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
285 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
286
Ronald Cronf1057d32020-11-26 19:19:10 +0100287/*
288 * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
289 */
290
291#if defined(PSA_CRYPTO_DRIVER_TEST)
292
293#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) || \
294 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY)
Ronald Cron784fb322020-11-30 13:55:05 +0100295
296psa_status_t mbedtls_transparent_test_driver_rsa_import_key(
297 const psa_key_attributes_t *attributes,
298 const uint8_t *data, size_t data_length,
299 uint8_t *key_buffer, size_t key_buffer_size,
300 size_t *key_buffer_length, size_t *bits )
301{
302 return( rsa_import_key( attributes, data, data_length,
303 key_buffer, key_buffer_size,
304 key_buffer_length, bits ) );
305}
306
Ronald Cronf1057d32020-11-26 19:19:10 +0100307psa_status_t mbedtls_transparent_test_driver_rsa_export_public_key(
308 const psa_key_attributes_t *attributes,
309 const uint8_t *key_buffer, size_t key_buffer_size,
310 uint8_t *data, size_t data_size, size_t *data_length )
311{
312 return( rsa_export_public_key( attributes, key_buffer, key_buffer_size,
313 data, data_size, data_length ) );
314}
Ronald Cron784fb322020-11-30 13:55:05 +0100315
Ronald Cronf1057d32020-11-26 19:19:10 +0100316#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) ||
317 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY) */
318
319#endif /* PSA_CRYPTO_DRIVER_TEST */
320
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100321#endif /* MBEDTLS_PSA_CRYPTO_C */