blob: 741f5d11ae517105eec8a734a3fd4715826c2d92 [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 Peskinec66ea6a2018-02-03 22:43:28 +0100157 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
158 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
159 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100160 {
161 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100162 mbedtls_pk_context pk;
163 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100164 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
165 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
166 else
167 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100168 if( ret != 0 )
169 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100170 switch( mbedtls_pk_get_type( &pk ) )
171 {
172#if defined(MBEDTLS_RSA_C)
173 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100174 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
175 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine969ac722018-01-28 18:16:59 +0100176 slot->data.rsa = pk.pk_ctx;
177 else
178 return( PSA_ERROR_INVALID_ARGUMENT );
179 break;
180#endif /* MBEDTLS_RSA_C */
181#if defined(MBEDTLS_ECP_C)
182 case MBEDTLS_PK_ECKEY:
183 if( PSA_KEY_TYPE_IS_ECC( type ) )
184 {
185 // TODO: check curve
186 slot->data.ecp = pk.pk_ctx;
187 }
188 else
189 return( PSA_ERROR_INVALID_ARGUMENT );
190 break;
191#endif /* MBEDTLS_ECP_C */
192 default:
193 return( PSA_ERROR_INVALID_ARGUMENT );
194 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100195 }
196 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100197#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100198 {
199 return( PSA_ERROR_NOT_SUPPORTED );
200 }
201
202 slot->type = type;
203 return( PSA_SUCCESS );
204}
205
206psa_status_t psa_destroy_key(psa_key_slot_t key)
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( slot->type == PSA_KEY_TYPE_NONE )
214 return( PSA_ERROR_EMPTY_SLOT );
215
216 if( slot->type == PSA_KEY_TYPE_RAW_DATA )
217 {
218 mbedtls_free( slot->data.raw.data );
219 }
220 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100221#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100222 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
223 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100224 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100225 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100226 }
227 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100228#endif /* defined(MBEDTLS_RSA_C) */
229#if defined(MBEDTLS_ECP_C)
230 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
231 {
232 mbedtls_ecp_keypair_free( slot->data.ecp );
233 }
234 else
235#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100236 {
237 /* Shouldn't happen: the key type is not any type that we
238 * put it. */
239 return( PSA_ERROR_TAMPERING_DETECTED );
240 }
241
242 mbedtls_zeroize( slot, sizeof( *slot ) );
243 return( PSA_SUCCESS );
244}
245
246psa_status_t psa_get_key_information(psa_key_slot_t key,
247 psa_key_type_t *type,
248 size_t *bits)
249{
250 key_slot_t *slot;
251
252 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100253 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100254 slot = &global_data.key_slots[key];
255 if( type != NULL )
256 *type = slot->type;
257 if( bits != NULL )
258 *bits = 0;
259 if( slot->type == PSA_KEY_TYPE_NONE )
260 return( PSA_ERROR_EMPTY_SLOT );
261
262 if( slot->type == PSA_KEY_TYPE_RAW_DATA )
263 {
264 if( bits != NULL )
265 *bits = slot->data.raw.bytes * 8;
266 }
267 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100268#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100269 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
270 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100271 {
272 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100273 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100274 }
275 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100276#endif /* defined(MBEDTLS_RSA_C) */
277#if defined(MBEDTLS_ECP_C)
278 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
279 {
280 if( bits != NULL )
281 *bits = slot->data.ecp->grp.pbits;
282 }
283 else
284#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100285 {
286 /* Shouldn't happen: the key type is not any type that we
287 * put it. */
288 return( PSA_ERROR_TAMPERING_DETECTED );
289 }
290
291 return( PSA_SUCCESS );
292}
293
294psa_status_t psa_export_key(psa_key_slot_t key,
295 uint8_t *data,
296 size_t data_size,
297 size_t *data_length)
298{
299 key_slot_t *slot;
300
301 if( key == 0 || key > MBEDTLS_PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100302 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100303 slot = &global_data.key_slots[key];
304 if( slot->type == PSA_KEY_TYPE_NONE )
305 return( PSA_ERROR_EMPTY_SLOT );
306
307 if( slot->type == PSA_KEY_TYPE_RAW_DATA )
308 {
309 if( slot->data.raw.bytes > data_size )
310 return( PSA_ERROR_BUFFER_TOO_SMALL );
311 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
312 *data_length = slot->data.raw.bytes;
313 return( PSA_SUCCESS );
314 }
315 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100316#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100317 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
318 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100319 PSA_KEY_TYPE_IS_ECC( slot->type ) )
320 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100321 mbedtls_pk_context pk;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100322 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100323 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100324 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
325 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine969ac722018-01-28 18:16:59 +0100326 {
327 pk.pk_info = &mbedtls_rsa_info;
328 pk.pk_ctx = slot->data.rsa;
329 }
330 else
331 {
332 pk.pk_info = &mbedtls_eckey_info;
333 pk.pk_ctx = slot->data.ecp;
334 }
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100335 if( PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
336 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
337 else
338 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100339 if( ret < 0 )
340 return( mbedtls_to_psa_error( ret ) );
341 *data_length = ret;
342 return( PSA_SUCCESS );
343 }
344 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100345#endif /* definedMBEDTLS_PK_WRITE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100346 {
347 return( PSA_ERROR_NOT_SUPPORTED );
348 }
349}
350
351
352
353/****************************************************************/
354/* Module setup */
355/****************************************************************/
356
Gilles Peskinee59236f2018-01-27 23:32:46 +0100357void mbedtls_psa_crypto_free( void )
358{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100359 size_t key;
360 for( key = 1; key < MBEDTLS_PSA_KEY_SLOT_COUNT; key++ )
361 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100362 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
363 mbedtls_entropy_free( &global_data.entropy );
364 mbedtls_zeroize( &global_data, sizeof( global_data ) );
365}
366
367psa_status_t psa_crypto_init( void )
368{
369 int ret;
370 const unsigned char drbg_seed[] = "PSA";
371
372 if( global_data.initialized != 0 )
373 return( PSA_SUCCESS );
374
375 mbedtls_zeroize( &global_data, sizeof( global_data ) );
376 mbedtls_entropy_init( &global_data.entropy );
377 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
378
379 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
380 mbedtls_entropy_func,
381 &global_data.entropy,
382 drbg_seed, sizeof( drbg_seed ) - 1 );
383 if( ret != 0 )
384 goto exit;
385
386exit:
387 if( ret != 0 )
388 mbedtls_psa_crypto_free( );
389 return( mbedtls_to_psa_error( ret ) );
390}
391
392#endif /* MBEDTLS_PSA_CRYPTO_C */