From 39cc9d755e20827cb7ebc3cde53065def94e2ef6 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 21 Dec 2023 17:57:14 +0000 Subject: [PATCH] Implement psa_register_read and psa_unregister_read Replaces psa_lock_key_slot and psa_unlock_key_slot. Future commits will remove the calls to locking/unlocking functions, and add calls to registering/unregistering functions. Signed-off-by: Ryan Everett --- library/psa_crypto_slot_management.c | 25 ++++++++++++----- library/psa_crypto_slot_management.h | 40 +++++++++++++++++----------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 5ecc3a76c7..32881e5e9e 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -394,26 +394,37 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ } -psa_status_t psa_unlock_key_slot(psa_key_slot_t *slot) +psa_status_t psa_unregister_read(psa_key_slot_t *slot) { if (slot == NULL) { return PSA_SUCCESS; } + if ((slot->state != PSA_SLOT_FULL) && + (slot->state != PSA_SLOT_PENDING_DELETION)) { + return PSA_ERROR_BAD_STATE; + } - if (slot->lock_count > 0) { - slot->lock_count--; + /* If we are the last reader and the slot is marked for deletion, + * we must wipe the slot here. */ + if ((slot->state == PSA_SLOT_PENDING_DELETION) && + (slot->registered_readers == 1)) { + return psa_wipe_key_slot(slot); + } + + if (psa_key_slot_has_readers(slot)) { + slot->registered_readers--; return PSA_SUCCESS; } /* * As the return error code may not be handled in case of multiple errors, - * do our best to report if the lock counter is equal to zero. Assert with - * MBEDTLS_TEST_HOOK_TEST_ASSERT that the lock counter is strictly greater - * than zero: if the MBEDTLS_TEST_HOOKS configuration option is enabled and + * do our best to report if there are no registered readers. Assert with + * MBEDTLS_TEST_HOOK_TEST_ASSERT that there are registered readers: + * if the MBEDTLS_TEST_HOOKS configuration option is enabled and * the function is called as part of the execution of a test suite, the * execution of the test suite is stopped in error if the assertion fails. */ - MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->lock_count > 0); + MBEDTLS_TEST_HOOK_TEST_ASSERT(psa_key_slot_has_readers(slot)); return PSA_ERROR_CORRUPTION_DETECTED; } diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index 6041a35289..c38876d3dd 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -113,32 +113,39 @@ void psa_wipe_all_key_slots(void); psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id, psa_key_slot_t **p_slot); -/** Lock a key slot. +/** Register as a reader of a key slot. * - * This function increments the key slot lock counter by one. + * This function increments the key slot registered reader counter by one. * * \param[in] slot The key slot. * * \retval #PSA_SUCCESS - The key slot lock counter was incremented. + The key slot registered reader counter was incremented. * \retval #PSA_ERROR_CORRUPTION_DETECTED - * The lock counter already reached its maximum value and was not + * The reader counter already reached its maximum value and was not * increased. + * \retval #PSA_ERROR_BAD_STATE + * The slot's state was not PSA_SLOT_FULL. */ -static inline psa_status_t psa_lock_key_slot(psa_key_slot_t *slot) +static inline psa_status_t psa_register_read(psa_key_slot_t *slot) { - if (slot->lock_count >= SIZE_MAX) { + if (slot->state != PSA_SLOT_FULL) { + return PSA_ERROR_BAD_STATE; + } + if (slot->registered_readers >= SIZE_MAX) { return PSA_ERROR_CORRUPTION_DETECTED; } - - slot->lock_count++; + slot->registered_readers++; return PSA_SUCCESS; } -/** Unlock a key slot. +/** Unregister from reading a key slot. * - * This function decrements the key slot lock counter by one. + * This function decrements the key slot registered reader counter by one. + * If the state of the slot is PSA_SLOT_PENDING_DELETION, + * and there is only one registered reader (the caller), + * this function will call psa_wipe_slot(). * * \note To ease the handling of errors in retrieving a key slot * a NULL input pointer is valid, and the function returns @@ -146,13 +153,16 @@ static inline psa_status_t psa_lock_key_slot(psa_key_slot_t *slot) * * \param[in] slot The key slot. * \retval #PSA_SUCCESS - * \p slot is NULL or the key slot lock counter has been - * decremented successfully. + * \p slot is NULL or the key slot reader counter has been + * decremented (and potentially wiped) successfully. * \retval #PSA_ERROR_CORRUPTION_DETECTED - * The lock counter was equal to 0. - * + * registered_readers was equal to 0. + * \retval #PSA_ERROR_BAD_STATE + * The slot's state was neither PSA_SLOT_FULL nor + * PSA_SLOT_PENDING_DELETION, or a wipe was attempted and + * the slot's state was not PSA_SLOT_PENDING_DELETION. */ -psa_status_t psa_unlock_key_slot(psa_key_slot_t *slot); +psa_status_t psa_unregister_read(psa_key_slot_t *slot); /** Test whether a lifetime designates a key in an external cryptoprocessor. *