blob: 714a03904bf3e13c1b26990e189893a0debae5e9 [file] [log] [blame]
Gilles Peskinea899a722019-06-24 14:06:43 +02001/*
2 * PSA crypto support for secure element drivers
3 */
4/* Copyright (C) 2019, 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
Gilles Peskinea8ade162019-06-26 11:24:49 +020028#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskinea899a722019-06-24 14:06:43 +020029
Gilles Peskine9717d102019-06-26 11:50:04 +020030#include <assert.h>
Gilles Peskine5243a202019-07-12 23:38:19 +020031#include <stdint.h>
Gilles Peskined0890212019-06-24 14:34:43 +020032#include <string.h>
33
Gilles Peskine5243a202019-07-12 23:38:19 +020034#include "psa/crypto_se_driver.h"
35
Gilles Peskinea899a722019-06-24 14:06:43 +020036#include "psa_crypto_se.h"
37
Gilles Peskine8b96cad2019-07-23 17:38:08 +020038#if defined(MBEDTLS_PSA_ITS_FILE_C)
39#include "psa_crypto_its.h"
40#else /* Native ITS implementation */
41#include "psa/error.h"
42#include "psa/internal_trusted_storage.h"
43#endif
44
Gilles Peskine5243a202019-07-12 23:38:19 +020045#include "mbedtls/platform.h"
46#if !defined(MBEDTLS_PLATFORM_C)
47#define mbedtls_calloc calloc
48#define mbedtls_free free
49#endif
50
51
52
Gilles Peskinef989dbe2019-06-26 18:18:12 +020053/****************************************************************/
54/* Driver lookup */
55/****************************************************************/
56
Gilles Peskine5243a202019-07-12 23:38:19 +020057/* This structure is identical to psa_drv_se_context_t declared in
58 * `crypto_se_driver.h`, except that some parts are writable here
59 * (non-const, or pointer to non-const). */
60typedef struct
61{
62 void *persistent_data;
63 size_t persistent_data_size;
64 uintptr_t transient_data;
65} psa_drv_se_internal_context_t;
66
Gilles Peskinef989dbe2019-06-26 18:18:12 +020067typedef struct psa_se_drv_table_entry_s
Gilles Peskinea899a722019-06-24 14:06:43 +020068{
69 psa_key_lifetime_t lifetime;
70 const psa_drv_se_t *methods;
Gilles Peskine5243a202019-07-12 23:38:19 +020071 union
72 {
73 psa_drv_se_internal_context_t internal;
74 psa_drv_se_context_t context;
75 };
Gilles Peskinef989dbe2019-06-26 18:18:12 +020076} psa_se_drv_table_entry_t;
Gilles Peskinea899a722019-06-24 14:06:43 +020077
Gilles Peskinef989dbe2019-06-26 18:18:12 +020078static psa_se_drv_table_entry_t driver_table[PSA_MAX_SE_DRIVERS];
79
Gilles Peskine5243a202019-07-12 23:38:19 +020080psa_se_drv_table_entry_t *psa_get_se_driver_entry(
Gilles Peskinef989dbe2019-06-26 18:18:12 +020081 psa_key_lifetime_t lifetime )
82{
83 size_t i;
84 if( lifetime == 0 )
85 return( NULL );
86 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
87 {
88 if( driver_table[i].lifetime == lifetime )
89 return( &driver_table[i] );
90 }
91 return( NULL );
92}
93
94const psa_drv_se_t *psa_get_se_driver_methods(
Gilles Peskine5243a202019-07-12 23:38:19 +020095 const psa_se_drv_table_entry_t *driver )
Gilles Peskinef989dbe2019-06-26 18:18:12 +020096{
Gilles Peskine5243a202019-07-12 23:38:19 +020097 return( driver->methods );
Gilles Peskinef989dbe2019-06-26 18:18:12 +020098}
99
Gilles Peskine5243a202019-07-12 23:38:19 +0200100psa_drv_se_context_t *psa_get_se_driver_context(
101 psa_se_drv_table_entry_t *driver )
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200102{
Gilles Peskine5243a202019-07-12 23:38:19 +0200103 return( &driver->context );
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200104}
105
Gilles Peskine5243a202019-07-12 23:38:19 +0200106int psa_get_se_driver( psa_key_lifetime_t lifetime,
107 const psa_drv_se_t **p_methods,
108 psa_drv_se_context_t **p_drv_context)
109{
110 psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry( lifetime );
111 if( p_methods != NULL )
112 *p_methods = ( driver ? driver->methods : NULL );
113 if( p_drv_context != NULL )
114 *p_drv_context = ( driver ? &driver->context : NULL );
115 return( driver != NULL );
116}
117
118
119
120/****************************************************************/
121/* Persistent data management */
122/****************************************************************/
123
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200124static psa_status_t psa_get_se_driver_its_file_uid(
125 const psa_se_drv_table_entry_t *driver,
126 psa_storage_uid_t *uid )
127{
128 if( driver->lifetime > PSA_MAX_SE_LIFETIME )
129 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine573bbc12019-07-23 19:59:23 +0200130
131#if SIZE_MAX > UINT32_MAX
132 /* ITS file sizes are limited to 32 bits. */
133 if( driver->internal.persistent_data_size > UINT32_MAX )
134 return( PSA_ERROR_NOT_SUPPORTED );
135#endif
136
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200137 *uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->lifetime;
138 return( PSA_SUCCESS );
139}
140
Gilles Peskine5243a202019-07-12 23:38:19 +0200141psa_status_t psa_load_se_persistent_data(
142 const psa_se_drv_table_entry_t *driver )
143{
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200144 psa_status_t status;
145 psa_storage_uid_t uid;
146
147 status = psa_get_se_driver_its_file_uid( driver, &uid );
148 if( status != PSA_SUCCESS )
149 return( status );
150
Gilles Peskine573bbc12019-07-23 19:59:23 +0200151 return( psa_its_get( uid, 0,
152 (uint32_t) driver->internal.persistent_data_size,
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200153 driver->internal.persistent_data ) );
Gilles Peskine5243a202019-07-12 23:38:19 +0200154}
155
156psa_status_t psa_save_se_persistent_data(
157 const psa_se_drv_table_entry_t *driver )
158{
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200159 psa_status_t status;
160 psa_storage_uid_t uid;
161
162 status = psa_get_se_driver_its_file_uid( driver, &uid );
163 if( status != PSA_SUCCESS )
164 return( status );
165
Gilles Peskine573bbc12019-07-23 19:59:23 +0200166 return( psa_its_set( uid,
167 (uint32_t) driver->internal.persistent_data_size,
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200168 driver->internal.persistent_data,
169 0 ) );
170}
171
172psa_status_t psa_destroy_se_persistent_data( psa_key_lifetime_t lifetime )
173{
174 psa_storage_uid_t uid;
175 if( lifetime > PSA_MAX_SE_LIFETIME )
176 return( PSA_ERROR_NOT_SUPPORTED );
177 uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime;
178 return( psa_its_remove( uid ) );
Gilles Peskine5243a202019-07-12 23:38:19 +0200179}
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200180
Gilles Peskinecbaff462019-07-12 23:46:04 +0200181psa_status_t psa_find_se_slot_for_key(
182 const psa_key_attributes_t *attributes,
183 psa_se_drv_table_entry_t *driver,
184 psa_key_slot_number_t *slot_number )
185{
186 psa_status_t status;
187 psa_drv_se_allocate_key_t p_allocate = NULL;
188
189 /* If the lifetime is wrong, it's a bug in the library. */
190 if( driver->lifetime != attributes->lifetime )
191 return( PSA_ERROR_CORRUPTION_DETECTED );
192
193 /* If the driver doesn't support key creation in any way, give up now. */
194 if( driver->methods->key_management == NULL )
195 return( PSA_ERROR_NOT_SUPPORTED );
196 p_allocate = driver->methods->key_management->p_allocate;
197
198 /* If the driver doesn't tell us how to allocate a slot, that's
199 * not supported for the time being. */
200 if( p_allocate == NULL )
201 return( PSA_ERROR_NOT_SUPPORTED );
202
203 status = ( *p_allocate )( &driver->context,
204 driver->internal.persistent_data,
205 attributes,
206 slot_number );
207 return( status );
208}
209
Gilles Peskine354f7672019-07-12 23:46:38 +0200210psa_status_t psa_destroy_se_key( psa_se_drv_table_entry_t *driver,
211 psa_key_slot_number_t slot_number )
212{
213 psa_status_t status;
214 psa_status_t storage_status;
215 if( driver->methods->key_management == NULL ||
216 driver->methods->key_management->p_destroy == NULL )
217 return( PSA_ERROR_NOT_PERMITTED );
218 status = driver->methods->key_management->p_destroy(
219 &driver->context,
220 driver->internal.persistent_data,
221 slot_number );
222 storage_status = psa_save_se_persistent_data( driver );
223 return( status == PSA_SUCCESS ? storage_status : status );
224}
225
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200226
227
228/****************************************************************/
229/* Driver registration */
230/****************************************************************/
Gilles Peskinea899a722019-06-24 14:06:43 +0200231
232psa_status_t psa_register_se_driver(
233 psa_key_lifetime_t lifetime,
234 const psa_drv_se_t *methods)
235{
236 size_t i;
Gilles Peskine5243a202019-07-12 23:38:19 +0200237 psa_status_t status;
Gilles Peskinea899a722019-06-24 14:06:43 +0200238
239 if( methods->hal_version != PSA_DRV_SE_HAL_VERSION )
240 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine9717d102019-06-26 11:50:04 +0200241 /* Driver table entries are 0-initialized. 0 is not a valid driver
242 * lifetime because it means a volatile key. */
243#if defined(static_assert)
244 static_assert( PSA_KEY_LIFETIME_VOLATILE == 0,
245 "Secure element support requires 0 to mean a volatile key" );
246#endif
Gilles Peskinea899a722019-06-24 14:06:43 +0200247 if( lifetime == PSA_KEY_LIFETIME_VOLATILE ||
248 lifetime == PSA_KEY_LIFETIME_PERSISTENT )
249 {
250 return( PSA_ERROR_INVALID_ARGUMENT );
251 }
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200252 if( lifetime > PSA_MAX_SE_LIFETIME )
253 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskinea899a722019-06-24 14:06:43 +0200254
255 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
256 {
257 if( driver_table[i].lifetime == 0 )
258 break;
259 /* Check that lifetime isn't already in use up to the first free
260 * entry. Since entries are created in order and never deleted,
261 * there can't be a used entry after the first free entry. */
262 if( driver_table[i].lifetime == lifetime )
263 return( PSA_ERROR_ALREADY_EXISTS );
264 }
265 if( i == PSA_MAX_SE_DRIVERS )
266 return( PSA_ERROR_INSUFFICIENT_MEMORY );
267
268 driver_table[i].lifetime = lifetime;
269 driver_table[i].methods = methods;
Gilles Peskine5243a202019-07-12 23:38:19 +0200270
271 if( methods->persistent_data_size != 0 )
272 {
273 driver_table[i].internal.persistent_data =
274 mbedtls_calloc( 1, methods->persistent_data_size );
275 if( driver_table[i].internal.persistent_data == NULL )
276 {
277 status = PSA_ERROR_INSUFFICIENT_MEMORY;
278 goto error;
279 }
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200280 /* Load the driver's persistent data. On first use, the persistent
281 * data does not exist in storage, and is initialized to
282 * all-bits-zero by the calloc call just above. */
Gilles Peskine5243a202019-07-12 23:38:19 +0200283 status = psa_load_se_persistent_data( &driver_table[i] );
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200284 if( status != PSA_SUCCESS && status != PSA_ERROR_DOES_NOT_EXIST )
Gilles Peskine5243a202019-07-12 23:38:19 +0200285 goto error;
286 }
287 driver_table[i].internal.persistent_data_size =
288 methods->persistent_data_size;
289
Gilles Peskinea899a722019-06-24 14:06:43 +0200290 return( PSA_SUCCESS );
Gilles Peskine5243a202019-07-12 23:38:19 +0200291
292error:
293 memset( &driver_table[i], 0, sizeof( driver_table[i] ) );
294 return( status );
Gilles Peskinea899a722019-06-24 14:06:43 +0200295}
296
Gilles Peskined0890212019-06-24 14:34:43 +0200297void psa_unregister_all_se_drivers( void )
298{
Gilles Peskine5243a202019-07-12 23:38:19 +0200299 size_t i;
300 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
301 {
302 if( driver_table[i].internal.persistent_data != NULL )
303 mbedtls_free( driver_table[i].internal.persistent_data );
304 }
Gilles Peskined0890212019-06-24 14:34:43 +0200305 memset( driver_table, 0, sizeof( driver_table ) );
306}
307
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200308
309
310/****************************************************************/
311/* The end */
312/****************************************************************/
313
Gilles Peskinea8ade162019-06-26 11:24:49 +0200314#endif /* MBEDTLS_PSA_CRYPTO_SE_C */