blob: 087c768f4ba230be668a9f97caf27b161c7f6de6 [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{
Gilles Peskine2b04f462020-05-10 00:44:04 +020069 psa_key_location_t location;
Gilles Peskinea899a722019-06-24 14:06:43 +020070 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;
Gilles Peskine1a75d0c2020-04-14 19:33:25 +020075 } u;
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 Peskine2b04f462020-05-10 00:44:04 +020084 psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( lifetime );
85 /* In the driver table, location=0 means an entry that isn't used.
86 * No driver has a location of 0 because it's a reserved value
87 * (which designates transparent keys). Make sure we never return
88 * a driver entry for location 0. */
89 if( location == 0 )
Gilles Peskinef989dbe2019-06-26 18:18:12 +020090 return( NULL );
91 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
92 {
Gilles Peskine2b04f462020-05-10 00:44:04 +020093 if( driver_table[i].location == location )
Gilles Peskinef989dbe2019-06-26 18:18:12 +020094 return( &driver_table[i] );
95 }
96 return( NULL );
97}
98
99const psa_drv_se_t *psa_get_se_driver_methods(
Gilles Peskine5243a202019-07-12 23:38:19 +0200100 const psa_se_drv_table_entry_t *driver )
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200101{
Gilles Peskine5243a202019-07-12 23:38:19 +0200102 return( driver->methods );
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200103}
104
Gilles Peskine5243a202019-07-12 23:38:19 +0200105psa_drv_se_context_t *psa_get_se_driver_context(
106 psa_se_drv_table_entry_t *driver )
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200107{
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200108 return( &driver->u.context );
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200109}
110
Gilles Peskine5243a202019-07-12 23:38:19 +0200111int psa_get_se_driver( psa_key_lifetime_t lifetime,
112 const psa_drv_se_t **p_methods,
113 psa_drv_se_context_t **p_drv_context)
114{
115 psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry( lifetime );
116 if( p_methods != NULL )
117 *p_methods = ( driver ? driver->methods : NULL );
118 if( p_drv_context != NULL )
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200119 *p_drv_context = ( driver ? &driver->u.context : NULL );
Gilles Peskine5243a202019-07-12 23:38:19 +0200120 return( driver != NULL );
121}
122
123
124
125/****************************************************************/
126/* Persistent data management */
127/****************************************************************/
128
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200129static psa_status_t psa_get_se_driver_its_file_uid(
130 const psa_se_drv_table_entry_t *driver,
131 psa_storage_uid_t *uid )
132{
Gilles Peskine2b04f462020-05-10 00:44:04 +0200133 if( driver->location > PSA_MAX_SE_LOCATION )
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200134 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine573bbc12019-07-23 19:59:23 +0200135
136#if SIZE_MAX > UINT32_MAX
137 /* ITS file sizes are limited to 32 bits. */
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200138 if( driver->u.internal.persistent_data_size > UINT32_MAX )
Gilles Peskine573bbc12019-07-23 19:59:23 +0200139 return( PSA_ERROR_NOT_SUPPORTED );
140#endif
141
Gilles Peskine75c126b2019-07-24 15:56:01 +0200142 /* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */
Gilles Peskine2b04f462020-05-10 00:44:04 +0200143 *uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->location;
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200144 return( PSA_SUCCESS );
145}
146
Gilles Peskine5243a202019-07-12 23:38:19 +0200147psa_status_t psa_load_se_persistent_data(
148 const psa_se_drv_table_entry_t *driver )
149{
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200150 psa_status_t status;
151 psa_storage_uid_t uid;
Gilles Peskine8b663892019-07-31 17:57:57 +0200152 size_t length;
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200153
154 status = psa_get_se_driver_its_file_uid( driver, &uid );
155 if( status != PSA_SUCCESS )
156 return( status );
157
Gilles Peskine8b663892019-07-31 17:57:57 +0200158 /* Read the amount of persistent data that the driver requests.
159 * If the data in storage is larger, it is truncated. If the data
160 * in storage is smaller, silently keep what is already at the end
161 * of the output buffer. */
Gilles Peskine75c126b2019-07-24 15:56:01 +0200162 /* psa_get_se_driver_its_file_uid ensures that the size_t
163 * persistent_data_size is in range, but compilers don't know that,
164 * so cast to reassure them. */
Gilles Peskine573bbc12019-07-23 19:59:23 +0200165 return( psa_its_get( uid, 0,
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200166 (uint32_t) driver->u.internal.persistent_data_size,
167 driver->u.internal.persistent_data,
Gilles Peskine8b663892019-07-31 17:57:57 +0200168 &length ) );
Gilles Peskine5243a202019-07-12 23:38:19 +0200169}
170
171psa_status_t psa_save_se_persistent_data(
172 const psa_se_drv_table_entry_t *driver )
173{
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200174 psa_status_t status;
175 psa_storage_uid_t uid;
176
177 status = psa_get_se_driver_its_file_uid( driver, &uid );
178 if( status != PSA_SUCCESS )
179 return( status );
180
Gilles Peskine75c126b2019-07-24 15:56:01 +0200181 /* psa_get_se_driver_its_file_uid ensures that the size_t
182 * persistent_data_size is in range, but compilers don't know that,
183 * so cast to reassure them. */
Gilles Peskine573bbc12019-07-23 19:59:23 +0200184 return( psa_its_set( uid,
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200185 (uint32_t) driver->u.internal.persistent_data_size,
186 driver->u.internal.persistent_data,
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200187 0 ) );
188}
189
Gilles Peskine2b04f462020-05-10 00:44:04 +0200190psa_status_t psa_destroy_se_persistent_data( psa_key_location_t location )
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200191{
192 psa_storage_uid_t uid;
Gilles Peskine2b04f462020-05-10 00:44:04 +0200193 if( location > PSA_MAX_SE_LOCATION )
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200194 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine2b04f462020-05-10 00:44:04 +0200195 uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + location;
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200196 return( psa_its_remove( uid ) );
Gilles Peskine5243a202019-07-12 23:38:19 +0200197}
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200198
Gilles Peskinecbaff462019-07-12 23:46:04 +0200199psa_status_t psa_find_se_slot_for_key(
200 const psa_key_attributes_t *attributes,
Gilles Peskinee88c2c12019-08-05 16:44:14 +0200201 psa_key_creation_method_t method,
Gilles Peskinecbaff462019-07-12 23:46:04 +0200202 psa_se_drv_table_entry_t *driver,
203 psa_key_slot_number_t *slot_number )
204{
205 psa_status_t status;
Gilles Peskine2b04f462020-05-10 00:44:04 +0200206 psa_key_location_t key_location =
207 PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime( attributes ) );
Gilles Peskinecbaff462019-07-12 23:46:04 +0200208
Gilles Peskine2b04f462020-05-10 00:44:04 +0200209 /* If the location is wrong, it's a bug in the library. */
210 if( driver->location != key_location )
Gilles Peskinecbaff462019-07-12 23:46:04 +0200211 return( PSA_ERROR_CORRUPTION_DETECTED );
212
213 /* If the driver doesn't support key creation in any way, give up now. */
214 if( driver->methods->key_management == NULL )
215 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskinecbaff462019-07-12 23:46:04 +0200216
Gilles Peskine46d94392019-08-05 14:55:50 +0200217 if( psa_get_key_slot_number( attributes, slot_number ) == PSA_SUCCESS )
218 {
219 /* The application wants to use a specific slot. Allow it if
220 * the driver supports it. On a system with isolation,
221 * the crypto service must check that the application is
222 * permitted to request this slot. */
223 psa_drv_se_validate_slot_number_t p_validate_slot_number =
224 driver->methods->key_management->p_validate_slot_number;
225 if( p_validate_slot_number == NULL )
226 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200227 status = p_validate_slot_number( &driver->u.context,
228 driver->u.internal.persistent_data,
Gilles Peskinee88c2c12019-08-05 16:44:14 +0200229 attributes, method,
Gilles Peskine46d94392019-08-05 14:55:50 +0200230 *slot_number );
231 }
Gilles Peskine3efcebb2019-10-01 14:18:35 +0200232 else if( method == PSA_KEY_CREATION_REGISTER )
233 {
234 /* The application didn't specify a slot number. This doesn't
235 * make sense when registering a slot. */
236 return( PSA_ERROR_INVALID_ARGUMENT );
237 }
Gilles Peskine46d94392019-08-05 14:55:50 +0200238 else
239 {
240 /* The application didn't tell us which slot to use. Let the driver
241 * choose. This is the normal case. */
242 psa_drv_se_allocate_key_t p_allocate =
243 driver->methods->key_management->p_allocate;
244 if( p_allocate == NULL )
245 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200246 status = p_allocate( &driver->u.context,
247 driver->u.internal.persistent_data,
Gilles Peskinee88c2c12019-08-05 16:44:14 +0200248 attributes, method,
Gilles Peskine46d94392019-08-05 14:55:50 +0200249 slot_number );
250 }
Gilles Peskinecbaff462019-07-12 23:46:04 +0200251 return( status );
252}
253
Gilles Peskine354f7672019-07-12 23:46:38 +0200254psa_status_t psa_destroy_se_key( psa_se_drv_table_entry_t *driver,
255 psa_key_slot_number_t slot_number )
256{
257 psa_status_t status;
258 psa_status_t storage_status;
Gilles Peskine340b1272019-07-25 14:13:24 +0200259 /* Normally a missing method would mean that the action is not
260 * supported. But psa_destroy_key() is not supposed to return
261 * PSA_ERROR_NOT_SUPPORTED: if you can create a key, you should
262 * be able to destroy it. The only use case for a driver that
263 * does not have a way to destroy keys at all is if the keys are
264 * locked in a read-only state: we can use the keys but not
265 * destroy them. Hence, if the driver doesn't support destroying
266 * keys, it's really a lack of permission. */
Gilles Peskine354f7672019-07-12 23:46:38 +0200267 if( driver->methods->key_management == NULL ||
268 driver->methods->key_management->p_destroy == NULL )
269 return( PSA_ERROR_NOT_PERMITTED );
270 status = driver->methods->key_management->p_destroy(
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200271 &driver->u.context,
272 driver->u.internal.persistent_data,
Gilles Peskine354f7672019-07-12 23:46:38 +0200273 slot_number );
274 storage_status = psa_save_se_persistent_data( driver );
275 return( status == PSA_SUCCESS ? storage_status : status );
276}
277
Gilles Peskined9348f22019-10-01 15:22:29 +0200278psa_status_t psa_init_all_se_drivers( void )
279{
280 size_t i;
281 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
282 {
283 psa_se_drv_table_entry_t *driver = &driver_table[i];
Gilles Peskine2b04f462020-05-10 00:44:04 +0200284 if( driver->location == 0 )
Gilles Peskined9348f22019-10-01 15:22:29 +0200285 continue; /* skipping unused entry */
286 const psa_drv_se_t *methods = psa_get_se_driver_methods( driver );
287 if( methods->p_init != NULL )
288 {
289 psa_status_t status = methods->p_init(
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200290 &driver->u.context,
291 driver->u.internal.persistent_data,
Gilles Peskine2b04f462020-05-10 00:44:04 +0200292 driver->location );
Gilles Peskined9348f22019-10-01 15:22:29 +0200293 if( status != PSA_SUCCESS )
294 return( status );
Gilles Peskinec84c70a2019-10-01 15:41:42 +0200295 status = psa_save_se_persistent_data( driver );
296 if( status != PSA_SUCCESS )
297 return( status );
Gilles Peskined9348f22019-10-01 15:22:29 +0200298 }
299 }
300 return( PSA_SUCCESS );
301}
302
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200303
304
305/****************************************************************/
306/* Driver registration */
307/****************************************************************/
Gilles Peskinea899a722019-06-24 14:06:43 +0200308
309psa_status_t psa_register_se_driver(
Gilles Peskine2b04f462020-05-10 00:44:04 +0200310 psa_key_location_t location,
Gilles Peskinea899a722019-06-24 14:06:43 +0200311 const psa_drv_se_t *methods)
312{
313 size_t i;
Gilles Peskine5243a202019-07-12 23:38:19 +0200314 psa_status_t status;
Gilles Peskinea899a722019-06-24 14:06:43 +0200315
316 if( methods->hal_version != PSA_DRV_SE_HAL_VERSION )
317 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine9717d102019-06-26 11:50:04 +0200318 /* Driver table entries are 0-initialized. 0 is not a valid driver
Gilles Peskine2b04f462020-05-10 00:44:04 +0200319 * location because it means a transparent key. */
Gilles Peskine9717d102019-06-26 11:50:04 +0200320#if defined(static_assert)
Gilles Peskine2b04f462020-05-10 00:44:04 +0200321 static_assert( PSA_KEY_LOCATION_LOCAL_STORAGE == 0,
322 "Secure element support requires 0 to mean a local key" );
Gilles Peskine9717d102019-06-26 11:50:04 +0200323#endif
Gilles Peskine2b04f462020-05-10 00:44:04 +0200324 if( location == PSA_KEY_LOCATION_LOCAL_STORAGE )
Gilles Peskinea899a722019-06-24 14:06:43 +0200325 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine2b04f462020-05-10 00:44:04 +0200326 if( location > PSA_MAX_SE_LOCATION )
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200327 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskinea899a722019-06-24 14:06:43 +0200328
329 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
330 {
Gilles Peskine2b04f462020-05-10 00:44:04 +0200331 if( driver_table[i].location == 0 )
Gilles Peskinea899a722019-06-24 14:06:43 +0200332 break;
Gilles Peskine2b04f462020-05-10 00:44:04 +0200333 /* Check that location isn't already in use up to the first free
Gilles Peskinea899a722019-06-24 14:06:43 +0200334 * entry. Since entries are created in order and never deleted,
335 * there can't be a used entry after the first free entry. */
Gilles Peskine2b04f462020-05-10 00:44:04 +0200336 if( driver_table[i].location == location )
Gilles Peskinea899a722019-06-24 14:06:43 +0200337 return( PSA_ERROR_ALREADY_EXISTS );
338 }
339 if( i == PSA_MAX_SE_DRIVERS )
340 return( PSA_ERROR_INSUFFICIENT_MEMORY );
341
Gilles Peskine2b04f462020-05-10 00:44:04 +0200342 driver_table[i].location = location;
Gilles Peskinea899a722019-06-24 14:06:43 +0200343 driver_table[i].methods = methods;
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200344 driver_table[i].u.internal.persistent_data_size =
Gilles Peskined5536d82019-10-01 16:55:29 +0200345 methods->persistent_data_size;
Gilles Peskine5243a202019-07-12 23:38:19 +0200346
347 if( methods->persistent_data_size != 0 )
348 {
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200349 driver_table[i].u.internal.persistent_data =
Gilles Peskine5243a202019-07-12 23:38:19 +0200350 mbedtls_calloc( 1, methods->persistent_data_size );
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200351 if( driver_table[i].u.internal.persistent_data == NULL )
Gilles Peskine5243a202019-07-12 23:38:19 +0200352 {
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 {
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200376 if( driver_table[i].u.internal.persistent_data != NULL )
377 mbedtls_free( driver_table[i].u.internal.persistent_data );
Gilles Peskine5243a202019-07-12 23:38:19 +0200378 }
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 */