Refuse to destroy read-only keys

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/ChangeLog.d/psa-read-only-keys.txt b/ChangeLog.d/psa-read-only-keys.txt
index 9e30810..a4a2823 100644
--- a/ChangeLog.d/psa-read-only-keys.txt
+++ b/ChangeLog.d/psa-read-only-keys.txt
@@ -1,4 +1,5 @@
-Features
-   * The PSA API no longer allows the creation of keys with a read-only lifetime.
-     The persistence level PSA_KEY_PERSISTENCE_READ_ONLY can now only be used
-     as intended, for keys that cannot be modified through normal use of the API.
+Bugfix
+   * The PSA API no longer allows the creation or destruction of keys with a
+     read-only lifetime. The persistence level PSA_KEY_PERSISTENCE_READ_ONLY
+     can now only be used as intended, for keys that cannot be modified through
+     normal use of the API.
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index a0acc3f..2177141 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1052,6 +1052,18 @@
        return( PSA_ERROR_GENERIC_ERROR );
     }
 
+    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
+         * by policy or actually physically read-only).
+         * Just do the best we can, which is to wipe the copy in memory. */
+        status = psa_wipe_key_slot( slot );
+        if( status != PSA_SUCCESS )
+            return( status );
+        return( PSA_ERROR_NOT_PERMITTED );
+    }
+
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
     driver = psa_get_se_driver_entry( slot->attr.lifetime );
     if( driver != NULL )