From 277a85f1ef7e46724f1cbd4f9e222bec6bce21ec Mon Sep 17 00:00:00 2001
From: Ronald Cron <ronald.cron@arm.com>
Date: Tue, 4 Aug 2020 15:49:48 +0200
Subject: [PATCH] Add psa_purge_key API

Signed-off-by: Ronald Cron <ronald.cron@arm.com>
---
 include/psa/crypto.h                 | 23 +++++++++++++++++++++++
 library/psa_crypto_slot_management.c | 15 +++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 2620af5ba3..15ffe2271f 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -387,6 +387,29 @@ void psa_reset_key_attributes(psa_key_attributes_t *attributes);
  * @{
  */
 
+/** Remove non-essential copies of key material from memory.
+ *
+ * If the key identifier designates a volatile key, this functions does not do
+ * anything and returns successfully.
+ *
+ * If the key identifier designates a persistent key, then this function will
+ * free all resources associated with the key in volatile memory. The key
+ * data in persistent storage is not affected and the key can still be used.
+ *
+ * \param key Identifier of the key to purge.
+ *
+ * \retval #PSA_SUCCESS
+ *         The key material will have been removed from memory if it is not
+ *         currently required.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         \p key is not a valid key identifier.
+ * \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.
+ */
+psa_status_t psa_purge_key(mbedtls_svc_key_id_t key);
+
 /** Make a copy of a key.
  *
  * Copy key material from one location to another.
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 8ef851bddf..6471591b5b 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -306,6 +306,21 @@ psa_status_t psa_close_key( psa_key_handle_t handle )
     return( psa_wipe_key_slot( slot ) );
 }
 
+psa_status_t psa_purge_key( mbedtls_svc_key_id_t key )
+{
+    psa_status_t status;
+    psa_key_slot_t *slot;
+
+    status = psa_get_key_slot( key, &slot );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    if( slot->attr.lifetime == PSA_KEY_LIFETIME_VOLATILE )
+        return PSA_SUCCESS;
+
+    return( psa_wipe_key_slot( slot ) );
+}
+
 void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats )
 {
     size_t slot_idx;