From 267c65666a1dbce3cd69df02419709b9b884d5b5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 27 May 2019 19:01:54 +0200 Subject: [PATCH] Simplify key slot allocation Now that psa_allocate_key() is no longer a public function, expose psa_internal_allocate_key_slot() instead, which provides a pointer to the slot to its caller. --- library/psa_crypto.c | 5 +- library/psa_crypto_slot_management.c | 103 +++++++-------------------- library/psa_crypto_slot_management.h | 11 +-- 3 files changed, 32 insertions(+), 87 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index f4eb3a11f..b3be2617b 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1305,10 +1305,7 @@ static psa_status_t psa_start_key_creation( psa_status_t status; psa_key_slot_t *slot; - status = psa_allocate_key( handle ); - if( status != PSA_SUCCESS ) - return( status ); - status = psa_get_key_slot( *handle, p_slot ); + status = psa_internal_allocate_key_slot( handle, p_slot ); if( status != PSA_SUCCESS ) return( status ); slot = *p_slot; diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 5251c19df..36900d92e 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -99,56 +99,25 @@ void psa_wipe_all_key_slots( void ) global_data.key_slots_initialized = 0; } -/** Find a free key slot and mark it as in use. - * - * \param[out] handle On success, a slot number that is not in use. This - * value can be used as a handle to the slot. - * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - */ -static psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle ) +psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle, + psa_key_slot_t **p_slot ) { + if( ! global_data.key_slots_initialized ) + return( PSA_ERROR_BAD_STATE ); + for( *handle = PSA_KEY_SLOT_COUNT; *handle != 0; --( *handle ) ) { - psa_key_slot_t *slot = &global_data.key_slots[*handle - 1]; - if( ! slot->allocated ) + *p_slot = &global_data.key_slots[*handle - 1]; + if( ! ( *p_slot )->allocated ) { - slot->allocated = 1; + ( *p_slot )->allocated = 1; return( PSA_SUCCESS ); } } + *p_slot = NULL; return( PSA_ERROR_INSUFFICIENT_MEMORY ); } -/** Wipe a key slot and mark it as available. - * - * This does not affect persistent storage. - * - * \param handle The handle to the key slot to release. - * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_CORRUPTION_DETECTED - */ -static psa_status_t psa_internal_release_key_slot( psa_key_handle_t handle ) -{ - psa_key_slot_t *slot; - psa_status_t status; - - status = psa_get_key_slot( handle, &slot ); - if( status != PSA_SUCCESS ) - return( status ); - - return( psa_wipe_key_slot( slot ) ); -} - -psa_status_t psa_allocate_key( psa_key_handle_t *handle ) -{ - *handle = 0; - return( psa_internal_allocate_key_slot( handle ) ); -} - #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *p_slot ) { @@ -194,41 +163,6 @@ static int psa_is_key_id_valid( psa_key_file_id_t file_id, else return( 0 ); } - -/** Declare a slot as persistent and load it from storage. - * - * This function may only be called immediately after a successful call - * to psa_internal_allocate_key_slot(). - * - * \param handle A handle to a key slot freshly allocated with - * psa_internal_allocate_key_slot(). - * - * \retval #PSA_SUCCESS - * The slot content was loaded successfully. - * \retval #PSA_ERROR_DOES_NOT_EXIST - * There is no content for this slot in persistent storage. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p id is not acceptable. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_STORAGE_FAILURE - */ -static psa_status_t psa_internal_make_key_persistent( psa_key_handle_t handle, - psa_key_file_id_t id ) -{ - psa_key_slot_t *slot; - psa_status_t status; - - status = psa_get_key_slot( handle, &slot ); - if( status != PSA_SUCCESS ) - return( status ); - - slot->lifetime = PSA_KEY_LIFETIME_PERSISTENT; - slot->persistent_storage_id = id; - status = psa_load_persistent_key_into_slot( slot ); - - return( status ); -} #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ psa_status_t psa_validate_persistent_key_parameters( @@ -259,6 +193,7 @@ static psa_status_t persistent_key_setup( psa_key_lifetime_t lifetime, psa_status_t status; psa_status_t wanted_load_status = ( creating ? PSA_ERROR_DOES_NOT_EXIST : PSA_SUCCESS ); + psa_key_slot_t *slot; *handle = 0; @@ -267,14 +202,17 @@ static psa_status_t persistent_key_setup( psa_key_lifetime_t lifetime, return( status ); #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - status = psa_internal_allocate_key_slot( handle ); + status = psa_internal_allocate_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); - status = psa_internal_make_key_persistent( *handle, id ); + slot->lifetime = PSA_KEY_LIFETIME_PERSISTENT; + slot->persistent_storage_id = id; + + status = psa_load_persistent_key_into_slot( slot ); if( status != wanted_load_status ) { - psa_internal_release_key_slot( *handle ); + psa_wipe_key_slot( slot ); *handle = 0; } return( status ); @@ -292,7 +230,14 @@ psa_status_t psa_open_key( psa_key_file_id_t id, psa_key_handle_t *handle ) psa_status_t psa_close_key( psa_key_handle_t handle ) { - return( psa_internal_release_key_slot( handle ) ); + psa_status_t status; + psa_key_slot_t *slot; + + status = psa_get_key_slot( handle, &slot ); + if( status != PSA_SUCCESS ) + return( status ); + + return( psa_wipe_key_slot( slot ) ); } #endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index d31067c53..aebe7db04 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -55,15 +55,18 @@ psa_status_t psa_initialize_key_slots( void ); * This does not affect persistent storage. */ void psa_wipe_all_key_slots( void ); -/** Allocate a key slot. +/** Find a free key slot and mark it as in use. * - * \param[out] handle On success, a handle to a newly allocated key slot. - * 0 if an error occurs. + * \param[out] handle On success, a slot number that is not in use. This + * value can be used as a handle to the slot. + * \param[out] p_slot On success, a pointer to the slot. * * \retval #PSA_SUCCESS * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_BAD_STATE */ -psa_status_t psa_allocate_key( psa_key_handle_t *handle ); +psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle, + psa_key_slot_t **p_slot ); /** Test whether the given parameters are acceptable for a persistent key. *