blob: 18147732d0ce165a1bd6f7727063a58dfbe8e05c [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 Crone5ca3d82020-11-26 16:36:16 +0100141psa_status_t mbedtls_psa_rsa_export_key( psa_key_type_t type,
142 mbedtls_rsa_context *rsa,
143 uint8_t *data,
144 size_t data_size,
145 size_t *data_length )
146{
147#if defined(MBEDTLS_PK_WRITE_C)
148 int ret;
149 mbedtls_pk_context pk;
150 uint8_t *pos = data + data_size;
151
152 mbedtls_pk_init( &pk );
153 pk.pk_info = &mbedtls_rsa_info;
154 pk.pk_ctx = rsa;
155
156 /* PSA Crypto API defines the format of an RSA key as a DER-encoded
157 * representation of the non-encrypted PKCS#1 RSAPrivateKey for a
158 * private key and of the RFC3279 RSAPublicKey for a public key. */
159 if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
160 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
161 else
162 ret = mbedtls_pk_write_pubkey( &pos, data, &pk );
163
164 if( ret < 0 )
165 {
166 /* Clean up in case pk_write failed halfway through. */
167 memset( data, 0, data_size );
168 return( mbedtls_to_psa_error( ret ) );
169 }
170
171 /* The mbedtls_pk_xxx functions write to the end of the buffer.
172 * Move the data to the beginning and erase remaining data
173 * at the original location. */
174 if( 2 * (size_t) ret <= data_size )
175 {
176 memcpy( data, data + data_size - ret, ret );
177 memset( data + data_size - ret, 0, ret );
178 }
179 else if( (size_t) ret < data_size )
180 {
181 memmove( data, data + data_size - ret, ret );
182 memset( data + ret, 0, data_size - ret );
183 }
184
185 *data_length = ret;
186 return( PSA_SUCCESS );
187#else
188 (void) type;
189 (void) rsa;
190 (void) data;
191 (void) data_size;
192 (void) data_length;
193 return( PSA_ERROR_NOT_SUPPORTED );
194#endif /* MBEDTLS_PK_WRITE_C */
195}
196
Ronald Cronf1057d32020-11-26 19:19:10 +0100197static psa_status_t rsa_export_public_key(
Ronald Crone5ca3d82020-11-26 16:36:16 +0100198 const psa_key_attributes_t *attributes,
199 const uint8_t *key_buffer, size_t key_buffer_size,
200 uint8_t *data, size_t data_size, size_t *data_length )
201{
202 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
203 mbedtls_rsa_context *rsa = NULL;
204
205 status = mbedtls_psa_rsa_load_representation(
206 attributes->core.type, key_buffer, key_buffer_size, &rsa );
207 if( status != PSA_SUCCESS )
208 return( status );
209
210 status = mbedtls_psa_rsa_export_key( PSA_KEY_TYPE_RSA_PUBLIC_KEY,
211 rsa,
212 data,
213 data_size,
214 data_length );
215
216 mbedtls_rsa_free( rsa );
217 mbedtls_free( rsa );
218
219 return( status );
220}
Ronald Cronf1057d32020-11-26 19:19:10 +0100221#endif /* defined(BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
222 * defined(BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
223
224#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
225 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
226
227psa_status_t mbedtls_psa_rsa_export_public_key(
228 const psa_key_attributes_t *attributes,
229 const uint8_t *key_buffer, size_t key_buffer_size,
230 uint8_t *data, size_t data_size, size_t *data_length )
231{
232 return( rsa_export_public_key( attributes, key_buffer, key_buffer_size,
233 data, data_size, data_length ) );
234}
235
Ronald Crone5ca3d82020-11-26 16:36:16 +0100236#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
237 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
238
Ronald Cronf1057d32020-11-26 19:19:10 +0100239/*
240 * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
241 */
242
243#if defined(PSA_CRYPTO_DRIVER_TEST)
244
245#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) || \
246 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY)
247psa_status_t mbedtls_transparent_test_driver_rsa_export_public_key(
248 const psa_key_attributes_t *attributes,
249 const uint8_t *key_buffer, size_t key_buffer_size,
250 uint8_t *data, size_t data_size, size_t *data_length )
251{
252 return( rsa_export_public_key( attributes, key_buffer, key_buffer_size,
253 data, data_size, data_length ) );
254}
255#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) ||
256 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY) */
257
258#endif /* PSA_CRYPTO_DRIVER_TEST */
259
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100260#endif /* MBEDTLS_PSA_CRYPTO_C */