blob: 9418b5f45c65f61ce942ea17cfe91c2d0f59cdcb [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 Peskine01fd8752020-04-14 19:31:52 +020067struct 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 Peskine01fd8752020-04-14 19:31:52 +020076};
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;
Gilles Peskine75c126b2019-07-24 15:56:01 +020084 /* In the driver table, lifetime=0 means an entry that isn't used.
85 * No driver has a lifetime of 0 because it's a reserved value
86 * (which designates volatile keys). Make sure we never return
87 * a driver entry for lifetime 0. */
Gilles Peskinef989dbe2019-06-26 18:18:12 +020088 if( lifetime == 0 )
89 return( NULL );
90 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
91 {
92 if( driver_table[i].lifetime == lifetime )
93 return( &driver_table[i] );
94 }
95 return( NULL );
96}
97
98const psa_drv_se_t *psa_get_se_driver_methods(
Gilles Peskine5243a202019-07-12 23:38:19 +020099 const psa_se_drv_table_entry_t *driver )
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200100{
Gilles Peskine5243a202019-07-12 23:38:19 +0200101 return( driver->methods );
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200102}
103
Gilles Peskine5243a202019-07-12 23:38:19 +0200104psa_drv_se_context_t *psa_get_se_driver_context(
105 psa_se_drv_table_entry_t *driver )
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200106{
Gilles Peskine5243a202019-07-12 23:38:19 +0200107 return( &driver->context );
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200108}
109
Gilles Peskine5243a202019-07-12 23:38:19 +0200110int psa_get_se_driver( psa_key_lifetime_t lifetime,
111 const psa_drv_se_t **p_methods,
112 psa_drv_se_context_t **p_drv_context)
113{
114 psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry( lifetime );
115 if( p_methods != NULL )
116 *p_methods = ( driver ? driver->methods : NULL );
117 if( p_drv_context != NULL )
118 *p_drv_context = ( driver ? &driver->context : NULL );
119 return( driver != NULL );
120}
121
122
123
124/****************************************************************/
125/* Persistent data management */
126/****************************************************************/
127
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200128static psa_status_t psa_get_se_driver_its_file_uid(
129 const psa_se_drv_table_entry_t *driver,
130 psa_storage_uid_t *uid )
131{
132 if( driver->lifetime > PSA_MAX_SE_LIFETIME )
133 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine573bbc12019-07-23 19:59:23 +0200134
135#if SIZE_MAX > UINT32_MAX
136 /* ITS file sizes are limited to 32 bits. */
137 if( driver->internal.persistent_data_size > UINT32_MAX )
138 return( PSA_ERROR_NOT_SUPPORTED );
139#endif
140
Gilles Peskine75c126b2019-07-24 15:56:01 +0200141 /* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200142 *uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->lifetime;
143 return( PSA_SUCCESS );
144}
145
Gilles Peskine5243a202019-07-12 23:38:19 +0200146psa_status_t psa_load_se_persistent_data(
147 const psa_se_drv_table_entry_t *driver )
148{
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200149 psa_status_t status;
150 psa_storage_uid_t uid;
Gilles Peskine8b663892019-07-31 17:57:57 +0200151 size_t length;
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200152
153 status = psa_get_se_driver_its_file_uid( driver, &uid );
154 if( status != PSA_SUCCESS )
155 return( status );
156
Gilles Peskine8b663892019-07-31 17:57:57 +0200157 /* Read the amount of persistent data that the driver requests.
158 * If the data in storage is larger, it is truncated. If the data
159 * in storage is smaller, silently keep what is already at the end
160 * of the output buffer. */
Gilles Peskine75c126b2019-07-24 15:56:01 +0200161 /* psa_get_se_driver_its_file_uid ensures that the size_t
162 * persistent_data_size is in range, but compilers don't know that,
163 * so cast to reassure them. */
Gilles Peskine573bbc12019-07-23 19:59:23 +0200164 return( psa_its_get( uid, 0,
165 (uint32_t) driver->internal.persistent_data_size,
Gilles Peskine8b663892019-07-31 17:57:57 +0200166 driver->internal.persistent_data,
167 &length ) );
Gilles Peskine5243a202019-07-12 23:38:19 +0200168}
169
170psa_status_t psa_save_se_persistent_data(
171 const psa_se_drv_table_entry_t *driver )
172{
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200173 psa_status_t status;
174 psa_storage_uid_t uid;
175
176 status = psa_get_se_driver_its_file_uid( driver, &uid );
177 if( status != PSA_SUCCESS )
178 return( status );
179
Gilles Peskine75c126b2019-07-24 15:56:01 +0200180 /* psa_get_se_driver_its_file_uid ensures that the size_t
181 * persistent_data_size is in range, but compilers don't know that,
182 * so cast to reassure them. */
Gilles Peskine573bbc12019-07-23 19:59:23 +0200183 return( psa_its_set( uid,
184 (uint32_t) driver->internal.persistent_data_size,
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200185 driver->internal.persistent_data,
186 0 ) );
187}
188
189psa_status_t psa_destroy_se_persistent_data( psa_key_lifetime_t lifetime )
190{
191 psa_storage_uid_t uid;
192 if( lifetime > PSA_MAX_SE_LIFETIME )
193 return( PSA_ERROR_NOT_SUPPORTED );
194 uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime;
195 return( psa_its_remove( uid ) );
Gilles Peskine5243a202019-07-12 23:38:19 +0200196}
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200197
Gilles Peskinecbaff462019-07-12 23:46:04 +0200198psa_status_t psa_find_se_slot_for_key(
199 const psa_key_attributes_t *attributes,
Gilles Peskinee88c2c12019-08-05 16:44:14 +0200200 psa_key_creation_method_t method,
Gilles Peskinecbaff462019-07-12 23:46:04 +0200201 psa_se_drv_table_entry_t *driver,
202 psa_key_slot_number_t *slot_number )
203{
204 psa_status_t status;
Gilles Peskinecbaff462019-07-12 23:46:04 +0200205
206 /* If the lifetime is wrong, it's a bug in the library. */
Gilles Peskine7e0cff92019-07-30 13:48:52 +0200207 if( driver->lifetime != psa_get_key_lifetime( attributes ) )
Gilles Peskinecbaff462019-07-12 23:46:04 +0200208 return( PSA_ERROR_CORRUPTION_DETECTED );
209
210 /* If the driver doesn't support key creation in any way, give up now. */
211 if( driver->methods->key_management == NULL )
212 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskinecbaff462019-07-12 23:46:04 +0200213
Gilles Peskine46d94392019-08-05 14:55:50 +0200214 if( psa_get_key_slot_number( attributes, slot_number ) == PSA_SUCCESS )
215 {
216 /* The application wants to use a specific slot. Allow it if
217 * the driver supports it. On a system with isolation,
218 * the crypto service must check that the application is
219 * permitted to request this slot. */
220 psa_drv_se_validate_slot_number_t p_validate_slot_number =
221 driver->methods->key_management->p_validate_slot_number;
222 if( p_validate_slot_number == NULL )
223 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskinee88c2c12019-08-05 16:44:14 +0200224 status = p_validate_slot_number( &driver->context,
Gilles Peskine5ec3a302019-10-01 14:27:23 +0200225 driver->internal.persistent_data,
Gilles Peskinee88c2c12019-08-05 16:44:14 +0200226 attributes, method,
Gilles Peskine46d94392019-08-05 14:55:50 +0200227 *slot_number );
228 }
Gilles Peskine3efcebb2019-10-01 14:18:35 +0200229 else if( method == PSA_KEY_CREATION_REGISTER )
230 {
231 /* The application didn't specify a slot number. This doesn't
232 * make sense when registering a slot. */
233 return( PSA_ERROR_INVALID_ARGUMENT );
234 }
Gilles Peskine46d94392019-08-05 14:55:50 +0200235 else
236 {
237 /* The application didn't tell us which slot to use. Let the driver
238 * choose. This is the normal case. */
239 psa_drv_se_allocate_key_t p_allocate =
240 driver->methods->key_management->p_allocate;
241 if( p_allocate == NULL )
242 return( PSA_ERROR_NOT_SUPPORTED );
243 status = p_allocate( &driver->context,
244 driver->internal.persistent_data,
Gilles Peskinee88c2c12019-08-05 16:44:14 +0200245 attributes, method,
Gilles Peskine46d94392019-08-05 14:55:50 +0200246 slot_number );
247 }
Gilles Peskinecbaff462019-07-12 23:46:04 +0200248 return( status );
249}
250
Gilles Peskine354f7672019-07-12 23:46:38 +0200251psa_status_t psa_destroy_se_key( psa_se_drv_table_entry_t *driver,
252 psa_key_slot_number_t slot_number )
253{
254 psa_status_t status;
255 psa_status_t storage_status;
Gilles Peskine340b1272019-07-25 14:13:24 +0200256 /* Normally a missing method would mean that the action is not
257 * supported. But psa_destroy_key() is not supposed to return
258 * PSA_ERROR_NOT_SUPPORTED: if you can create a key, you should
259 * be able to destroy it. The only use case for a driver that
260 * does not have a way to destroy keys at all is if the keys are
261 * locked in a read-only state: we can use the keys but not
262 * destroy them. Hence, if the driver doesn't support destroying
263 * keys, it's really a lack of permission. */
Gilles Peskine354f7672019-07-12 23:46:38 +0200264 if( driver->methods->key_management == NULL ||
265 driver->methods->key_management->p_destroy == NULL )
266 return( PSA_ERROR_NOT_PERMITTED );
267 status = driver->methods->key_management->p_destroy(
268 &driver->context,
269 driver->internal.persistent_data,
270 slot_number );
271 storage_status = psa_save_se_persistent_data( driver );
272 return( status == PSA_SUCCESS ? storage_status : status );
273}
274
Gilles Peskined9348f22019-10-01 15:22:29 +0200275psa_status_t psa_init_all_se_drivers( void )
276{
277 size_t i;
278 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
279 {
280 psa_se_drv_table_entry_t *driver = &driver_table[i];
281 if( driver->lifetime == 0 )
282 continue; /* skipping unused entry */
283 const psa_drv_se_t *methods = psa_get_se_driver_methods( driver );
284 if( methods->p_init != NULL )
285 {
286 psa_status_t status = methods->p_init(
287 &driver->context,
288 driver->internal.persistent_data,
289 driver->lifetime );
290 if( status != PSA_SUCCESS )
291 return( status );
Gilles Peskinec84c70a2019-10-01 15:41:42 +0200292 status = psa_save_se_persistent_data( driver );
293 if( status != PSA_SUCCESS )
294 return( status );
Gilles Peskined9348f22019-10-01 15:22:29 +0200295 }
296 }
297 return( PSA_SUCCESS );
298}
299
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200300
301
302/****************************************************************/
303/* Driver registration */
304/****************************************************************/
Gilles Peskinea899a722019-06-24 14:06:43 +0200305
306psa_status_t psa_register_se_driver(
307 psa_key_lifetime_t lifetime,
308 const psa_drv_se_t *methods)
309{
310 size_t i;
Gilles Peskine5243a202019-07-12 23:38:19 +0200311 psa_status_t status;
Gilles Peskinea899a722019-06-24 14:06:43 +0200312
313 if( methods->hal_version != PSA_DRV_SE_HAL_VERSION )
314 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine9717d102019-06-26 11:50:04 +0200315 /* Driver table entries are 0-initialized. 0 is not a valid driver
316 * lifetime because it means a volatile key. */
317#if defined(static_assert)
318 static_assert( PSA_KEY_LIFETIME_VOLATILE == 0,
319 "Secure element support requires 0 to mean a volatile key" );
320#endif
Gilles Peskinea899a722019-06-24 14:06:43 +0200321 if( lifetime == PSA_KEY_LIFETIME_VOLATILE ||
322 lifetime == PSA_KEY_LIFETIME_PERSISTENT )
323 {
324 return( PSA_ERROR_INVALID_ARGUMENT );
325 }
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200326 if( lifetime > PSA_MAX_SE_LIFETIME )
327 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskinea899a722019-06-24 14:06:43 +0200328
329 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
330 {
331 if( driver_table[i].lifetime == 0 )
332 break;
333 /* Check that lifetime isn't already in use up to the first free
334 * entry. Since entries are created in order and never deleted,
335 * there can't be a used entry after the first free entry. */
336 if( driver_table[i].lifetime == lifetime )
337 return( PSA_ERROR_ALREADY_EXISTS );
338 }
339 if( i == PSA_MAX_SE_DRIVERS )
340 return( PSA_ERROR_INSUFFICIENT_MEMORY );
341
342 driver_table[i].lifetime = lifetime;
343 driver_table[i].methods = methods;
Gilles Peskined5536d82019-10-01 16:55:29 +0200344 driver_table[i].internal.persistent_data_size =
345 methods->persistent_data_size;
Gilles Peskine5243a202019-07-12 23:38:19 +0200346
347 if( methods->persistent_data_size != 0 )
348 {
349 driver_table[i].internal.persistent_data =
350 mbedtls_calloc( 1, methods->persistent_data_size );
351 if( driver_table[i].internal.persistent_data == NULL )
352 {
353 status = PSA_ERROR_INSUFFICIENT_MEMORY;
354 goto error;
355 }
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200356 /* Load the driver's persistent data. On first use, the persistent
357 * data does not exist in storage, and is initialized to
358 * all-bits-zero by the calloc call just above. */
Gilles Peskine5243a202019-07-12 23:38:19 +0200359 status = psa_load_se_persistent_data( &driver_table[i] );
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200360 if( status != PSA_SUCCESS && status != PSA_ERROR_DOES_NOT_EXIST )
Gilles Peskine5243a202019-07-12 23:38:19 +0200361 goto error;
362 }
Gilles Peskine5243a202019-07-12 23:38:19 +0200363
Gilles Peskinea899a722019-06-24 14:06:43 +0200364 return( PSA_SUCCESS );
Gilles Peskine5243a202019-07-12 23:38:19 +0200365
366error:
367 memset( &driver_table[i], 0, sizeof( driver_table[i] ) );
368 return( status );
Gilles Peskinea899a722019-06-24 14:06:43 +0200369}
370
Gilles Peskined0890212019-06-24 14:34:43 +0200371void psa_unregister_all_se_drivers( void )
372{
Gilles Peskine5243a202019-07-12 23:38:19 +0200373 size_t i;
374 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
375 {
376 if( driver_table[i].internal.persistent_data != NULL )
377 mbedtls_free( driver_table[i].internal.persistent_data );
378 }
Gilles Peskined0890212019-06-24 14:34:43 +0200379 memset( driver_table, 0, sizeof( driver_table ) );
380}
381
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200382
383
384/****************************************************************/
385/* The end */
386/****************************************************************/
387
Gilles Peskinea8ade162019-06-26 11:24:49 +0200388#endif /* MBEDTLS_PSA_CRYPTO_SE_C */