blob: f6da44e9d61918c68da0156cc6ac36f85674fdad [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"
Gilles Peskine969ac722018-01-28 18:16:59 +010042#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010043#include "mbedtls/entropy.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010044#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010045#include "mbedtls/pk_internal.h"
46#include "mbedtls/rsa.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010047
48
49/* Implementation that should never be optimized out by the compiler */
50static void mbedtls_zeroize( void *v, size_t n )
51{
52 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
53}
54
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010055/****************************************************************/
56/* Global data, support functions and library management */
57/****************************************************************/
58
59/* Number of key slots (plus one because 0 is not used).
60 * The value is a compile-time constant for now, for simplicity. */
61#define MBEDTLS_PSA_KEY_SLOT_COUNT 32
62
63typedef struct {
64 psa_key_type_t type;
65 union {
66 struct raw_data {
67 uint8_t *data;
68 size_t bytes;
69 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +010070#if defined(MBEDTLS_RSA_C)
71 mbedtls_rsa_context *rsa;
72#endif /* MBEDTLS_RSA_C */
73#if defined(MBEDTLS_ECP_C)
74 mbedtls_ecp_keypair *ecp;
75#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010076 } data;
77} key_slot_t;
78
Gilles Peskinee59236f2018-01-27 23:32:46 +010079typedef struct {
80 int initialized;
81 mbedtls_entropy_context entropy;
82 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010083 key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +010084} psa_global_data_t;
85
86static psa_global_data_t global_data;
87
88static psa_status_t mbedtls_to_psa_error( int ret )
89{
90 switch( ret )
91 {
92 case 0:
93 return( PSA_SUCCESS );
94 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
95 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
96 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
97 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010098 case MBEDTLS_ERR_PK_ALLOC_FAILED:
99 return( PSA_ERROR_INSUFFICIENT_MEMORY );
100 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
101 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
102 return( PSA_ERROR_INVALID_ARGUMENT );
103 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
104 return( PSA_ERROR_TAMPERING_DETECTED );
105 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
106 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
107 return( PSA_ERROR_INVALID_ARGUMENT );
108 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
109 return( PSA_ERROR_NOT_SUPPORTED );
110 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
111 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
112 return( PSA_ERROR_NOT_PERMITTED );
113 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
114 return( PSA_ERROR_INVALID_ARGUMENT );
115 case MBEDTLS_ERR_PK_INVALID_ALG:
116 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
117 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
118 return( PSA_ERROR_NOT_SUPPORTED );
119 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
120 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100121 default:
122 return( PSA_ERROR_UNKNOWN_ERROR );
123 }
124}
125
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100126
127
128/****************************************************************/
129/* Key management */
130/****************************************************************/
131
132psa_status_t psa_import_key(psa_key_slot_t key,
133 psa_key_type_t type,
134 const uint8_t *data,
135 size_t data_length)
136{
137 key_slot_t *slot;
138
139 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
140 return( PSA_ERROR_INVALID_ARGUMENT );
141 slot = &global_data.key_slots[key];
142 if( slot->type != PSA_KEY_TYPE_NONE )
143 return( PSA_ERROR_OCCUPIED_SLOT );
144
145 if( type == PSA_KEY_TYPE_RAW_DATA )
146 {
147 if( data_length > SIZE_MAX / 8 )
148 return( PSA_ERROR_NOT_SUPPORTED );
149 slot->data.raw.data = mbedtls_calloc( 1, data_length );
150 if( slot->data.raw.data == NULL )
151 return( PSA_ERROR_INSUFFICIENT_MEMORY );
152 memcpy( slot->data.raw.data, data, data_length );
153 slot->data.raw.bytes = data_length;
154 }
155 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100156#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100157 if( type == PSA_KEY_TYPE_RSA || PSA_KEY_TYPE_IS_ECC( type ) )
158 {
159 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100160 mbedtls_pk_context pk;
161 mbedtls_pk_init( &pk );
162 ret = mbedtls_pk_parse_key( &pk, data, data_length,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100163 NULL, 0 );
164 if( ret != 0 )
165 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100166 switch( mbedtls_pk_get_type( &pk ) )
167 {
168#if defined(MBEDTLS_RSA_C)
169 case MBEDTLS_PK_RSA:
170 if( type == PSA_KEY_TYPE_RSA )
171 slot->data.rsa = pk.pk_ctx;
172 else
173 return( PSA_ERROR_INVALID_ARGUMENT );
174 break;
175#endif /* MBEDTLS_RSA_C */
176#if defined(MBEDTLS_ECP_C)
177 case MBEDTLS_PK_ECKEY:
178 if( PSA_KEY_TYPE_IS_ECC( type ) )
179 {
180 // TODO: check curve
181 slot->data.ecp = pk.pk_ctx;
182 }
183 else
184 return( PSA_ERROR_INVALID_ARGUMENT );
185 break;
186#endif /* MBEDTLS_ECP_C */
187 default:
188 return( PSA_ERROR_INVALID_ARGUMENT );
189 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100190 }
191 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100192#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100193 {
194 return( PSA_ERROR_NOT_SUPPORTED );
195 }
196
197 slot->type = type;
198 return( PSA_SUCCESS );
199}
200
201psa_status_t psa_destroy_key(psa_key_slot_t key)
202{
203 key_slot_t *slot;
204
205 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
206 return( PSA_ERROR_INVALID_ARGUMENT );
207 slot = &global_data.key_slots[key];
208 if( slot->type == PSA_KEY_TYPE_NONE )
209 return( PSA_ERROR_EMPTY_SLOT );
210
211 if( slot->type == PSA_KEY_TYPE_RAW_DATA )
212 {
213 mbedtls_free( slot->data.raw.data );
214 }
215 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100216#if defined(MBEDTLS_RSA_C)
217 if( slot->type == PSA_KEY_TYPE_RSA )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100218 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100219 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100220 }
221 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100222#endif /* defined(MBEDTLS_RSA_C) */
223#if defined(MBEDTLS_ECP_C)
224 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
225 {
226 mbedtls_ecp_keypair_free( slot->data.ecp );
227 }
228 else
229#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100230 {
231 /* Shouldn't happen: the key type is not any type that we
232 * put it. */
233 return( PSA_ERROR_TAMPERING_DETECTED );
234 }
235
236 mbedtls_zeroize( slot, sizeof( *slot ) );
237 return( PSA_SUCCESS );
238}
239
240psa_status_t psa_get_key_information(psa_key_slot_t key,
241 psa_key_type_t *type,
242 size_t *bits)
243{
244 key_slot_t *slot;
245
246 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
247 return( PSA_ERROR_INVALID_ARGUMENT );
248 slot = &global_data.key_slots[key];
249 if( type != NULL )
250 *type = slot->type;
251 if( bits != NULL )
252 *bits = 0;
253 if( slot->type == PSA_KEY_TYPE_NONE )
254 return( PSA_ERROR_EMPTY_SLOT );
255
256 if( slot->type == PSA_KEY_TYPE_RAW_DATA )
257 {
258 if( bits != NULL )
259 *bits = slot->data.raw.bytes * 8;
260 }
261 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100262#if defined(MBEDTLS_RSA_C)
263 if( slot->type == PSA_KEY_TYPE_RSA )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100264 {
265 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100266 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100267 }
268 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100269#endif /* defined(MBEDTLS_RSA_C) */
270#if defined(MBEDTLS_ECP_C)
271 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
272 {
273 if( bits != NULL )
274 *bits = slot->data.ecp->grp.pbits;
275 }
276 else
277#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100278 {
279 /* Shouldn't happen: the key type is not any type that we
280 * put it. */
281 return( PSA_ERROR_TAMPERING_DETECTED );
282 }
283
284 return( PSA_SUCCESS );
285}
286
287psa_status_t psa_export_key(psa_key_slot_t key,
288 uint8_t *data,
289 size_t data_size,
290 size_t *data_length)
291{
292 key_slot_t *slot;
293
294 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
295 return( PSA_ERROR_INVALID_ARGUMENT );
296 slot = &global_data.key_slots[key];
297 if( slot->type == PSA_KEY_TYPE_NONE )
298 return( PSA_ERROR_EMPTY_SLOT );
299
300 if( slot->type == PSA_KEY_TYPE_RAW_DATA )
301 {
302 if( slot->data.raw.bytes > data_size )
303 return( PSA_ERROR_BUFFER_TOO_SMALL );
304 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
305 *data_length = slot->data.raw.bytes;
306 return( PSA_SUCCESS );
307 }
308 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100309#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100310 if( slot->type == PSA_KEY_TYPE_RSA ||
311 PSA_KEY_TYPE_IS_ECC( slot->type ) )
312 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100313 mbedtls_pk_context pk;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100314 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100315 mbedtls_pk_init( &pk );
316 if( slot->type == PSA_KEY_TYPE_RSA )
317 {
318 pk.pk_info = &mbedtls_rsa_info;
319 pk.pk_ctx = slot->data.rsa;
320 }
321 else
322 {
323 pk.pk_info = &mbedtls_eckey_info;
324 pk.pk_ctx = slot->data.ecp;
325 }
326 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100327 if( ret < 0 )
328 return( mbedtls_to_psa_error( ret ) );
329 *data_length = ret;
330 return( PSA_SUCCESS );
331 }
332 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100333#endif /* definedMBEDTLS_PK_WRITE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100334 {
335 return( PSA_ERROR_NOT_SUPPORTED );
336 }
337}
338
339
340
341/****************************************************************/
342/* Module setup */
343/****************************************************************/
344
Gilles Peskinee59236f2018-01-27 23:32:46 +0100345void mbedtls_psa_crypto_free( void )
346{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100347 size_t key;
348 for( key = 1; key < MBEDTLS_PSA_KEY_SLOT_COUNT; key++ )
349 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100350 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
351 mbedtls_entropy_free( &global_data.entropy );
352 mbedtls_zeroize( &global_data, sizeof( global_data ) );
353}
354
355psa_status_t psa_crypto_init( void )
356{
357 int ret;
358 const unsigned char drbg_seed[] = "PSA";
359
360 if( global_data.initialized != 0 )
361 return( PSA_SUCCESS );
362
363 mbedtls_zeroize( &global_data, sizeof( global_data ) );
364 mbedtls_entropy_init( &global_data.entropy );
365 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
366
367 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
368 mbedtls_entropy_func,
369 &global_data.entropy,
370 drbg_seed, sizeof( drbg_seed ) - 1 );
371 if( ret != 0 )
372 goto exit;
373
374exit:
375 if( ret != 0 )
376 mbedtls_psa_crypto_free( );
377 return( mbedtls_to_psa_error( ret ) );
378}
379
380#endif /* MBEDTLS_PSA_CRYPTO_C */