blob: 8ef851bddf4fccf2c588c6473f8f6f0af9931e27 [file] [log] [blame]
Gilles Peskine961849f2018-11-30 18:54:54 +01001/*
2 * PSA crypto layer on top of Mbed TLS crypto
3 */
Bence Szépkúti86974652020-06-15 11:59:37 +02004/*
Bence Szépkúti1e148272020-08-07 13:07:28 +02005 * Copyright The Mbed TLS Contributors
Gilles Peskine961849f2018-11-30 18:54:54 +01006 * 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.
Gilles Peskine961849f2018-11-30 18:54:54 +010019 */
20
Gilles Peskinedb09ef62020-06-03 01:43:33 +020021#include "common.h"
Gilles Peskine961849f2018-11-30 18:54:54 +010022
23#if defined(MBEDTLS_PSA_CRYPTO_C)
24
itayzafrir7723ab12019-02-14 10:28:02 +020025#include "psa_crypto_service_integration.h"
Gilles Peskine961849f2018-11-30 18:54:54 +010026#include "psa/crypto.h"
27
Gilles Peskine66fb1262018-12-10 16:29:04 +010028#include "psa_crypto_core.h"
Gilles Peskine961849f2018-11-30 18:54:54 +010029#include "psa_crypto_slot_management.h"
30#include "psa_crypto_storage.h"
Gilles Peskineb46bef22019-07-30 21:32:04 +020031#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
32#include "psa_crypto_se.h"
33#endif
Gilles Peskine961849f2018-11-30 18:54:54 +010034
35#include <stdlib.h>
36#include <string.h>
37#if defined(MBEDTLS_PLATFORM_C)
38#include "mbedtls/platform.h"
39#else
40#define mbedtls_calloc calloc
41#define mbedtls_free free
42#endif
43
44#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
45
Gilles Peskine66fb1262018-12-10 16:29:04 +010046typedef struct
47{
48 psa_key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
49 unsigned key_slots_initialized : 1;
50} psa_global_data_t;
51
Gilles Peskine2e14bd32018-12-12 14:05:08 +010052static psa_global_data_t global_data;
Gilles Peskine66fb1262018-12-10 16:29:04 +010053
Ronald Crond2ed4812020-07-17 16:11:30 +020054psa_status_t psa_validate_key_id( mbedtls_svc_key_id_t key, int vendor_ok )
55{
56 psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key );
57
58 if( ( PSA_KEY_ID_USER_MIN <= key_id ) &&
59 ( key_id <= PSA_KEY_ID_USER_MAX ) )
60 return( PSA_SUCCESS );
61
62 if( vendor_ok &&
63 ( PSA_KEY_ID_VENDOR_MIN <= key_id ) &&
64 ( key_id <= PSA_KEY_ID_VENDOR_MAX ) )
65 return( PSA_SUCCESS );
66
Ronald Cronc4d1b512020-07-31 11:26:37 +020067 return( PSA_ERROR_INVALID_HANDLE );
Ronald Crond2ed4812020-07-17 16:11:30 +020068}
69
Ronald Cronc4d1b512020-07-31 11:26:37 +020070static psa_key_slot_t* psa_get_slot_from_volatile_key_id(
71 mbedtls_svc_key_id_t key )
Gilles Peskine66fb1262018-12-10 16:29:04 +010072{
Ronald Cronc4d1b512020-07-31 11:26:37 +020073 psa_key_slot_t *slot;
74 psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key );
Gilles Peskine66fb1262018-12-10 16:29:04 +010075
Ronald Cronc4d1b512020-07-31 11:26:37 +020076 if( ( key_id < PSA_KEY_ID_VOLATILE_MIN ) ||
77 ( key_id > PSA_KEY_ID_VOLATILE_MAX ) )
78 return( NULL );
Gilles Peskine66fb1262018-12-10 16:29:04 +010079
Ronald Cronc4d1b512020-07-31 11:26:37 +020080 slot = &global_data.key_slots[ key_id - PSA_KEY_ID_VOLATILE_MIN ];
Gilles Peskine66fb1262018-12-10 16:29:04 +010081
Ronald Cronc4d1b512020-07-31 11:26:37 +020082 return( mbedtls_svc_key_id_equal( key, slot->attr.id ) ? slot : NULL );
Gilles Peskine66fb1262018-12-10 16:29:04 +010083}
84
Ronald Cronc4d1b512020-07-31 11:26:37 +020085#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
86static psa_key_slot_t* psa_get_slot_from_key_id(
87 mbedtls_svc_key_id_t key )
88{
89 psa_key_slot_t *slot = &global_data.key_slots[ PSA_KEY_SLOT_COUNT ];
90
91 while( slot > &global_data.key_slots[ 0 ] )
92 {
93 slot--;
94 if( mbedtls_svc_key_id_equal( key, slot->attr.id ) )
95 return( slot );
96 }
97
98 return( NULL );
99}
100#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
101
Gilles Peskine66fb1262018-12-10 16:29:04 +0100102psa_status_t psa_initialize_key_slots( void )
103{
104 /* Nothing to do: program startup and psa_wipe_all_key_slots() both
105 * guarantee that the key slots are initialized to all-zero, which
106 * means that all the key slots are in a valid, empty state. */
107 global_data.key_slots_initialized = 1;
108 return( PSA_SUCCESS );
109}
110
111void psa_wipe_all_key_slots( void )
112{
Ronald Cron98a54dd2020-07-24 16:33:11 +0200113 size_t slot_idx;
114
115 for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ )
Gilles Peskine66fb1262018-12-10 16:29:04 +0100116 {
Ronald Cron98a54dd2020-07-24 16:33:11 +0200117 psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ];
Gilles Peskine66fb1262018-12-10 16:29:04 +0100118 (void) psa_wipe_key_slot( slot );
119 }
120 global_data.key_slots_initialized = 0;
121}
122
Ronald Cronc4d1b512020-07-31 11:26:37 +0200123psa_status_t psa_get_empty_key_slot( psa_key_id_t *volatile_key_id,
Ronald Cron2a993152020-07-17 14:13:26 +0200124 psa_key_slot_t **p_slot )
Gilles Peskine66fb1262018-12-10 16:29:04 +0100125{
Ronald Cron98a54dd2020-07-24 16:33:11 +0200126 size_t slot_idx;
127
Gilles Peskine267c6562019-05-27 19:01:54 +0200128 if( ! global_data.key_slots_initialized )
129 return( PSA_ERROR_BAD_STATE );
130
Ronald Cron98a54dd2020-07-24 16:33:11 +0200131 for( slot_idx = PSA_KEY_SLOT_COUNT; slot_idx > 0; slot_idx-- )
Gilles Peskine66fb1262018-12-10 16:29:04 +0100132 {
Ronald Cron98a54dd2020-07-24 16:33:11 +0200133 *p_slot = &global_data.key_slots[ slot_idx - 1 ];
Gilles Peskine41e50d22019-07-31 15:01:55 +0200134 if( ! psa_is_key_slot_occupied( *p_slot ) )
Ronald Cron2a993152020-07-17 14:13:26 +0200135 {
Ronald Cron98a54dd2020-07-24 16:33:11 +0200136 *volatile_key_id = PSA_KEY_ID_VOLATILE_MIN +
137 ( (psa_key_id_t)slot_idx ) - 1;
Ronald Cron2a993152020-07-17 14:13:26 +0200138
Gilles Peskine66fb1262018-12-10 16:29:04 +0100139 return( PSA_SUCCESS );
Ronald Cron2a993152020-07-17 14:13:26 +0200140 }
Gilles Peskine66fb1262018-12-10 16:29:04 +0100141 }
Gilles Peskine267c6562019-05-27 19:01:54 +0200142 *p_slot = NULL;
Gilles Peskine66fb1262018-12-10 16:29:04 +0100143 return( PSA_ERROR_INSUFFICIENT_MEMORY );
144}
145
Gilles Peskinefa4135b2018-12-10 16:48:53 +0100146#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskine24318592019-07-30 20:30:51 +0200147static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *slot )
Gilles Peskinefa4135b2018-12-10 16:48:53 +0100148{
149 psa_status_t status = PSA_SUCCESS;
150 uint8_t *key_data = NULL;
151 size_t key_data_length = 0;
152
Gilles Peskine24318592019-07-30 20:30:51 +0200153 status = psa_load_persistent_key( &slot->attr,
Gilles Peskinebfd322f2019-07-23 11:58:03 +0200154 &key_data, &key_data_length );
Gilles Peskinefa4135b2018-12-10 16:48:53 +0100155 if( status != PSA_SUCCESS )
156 goto exit;
Gilles Peskine1df83d42019-07-23 16:13:14 +0200157
158#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine24318592019-07-30 20:30:51 +0200159 if( psa_key_lifetime_is_external( slot->attr.lifetime ) )
Gilles Peskine1df83d42019-07-23 16:13:14 +0200160 {
Gilles Peskineb46bef22019-07-30 21:32:04 +0200161 psa_se_key_data_storage_t *data;
162 if( key_data_length != sizeof( *data ) )
Gilles Peskine1df83d42019-07-23 16:13:14 +0200163 {
164 status = PSA_ERROR_STORAGE_FAILURE;
165 goto exit;
166 }
Gilles Peskineb46bef22019-07-30 21:32:04 +0200167 data = (psa_se_key_data_storage_t *) key_data;
168 memcpy( &slot->data.se.slot_number, &data->slot_number,
169 sizeof( slot->data.se.slot_number ) );
Gilles Peskine1df83d42019-07-23 16:13:14 +0200170 }
171 else
172#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
173 {
Steven Cooreman3ea0ce42020-10-23 11:37:05 +0200174 status = psa_copy_key_material_into_slot( slot, key_data, key_data_length );
175 if( status != PSA_SUCCESS )
176 goto exit;
Gilles Peskine1df83d42019-07-23 16:13:14 +0200177 }
178
Gilles Peskinefa4135b2018-12-10 16:48:53 +0100179exit:
180 psa_free_persistent_key_data( key_data, key_data_length );
181 return( status );
182}
Ronald Cronc4d1b512020-07-31 11:26:37 +0200183#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
184
185psa_status_t psa_get_key_slot( mbedtls_svc_key_id_t key,
186 psa_key_slot_t **p_slot )
187{
188 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
189
190 *p_slot = NULL;
191 if( ! global_data.key_slots_initialized )
192 return( PSA_ERROR_BAD_STATE );
193
194 status = psa_validate_key_id( key, 1 );
195 if( status != PSA_SUCCESS )
196 return( status );
197
198 *p_slot = psa_get_slot_from_volatile_key_id( key );
199 if( *p_slot != NULL )
200 return( PSA_SUCCESS );
201
202#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
203 psa_key_id_t volatile_key_id;
204
205 *p_slot = psa_get_slot_from_key_id( key );
206 if( *p_slot != NULL )
207 return( PSA_SUCCESS );
208
209 status = psa_get_empty_key_slot( &volatile_key_id, p_slot );
210 if( status != PSA_SUCCESS )
211 return( status );
212
213 (*p_slot)->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
214 (*p_slot)->attr.id = key;
215
216 status = psa_load_persistent_key_into_slot( *p_slot );
217 if( status != PSA_SUCCESS )
218 psa_wipe_key_slot( *p_slot );
219
220 return( status );
221#else
222 return( PSA_ERROR_DOES_NOT_EXIST );
Gilles Peskine30afafd2019-04-25 13:47:40 +0200223#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskinefa4135b2018-12-10 16:48:53 +0100224
Ronald Cronc4d1b512020-07-31 11:26:37 +0200225}
226
Steven Cooreman8c1e7592020-06-17 14:52:05 +0200227psa_status_t psa_validate_key_location( psa_key_lifetime_t lifetime,
Steven Cooreman81fe7c32020-06-08 18:37:19 +0200228 psa_se_drv_table_entry_t **p_drv )
Gilles Peskined167b942019-04-19 18:19:40 +0200229{
Steven Cooreman81fe7c32020-06-08 18:37:19 +0200230 if ( psa_key_lifetime_is_external( lifetime ) )
Gilles Peskine011e4282019-06-26 18:34:38 +0200231 {
Steven Cooreman81fe7c32020-06-08 18:37:19 +0200232#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Steven Cooreman00106a12020-06-08 18:54:23 +0200233 psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry( lifetime );
234 if( driver == NULL )
Gilles Peskine011e4282019-06-26 18:34:38 +0200235 return( PSA_ERROR_INVALID_ARGUMENT );
Steven Cooreman81fe7c32020-06-08 18:37:19 +0200236 else
237 {
238 if (p_drv != NULL)
Steven Cooreman00106a12020-06-08 18:54:23 +0200239 *p_drv = driver;
Steven Cooreman81fe7c32020-06-08 18:37:19 +0200240 return( PSA_SUCCESS );
241 }
242#else
243 (void) p_drv;
244 return( PSA_ERROR_INVALID_ARGUMENT );
245#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine011e4282019-06-26 18:34:38 +0200246 }
247 else
Steven Cooreman81fe7c32020-06-08 18:37:19 +0200248 /* Local/internal keys are always valid */
249 return( PSA_SUCCESS );
250}
Gilles Peskine30afafd2019-04-25 13:47:40 +0200251
Ronald Crond2ed4812020-07-17 16:11:30 +0200252psa_status_t psa_validate_key_persistence( psa_key_lifetime_t lifetime )
Steven Cooreman81fe7c32020-06-08 18:37:19 +0200253{
Steven Cooreman81fe7c32020-06-08 18:37:19 +0200254 if ( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) )
255 {
256 /* Volatile keys are always supported */
257 return( PSA_SUCCESS );
258 }
259 else
260 {
261 /* Persistent keys require storage support */
Gilles Peskine30afafd2019-04-25 13:47:40 +0200262#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Ronald Crond2ed4812020-07-17 16:11:30 +0200263 return( PSA_SUCCESS );
Gilles Peskine30afafd2019-04-25 13:47:40 +0200264#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
Steven Cooreman81fe7c32020-06-08 18:37:19 +0200265 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine30afafd2019-04-25 13:47:40 +0200266#endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */
Steven Cooreman81fe7c32020-06-08 18:37:19 +0200267 }
Gilles Peskined167b942019-04-19 18:19:40 +0200268}
269
Ronald Cron71016a92020-08-28 19:01:50 +0200270psa_status_t psa_open_key( mbedtls_svc_key_id_t key, psa_key_handle_t *handle )
Gilles Peskine961849f2018-11-30 18:54:54 +0100271{
Gilles Peskine70e085a2019-05-27 19:04:07 +0200272#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskine961849f2018-11-30 18:54:54 +0100273 psa_status_t status;
Gilles Peskine267c6562019-05-27 19:01:54 +0200274 psa_key_slot_t *slot;
Gilles Peskine961849f2018-11-30 18:54:54 +0100275
Ronald Cronc4d1b512020-07-31 11:26:37 +0200276 status = psa_get_key_slot( key, &slot );
Gilles Peskine70e085a2019-05-27 19:04:07 +0200277 if( status != PSA_SUCCESS )
Gilles Peskine961849f2018-11-30 18:54:54 +0100278 {
Ronald Cron91e95152020-07-30 17:48:03 +0200279 *handle = PSA_KEY_HANDLE_INIT;
Ronald Cronc4d1b512020-07-31 11:26:37 +0200280 return( status );
Gilles Peskine961849f2018-11-30 18:54:54 +0100281 }
Ronald Cronc4d1b512020-07-31 11:26:37 +0200282
283 *handle = key;
284
285 return( PSA_SUCCESS );
Gilles Peskine70e085a2019-05-27 19:04:07 +0200286
Gilles Peskine30afafd2019-04-25 13:47:40 +0200287#else /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Ronald Cron27238fc2020-07-23 12:30:41 +0200288 (void) key;
Ronald Cron91e95152020-07-30 17:48:03 +0200289 *handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine30afafd2019-04-25 13:47:40 +0200290 return( PSA_ERROR_NOT_SUPPORTED );
291#endif /* !defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskine961849f2018-11-30 18:54:54 +0100292}
293
Gilles Peskine961849f2018-11-30 18:54:54 +0100294psa_status_t psa_close_key( psa_key_handle_t handle )
295{
Gilles Peskine267c6562019-05-27 19:01:54 +0200296 psa_status_t status;
297 psa_key_slot_t *slot;
298
Ronald Cronc26f8d42020-09-01 10:51:51 +0200299 if( psa_key_handle_is_null( handle ) )
Gilles Peskine1841cf42019-10-08 15:48:25 +0200300 return( PSA_SUCCESS );
301
Gilles Peskine267c6562019-05-27 19:01:54 +0200302 status = psa_get_key_slot( handle, &slot );
303 if( status != PSA_SUCCESS )
304 return( status );
305
306 return( psa_wipe_key_slot( slot ) );
Gilles Peskine961849f2018-11-30 18:54:54 +0100307}
308
Gilles Peskine4bac9a42019-05-23 20:32:30 +0200309void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats )
310{
Ronald Cron98a54dd2020-07-24 16:33:11 +0200311 size_t slot_idx;
312
Gilles Peskine4bac9a42019-05-23 20:32:30 +0200313 memset( stats, 0, sizeof( *stats ) );
Ronald Cron98a54dd2020-07-24 16:33:11 +0200314
315 for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ )
Gilles Peskine4bac9a42019-05-23 20:32:30 +0200316 {
Ronald Cron98a54dd2020-07-24 16:33:11 +0200317 const psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ];
Gilles Peskine41e50d22019-07-31 15:01:55 +0200318 if( ! psa_is_key_slot_occupied( slot ) )
Gilles Peskine4bac9a42019-05-23 20:32:30 +0200319 {
Gilles Peskine41e50d22019-07-31 15:01:55 +0200320 ++stats->empty_slots;
Gilles Peskine4bac9a42019-05-23 20:32:30 +0200321 continue;
322 }
Gilles Peskine8e338702019-07-30 20:06:31 +0200323 if( slot->attr.lifetime == PSA_KEY_LIFETIME_VOLATILE )
Gilles Peskine4bac9a42019-05-23 20:32:30 +0200324 ++stats->volatile_slots;
Gilles Peskine8e338702019-07-30 20:06:31 +0200325 else if( slot->attr.lifetime == PSA_KEY_LIFETIME_PERSISTENT )
Gilles Peskine4bac9a42019-05-23 20:32:30 +0200326 {
Ronald Cron71016a92020-08-28 19:01:50 +0200327 psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot->attr.id );
Gilles Peskine4bac9a42019-05-23 20:32:30 +0200328 ++stats->persistent_slots;
Jaeden Amero6fa62a52019-08-20 17:43:48 +0100329 if( id > stats->max_open_internal_key_id )
330 stats->max_open_internal_key_id = id;
Gilles Peskine4bac9a42019-05-23 20:32:30 +0200331 }
332 else
333 {
Ronald Cron71016a92020-08-28 19:01:50 +0200334 psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot->attr.id );
Gilles Peskine4bac9a42019-05-23 20:32:30 +0200335 ++stats->external_slots;
Jaeden Amero6fa62a52019-08-20 17:43:48 +0100336 if( id > stats->max_open_external_key_id )
337 stats->max_open_external_key_id = id;
Gilles Peskine4bac9a42019-05-23 20:32:30 +0200338 }
339 }
340}
341
Gilles Peskine961849f2018-11-30 18:54:54 +0100342#endif /* MBEDTLS_PSA_CRYPTO_C */