blob: 53a2600073232c81d8a8ec446a5f247af2cce0b2 [file] [log] [blame]
Gilles Peskinea899a722019-06-24 14:06:43 +02001/*
2 * PSA crypto support for secure element drivers
3 */
Bence Szépkúti86974652020-06-15 11:59:37 +02004/*
5 * Copyright (C) 2019, ARM Limited, All Rights Reserved
Gilles Peskinea899a722019-06-24 14:06:43 +02006 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 * This file is part of Mbed TLS (https://tls.mbed.org)
21 */
22
23#if !defined(MBEDTLS_CONFIG_FILE)
24#include "mbedtls/config.h"
25#else
26#include MBEDTLS_CONFIG_FILE
27#endif
28
Gilles Peskinea8ade162019-06-26 11:24:49 +020029#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskinea899a722019-06-24 14:06:43 +020030
Gilles Peskine9717d102019-06-26 11:50:04 +020031#include <assert.h>
Gilles Peskine5243a202019-07-12 23:38:19 +020032#include <stdint.h>
Gilles Peskined0890212019-06-24 14:34:43 +020033#include <string.h>
34
Gilles Peskine5243a202019-07-12 23:38:19 +020035#include "psa/crypto_se_driver.h"
36
Gilles Peskinea899a722019-06-24 14:06:43 +020037#include "psa_crypto_se.h"
38
Gilles Peskine8b96cad2019-07-23 17:38:08 +020039#if defined(MBEDTLS_PSA_ITS_FILE_C)
40#include "psa_crypto_its.h"
41#else /* Native ITS implementation */
42#include "psa/error.h"
43#include "psa/internal_trusted_storage.h"
44#endif
45
Gilles Peskine5243a202019-07-12 23:38:19 +020046#include "mbedtls/platform.h"
47#if !defined(MBEDTLS_PLATFORM_C)
48#define mbedtls_calloc calloc
49#define mbedtls_free free
50#endif
51
52
53
Gilles Peskinef989dbe2019-06-26 18:18:12 +020054/****************************************************************/
55/* Driver lookup */
56/****************************************************************/
57
Gilles Peskine5243a202019-07-12 23:38:19 +020058/* This structure is identical to psa_drv_se_context_t declared in
59 * `crypto_se_driver.h`, except that some parts are writable here
60 * (non-const, or pointer to non-const). */
61typedef struct
62{
63 void *persistent_data;
64 size_t persistent_data_size;
65 uintptr_t transient_data;
66} psa_drv_se_internal_context_t;
67
Gilles Peskine01fd8752020-04-14 19:31:52 +020068struct psa_se_drv_table_entry_s
Gilles Peskinea899a722019-06-24 14:06:43 +020069{
Gilles Peskine2b04f462020-05-10 00:44:04 +020070 psa_key_location_t location;
Gilles Peskinea899a722019-06-24 14:06:43 +020071 const psa_drv_se_t *methods;
Gilles Peskine5243a202019-07-12 23:38:19 +020072 union
73 {
74 psa_drv_se_internal_context_t internal;
75 psa_drv_se_context_t context;
Gilles Peskine1a75d0c2020-04-14 19:33:25 +020076 } u;
Gilles Peskine01fd8752020-04-14 19:31:52 +020077};
Gilles Peskinea899a722019-06-24 14:06:43 +020078
Gilles Peskinef989dbe2019-06-26 18:18:12 +020079static psa_se_drv_table_entry_t driver_table[PSA_MAX_SE_DRIVERS];
80
Gilles Peskine5243a202019-07-12 23:38:19 +020081psa_se_drv_table_entry_t *psa_get_se_driver_entry(
Gilles Peskinef989dbe2019-06-26 18:18:12 +020082 psa_key_lifetime_t lifetime )
83{
84 size_t i;
Gilles Peskine2b04f462020-05-10 00:44:04 +020085 psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( lifetime );
86 /* In the driver table, location=0 means an entry that isn't used.
87 * No driver has a location of 0 because it's a reserved value
88 * (which designates transparent keys). Make sure we never return
89 * a driver entry for location 0. */
90 if( location == 0 )
Gilles Peskinef989dbe2019-06-26 18:18:12 +020091 return( NULL );
92 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
93 {
Gilles Peskine2b04f462020-05-10 00:44:04 +020094 if( driver_table[i].location == location )
Gilles Peskinef989dbe2019-06-26 18:18:12 +020095 return( &driver_table[i] );
96 }
97 return( NULL );
98}
99
100const psa_drv_se_t *psa_get_se_driver_methods(
Gilles Peskine5243a202019-07-12 23:38:19 +0200101 const 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->methods );
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200104}
105
Gilles Peskine5243a202019-07-12 23:38:19 +0200106psa_drv_se_context_t *psa_get_se_driver_context(
107 psa_se_drv_table_entry_t *driver )
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200108{
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200109 return( &driver->u.context );
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200110}
111
Gilles Peskine5243a202019-07-12 23:38:19 +0200112int psa_get_se_driver( psa_key_lifetime_t lifetime,
113 const psa_drv_se_t **p_methods,
114 psa_drv_se_context_t **p_drv_context)
115{
116 psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry( lifetime );
117 if( p_methods != NULL )
118 *p_methods = ( driver ? driver->methods : NULL );
119 if( p_drv_context != NULL )
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200120 *p_drv_context = ( driver ? &driver->u.context : NULL );
Gilles Peskine5243a202019-07-12 23:38:19 +0200121 return( driver != NULL );
122}
123
124
125
126/****************************************************************/
127/* Persistent data management */
128/****************************************************************/
129
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200130static psa_status_t psa_get_se_driver_its_file_uid(
131 const psa_se_drv_table_entry_t *driver,
132 psa_storage_uid_t *uid )
133{
Gilles Peskine2b04f462020-05-10 00:44:04 +0200134 if( driver->location > PSA_MAX_SE_LOCATION )
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200135 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine573bbc12019-07-23 19:59:23 +0200136
137#if SIZE_MAX > UINT32_MAX
138 /* ITS file sizes are limited to 32 bits. */
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200139 if( driver->u.internal.persistent_data_size > UINT32_MAX )
Gilles Peskine573bbc12019-07-23 19:59:23 +0200140 return( PSA_ERROR_NOT_SUPPORTED );
141#endif
142
Gilles Peskine75c126b2019-07-24 15:56:01 +0200143 /* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */
Gilles Peskine2b04f462020-05-10 00:44:04 +0200144 *uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->location;
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200145 return( PSA_SUCCESS );
146}
147
Gilles Peskine5243a202019-07-12 23:38:19 +0200148psa_status_t psa_load_se_persistent_data(
149 const psa_se_drv_table_entry_t *driver )
150{
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200151 psa_status_t status;
152 psa_storage_uid_t uid;
Gilles Peskine8b663892019-07-31 17:57:57 +0200153 size_t length;
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200154
155 status = psa_get_se_driver_its_file_uid( driver, &uid );
156 if( status != PSA_SUCCESS )
157 return( status );
158
Gilles Peskine8b663892019-07-31 17:57:57 +0200159 /* Read the amount of persistent data that the driver requests.
160 * If the data in storage is larger, it is truncated. If the data
161 * in storage is smaller, silently keep what is already at the end
162 * of the output buffer. */
Gilles Peskine75c126b2019-07-24 15:56:01 +0200163 /* psa_get_se_driver_its_file_uid ensures that the size_t
164 * persistent_data_size is in range, but compilers don't know that,
165 * so cast to reassure them. */
Gilles Peskine573bbc12019-07-23 19:59:23 +0200166 return( psa_its_get( uid, 0,
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200167 (uint32_t) driver->u.internal.persistent_data_size,
168 driver->u.internal.persistent_data,
Gilles Peskine8b663892019-07-31 17:57:57 +0200169 &length ) );
Gilles Peskine5243a202019-07-12 23:38:19 +0200170}
171
172psa_status_t psa_save_se_persistent_data(
173 const psa_se_drv_table_entry_t *driver )
174{
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200175 psa_status_t status;
176 psa_storage_uid_t uid;
177
178 status = psa_get_se_driver_its_file_uid( driver, &uid );
179 if( status != PSA_SUCCESS )
180 return( status );
181
Gilles Peskine75c126b2019-07-24 15:56:01 +0200182 /* psa_get_se_driver_its_file_uid ensures that the size_t
183 * persistent_data_size is in range, but compilers don't know that,
184 * so cast to reassure them. */
Gilles Peskine573bbc12019-07-23 19:59:23 +0200185 return( psa_its_set( uid,
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200186 (uint32_t) driver->u.internal.persistent_data_size,
187 driver->u.internal.persistent_data,
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200188 0 ) );
189}
190
Gilles Peskine2b04f462020-05-10 00:44:04 +0200191psa_status_t psa_destroy_se_persistent_data( psa_key_location_t location )
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200192{
193 psa_storage_uid_t uid;
Gilles Peskine2b04f462020-05-10 00:44:04 +0200194 if( location > PSA_MAX_SE_LOCATION )
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200195 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine2b04f462020-05-10 00:44:04 +0200196 uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + location;
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200197 return( psa_its_remove( uid ) );
Gilles Peskine5243a202019-07-12 23:38:19 +0200198}
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200199
Gilles Peskinecbaff462019-07-12 23:46:04 +0200200psa_status_t psa_find_se_slot_for_key(
201 const psa_key_attributes_t *attributes,
Gilles Peskinee88c2c12019-08-05 16:44:14 +0200202 psa_key_creation_method_t method,
Gilles Peskinecbaff462019-07-12 23:46:04 +0200203 psa_se_drv_table_entry_t *driver,
204 psa_key_slot_number_t *slot_number )
205{
206 psa_status_t status;
Gilles Peskine2b04f462020-05-10 00:44:04 +0200207 psa_key_location_t key_location =
208 PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime( attributes ) );
Gilles Peskinecbaff462019-07-12 23:46:04 +0200209
Gilles Peskine2b04f462020-05-10 00:44:04 +0200210 /* If the location is wrong, it's a bug in the library. */
211 if( driver->location != key_location )
Gilles Peskinecbaff462019-07-12 23:46:04 +0200212 return( PSA_ERROR_CORRUPTION_DETECTED );
213
214 /* If the driver doesn't support key creation in any way, give up now. */
215 if( driver->methods->key_management == NULL )
216 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskinecbaff462019-07-12 23:46:04 +0200217
Gilles Peskine46d94392019-08-05 14:55:50 +0200218 if( psa_get_key_slot_number( attributes, slot_number ) == PSA_SUCCESS )
219 {
220 /* The application wants to use a specific slot. Allow it if
221 * the driver supports it. On a system with isolation,
222 * the crypto service must check that the application is
223 * permitted to request this slot. */
224 psa_drv_se_validate_slot_number_t p_validate_slot_number =
225 driver->methods->key_management->p_validate_slot_number;
226 if( p_validate_slot_number == NULL )
227 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200228 status = p_validate_slot_number( &driver->u.context,
229 driver->u.internal.persistent_data,
Gilles Peskinee88c2c12019-08-05 16:44:14 +0200230 attributes, method,
Gilles Peskine46d94392019-08-05 14:55:50 +0200231 *slot_number );
232 }
Gilles Peskine3efcebb2019-10-01 14:18:35 +0200233 else if( method == PSA_KEY_CREATION_REGISTER )
234 {
235 /* The application didn't specify a slot number. This doesn't
236 * make sense when registering a slot. */
237 return( PSA_ERROR_INVALID_ARGUMENT );
238 }
Gilles Peskine46d94392019-08-05 14:55:50 +0200239 else
240 {
241 /* The application didn't tell us which slot to use. Let the driver
242 * choose. This is the normal case. */
243 psa_drv_se_allocate_key_t p_allocate =
244 driver->methods->key_management->p_allocate;
245 if( p_allocate == NULL )
246 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200247 status = p_allocate( &driver->u.context,
248 driver->u.internal.persistent_data,
Gilles Peskinee88c2c12019-08-05 16:44:14 +0200249 attributes, method,
Gilles Peskine46d94392019-08-05 14:55:50 +0200250 slot_number );
251 }
Gilles Peskinecbaff462019-07-12 23:46:04 +0200252 return( status );
253}
254
Gilles Peskine354f7672019-07-12 23:46:38 +0200255psa_status_t psa_destroy_se_key( psa_se_drv_table_entry_t *driver,
256 psa_key_slot_number_t slot_number )
257{
258 psa_status_t status;
259 psa_status_t storage_status;
Gilles Peskine340b1272019-07-25 14:13:24 +0200260 /* Normally a missing method would mean that the action is not
261 * supported. But psa_destroy_key() is not supposed to return
262 * PSA_ERROR_NOT_SUPPORTED: if you can create a key, you should
263 * be able to destroy it. The only use case for a driver that
264 * does not have a way to destroy keys at all is if the keys are
265 * locked in a read-only state: we can use the keys but not
266 * destroy them. Hence, if the driver doesn't support destroying
267 * keys, it's really a lack of permission. */
Gilles Peskine354f7672019-07-12 23:46:38 +0200268 if( driver->methods->key_management == NULL ||
269 driver->methods->key_management->p_destroy == NULL )
270 return( PSA_ERROR_NOT_PERMITTED );
271 status = driver->methods->key_management->p_destroy(
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200272 &driver->u.context,
273 driver->u.internal.persistent_data,
Gilles Peskine354f7672019-07-12 23:46:38 +0200274 slot_number );
275 storage_status = psa_save_se_persistent_data( driver );
276 return( status == PSA_SUCCESS ? storage_status : status );
277}
278
Gilles Peskined9348f22019-10-01 15:22:29 +0200279psa_status_t psa_init_all_se_drivers( void )
280{
281 size_t i;
282 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
283 {
284 psa_se_drv_table_entry_t *driver = &driver_table[i];
Gilles Peskine2b04f462020-05-10 00:44:04 +0200285 if( driver->location == 0 )
Gilles Peskined9348f22019-10-01 15:22:29 +0200286 continue; /* skipping unused entry */
287 const psa_drv_se_t *methods = psa_get_se_driver_methods( driver );
288 if( methods->p_init != NULL )
289 {
290 psa_status_t status = methods->p_init(
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200291 &driver->u.context,
292 driver->u.internal.persistent_data,
Gilles Peskine2b04f462020-05-10 00:44:04 +0200293 driver->location );
Gilles Peskined9348f22019-10-01 15:22:29 +0200294 if( status != PSA_SUCCESS )
295 return( status );
Gilles Peskinec84c70a2019-10-01 15:41:42 +0200296 status = psa_save_se_persistent_data( driver );
297 if( status != PSA_SUCCESS )
298 return( status );
Gilles Peskined9348f22019-10-01 15:22:29 +0200299 }
300 }
301 return( PSA_SUCCESS );
302}
303
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200304
305
306/****************************************************************/
307/* Driver registration */
308/****************************************************************/
Gilles Peskinea899a722019-06-24 14:06:43 +0200309
310psa_status_t psa_register_se_driver(
Gilles Peskine2b04f462020-05-10 00:44:04 +0200311 psa_key_location_t location,
Gilles Peskinea899a722019-06-24 14:06:43 +0200312 const psa_drv_se_t *methods)
313{
314 size_t i;
Gilles Peskine5243a202019-07-12 23:38:19 +0200315 psa_status_t status;
Gilles Peskinea899a722019-06-24 14:06:43 +0200316
317 if( methods->hal_version != PSA_DRV_SE_HAL_VERSION )
318 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine9717d102019-06-26 11:50:04 +0200319 /* Driver table entries are 0-initialized. 0 is not a valid driver
Gilles Peskine2b04f462020-05-10 00:44:04 +0200320 * location because it means a transparent key. */
Gilles Peskine9717d102019-06-26 11:50:04 +0200321#if defined(static_assert)
Gilles Peskine2b04f462020-05-10 00:44:04 +0200322 static_assert( PSA_KEY_LOCATION_LOCAL_STORAGE == 0,
323 "Secure element support requires 0 to mean a local key" );
Gilles Peskine9717d102019-06-26 11:50:04 +0200324#endif
Gilles Peskine2b04f462020-05-10 00:44:04 +0200325 if( location == PSA_KEY_LOCATION_LOCAL_STORAGE )
Gilles Peskinea899a722019-06-24 14:06:43 +0200326 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine2b04f462020-05-10 00:44:04 +0200327 if( location > PSA_MAX_SE_LOCATION )
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200328 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskinea899a722019-06-24 14:06:43 +0200329
330 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
331 {
Gilles Peskine2b04f462020-05-10 00:44:04 +0200332 if( driver_table[i].location == 0 )
Gilles Peskinea899a722019-06-24 14:06:43 +0200333 break;
Gilles Peskine2b04f462020-05-10 00:44:04 +0200334 /* Check that location isn't already in use up to the first free
Gilles Peskinea899a722019-06-24 14:06:43 +0200335 * entry. Since entries are created in order and never deleted,
336 * there can't be a used entry after the first free entry. */
Gilles Peskine2b04f462020-05-10 00:44:04 +0200337 if( driver_table[i].location == location )
Gilles Peskinea899a722019-06-24 14:06:43 +0200338 return( PSA_ERROR_ALREADY_EXISTS );
339 }
340 if( i == PSA_MAX_SE_DRIVERS )
341 return( PSA_ERROR_INSUFFICIENT_MEMORY );
342
Gilles Peskine2b04f462020-05-10 00:44:04 +0200343 driver_table[i].location = location;
Gilles Peskinea899a722019-06-24 14:06:43 +0200344 driver_table[i].methods = methods;
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200345 driver_table[i].u.internal.persistent_data_size =
Gilles Peskined5536d82019-10-01 16:55:29 +0200346 methods->persistent_data_size;
Gilles Peskine5243a202019-07-12 23:38:19 +0200347
348 if( methods->persistent_data_size != 0 )
349 {
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200350 driver_table[i].u.internal.persistent_data =
Gilles Peskine5243a202019-07-12 23:38:19 +0200351 mbedtls_calloc( 1, methods->persistent_data_size );
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200352 if( driver_table[i].u.internal.persistent_data == NULL )
Gilles Peskine5243a202019-07-12 23:38:19 +0200353 {
354 status = PSA_ERROR_INSUFFICIENT_MEMORY;
355 goto error;
356 }
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200357 /* Load the driver's persistent data. On first use, the persistent
358 * data does not exist in storage, and is initialized to
359 * all-bits-zero by the calloc call just above. */
Gilles Peskine5243a202019-07-12 23:38:19 +0200360 status = psa_load_se_persistent_data( &driver_table[i] );
Gilles Peskine8b96cad2019-07-23 17:38:08 +0200361 if( status != PSA_SUCCESS && status != PSA_ERROR_DOES_NOT_EXIST )
Gilles Peskine5243a202019-07-12 23:38:19 +0200362 goto error;
363 }
Gilles Peskine5243a202019-07-12 23:38:19 +0200364
Gilles Peskinea899a722019-06-24 14:06:43 +0200365 return( PSA_SUCCESS );
Gilles Peskine5243a202019-07-12 23:38:19 +0200366
367error:
368 memset( &driver_table[i], 0, sizeof( driver_table[i] ) );
369 return( status );
Gilles Peskinea899a722019-06-24 14:06:43 +0200370}
371
Gilles Peskined0890212019-06-24 14:34:43 +0200372void psa_unregister_all_se_drivers( void )
373{
Gilles Peskine5243a202019-07-12 23:38:19 +0200374 size_t i;
375 for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
376 {
Gilles Peskine1a75d0c2020-04-14 19:33:25 +0200377 if( driver_table[i].u.internal.persistent_data != NULL )
378 mbedtls_free( driver_table[i].u.internal.persistent_data );
Gilles Peskine5243a202019-07-12 23:38:19 +0200379 }
Gilles Peskined0890212019-06-24 14:34:43 +0200380 memset( driver_table, 0, sizeof( driver_table ) );
381}
382
Gilles Peskinef989dbe2019-06-26 18:18:12 +0200383
384
385/****************************************************************/
386/* The end */
387/****************************************************************/
388
Gilles Peskinea8ade162019-06-26 11:24:49 +0200389#endif /* MBEDTLS_PSA_CRYPTO_SE_C */