blob: 31dd0d640c14d457f772e52f3397c30cb7ec4495 [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/*
2 * PSA crypto layer on top of Mbed TLS crypto
3 */
4/* Copyright (C) 2018, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PSA_CRYPTO_C)
29
30#include "psa/crypto.h"
31
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010032#include <stdlib.h>
33#include <string.h>
34#if defined(MBEDTLS_PLATFORM_C)
35#include "mbedtls/platform.h"
36#else
37#define mbedtls_calloc calloc
38#define mbedtls_free free
39#endif
40
Gilles Peskinee59236f2018-01-27 23:32:46 +010041#include "mbedtls/ctr_drbg.h"
42#include "mbedtls/entropy.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010043#include "mbedtls/pk.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010044
45
46/* Implementation that should never be optimized out by the compiler */
47static void mbedtls_zeroize( void *v, size_t n )
48{
49 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
50}
51
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010052/****************************************************************/
53/* Global data, support functions and library management */
54/****************************************************************/
55
56/* Number of key slots (plus one because 0 is not used).
57 * The value is a compile-time constant for now, for simplicity. */
58#define MBEDTLS_PSA_KEY_SLOT_COUNT 32
59
60typedef struct {
61 psa_key_type_t type;
62 union {
63 struct raw_data {
64 uint8_t *data;
65 size_t bytes;
66 } raw;
67#if defined(MBEDTLS_PK_C)
68 mbedtls_pk_context pk;
69#endif /* MBEDTLS_PK_C */
70 } data;
71} key_slot_t;
72
Gilles Peskinee59236f2018-01-27 23:32:46 +010073typedef struct {
74 int initialized;
75 mbedtls_entropy_context entropy;
76 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010077 key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +010078} psa_global_data_t;
79
80static psa_global_data_t global_data;
81
82static psa_status_t mbedtls_to_psa_error( int ret )
83{
84 switch( ret )
85 {
86 case 0:
87 return( PSA_SUCCESS );
88 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
89 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
90 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
91 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010092 case MBEDTLS_ERR_PK_ALLOC_FAILED:
93 return( PSA_ERROR_INSUFFICIENT_MEMORY );
94 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
95 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
96 return( PSA_ERROR_INVALID_ARGUMENT );
97 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
98 return( PSA_ERROR_TAMPERING_DETECTED );
99 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
100 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
101 return( PSA_ERROR_INVALID_ARGUMENT );
102 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
103 return( PSA_ERROR_NOT_SUPPORTED );
104 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
105 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
106 return( PSA_ERROR_NOT_PERMITTED );
107 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
108 return( PSA_ERROR_INVALID_ARGUMENT );
109 case MBEDTLS_ERR_PK_INVALID_ALG:
110 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
111 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
112 return( PSA_ERROR_NOT_SUPPORTED );
113 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
114 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100115 default:
116 return( PSA_ERROR_UNKNOWN_ERROR );
117 }
118}
119
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100120
121
122/****************************************************************/
123/* Key management */
124/****************************************************************/
125
126psa_status_t psa_import_key(psa_key_slot_t key,
127 psa_key_type_t type,
128 const uint8_t *data,
129 size_t data_length)
130{
131 key_slot_t *slot;
132
133 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
134 return( PSA_ERROR_INVALID_ARGUMENT );
135 slot = &global_data.key_slots[key];
136 if( slot->type != PSA_KEY_TYPE_NONE )
137 return( PSA_ERROR_OCCUPIED_SLOT );
138
139 if( type == PSA_KEY_TYPE_RAW_DATA )
140 {
141 if( data_length > SIZE_MAX / 8 )
142 return( PSA_ERROR_NOT_SUPPORTED );
143 slot->data.raw.data = mbedtls_calloc( 1, data_length );
144 if( slot->data.raw.data == NULL )
145 return( PSA_ERROR_INSUFFICIENT_MEMORY );
146 memcpy( slot->data.raw.data, data, data_length );
147 slot->data.raw.bytes = data_length;
148 }
149 else
150#if defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_PARSE_C)
151 if( type == PSA_KEY_TYPE_RSA || PSA_KEY_TYPE_IS_ECC( type ) )
152 {
153 int ret;
154 mbedtls_pk_init( &slot->data.pk );
155 ret = mbedtls_pk_parse_key( &slot->data.pk,
156 data, data_length,
157 NULL, 0 );
158 if( ret != 0 )
159 return( mbedtls_to_psa_error( ret ) );
160 }
161 else
162#endif /* defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_PARSE_C) */
163 {
164 return( PSA_ERROR_NOT_SUPPORTED );
165 }
166
167 slot->type = type;
168 return( PSA_SUCCESS );
169}
170
171psa_status_t psa_destroy_key(psa_key_slot_t key)
172{
173 key_slot_t *slot;
174
175 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
176 return( PSA_ERROR_INVALID_ARGUMENT );
177 slot = &global_data.key_slots[key];
178 if( slot->type == PSA_KEY_TYPE_NONE )
179 return( PSA_ERROR_EMPTY_SLOT );
180
181 if( slot->type == PSA_KEY_TYPE_RAW_DATA )
182 {
183 mbedtls_free( slot->data.raw.data );
184 }
185 else
186#if defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_PARSE_C)
187 if( slot->type == PSA_KEY_TYPE_RSA ||
188 PSA_KEY_TYPE_IS_ECC( slot->type ) )
189 {
190 mbedtls_pk_free( &slot->data.pk );
191 }
192 else
193#endif /* defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_PARSE_C) */
194 {
195 /* Shouldn't happen: the key type is not any type that we
196 * put it. */
197 return( PSA_ERROR_TAMPERING_DETECTED );
198 }
199
200 mbedtls_zeroize( slot, sizeof( *slot ) );
201 return( PSA_SUCCESS );
202}
203
204psa_status_t psa_get_key_information(psa_key_slot_t key,
205 psa_key_type_t *type,
206 size_t *bits)
207{
208 key_slot_t *slot;
209
210 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
211 return( PSA_ERROR_INVALID_ARGUMENT );
212 slot = &global_data.key_slots[key];
213 if( type != NULL )
214 *type = slot->type;
215 if( bits != NULL )
216 *bits = 0;
217 if( slot->type == PSA_KEY_TYPE_NONE )
218 return( PSA_ERROR_EMPTY_SLOT );
219
220 if( slot->type == PSA_KEY_TYPE_RAW_DATA )
221 {
222 if( bits != NULL )
223 *bits = slot->data.raw.bytes * 8;
224 }
225 else
226#if defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_PARSE_C)
227 if( slot->type == PSA_KEY_TYPE_RSA ||
228 PSA_KEY_TYPE_IS_ECC( slot->type ) )
229 {
230 if( bits != NULL )
231 *bits = mbedtls_pk_get_bitlen( &slot->data.pk );
232 }
233 else
234#endif /* defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_PARSE_C) */
235 {
236 /* Shouldn't happen: the key type is not any type that we
237 * put it. */
238 return( PSA_ERROR_TAMPERING_DETECTED );
239 }
240
241 return( PSA_SUCCESS );
242}
243
244psa_status_t psa_export_key(psa_key_slot_t key,
245 uint8_t *data,
246 size_t data_size,
247 size_t *data_length)
248{
249 key_slot_t *slot;
250
251 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
252 return( PSA_ERROR_INVALID_ARGUMENT );
253 slot = &global_data.key_slots[key];
254 if( slot->type == PSA_KEY_TYPE_NONE )
255 return( PSA_ERROR_EMPTY_SLOT );
256
257 if( slot->type == PSA_KEY_TYPE_RAW_DATA )
258 {
259 if( slot->data.raw.bytes > data_size )
260 return( PSA_ERROR_BUFFER_TOO_SMALL );
261 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
262 *data_length = slot->data.raw.bytes;
263 return( PSA_SUCCESS );
264 }
265 else
266#if defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_PARSE_C)
267 if( slot->type == PSA_KEY_TYPE_RSA ||
268 PSA_KEY_TYPE_IS_ECC( slot->type ) )
269 {
270 int ret;
271 ret = mbedtls_pk_write_key_der( &slot->data.pk,
272 data, data_size );
273 if( ret < 0 )
274 return( mbedtls_to_psa_error( ret ) );
275 *data_length = ret;
276 return( PSA_SUCCESS );
277 }
278 else
279#endif /* defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_PARSE_C) */
280 {
281 return( PSA_ERROR_NOT_SUPPORTED );
282 }
283}
284
285
286
287/****************************************************************/
288/* Module setup */
289/****************************************************************/
290
Gilles Peskinee59236f2018-01-27 23:32:46 +0100291void mbedtls_psa_crypto_free( void )
292{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100293 size_t key;
294 for( key = 1; key < MBEDTLS_PSA_KEY_SLOT_COUNT; key++ )
295 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100296 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
297 mbedtls_entropy_free( &global_data.entropy );
298 mbedtls_zeroize( &global_data, sizeof( global_data ) );
299}
300
301psa_status_t psa_crypto_init( void )
302{
303 int ret;
304 const unsigned char drbg_seed[] = "PSA";
305
306 if( global_data.initialized != 0 )
307 return( PSA_SUCCESS );
308
309 mbedtls_zeroize( &global_data, sizeof( global_data ) );
310 mbedtls_entropy_init( &global_data.entropy );
311 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
312
313 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
314 mbedtls_entropy_func,
315 &global_data.entropy,
316 drbg_seed, sizeof( drbg_seed ) - 1 );
317 if( ret != 0 )
318 goto exit;
319
320exit:
321 if( ret != 0 )
322 mbedtls_psa_crypto_free( );
323 return( mbedtls_to_psa_error( ret ) );
324}
325
326#endif /* MBEDTLS_PSA_CRYPTO_C */