Update and rename psa_get_empty_key_slot

Rename to psa_reserve_free_key_slot, as this function reserves a slot which is
free (not always empty) for filling.
Implement necessary state transitions and state checks.
Rename unlocked_persistent_key_slot to unused_persistent_key_slot.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
This commit is contained in:
Ryan Everett 2023-12-22 15:59:45 +00:00
parent 4a78277cb2
commit 2afb516011
2 changed files with 39 additions and 24 deletions

View File

@ -147,30 +147,31 @@ void psa_wipe_all_key_slots(void)
global_data.key_slots_initialized = 0;
}
psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id,
psa_key_slot_t **p_slot)
psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
psa_key_slot_t **p_slot)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t slot_idx;
psa_key_slot_t *selected_slot, *unlocked_persistent_key_slot;
psa_key_slot_t *selected_slot, *unused_persistent_key_slot;
if (!global_data.key_slots_initialized) {
status = PSA_ERROR_BAD_STATE;
goto error;
}
selected_slot = unlocked_persistent_key_slot = NULL;
selected_slot = unused_persistent_key_slot = NULL;
for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
psa_key_slot_t *slot = &global_data.key_slots[slot_idx];
if (!psa_is_key_slot_occupied(slot)) {
if (slot->state == PSA_SLOT_EMPTY) {
selected_slot = slot;
break;
}
if ((unlocked_persistent_key_slot == NULL) &&
(!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) &&
(!psa_is_key_slot_locked(slot))) {
unlocked_persistent_key_slot = slot;
if ((unused_persistent_key_slot == NULL) &&
(slot->state == PSA_SLOT_FULL) &&
(!psa_key_slot_has_readers(slot)) &&
(!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime))) {
unused_persistent_key_slot = slot;
}
}
@ -182,16 +183,24 @@ psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id,
* storage.
*/
if ((selected_slot == NULL) &&
(unlocked_persistent_key_slot != NULL)) {
selected_slot = unlocked_persistent_key_slot;
selected_slot->lock_count = 1;
psa_wipe_key_slot(selected_slot);
(unused_persistent_key_slot != NULL)) {
selected_slot = unused_persistent_key_slot;
psa_register_read(selected_slot);
/* If the state is not changed then psa_wipe_key_slot
* will report an error. */
psa_key_slot_state_transition(selected_slot, PSA_SLOT_FULL,
PSA_SLOT_PENDING_DELETION);
status = psa_wipe_key_slot(selected_slot);
if (status != PSA_SUCCESS) {
goto error;
}
}
if (selected_slot != NULL) {
status = psa_lock_key_slot(selected_slot);
status = psa_key_slot_state_transition(selected_slot, PSA_SLOT_EMPTY,
PSA_SLOT_FILLING);
if (status != PSA_SUCCESS) {
goto error;
return status;
}
*volatile_key_id = PSA_KEY_ID_VOLATILE_MIN +

View File

@ -95,23 +95,29 @@ 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.
/** Find a free key slot and reserve it to be filled with a key.
*
* This function returns a key slot that is available for use and is in its
* ground state (all-bits-zero). On success, the key slot is locked. It is
* the responsibility of the caller to unlock the key slot when it does not
* access it anymore.
* This function finds a key slot that is free,
* sets its state to PSA_SLOT_FILLING and then returns the slot.
*
* On success, the key slot's state is PSA_SLOT_FILLING.
* It is the responsibility of the caller to change the slot's state to
* PSA_SLOT_EMPTY/FULL once key creation has finished.
*
* \param[out] volatile_key_id On success, volatile key identifier
* associated to the returned slot.
* \param[out] p_slot On success, a pointer to the slot.
*
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_BAD_STATE \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* There were no free key slots.
* \retval #PSA_ERROR_BAD_STATE
* This function attempted to operate on a key slot which was in an
* unexpected state.
*/
psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id,
psa_key_slot_t **p_slot);
psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
psa_key_slot_t **p_slot);
/** Change the state of a key slot.
*
* This function changes the state of the key slot from expected_state to