Update psa_destroy_key, psa_purge_key and psa_close_key

This does not yet implement destruction while a key is in use for psa_destroy_key;
that will be implemented in a separate pr.
(I am not sure if I am allowed to change the documentation in the include files.)

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index fe10ee0..fd1928a 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -415,7 +415,9 @@
  * \retval #PSA_ERROR_BAD_STATE
  *         The library has not been previously initialized by psa_crypto_init().
  *         It is implementation-dependent whether a failure to initialize
- *         results in this error code.
+ *         results in this error code. Or,
+ *         this call was operating on a key slot and found the slot in
+ *         an invalid state for the operation.
  */
 psa_status_t psa_purge_key(mbedtls_svc_key_id_t key);
 
@@ -555,7 +557,9 @@
  * \retval #PSA_ERROR_BAD_STATE
  *         The library has not been previously initialized by psa_crypto_init().
  *         It is implementation-dependent whether a failure to initialize
- *         results in this error code.
+ *         results in this error code. Or,
+ *         this call was operating on a key slot and found the slot in
+ *         an invalid state for the operation.
  */
 psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key);
 
diff --git a/include/psa/crypto_compat.h b/include/psa/crypto_compat.h
index f896fae..bfc0016 100644
--- a/include/psa/crypto_compat.h
+++ b/include/psa/crypto_compat.h
@@ -142,7 +142,9 @@
  * \retval #PSA_ERROR_BAD_STATE
  *         The library has not been previously initialized by psa_crypto_init().
  *         It is implementation-dependent whether a failure to initialize
- *         results in this error code.
+ *         results in this error code. Or,
+ *         this call was operating on a key slot and found the slot in
+ *         an invalid state for the operation.
  */
 psa_status_t psa_close_key(psa_key_handle_t handle);
 
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index a27fd42..3e49d0a 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1048,11 +1048,13 @@
      * implemented), the key should be destroyed when all accesses have
      * stopped.
      */
-    if (slot->lock_count > 1) {
-        psa_unlock_key_slot(slot);
+    if (slot->registered_readers > 1) {
+        psa_unregister_read(slot);
         return PSA_ERROR_GENERIC_ERROR;
     }
 
+    slot->state = PSA_SLOT_PENDING_DELETION;
+
     if (PSA_KEY_LIFETIME_IS_READ_ONLY(slot->attr.lifetime)) {
         /* Refuse the destruction of a read-only key (which may or may not work
          * if we attempt it, depending on whether the key is merely read-only
@@ -1126,7 +1128,7 @@
 
 exit:
     status = psa_wipe_key_slot(slot);
-    /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */
+    /* Prioritize an error from wiping over a storage error */
     if (status != PSA_SUCCESS) {
         overall_status = status;
     }
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 4846e33..a21388a 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -539,11 +539,14 @@
 
         return status;
     }
-    if (slot->lock_count <= 1) {
-        return psa_wipe_key_slot(slot);
-    } else {
-        return psa_unlock_key_slot(slot);
+    if (slot->registered_readers == 1) {
+        status = psa_key_slot_state_transition(slot, PSA_SLOT_FULL,
+                                               PSA_SLOT_PENDING_DELETION);
+        if (status != PSA_SUCCESS) {
+            return status;
+        }
     }
+    return psa_unregister_read(slot);
 }
 
 psa_status_t psa_purge_key(mbedtls_svc_key_id_t key)
@@ -557,11 +560,11 @@
     }
 
     if ((!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) &&
-        (slot->lock_count <= 1)) {
-        return psa_wipe_key_slot(slot);
-    } else {
-        return psa_unlock_key_slot(slot);
+        (slot->registered_readers == 1)) {
+        psa_key_slot_state_transition(slot, PSA_SLOT_FULL,
+                                      PSA_SLOT_PENDING_DELETION);
     }
+    return psa_unregister_read(slot);
 }
 
 void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats)