Branch data Line data Source code
1 : : /*
2 : : * PSA crypto layer on top of Mbed TLS crypto
3 : : */
4 : : /*
5 : : * Copyright The Mbed TLS Contributors
6 : : * 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 : :
21 : : #include "common.h"
22 : :
23 : : #if defined(MBEDTLS_PSA_CRYPTO_C)
24 : :
25 : : #include "psa/crypto.h"
26 : :
27 : : #include "psa_crypto_core.h"
28 : : #include "psa_crypto_driver_wrappers.h"
29 : : #include "psa_crypto_slot_management.h"
30 : : #include "psa_crypto_storage.h"
31 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
32 : : #include "psa_crypto_se.h"
33 : : #endif
34 : :
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 : :
46 : : typedef struct
47 : : {
48 : : psa_key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT];
49 : : unsigned key_slots_initialized : 1;
50 : : } psa_global_data_t;
51 : :
52 : : static psa_global_data_t global_data;
53 : :
54 : 0 : int psa_is_valid_key_id( mbedtls_svc_key_id_t key, int vendor_ok )
55 : : {
56 : 0 : psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key );
57 : :
58 [ # # ]: 0 : if( ( PSA_KEY_ID_USER_MIN <= key_id ) &&
59 : : ( key_id <= PSA_KEY_ID_USER_MAX ) )
60 : : return( 1 );
61 : :
62 : 0 : if( vendor_ok &&
63 [ # # ]: 0 : ( PSA_KEY_ID_VENDOR_MIN <= key_id ) &&
64 [ # # ]: 0 : ( key_id <= PSA_KEY_ID_VENDOR_MAX ) )
65 : 0 : return( 1 );
66 : :
67 : : return( 0 );
68 : : }
69 : :
70 : : /** Get the description in memory of a key given its identifier and lock it.
71 : : *
72 : : * The descriptions of volatile keys and loaded persistent keys are
73 : : * stored in key slots. This function returns a pointer to the key slot
74 : : * containing the description of a key given its identifier.
75 : : *
76 : : * The function searches the key slots containing the description of the key
77 : : * with \p key identifier. The function does only read accesses to the key
78 : : * slots. The function does not load any persistent key thus does not access
79 : : * any storage.
80 : : *
81 : : * For volatile key identifiers, only one key slot is queried as a volatile
82 : : * key with identifier key_id can only be stored in slot of index
83 : : * ( key_id - #PSA_KEY_ID_VOLATILE_MIN ).
84 : : *
85 : : * On success, the function locks the key slot. It is the responsibility of
86 : : * the caller to unlock the key slot when it does not access it anymore.
87 : : *
88 : : * \param key Key identifier to query.
89 : : * \param[out] p_slot On success, `*p_slot` contains a pointer to the
90 : : * key slot containing the description of the key
91 : : * identified by \p key.
92 : : *
93 : : * \retval #PSA_SUCCESS
94 : : * The pointer to the key slot containing the description of the key
95 : : * identified by \p key was returned.
96 : : * \retval #PSA_ERROR_INVALID_HANDLE
97 : : * \p key is not a valid key identifier.
98 : : * \retval #PSA_ERROR_DOES_NOT_EXIST
99 : : * There is no key with key identifier \p key in the key slots.
100 : : */
101 : 374 : static psa_status_t psa_get_and_lock_key_slot_in_memory(
102 : : mbedtls_svc_key_id_t key, psa_key_slot_t **p_slot )
103 : : {
104 : 374 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
105 : 374 : psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key );
106 : 374 : size_t slot_idx;
107 : 374 : psa_key_slot_t *slot = NULL;
108 : :
109 [ + - ]: 374 : if( psa_key_id_is_volatile( key_id ) )
110 : : {
111 : 374 : slot = &global_data.key_slots[ key_id - PSA_KEY_ID_VOLATILE_MIN ];
112 : :
113 : : /*
114 : : * Check if both the PSA key identifier key_id and the owner
115 : : * identifier of key match those of the key slot.
116 : : *
117 : : * Note that, if the key slot is not occupied, its PSA key identifier
118 : : * is equal to zero. This is an invalid value for a PSA key identifier
119 : : * and thus cannot be equal to the valid PSA key identifier key_id.
120 : : */
121 : 374 : status = mbedtls_svc_key_id_equal( key, slot->attr.id ) ?
122 [ - + ]: 374 : PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
123 : : }
124 : : else
125 : : {
126 [ # # ]: 0 : if ( !psa_is_valid_key_id( key, 1 ) )
127 : : return( PSA_ERROR_INVALID_HANDLE );
128 : :
129 [ # # ]: 0 : for( slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++ )
130 : : {
131 : 0 : slot = &global_data.key_slots[ slot_idx ];
132 [ # # ]: 0 : if( mbedtls_svc_key_id_equal( key, slot->attr.id ) )
133 : : break;
134 : : }
135 : 0 : status = ( slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT ) ?
136 [ # # ]: 0 : PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
137 : : }
138 : :
139 [ + - ]: 374 : if( status == PSA_SUCCESS )
140 : : {
141 : 374 : status = psa_lock_key_slot( slot );
142 [ + - ]: 374 : if( status == PSA_SUCCESS )
143 : 374 : *p_slot = slot;
144 : : }
145 : :
146 : : return( status );
147 : : }
148 : :
149 : 1 : psa_status_t psa_initialize_key_slots( void )
150 : : {
151 : : /* Nothing to do: program startup and psa_wipe_all_key_slots() both
152 : : * guarantee that the key slots are initialized to all-zero, which
153 : : * means that all the key slots are in a valid, empty state. */
154 : 1 : global_data.key_slots_initialized = 1;
155 : 1 : return( PSA_SUCCESS );
156 : : }
157 : :
158 : 0 : void psa_wipe_all_key_slots( void )
159 : : {
160 : 0 : size_t slot_idx;
161 : :
162 [ # # ]: 0 : for( slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++ )
163 : : {
164 : 0 : psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ];
165 : 0 : slot->lock_count = 1;
166 : 0 : (void) psa_wipe_key_slot( slot );
167 : : }
168 : 0 : global_data.key_slots_initialized = 0;
169 : 0 : }
170 : :
171 : 172 : psa_status_t psa_get_empty_key_slot( psa_key_id_t *volatile_key_id,
172 : : psa_key_slot_t **p_slot )
173 : : {
174 : 172 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
175 : 172 : size_t slot_idx;
176 : 172 : psa_key_slot_t *selected_slot, *unlocked_persistent_key_slot;
177 : :
178 [ - + ]: 172 : if( ! global_data.key_slots_initialized )
179 : : {
180 : 0 : status = PSA_ERROR_BAD_STATE;
181 : 0 : goto error;
182 : : }
183 : :
184 : 172 : selected_slot = unlocked_persistent_key_slot = NULL;
185 [ + - ]: 172 : for( slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++ )
186 : : {
187 : 172 : psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ];
188 [ - + ]: 172 : if( ! psa_is_key_slot_occupied( slot ) )
189 : : {
190 : : selected_slot = slot;
191 : : break;
192 : : }
193 : :
194 [ # # ]: 0 : if( ( unlocked_persistent_key_slot == NULL ) &&
195 [ # # ]: 0 : ( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) ) &&
196 [ # # ]: 0 : ( ! psa_is_key_slot_locked( slot ) ) )
197 : 0 : unlocked_persistent_key_slot = slot;
198 : : }
199 : :
200 : : /*
201 : : * If there is no unused key slot and there is at least one unlocked key
202 : : * slot containing the description of a persistent key, recycle the first
203 : : * such key slot we encountered. If we later need to operate on the
204 : : * persistent key we are evicting now, we will reload its description from
205 : : * storage.
206 : : */
207 : 172 : if( ( selected_slot == NULL ) &&
208 [ - + ]: 172 : ( unlocked_persistent_key_slot != NULL ) )
209 : : {
210 : 0 : selected_slot = unlocked_persistent_key_slot;
211 : 0 : selected_slot->lock_count = 1;
212 : 0 : psa_wipe_key_slot( selected_slot );
213 : : }
214 : :
215 [ + - ]: 172 : if( selected_slot != NULL )
216 : : {
217 : 172 : status = psa_lock_key_slot( selected_slot );
218 [ - + ]: 172 : if( status != PSA_SUCCESS )
219 : 0 : goto error;
220 : :
221 : 172 : *volatile_key_id = PSA_KEY_ID_VOLATILE_MIN +
222 : 172 : ( (psa_key_id_t)( selected_slot - global_data.key_slots ) );
223 : 172 : *p_slot = selected_slot;
224 : :
225 : 172 : return( PSA_SUCCESS );
226 : : }
227 : : status = PSA_ERROR_INSUFFICIENT_MEMORY;
228 : :
229 : 0 : error:
230 : 0 : *p_slot = NULL;
231 : 0 : *volatile_key_id = 0;
232 : :
233 : 0 : return( status );
234 : : }
235 : :
236 : : #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
237 : : static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *slot )
238 : : {
239 : : psa_status_t status = PSA_SUCCESS;
240 : : uint8_t *key_data = NULL;
241 : : size_t key_data_length = 0;
242 : :
243 : : status = psa_load_persistent_key( &slot->attr,
244 : : &key_data, &key_data_length );
245 : : if( status != PSA_SUCCESS )
246 : : goto exit;
247 : :
248 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
249 : : /* Special handling is required for loading keys associated with a
250 : : * dynamically registered SE interface. */
251 : : const psa_drv_se_t *drv;
252 : : psa_drv_se_context_t *drv_context;
253 : : if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
254 : : {
255 : : psa_se_key_data_storage_t *data;
256 : :
257 : : if( key_data_length != sizeof( *data ) )
258 : : {
259 : : status = PSA_ERROR_DATA_INVALID;
260 : : goto exit;
261 : : }
262 : : data = (psa_se_key_data_storage_t *) key_data;
263 : : status = psa_copy_key_material_into_slot(
264 : : slot, data->slot_number, sizeof( data->slot_number ) );
265 : : goto exit;
266 : : }
267 : : #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
268 : :
269 : : status = psa_copy_key_material_into_slot( slot, key_data, key_data_length );
270 : :
271 : : exit:
272 : : psa_free_persistent_key_data( key_data, key_data_length );
273 : : return( status );
274 : : }
275 : : #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
276 : :
277 : : #if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
278 : :
279 : : static psa_status_t psa_load_builtin_key_into_slot( psa_key_slot_t *slot )
280 : : {
281 : : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
282 : : psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
283 : : psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_VOLATILE;
284 : : psa_drv_slot_number_t slot_number = 0;
285 : : size_t key_buffer_size = 0;
286 : : size_t key_buffer_length = 0;
287 : :
288 : : if( ! psa_key_id_is_builtin(
289 : : MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot->attr.id ) ) )
290 : : {
291 : : return( PSA_ERROR_DOES_NOT_EXIST );
292 : : }
293 : :
294 : : /* Check the platform function to see whether this key actually exists */
295 : : status = mbedtls_psa_platform_get_builtin_key(
296 : : slot->attr.id, &lifetime, &slot_number );
297 : : if( status != PSA_SUCCESS )
298 : : return( status );
299 : :
300 : : /* Set required key attributes to ensure get_builtin_key can retrieve the
301 : : * full attributes. */
302 : : psa_set_key_id( &attributes, slot->attr.id );
303 : : psa_set_key_lifetime( &attributes, lifetime );
304 : :
305 : : /* Get the full key attributes from the driver in order to be able to
306 : : * calculate the required buffer size. */
307 : : status = psa_driver_wrapper_get_builtin_key(
308 : : slot_number, &attributes,
309 : : NULL, 0, NULL );
310 : : if( status != PSA_ERROR_BUFFER_TOO_SMALL )
311 : : {
312 : : /* Builtin keys cannot be defined by the attributes alone */
313 : : if( status == PSA_SUCCESS )
314 : : status = PSA_ERROR_CORRUPTION_DETECTED;
315 : : return( status );
316 : : }
317 : :
318 : : /* If the key should exist according to the platform, then ask the driver
319 : : * what its expected size is. */
320 : : status = psa_driver_wrapper_get_key_buffer_size( &attributes,
321 : : &key_buffer_size );
322 : : if( status != PSA_SUCCESS )
323 : : return( status );
324 : :
325 : : /* Allocate a buffer of the required size and load the builtin key directly
326 : : * into the (now properly sized) slot buffer. */
327 : : status = psa_allocate_buffer_to_slot( slot, key_buffer_size );
328 : : if( status != PSA_SUCCESS )
329 : : return( status );
330 : :
331 : : status = psa_driver_wrapper_get_builtin_key(
332 : : slot_number, &attributes,
333 : : slot->key.data, slot->key.bytes, &key_buffer_length );
334 : : if( status != PSA_SUCCESS )
335 : : goto exit;
336 : :
337 : : /* Copy actual key length and core attributes into the slot on success */
338 : : slot->key.bytes = key_buffer_length;
339 : : slot->attr = attributes.core;
340 : :
341 : : exit:
342 : : if( status != PSA_SUCCESS )
343 : : psa_remove_key_data_from_memory( slot );
344 : : return( status );
345 : : }
346 : : #endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
347 : :
348 : 374 : psa_status_t psa_get_and_lock_key_slot( mbedtls_svc_key_id_t key,
349 : : psa_key_slot_t **p_slot )
350 : : {
351 : 374 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
352 : :
353 : 374 : *p_slot = NULL;
354 [ + - ]: 374 : if( ! global_data.key_slots_initialized )
355 : : return( PSA_ERROR_BAD_STATE );
356 : :
357 : : /*
358 : : * On success, the pointer to the slot is passed directly to the caller
359 : : * thus no need to unlock the key slot here.
360 : : */
361 : 374 : status = psa_get_and_lock_key_slot_in_memory( key, p_slot );
362 [ + - ]: 374 : if( status != PSA_ERROR_DOES_NOT_EXIST )
363 : 374 : return( status );
364 : :
365 : : /* Loading keys from storage requires support for such a mechanism */
366 : : #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || \
367 : : defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
368 : : psa_key_id_t volatile_key_id;
369 : :
370 : : status = psa_get_empty_key_slot( &volatile_key_id, p_slot );
371 : : if( status != PSA_SUCCESS )
372 : : return( status );
373 : :
374 : : (*p_slot)->attr.id = key;
375 : : (*p_slot)->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
376 : :
377 : : status = PSA_ERROR_DOES_NOT_EXIST;
378 : : #if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
379 : : /* Load keys in the 'builtin' range through their own interface */
380 : : status = psa_load_builtin_key_into_slot( *p_slot );
381 : : #endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
382 : :
383 : : #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
384 : : if( status == PSA_ERROR_DOES_NOT_EXIST )
385 : : status = psa_load_persistent_key_into_slot( *p_slot );
386 : : #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
387 : :
388 : : if( status != PSA_SUCCESS )
389 : : {
390 : : psa_wipe_key_slot( *p_slot );
391 : : if( status == PSA_ERROR_DOES_NOT_EXIST )
392 : : status = PSA_ERROR_INVALID_HANDLE;
393 : : }
394 : : else
395 : : /* Add implicit usage flags. */
396 : : psa_extend_key_usage_flags( &(*p_slot)->attr.policy.usage );
397 : :
398 : : return( status );
399 : : #else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
400 : : return( PSA_ERROR_INVALID_HANDLE );
401 : : #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
402 : : }
403 : :
404 : 374 : psa_status_t psa_unlock_key_slot( psa_key_slot_t *slot )
405 : : {
406 [ + - ]: 374 : if( slot == NULL )
407 : : return( PSA_SUCCESS );
408 : :
409 [ + - ]: 374 : if( slot->lock_count > 0 )
410 : : {
411 : 374 : slot->lock_count--;
412 : 374 : return( PSA_SUCCESS );
413 : : }
414 : :
415 : : /*
416 : : * As the return error code may not be handled in case of multiple errors,
417 : : * do our best to report if the lock counter is equal to zero. Assert with
418 : : * MBEDTLS_TEST_HOOK_TEST_ASSERT that the lock counter is strictly greater
419 : : * than zero: if the MBEDTLS_TEST_HOOKS configuration option is enabled and
420 : : * the function is called as part of the execution of a test suite, the
421 : : * execution of the test suite is stopped in error if the assertion fails.
422 : : */
423 : : MBEDTLS_TEST_HOOK_TEST_ASSERT( slot->lock_count > 0 );
424 : : return( PSA_ERROR_CORRUPTION_DETECTED );
425 : : }
426 : :
427 : 172 : psa_status_t psa_validate_key_location( psa_key_lifetime_t lifetime,
428 : : psa_se_drv_table_entry_t **p_drv )
429 : : {
430 [ + - ]: 172 : if ( psa_key_lifetime_is_external( lifetime ) )
431 : : {
432 : : #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
433 : : /* Check whether a driver is registered against this lifetime */
434 : : psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry( lifetime );
435 : : if( driver != NULL )
436 : : {
437 : : if (p_drv != NULL)
438 : : *p_drv = driver;
439 : : return( PSA_SUCCESS );
440 : : }
441 : : #else /* MBEDTLS_PSA_CRYPTO_SE_C */
442 : : (void) p_drv;
443 : : #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
444 : :
445 : : #if defined(MBEDTLS_PSA_CRYPTO_DRIVERS)
446 : : /* Key location for external keys gets checked by the wrapper */
447 : : return( PSA_SUCCESS );
448 : : #else /* MBEDTLS_PSA_CRYPTO_DRIVERS */
449 : : /* No support for external lifetimes at all, or dynamic interface
450 : : * did not find driver for requested lifetime. */
451 : : return( PSA_ERROR_INVALID_ARGUMENT );
452 : : #endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */
453 : : }
454 : : else
455 : : /* Local/internal keys are always valid */
456 : 172 : return( PSA_SUCCESS );
457 : : }
458 : :
459 : 172 : psa_status_t psa_validate_key_persistence( psa_key_lifetime_t lifetime )
460 : : {
461 [ - + ]: 172 : if ( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) )
462 : : {
463 : : /* Volatile keys are always supported */
464 : : return( PSA_SUCCESS );
465 : : }
466 : : else
467 : : {
468 : : /* Persistent keys require storage support */
469 : : #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
470 : : if( PSA_KEY_LIFETIME_IS_READ_ONLY( lifetime ) )
471 : : return( PSA_ERROR_INVALID_ARGUMENT );
472 : : else
473 : : return( PSA_SUCCESS );
474 : : #else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
475 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
476 : : #endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */
477 : : }
478 : : }
479 : :
480 : 0 : psa_status_t psa_open_key( mbedtls_svc_key_id_t key, psa_key_handle_t *handle )
481 : : {
482 : : #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || \
483 : : defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
484 : : psa_status_t status;
485 : : psa_key_slot_t *slot;
486 : :
487 : : status = psa_get_and_lock_key_slot( key, &slot );
488 : : if( status != PSA_SUCCESS )
489 : : {
490 : : *handle = PSA_KEY_HANDLE_INIT;
491 : : if( status == PSA_ERROR_INVALID_HANDLE )
492 : : status = PSA_ERROR_DOES_NOT_EXIST;
493 : :
494 : : return( status );
495 : : }
496 : :
497 : : *handle = key;
498 : :
499 : : return( psa_unlock_key_slot( slot ) );
500 : :
501 : : #else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
502 : 0 : (void) key;
503 : 0 : *handle = PSA_KEY_HANDLE_INIT;
504 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
505 : : #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
506 : : }
507 : :
508 : 0 : psa_status_t psa_close_key( psa_key_handle_t handle )
509 : : {
510 : 0 : psa_status_t status;
511 : 0 : psa_key_slot_t *slot;
512 : :
513 [ # # ]: 0 : if( psa_key_handle_is_null( handle ) )
514 : : return( PSA_SUCCESS );
515 : :
516 : 0 : status = psa_get_and_lock_key_slot_in_memory( handle, &slot );
517 [ # # ]: 0 : if( status != PSA_SUCCESS )
518 : : {
519 [ # # ]: 0 : if( status == PSA_ERROR_DOES_NOT_EXIST )
520 : 0 : status = PSA_ERROR_INVALID_HANDLE;
521 : :
522 : 0 : return( status );
523 : : }
524 [ # # ]: 0 : if( slot->lock_count <= 1 )
525 : 0 : return( psa_wipe_key_slot( slot ) );
526 : : else
527 : 0 : return( psa_unlock_key_slot( slot ) );
528 : : }
529 : :
530 : 0 : psa_status_t psa_purge_key( mbedtls_svc_key_id_t key )
531 : : {
532 : 0 : psa_status_t status;
533 : 0 : psa_key_slot_t *slot;
534 : :
535 : 0 : status = psa_get_and_lock_key_slot_in_memory( key, &slot );
536 [ # # ]: 0 : if( status != PSA_SUCCESS )
537 : : return( status );
538 : :
539 [ # # ]: 0 : if( ( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) ) &&
540 [ # # ]: 0 : ( slot->lock_count <= 1 ) )
541 : 0 : return( psa_wipe_key_slot( slot ) );
542 : : else
543 : 0 : return( psa_unlock_key_slot( slot ) );
544 : : }
545 : :
546 : 0 : void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats )
547 : : {
548 : 0 : size_t slot_idx;
549 : :
550 : 0 : memset( stats, 0, sizeof( *stats ) );
551 : :
552 [ # # ]: 0 : for( slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++ )
553 : : {
554 : 0 : const psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ];
555 [ # # ]: 0 : if( psa_is_key_slot_locked( slot ) )
556 : : {
557 : 0 : ++stats->locked_slots;
558 : : }
559 [ # # ]: 0 : if( ! psa_is_key_slot_occupied( slot ) )
560 : : {
561 : 0 : ++stats->empty_slots;
562 : 0 : continue;
563 : : }
564 [ # # ]: 0 : if( PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
565 : 0 : ++stats->volatile_slots;
566 : : else
567 : : {
568 : 0 : psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot->attr.id );
569 : 0 : ++stats->persistent_slots;
570 [ # # ]: 0 : if( id > stats->max_open_internal_key_id )
571 : 0 : stats->max_open_internal_key_id = id;
572 : : }
573 [ # # ]: 0 : if( PSA_KEY_LIFETIME_GET_LOCATION( slot->attr.lifetime ) !=
574 : : PSA_KEY_LOCATION_LOCAL_STORAGE )
575 : : {
576 : 0 : psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot->attr.id );
577 : 0 : ++stats->external_slots;
578 [ # # ]: 0 : if( id > stats->max_open_external_key_id )
579 : 0 : stats->max_open_external_key_id = id;
580 : : }
581 : : }
582 : 0 : }
583 : :
584 : : #endif /* MBEDTLS_PSA_CRYPTO_C */
|