mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-03-29 22:20:30 +00:00
Merge pull request #8764 from Ryan-Everett-arm/threadsafe-key-wiping
Make key destruction thread safe
This commit is contained in:
commit
f741db3d6e
@ -198,6 +198,8 @@ psa_status_t mbedtls_psa_register_se_key(
|
|||||||
*
|
*
|
||||||
* This function clears all data associated with the PSA layer,
|
* This function clears all data associated with the PSA layer,
|
||||||
* including the whole key store.
|
* including the whole key store.
|
||||||
|
* This function is not thread safe, it wipes every key slot regardless of
|
||||||
|
* state and reader count. It should only be called when no slot is in use.
|
||||||
*
|
*
|
||||||
* This is an Mbed TLS extension.
|
* This is an Mbed TLS extension.
|
||||||
*/
|
*/
|
||||||
|
@ -1089,6 +1089,14 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
/* We cannot unlock between setting the state to PENDING_DELETION
|
||||||
|
* and destroying the key in storage, as otherwise another thread
|
||||||
|
* could load the key into a new slot and the key will not be
|
||||||
|
* fully destroyed. */
|
||||||
|
PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(
|
||||||
|
&mbedtls_threading_key_slot_mutex));
|
||||||
|
#endif
|
||||||
/* Set the key slot containing the key description's state to
|
/* Set the key slot containing the key description's state to
|
||||||
* PENDING_DELETION. This stops new operations from registering
|
* PENDING_DELETION. This stops new operations from registering
|
||||||
* to read the slot. Current readers can safely continue to access
|
* to read the slot. Current readers can safely continue to access
|
||||||
@ -1097,7 +1105,12 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key)
|
|||||||
* If the key is persistent, we can now delete the copy of the key
|
* If the key is persistent, we can now delete the copy of the key
|
||||||
* from memory. If the key is opaque, we require the driver to
|
* from memory. If the key is opaque, we require the driver to
|
||||||
* deal with the deletion. */
|
* deal with the deletion. */
|
||||||
slot->state = PSA_SLOT_PENDING_DELETION;
|
status = psa_key_slot_state_transition(slot, PSA_SLOT_FULL,
|
||||||
|
PSA_SLOT_PENDING_DELETION);
|
||||||
|
|
||||||
|
if (status != PSA_SUCCESS) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
if (PSA_KEY_LIFETIME_IS_READ_ONLY(slot->attr.lifetime)) {
|
if (PSA_KEY_LIFETIME_IS_READ_ONLY(slot->attr.lifetime)) {
|
||||||
/* Refuse the destruction of a read-only key (which may or may not work
|
/* Refuse the destruction of a read-only key (which may or may not work
|
||||||
@ -1152,11 +1165,6 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key)
|
|||||||
if (overall_status == PSA_SUCCESS) {
|
if (overall_status == PSA_SUCCESS) {
|
||||||
overall_status = status;
|
overall_status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: other slots may have a copy of the same key. We should
|
|
||||||
* invalidate them.
|
|
||||||
* https://github.com/ARMmbed/mbed-crypto/issues/214
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
|
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
|
||||||
|
|
||||||
@ -1182,6 +1190,14 @@ exit:
|
|||||||
if (status != PSA_SUCCESS) {
|
if (status != PSA_SUCCESS) {
|
||||||
overall_status = status;
|
overall_status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
/* Don't overwrite existing errors if the unlock fails. */
|
||||||
|
status = overall_status;
|
||||||
|
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||||
|
&mbedtls_threading_key_slot_mutex));
|
||||||
|
#endif
|
||||||
|
|
||||||
return overall_status;
|
return overall_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,44 +521,78 @@ psa_status_t psa_open_key(mbedtls_svc_key_id_t key, psa_key_handle_t *handle)
|
|||||||
|
|
||||||
psa_status_t psa_close_key(psa_key_handle_t handle)
|
psa_status_t psa_close_key(psa_key_handle_t handle)
|
||||||
{
|
{
|
||||||
psa_status_t status;
|
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||||
psa_key_slot_t *slot;
|
psa_key_slot_t *slot;
|
||||||
|
|
||||||
if (psa_key_handle_is_null(handle)) {
|
if (psa_key_handle_is_null(handle)) {
|
||||||
return PSA_SUCCESS;
|
return PSA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
/* We need to set status as success, otherwise CORRUPTION_DETECTED
|
||||||
|
* would be returned if the lock fails. */
|
||||||
|
status = PSA_SUCCESS;
|
||||||
|
PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
|
||||||
|
&mbedtls_threading_key_slot_mutex));
|
||||||
|
#endif
|
||||||
status = psa_get_and_lock_key_slot_in_memory(handle, &slot);
|
status = psa_get_and_lock_key_slot_in_memory(handle, &slot);
|
||||||
if (status != PSA_SUCCESS) {
|
if (status != PSA_SUCCESS) {
|
||||||
if (status == PSA_ERROR_DOES_NOT_EXIST) {
|
if (status == PSA_ERROR_DOES_NOT_EXIST) {
|
||||||
status = PSA_ERROR_INVALID_HANDLE;
|
status = PSA_ERROR_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||||
|
&mbedtls_threading_key_slot_mutex));
|
||||||
|
#endif
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slot->registered_readers == 1) {
|
if (slot->registered_readers == 1) {
|
||||||
return psa_wipe_key_slot(slot);
|
status = psa_wipe_key_slot(slot);
|
||||||
} else {
|
} else {
|
||||||
return psa_unregister_read(slot);
|
status = psa_unregister_read(slot);
|
||||||
}
|
}
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||||
|
&mbedtls_threading_key_slot_mutex));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
psa_status_t psa_purge_key(mbedtls_svc_key_id_t key)
|
psa_status_t psa_purge_key(mbedtls_svc_key_id_t key)
|
||||||
{
|
{
|
||||||
psa_status_t status;
|
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||||
psa_key_slot_t *slot;
|
psa_key_slot_t *slot;
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
/* We need to set status as success, otherwise CORRUPTION_DETECTED
|
||||||
|
* would be returned if the lock fails. */
|
||||||
|
status = PSA_SUCCESS;
|
||||||
|
PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
|
||||||
|
&mbedtls_threading_key_slot_mutex));
|
||||||
|
#endif
|
||||||
status = psa_get_and_lock_key_slot_in_memory(key, &slot);
|
status = psa_get_and_lock_key_slot_in_memory(key, &slot);
|
||||||
if (status != PSA_SUCCESS) {
|
if (status != PSA_SUCCESS) {
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||||
|
&mbedtls_threading_key_slot_mutex));
|
||||||
|
#endif
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) &&
|
if ((!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) &&
|
||||||
(slot->registered_readers == 1)) {
|
(slot->registered_readers == 1)) {
|
||||||
return psa_wipe_key_slot(slot);
|
status = psa_wipe_key_slot(slot);
|
||||||
} else {
|
} else {
|
||||||
return psa_unregister_read(slot);
|
status = psa_unregister_read(slot);
|
||||||
}
|
}
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||||
|
&mbedtls_threading_key_slot_mutex));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats)
|
void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats)
|
||||||
|
@ -92,6 +92,8 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
|
|||||||
psa_status_t psa_initialize_key_slots(void);
|
psa_status_t psa_initialize_key_slots(void);
|
||||||
|
|
||||||
/** Delete all data from key slots in memory.
|
/** Delete all data from key slots in memory.
|
||||||
|
* This function is not thread safe, it wipes every key slot regardless of
|
||||||
|
* state and reader count. It should only be called when no slot is in use.
|
||||||
*
|
*
|
||||||
* This does not affect persistent storage. */
|
* This does not affect persistent storage. */
|
||||||
void psa_wipe_all_key_slots(void);
|
void psa_wipe_all_key_slots(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user