psa: Do not reset a key slot under access

When psa_close/destroy/purge_key is called, do not
reset a key slot containing the description
of a persistent key if it is currently accessed.

Signed-off-by: Ronald Cron <ronald.cron@arm.com>
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 04a6514..1f69b55 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1344,10 +1344,30 @@
     if( mbedtls_svc_key_id_is_null( key ) )
         return( PSA_SUCCESS );
 
+    /*
+     * Get the description of the key in a key slot. In case of a permanent
+     * key, this will load the key description from persistent memory if not
+     * done yet. We cannot avoid this loading as without it we don't know if
+     * the key is operated by an SE or not and this information is needed by
+     * the current implementation.
+     */
     status = psa_get_key_slot( key, &slot );
     if( status != PSA_SUCCESS )
         return( status );
 
+    /*
+     * If the key slot containing the key description is under access by the
+     * library (apart from the present access), the key cannot be destroyed
+     * yet. For the time being, just return in error. Eventually (to be
+     * implemented), the key should be destroyed when all accesses have
+     * stopped.
+     */
+    if( slot->access_count > 1 )
+    {
+       psa_decrement_key_slot_access_count( slot );
+       return( PSA_ERROR_GENERIC_ERROR );
+    }
+
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
     driver = psa_get_se_driver_entry( slot->attr.lifetime );
     if( driver != NULL )
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 7bfcc4d..9271e14 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -382,7 +382,10 @@
     if( status != PSA_SUCCESS )
         return( status );
 
-    return( psa_wipe_key_slot( slot ) );
+    if( slot->access_count <= 1 )
+        return( psa_wipe_key_slot( slot ) );
+    else
+        return( psa_decrement_key_slot_access_count( slot ) );
 }
 
 psa_status_t psa_purge_key( mbedtls_svc_key_id_t key )
@@ -394,10 +397,11 @@
     if( status != PSA_SUCCESS )
         return( status );
 
-    if( PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
+    if( ( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) ) &&
+        ( slot->access_count <= 1 ) )
+        return( psa_wipe_key_slot( slot ) );
+    else
         return( psa_decrement_key_slot_access_count( slot ) );
-
-    return( psa_wipe_key_slot( slot ) );
 }
 
 void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats )