From 41e50d26eac2fefff81c374731c53838480d598b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 31 Jul 2019 15:01:55 +0200 Subject: [PATCH] Remove "allocated" flag from key slots The flag to mark key slots as allocated was introduced to mark slots that are claimed and in use, but do not have key material yet, at a time when creating a key used several API functions: allocate a slot, then progressively set its metadata, and finally create the key material. Now that all of these steps are combined into a single API function call, the notion of allocated-but-not-filled slot is no longer relevant. So remove the corresponding flag. A slot is occupied iff there is a key in it. (For a key in a secure element, the key material is not present, but the slot contains the key metadata.) This key must have a type which is nonzero, so use this as an indicator that a slot is in use. --- library/psa_crypto.c | 5 ----- library/psa_crypto_core.h | 16 +++++++++++++--- library/psa_crypto_slot_management.c | 19 ++++++------------- library/psa_crypto_slot_management.h | 10 +++++----- 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index cb8054681..f1ddb147e 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -897,8 +897,6 @@ static psa_status_t psa_get_key_from_slot( psa_key_handle_t handle, status = psa_get_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); - if( slot->attr.type == PSA_KEY_TYPE_NONE ) - return( PSA_ERROR_DOES_NOT_EXIST ); /* Enforce that usage policy for the key slot contains all the flags * required by the usage parameter. There is one exception: public @@ -1488,9 +1486,6 @@ static psa_status_t psa_start_key_creation( * is optional (import, copy). */ slot->attr = attributes->core; - /* This is awkward... Copying the attributes has overwritten the - * flag that marks this slot as used. Restore it. */ - psa_key_slot_set_bits_in_flags( slot, PSA_KEY_SLOT_FLAG_ALLOCATED ); #if defined(MBEDTLS_PSA_CRYPTO_SE_C) /* For a key in a secure element, we need to do three things: diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 1ae298e5f..fbfb6daef 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -64,9 +64,19 @@ typedef struct } data; } psa_key_slot_t; -/** Flag for psa_key_slot_t::attr::core::flags indicating that the - * slot is in use. */ -#define PSA_KEY_SLOT_FLAG_ALLOCATED ( (uint16_t) 0x0001 ) +/** Test whether a key slot is occupied. + * + * A key slot is occupied iff the key type is nonzero. This works because + * no valid key can have 0 as its key type. + * + * \param[in] slot The key slot to test. + * + * \return 1 if the slot is occupied, 0 otherwise. + */ +static inline int psa_is_key_slot_occupied( const psa_key_slot_t *slot ) +{ + return( slot->attr.type != 0 ); +} /** Retrieve flags from psa_key_slot_t::attr::core::flags. * diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 43ba4123c..073400988 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -74,8 +74,8 @@ psa_status_t psa_get_key_slot( psa_key_handle_t handle, return( PSA_ERROR_INVALID_HANDLE ); slot = &global_data.key_slots[handle - 1]; - /* If the slot hasn't been allocated, the handle is invalid. */ - if( ! psa_key_slot_get_flags( slot, PSA_KEY_SLOT_FLAG_ALLOCATED ) ) + /* If the slot isn't occupied, the handle is invalid. */ + if( ! psa_is_key_slot_occupied( slot ) ) return( PSA_ERROR_INVALID_HANDLE ); *p_slot = slot; @@ -111,12 +111,8 @@ psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle, for( *handle = PSA_KEY_SLOT_COUNT; *handle != 0; --( *handle ) ) { *p_slot = &global_data.key_slots[*handle - 1]; - if( ! psa_key_slot_get_flags( *p_slot, PSA_KEY_SLOT_FLAG_ALLOCATED ) ) - { - psa_key_slot_set_bits_in_flags( *p_slot, - PSA_KEY_SLOT_FLAG_ALLOCATED ); + if( ! psa_is_key_slot_occupied( *p_slot ) ) return( PSA_SUCCESS ); - } } *p_slot = NULL; return( PSA_ERROR_INSUFFICIENT_MEMORY ); @@ -272,13 +268,10 @@ void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats ) memset( stats, 0, sizeof( *stats ) ); for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ ) { - psa_key_slot_t *slot = &global_data.key_slots[key - 1]; - if( slot->attr.type == PSA_KEY_TYPE_NONE ) + const psa_key_slot_t *slot = &global_data.key_slots[key - 1]; + if( ! psa_is_key_slot_occupied( slot ) ) { - if( psa_key_slot_get_flags( slot, PSA_KEY_SLOT_FLAG_ALLOCATED ) ) - ++stats->half_filled_slots; - else - ++stats->empty_slots; + ++stats->empty_slots; continue; } if( slot->attr.lifetime == PSA_KEY_LIFETIME_VOLATILE ) diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index 049520d4b..cde590fc5 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -58,13 +58,13 @@ psa_status_t psa_initialize_key_slots( void ); * This does not affect persistent storage. */ void psa_wipe_all_key_slots( void ); -/** Find a free key slot and mark it as in use. +/** Find a free key slot. + * + * This function returns a key slot that is available for use and is in its + * ground state (all-bits-zero). * * \param[out] handle On success, a slot number that can be used as a - * handle to the slot. The selected slot was not - * in use before. This function marks it as in use - * and otherwise leaves it in a freshly-initialized - * state. + * handle to the slot. * \param[out] p_slot On success, a pointer to the slot. * * \retval #PSA_SUCCESS