Crypto: Upgrade Mbed TLS to 2.25

Set the MBEDCRYPTO_VERSION to 2.25.0.

First three patches in existing v2.24 already applied in v2.25
and hence removed.

Replaced MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER with
MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER in all configuration and
source as updated in v2.25 library.

Update all headers of psa/include as per mbedtls-v2.25 excluding
changes required to hide some implementation.

Update id field in the client_key_attributes structure to
psa_key_id_t.

Update Copyright year to 2021!

Removed patch 006 as not required in MbedTLS v2.25.0.

Update references of handle to key as per MbedTLS api changes.

Increase NUM_HANDLES to 32 to accommodate crypto api tests.

Added corresponding tfm implementation of psa_purge_key().

Signed-off-by: Maulik Patel <maulik.patel@arm.com>
Change-Id: I6a532da96735cf32996250c4a8733a8654c1f44e
diff --git a/interface/include/psa/crypto.h b/interface/include/psa/crypto.h
index c58abda..e9d3c66 100644
--- a/interface/include/psa/crypto.h
+++ b/interface/include/psa/crypto.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -24,16 +24,6 @@
  * @{
  */
 
-/** \brief Key handle.
- *
- * This type represents open handles to keys. It must be an unsigned integral
- * type. The choice of type is implementation-dependent.
- *
- * 0 is not a valid key handle. How other handle values are assigned is
- * implementation-dependent.
- */
-typedef _unsigned_integral_type_ psa_key_handle_t;
-
 /**@}*/
 #endif /* __DOXYGEN_ONLY__ */
 
@@ -134,11 +124,11 @@
  * linkage). This function may be provided as a function-like macro,
  * but in this case it must evaluate each of its arguments exactly once.
  *
- * \param[out] attributes       The attribute structure to write to.
- * \param id                    The persistent identifier for the key.
+ * \param[out] attributes  The attribute structure to write to.
+ * \param key              The persistent identifier for the key.
  */
 static void psa_set_key_id(psa_key_attributes_t *attributes,
-                           psa_key_id_t id);
+                           psa_key_id_t key);
 
 /** Set the location of a persistent key.
  *
@@ -335,7 +325,7 @@
  *       Once you have called this function on an attribute structure,
  *       you must call psa_reset_key_attributes() to free these resources.
  *
- * \param[in] handle            Handle to the key to query.
+ * \param[in] key               Identifier of the key to query.
  * \param[in,out] attributes    On success, the attributes of the key.
  *                              On failure, equivalent to a
  *                              freshly-initialized structure.
@@ -351,7 +341,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_get_key_attributes(psa_key_handle_t handle,
+psa_status_t psa_get_key_attributes(psa_key_id_t key,
                                     psa_key_attributes_t *attributes);
 
 /** Reset a key attribute structure to a freshly initialized state.
@@ -374,93 +364,28 @@
  * @{
  */
 
-/** Open a handle to an existing persistent key.
+/** Remove non-essential copies of key material from memory.
  *
- * Open a handle to a persistent key. A key is persistent if it was created
- * with a lifetime other than #PSA_KEY_LIFETIME_VOLATILE. A persistent key
- * always has a nonzero key identifier, set with psa_set_key_id() when
- * creating the key. Implementations may provide additional pre-provisioned
- * keys that can be opened with psa_open_key(). Such keys have a key identifier
- * in the vendor range, as documented in the description of #psa_key_id_t.
+ * If the key identifier designates a volatile key, this functions does not do
+ * anything and returns successfully.
  *
- * The application must eventually close the handle with psa_close_key() or
- * psa_destroy_key() to release associated resources. If the application dies
- * without calling one of these functions, the implementation should perform
- * the equivalent of a call to psa_close_key().
+ * 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.
  *
- * Some implementations permit an application to open the same key multiple
- * times. If this is successful, each call to psa_open_key() will return a
- * different key handle.
- *
- * \note Applications that rely on opening a key multiple times will not be
- * portable to implementations that only permit a single key handle to be
- * opened. See also :ref:\`key-handles\`.
- *
- * \param id            The persistent identifier of the key.
- * \param[out] handle   On success, a handle to the key.
+ * \param key Identifier of the key to purge.
  *
  * \retval #PSA_SUCCESS
- *         Success. The application can now use the value of `*handle`
- *         to access the key.
- * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
- *         The implementation does not have sufficient resources to open the
- *         key. This can be due to reaching an implementation limit on the
- *         number of open keys, the number of open key handles, or available
- *         memory.
- * \retval #PSA_ERROR_DOES_NOT_EXIST
- *         There is no persistent key with key identifier \p id.
+ *         The key material will have been removed from memory if it is not
+ *         currently required.
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p id is not a valid persistent key identifier.
- * \retval #PSA_ERROR_NOT_PERMITTED
- *         The specified key exists, but the application does not have the
- *         permission to access it. Note that this specification does not
- *         define any way to create such a key, but it may be possible
- *         through implementation-specific means.
- * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_CORRUPTION_DETECTED
- * \retval #PSA_ERROR_STORAGE_FAILURE
+ *         \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_open_key(psa_key_id_t id,
-                          psa_key_handle_t *handle);
-
-
-/** Close a key handle.
- *
- * If the handle designates a volatile key, this will destroy the key material
- * and free all associated resources, just like psa_destroy_key().
- *
- * If this is the last open handle to a persistent key, then closing the handle
- * will free all resources associated with the key in volatile memory. The key
- * data in persistent storage is not affected and can be opened again later
- * with a call to psa_open_key().
- *
- * Closing the key handle makes the handle invalid, and the key handle
- * must not be used again by the application.
- *
- * \note If the key handle was used to set up an active
- * :ref:\`multipart operation <multipart-operations>\`, then closing the
- * key handle can cause the multipart operation to fail. Applications should
- * maintain the key handle until after the multipart operation has finished.
- *
- * \param handle        The key handle to close.
- *                      If this is \c 0, do nothing and return \c PSA_SUCCESS.
- *
- * \retval #PSA_SUCCESS
- *         \p handle was a valid handle or \c 0. It is now closed.
- * \retval #PSA_ERROR_INVALID_HANDLE
- *         \p handle is not a valid handle nor \c 0.
- * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_CORRUPTION_DETECTED
- * \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_close_key(psa_key_handle_t handle);
+psa_status_t psa_purge_key(psa_key_id_t key);
 
 /** Make a copy of a key.
  *
@@ -499,7 +424,10 @@
  * The effect of this function on implementation-defined attributes is
  * implementation-defined.
  *
- * \param source_handle     The key to copy. It must be a valid key handle.
+ * \param source_key        The key to copy. It must allow the usage
+ *                          #PSA_KEY_USAGE_COPY. If a private or secret key is
+ *                          being copied outside of a secure element it must
+ *                          also allow #PSA_KEY_USAGE_EXPORT.
  * \param[in] attributes    The attributes for the new key.
  *                          They are used as follows:
  *                          - The key type and size may be 0. If either is
@@ -513,12 +441,14 @@
  *                            the source key and \p attributes so that
  *                            both sets of restrictions apply, as
  *                            described in the documentation of this function.
- * \param[out] target_handle On success, a handle to the newly created key.
+ * \param[out] target_key   On success, an identifier for the newly created
+ *                          key. For persistent keys, this is the key
+ *                          identifier defined in \p attributes.
  *                          \c 0 on failure.
  *
  * \retval #PSA_SUCCESS
  * \retval #PSA_ERROR_INVALID_HANDLE
- *         \p source_handle is invalid.
+ *         \p source_key is invalid.
  * \retval #PSA_ERROR_ALREADY_EXISTS
  *         This is an attempt to create a persistent key, and there is
  *         already a persistent key with the given identifier.
@@ -546,9 +476,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_copy_key(psa_key_handle_t source_handle,
+psa_status_t psa_copy_key(psa_key_id_t source_key,
                           const psa_key_attributes_t *attributes,
-                          psa_key_handle_t *target_handle);
+                          psa_key_id_t *target_key);
 
 
 /**
@@ -559,28 +489,22 @@
  * make a best effort to ensure that that the key material cannot be recovered.
  *
  * This function also erases any metadata such as policies and frees
- * resources associated with the key. To free all resources associated with
- * the key, all handles to the key must be closed or destroyed.
- *
- * Destroying the key makes the handle invalid, and the key handle
- * must not be used again by the application. Using other open handles to the
- * destroyed key in a cryptographic operation will result in an error.
+ * resources associated with the key.
  *
  * If a key is currently in use in a multipart operation, then destroying the
  * key will cause the multipart operation to fail.
  *
- * \param handle        Handle to the key to erase.
- *                      If this is \c 0, do nothing and return \c PSA_SUCCESS.
+ * \param key  Identifier of the key to erase. If this is \c 0, do nothing and
+ *             return #PSA_SUCCESS.
  *
  * \retval #PSA_SUCCESS
- *         \p handle was a valid handle and the key material that it
- *         referred to has been erased.
- *         Alternatively, \p handle is \c 0.
+ *         \p key was a valid identifier and the key material that it
+ *         referred to has been erased. Alternatively, \p key is \c 0.
  * \retval #PSA_ERROR_NOT_PERMITTED
  *         The key cannot be erased because it is
  *         read-only, either due to a policy or due to physical restrictions.
  * \retval #PSA_ERROR_INVALID_HANDLE
- *         \p handle is not a valid handle nor \c 0.
+ *         \p key is not a valid identifier nor \c 0.
  * \retval #PSA_ERROR_COMMUNICATION_FAILURE
  *         There was an failure in communication with the cryptoprocessor.
  *         The key material may still be present in the cryptoprocessor.
@@ -598,7 +522,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_destroy_key(psa_key_handle_t handle);
+psa_status_t psa_destroy_key(psa_key_id_t key);
 
 /**@}*/
 
@@ -633,7 +557,9 @@
  *                          \p data buffer.
  *                          If the key size in \p attributes is nonzero,
  *                          it must be equal to the size from \p data.
- * \param[out] handle       On success, a handle to the newly created key.
+ * \param[out] key          On success, an identifier to the newly created key.
+ *                          For persistent keys, this is the key identifier
+ *                          defined in \p attributes.
  *                          \c 0 on failure.
  * \param[in] data    Buffer containing the key data. The content of this
  *                    buffer is interpreted according to the type declared
@@ -678,7 +604,7 @@
 psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
                             const uint8_t *data,
                             size_t data_length,
-                            psa_key_handle_t *handle);
+                            psa_key_id_t *key);
 
 
 
@@ -739,7 +665,9 @@
  *
  * The policy on the key must have the usage flag #PSA_KEY_USAGE_EXPORT set.
  *
- * \param handle            Handle to the key to export.
+ * \param key               Identifier of the key to export. It must allow the
+ *                          usage #PSA_KEY_USAGE_EXPORT, unless it is a public
+ *                          key.
  * \param[out] data         Buffer where the key data is to be written.
  * \param data_size         Size of the \p data buffer in bytes.
  * \param[out] data_length  On success, the number of bytes
@@ -766,7 +694,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_export_key(psa_key_handle_t handle,
+psa_status_t psa_export_key(psa_key_id_t key,
                             uint8_t *data,
                             size_t data_size,
                             size_t *data_length);
@@ -809,7 +737,7 @@
  * Exporting a public key object or the public part of a key pair is
  * always permitted, regardless of the key's usage flags.
  *
- * \param handle            Handle to the key to export.
+ * \param key               Identifier of the key to export.
  * \param[out] data         Buffer where the key data is to be written.
  * \param data_size         Size of the \p data buffer in bytes.
  * \param[out] data_length  On success, the number of bytes
@@ -836,7 +764,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_export_public_key(psa_key_handle_t handle,
+psa_status_t psa_export_public_key(psa_key_id_t key,
                                    uint8_t *data,
                                    size_t data_size,
                                    size_t *data_length);
@@ -1213,7 +1141,8 @@
  *       about the MAC value which could allow an attacker to guess
  *       a valid MAC and thereby bypass security controls.
  *
- * \param handle            Handle to the key to use for the operation.
+ * \param key               Identifier of the key to use for the operation. It
+ *                          must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE.
  * \param alg               The MAC algorithm to compute (\c PSA_ALG_XXX value
  *                          such that #PSA_ALG_IS_MAC(\p alg) is true).
  * \param[in] input         Buffer containing the input message.
@@ -1228,7 +1157,7 @@
  * \retval #PSA_ERROR_INVALID_HANDLE
  * \retval #PSA_ERROR_NOT_PERMITTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p handle is not compatible with \p alg.
+ *         \p key is not compatible with \p alg.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  *         \p alg is not supported or is not a MAC algorithm.
  * \retval #PSA_ERROR_BUFFER_TOO_SMALL
@@ -1244,7 +1173,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_mac_compute(psa_key_handle_t handle,
+psa_status_t psa_mac_compute(psa_key_id_t key,
                              psa_algorithm_t alg,
                              const uint8_t *input,
                              size_t input_length,
@@ -1254,7 +1183,8 @@
 
 /** Calculate the MAC of a message and compare it with a reference value.
  *
- * \param handle            Handle to the key to use for the operation.
+ * \param key               Identifier of the key to use for the operation. It
+ *                          must allow the usage PSA_KEY_USAGE_VERIFY_MESSAGE.
  * \param alg               The MAC algorithm to compute (\c PSA_ALG_XXX value
  *                          such that #PSA_ALG_IS_MAC(\p alg) is true).
  * \param[in] input         Buffer containing the input message.
@@ -1270,7 +1200,7 @@
  * \retval #PSA_ERROR_INVALID_HANDLE
  * \retval #PSA_ERROR_NOT_PERMITTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p handle is not compatible with \p alg.
+ *         \p key is not compatible with \p alg.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  *         \p alg is not supported or is not a MAC algorithm.
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
@@ -1284,7 +1214,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_mac_verify(psa_key_handle_t handle,
+psa_status_t psa_mac_verify(psa_key_id_t key,
                             psa_algorithm_t alg,
                             const uint8_t *input,
                             size_t input_length,
@@ -1369,9 +1299,9 @@
  * \param[in,out] operation The operation object to set up. It must have
  *                          been initialized as per the documentation for
  *                          #psa_mac_operation_t and not yet in use.
- * \param handle            Handle to the key to use for the operation.
- *                          It must remain valid until the operation
- *                          terminates.
+ * \param key               Identifier of the key to use for the operation. It
+ *                          must remain valid until the operation terminates.
+ *                          It must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE.
  * \param alg               The MAC algorithm to compute (\c PSA_ALG_XXX value
  *                          such that #PSA_ALG_IS_MAC(\p alg) is true).
  *
@@ -1380,7 +1310,7 @@
  * \retval #PSA_ERROR_INVALID_HANDLE
  * \retval #PSA_ERROR_NOT_PERMITTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p handle is not compatible with \p alg.
+ *         \p key is not compatible with \p alg.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  *         \p alg is not supported or is not a MAC algorithm.
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
@@ -1397,7 +1327,7 @@
  *         results in this error code.
  */
 psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
-                                psa_key_handle_t handle,
+                                psa_key_id_t key,
                                 psa_algorithm_t alg);
 
 /** Set up a multipart MAC verification operation.
@@ -1431,9 +1361,10 @@
  * \param[in,out] operation The operation object to set up. It must have
  *                          been initialized as per the documentation for
  *                          #psa_mac_operation_t and not yet in use.
- * \param handle            Handle to the key to use for the operation.
- *                          It must remain valid until the operation
- *                          terminates.
+ * \param key               Identifier of the key to use for the operation. It
+ *                          must remain valid until the operation terminates.
+ *                          It must allow the usage
+ *                          PSA_KEY_USAGE_VERIFY_MESSAGE.
  * \param alg               The MAC algorithm to compute (\c PSA_ALG_XXX value
  *                          such that #PSA_ALG_IS_MAC(\p alg) is true).
  *
@@ -1459,7 +1390,7 @@
  *         results in this error code.
  */
 psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation,
-                                  psa_key_handle_t handle,
+                                  psa_key_id_t key,
                                   psa_algorithm_t alg);
 
 /** Add a message fragment to a multipart MAC operation.
@@ -1626,9 +1557,8 @@
  * vector). Use the multipart operation interface with a
  * #psa_cipher_operation_t object to provide other forms of IV.
  *
- * \param handle                Handle to the key to use for the operation.
- *                              It must remain valid until the operation
- *                              terminates.
+ * \param key                   Identifier of the key to use for the operation.
+ *                              It must allow the usage #PSA_KEY_USAGE_ENCRYPT.
  * \param alg                   The cipher algorithm to compute
  *                              (\c PSA_ALG_XXX value such that
  *                              #PSA_ALG_IS_CIPHER(\p alg) is true).
@@ -1646,7 +1576,7 @@
  * \retval #PSA_ERROR_INVALID_HANDLE
  * \retval #PSA_ERROR_NOT_PERMITTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p handle is not compatible with \p alg.
+ *         \p key is not compatible with \p alg.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  *         \p alg is not supported or is not a cipher algorithm.
  * \retval #PSA_ERROR_BUFFER_TOO_SMALL
@@ -1660,7 +1590,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_cipher_encrypt(psa_key_handle_t handle,
+psa_status_t psa_cipher_encrypt(psa_key_id_t key,
                                 psa_algorithm_t alg,
                                 const uint8_t *input,
                                 size_t input_length,
@@ -1672,9 +1602,10 @@
  *
  * This function decrypts a message encrypted with a symmetric cipher.
  *
- * \param handle                Handle to the key to use for the operation.
+ * \param key                   Identifier of the key to use for the operation.
  *                              It must remain valid until the operation
- *                              terminates.
+ *                              terminates. It must allow the usage
+ *                              #PSA_KEY_USAGE_DECRYPT.
  * \param alg                   The cipher algorithm to compute
  *                              (\c PSA_ALG_XXX value such that
  *                              #PSA_ALG_IS_CIPHER(\p alg) is true).
@@ -1692,7 +1623,7 @@
  * \retval #PSA_ERROR_INVALID_HANDLE
  * \retval #PSA_ERROR_NOT_PERMITTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p handle is not compatible with \p alg.
+ *         \p key is not compatible with \p alg.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  *         \p alg is not supported or is not a cipher algorithm.
  * \retval #PSA_ERROR_BUFFER_TOO_SMALL
@@ -1706,7 +1637,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_cipher_decrypt(psa_key_handle_t handle,
+psa_status_t psa_cipher_decrypt(psa_key_id_t key,
                                 psa_algorithm_t alg,
                                 const uint8_t *input,
                                 size_t input_length,
@@ -1792,9 +1723,10 @@
  * \param[in,out] operation     The operation object to set up. It must have
  *                              been initialized as per the documentation for
  *                              #psa_cipher_operation_t and not yet in use.
- * \param handle                Handle to the key to use for the operation.
+ * \param key                   Identifier of the key to use for the operation.
  *                              It must remain valid until the operation
- *                              terminates.
+ *                              terminates. It must allow the usage
+ *                              #PSA_KEY_USAGE_ENCRYPT.
  * \param alg                   The cipher algorithm to compute
  *                              (\c PSA_ALG_XXX value such that
  *                              #PSA_ALG_IS_CIPHER(\p alg) is true).
@@ -1804,7 +1736,7 @@
  * \retval #PSA_ERROR_INVALID_HANDLE
  * \retval #PSA_ERROR_NOT_PERMITTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p handle is not compatible with \p alg.
+ *         \p key is not compatible with \p alg.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  *         \p alg is not supported or is not a cipher algorithm.
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
@@ -1820,7 +1752,7 @@
  *         results in this error code.
  */
 psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
-                                      psa_key_handle_t handle,
+                                      psa_key_id_t key,
                                       psa_algorithm_t alg);
 
 /** Set the key for a multipart symmetric decryption operation.
@@ -1855,9 +1787,10 @@
  * \param[in,out] operation     The operation object to set up. It must have
  *                              been initialized as per the documentation for
  *                              #psa_cipher_operation_t and not yet in use.
- * \param handle                Handle to the key to use for the operation.
+ * \param key                   Identifier of the key to use for the operation.
  *                              It must remain valid until the operation
- *                              terminates.
+ *                              terminates. It must allow the usage
+ *                              #PSA_KEY_USAGE_DECRYPT.
  * \param alg                   The cipher algorithm to compute
  *                              (\c PSA_ALG_XXX value such that
  *                              #PSA_ALG_IS_CIPHER(\p alg) is true).
@@ -1867,7 +1800,7 @@
  * \retval #PSA_ERROR_INVALID_HANDLE
  * \retval #PSA_ERROR_NOT_PERMITTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p handle is not compatible with \p alg.
+ *         \p key is not compatible with \p alg.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  *         \p alg is not supported or is not a cipher algorithm.
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
@@ -1883,7 +1816,7 @@
  *         results in this error code.
  */
 psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
-                                      psa_key_handle_t handle,
+                                      psa_key_id_t key,
                                       psa_algorithm_t alg);
 
 /** Generate an IV for a symmetric encryption operation.
@@ -2097,7 +2030,9 @@
 
 /** Process an authenticated encryption operation.
  *
- * \param handle                  Handle to the key to use for the operation.
+ * \param key                     Identifier of the key to use for the
+ *                                operation. It must allow the usage
+ *                                #PSA_KEY_USAGE_ENCRYPT.
  * \param alg                     The AEAD algorithm to compute
  *                                (\c PSA_ALG_XXX value such that
  *                                #PSA_ALG_IS_AEAD(\p alg) is true).
@@ -2128,7 +2063,7 @@
  * \retval #PSA_ERROR_INVALID_HANDLE
  * \retval #PSA_ERROR_NOT_PERMITTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p handle is not compatible with \p alg.
+ *         \p key is not compatible with \p alg.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  *         \p alg is not supported or is not an AEAD algorithm.
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
@@ -2143,7 +2078,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_encrypt(psa_key_handle_t handle,
+psa_status_t psa_aead_encrypt(psa_key_id_t key,
                               psa_algorithm_t alg,
                               const uint8_t *nonce,
                               size_t nonce_length,
@@ -2157,7 +2092,9 @@
 
 /** Process an authenticated decryption operation.
  *
- * \param handle                  Handle to the key to use for the operation.
+ * \param key                     Identifier of the key to use for the
+ *                                operation. It must allow the usage
+ *                                #PSA_KEY_USAGE_DECRYPT.
  * \param alg                     The AEAD algorithm to compute
  *                                (\c PSA_ALG_XXX value such that
  *                                #PSA_ALG_IS_AEAD(\p alg) is true).
@@ -2188,7 +2125,7 @@
  *         The ciphertext is not authentic.
  * \retval #PSA_ERROR_NOT_PERMITTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p handle is not compatible with \p alg.
+ *         \p key is not compatible with \p alg.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  *         \p alg is not supported or is not an AEAD algorithm.
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
@@ -2203,7 +2140,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_decrypt(psa_key_handle_t handle,
+psa_status_t psa_aead_decrypt(psa_key_id_t key,
                               psa_algorithm_t alg,
                               const uint8_t *nonce,
                               size_t nonce_length,
@@ -2299,9 +2236,10 @@
  * \param[in,out] operation     The operation object to set up. It must have
  *                              been initialized as per the documentation for
  *                              #psa_aead_operation_t and not yet in use.
- * \param handle                Handle to the key to use for the operation.
+ * \param key                   Identifier of the key to use for the operation.
  *                              It must remain valid until the operation
- *                              terminates.
+ *                              terminates. It must allow the usage
+ *                              #PSA_KEY_USAGE_ENCRYPT.
  * \param alg                   The AEAD algorithm to compute
  *                              (\c PSA_ALG_XXX value such that
  *                              #PSA_ALG_IS_AEAD(\p alg) is true).
@@ -2310,10 +2248,10 @@
  *         Success.
  * \retval #PSA_ERROR_BAD_STATE
  *         The operation state is not valid (it must be inactive).
-  * \retval #PSA_ERROR_INVALID_HANDLE
+ * \retval #PSA_ERROR_INVALID_HANDLE
  * \retval #PSA_ERROR_NOT_PERMITTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p handle is not compatible with \p alg.
+ *         \p key is not compatible with \p alg.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  *         \p alg is not supported or is not an AEAD algorithm.
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
@@ -2327,7 +2265,7 @@
  *         results in this error code.
  */
 psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
-                                    psa_key_handle_t handle,
+                                    psa_key_id_t key,
                                     psa_algorithm_t alg);
 
 /** Set the key for a multipart authenticated decryption operation.
@@ -2365,9 +2303,10 @@
  * \param[in,out] operation     The operation object to set up. It must have
  *                              been initialized as per the documentation for
  *                              #psa_aead_operation_t and not yet in use.
- * \param handle                Handle to the key to use for the operation.
+ * \param key                   Identifier of the key to use for the operation.
  *                              It must remain valid until the operation
- *                              terminates.
+ *                              terminates. It must allow the usage
+ *                              #PSA_KEY_USAGE_DECRYPT.
  * \param alg                   The AEAD algorithm to compute
  *                              (\c PSA_ALG_XXX value such that
  *                              #PSA_ALG_IS_AEAD(\p alg) is true).
@@ -2376,10 +2315,10 @@
  *         Success.
  * \retval #PSA_ERROR_BAD_STATE
  *         The operation state is not valid (it must be inactive).
-  * \retval #PSA_ERROR_INVALID_HANDLE
+ * \retval #PSA_ERROR_INVALID_HANDLE
  * \retval #PSA_ERROR_NOT_PERMITTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p handle is not compatible with \p alg.
+ *         \p key is not compatible with \p alg.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  *         \p alg is not supported or is not an AEAD algorithm.
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
@@ -2393,7 +2332,7 @@
  *         results in this error code.
  */
 psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
-                                    psa_key_handle_t handle,
+                                    psa_key_id_t key,
                                     psa_algorithm_t alg);
 
 /** Generate a random nonce for an authenticated encryption operation.
@@ -2419,7 +2358,7 @@
  *         Success.
  * \retval #PSA_ERROR_BAD_STATE
  *         The operation state is not valid (it must be an active aead encrypt
-           operation, with no nonce set).
+ *         operation, with no nonce set).
  * \retval #PSA_ERROR_BUFFER_TOO_SMALL
  *         The size of the \p nonce buffer is too small.
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
@@ -2851,10 +2790,11 @@
  * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg)
  * to determine the hash algorithm to use.
  *
- * \param handle                Handle to the key to use for the operation.
- *                              It must be an asymmetric key pair.
+ * \param key                   Identifier of the key to use for the operation.
+ *                              It must be an asymmetric key pair. The key must
+ *                              allow the usage #PSA_KEY_USAGE_SIGN_HASH.
  * \param alg                   A signature algorithm that is compatible with
- *                              the type of \p handle.
+ *                              the type of \p key.
  * \param[in] hash              The hash or message to sign.
  * \param hash_length           Size of the \p hash buffer in bytes.
  * \param[out] signature        Buffer where the signature is to be written.
@@ -2870,7 +2810,7 @@
  *         determine a sufficient buffer size by calling
  *         #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
  *         where \c key_type and \c key_bits are the type and bit-size
- *         respectively of \p handle.
+ *         respectively of \p key.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
@@ -2884,7 +2824,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_sign_hash(psa_key_handle_t handle,
+psa_status_t psa_sign_hash(psa_key_id_t key,
                            psa_algorithm_t alg,
                            const uint8_t *hash,
                            size_t hash_length,
@@ -2901,10 +2841,12 @@
  * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg)
  * to determine the hash algorithm to use.
  *
- * \param handle            Handle to the key to use for the operation.
- *                          It must be a public key or an asymmetric key pair.
+ * \param key               Identifier of the key to use for the operation. It
+ *                          must be a public key or an asymmetric key pair. The
+ *                          key must allow the usage
+ *                          #PSA_KEY_USAGE_VERIFY_HASH.
  * \param alg               A signature algorithm that is compatible with
- *                          the type of \p handle.
+ *                          the type of \p key.
  * \param[in] hash          The hash or message whose signature is to be
  *                          verified.
  * \param hash_length       Size of the \p hash buffer in bytes.
@@ -2930,7 +2872,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_verify_hash(psa_key_handle_t handle,
+psa_status_t psa_verify_hash(psa_key_id_t key,
                              psa_algorithm_t alg,
                              const uint8_t *hash,
                              size_t hash_length,
@@ -2940,11 +2882,12 @@
 /**
  * \brief Encrypt a short message with a public key.
  *
- * \param handle                Handle to the key to use for the operation.
- *                              It must be a public key or an asymmetric
- *                              key pair.
+ * \param key                   Identifer of the key to use for the operation.
+ *                              It must be a public key or an asymmetric key
+ *                              pair. It must allow the usage
+ *                              #PSA_KEY_USAGE_ENCRYPT.
  * \param alg                   An asymmetric encryption algorithm that is
- *                              compatible with the type of \p handle.
+ *                              compatible with the type of \p key.
  * \param[in] input             The message to encrypt.
  * \param input_length          Size of the \p input buffer in bytes.
  * \param[in] salt              A salt or label, if supported by the
@@ -2973,7 +2916,7 @@
  *         determine a sufficient buffer size by calling
  *         #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
  *         where \c key_type and \c key_bits are the type and bit-size
- *         respectively of \p handle.
+ *         respectively of \p key.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
@@ -2987,7 +2930,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_asymmetric_encrypt(psa_key_handle_t handle,
+psa_status_t psa_asymmetric_encrypt(psa_key_id_t key,
                                     psa_algorithm_t alg,
                                     const uint8_t *input,
                                     size_t input_length,
@@ -3000,10 +2943,11 @@
 /**
  * \brief Decrypt a short message with a private key.
  *
- * \param handle                Handle to the key to use for the operation.
- *                              It must be an asymmetric key pair.
+ * \param key                   Identifier of the key to use for the operation.
+ *                              It must be an asymmetric key pair. It must
+ *                              allow the usage #PSA_KEY_USAGE_DECRYPT.
  * \param alg                   An asymmetric encryption algorithm that is
- *                              compatible with the type of \p handle.
+ *                              compatible with the type of \p key.
  * \param[in] input             The message to decrypt.
  * \param input_length          Size of the \p input buffer in bytes.
  * \param[in] salt              A salt or label, if supported by the
@@ -3032,7 +2976,7 @@
  *         determine a sufficient buffer size by calling
  *         #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
  *         where \c key_type and \c key_bits are the type and bit-size
- *         respectively of \p handle.
+ *         respectively of \p key.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
@@ -3047,7 +2991,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_asymmetric_decrypt(psa_key_handle_t handle,
+psa_status_t psa_asymmetric_decrypt(psa_key_id_t key,
                                     psa_algorithm_t alg,
                                     const uint8_t *input,
                                     size_t input_length,
@@ -3305,9 +3249,9 @@
  *                                psa_key_derivation_setup() and must not
  *                                have produced any output yet.
  * \param step                    Which step the input data is for.
- * \param handle                  Handle to the key. It must have an
- *                                appropriate type for \p step and must
- *                                allow the usage #PSA_KEY_USAGE_DERIVE.
+ * \param key                     Identifier of the key. It must have an
+ *                                appropriate type for step and must allow the
+ *                                usage #PSA_KEY_USAGE_DERIVE.
  *
  * \retval #PSA_SUCCESS
  *         Success.
@@ -3333,7 +3277,7 @@
 psa_status_t psa_key_derivation_input_key(
     psa_key_derivation_operation_t *operation,
     psa_key_derivation_step_t step,
-    psa_key_handle_t handle);
+    psa_key_id_t key);
 
 /** Perform a key agreement and use the shared secret as input to a key
  * derivation.
@@ -3358,7 +3302,8 @@
  *                                The operation must be ready for an
  *                                input of the type given by \p step.
  * \param step                    Which step the input data is for.
- * \param private_key             Handle to the private key to use.
+ * \param private_key             Identifier of the private key to use. It must
+ *                                allow the usage #PSA_KEY_USAGE_DERIVE.
  * \param[in] peer_key      Public key of the peer. The peer key must be in the
  *                          same format that psa_import_key() accepts for the
  *                          public key type corresponding to the type of
@@ -3402,7 +3347,7 @@
 psa_status_t psa_key_derivation_key_agreement(
     psa_key_derivation_operation_t *operation,
     psa_key_derivation_step_t step,
-    psa_key_handle_t private_key,
+    psa_key_id_t private_key,
     const uint8_t *peer_key,
     size_t peer_key_length);
 
@@ -3546,7 +3491,9 @@
  *
  * \param[in] attributes    The attributes for the new key.
  * \param[in,out] operation The key derivation operation object to read from.
- * \param[out] handle       On success, a handle to the newly created key.
+ * \param[out] key          On success, an identifier for the newly created
+ *                          key. For persistent keys, this is the key
+ *                          identifier defined in \p attributes.
  *                          \c 0 on failure.
  *
  * \retval #PSA_SUCCESS
@@ -3586,7 +3533,7 @@
 psa_status_t psa_key_derivation_output_key(
     const psa_key_attributes_t *attributes,
     psa_key_derivation_operation_t *operation,
-    psa_key_handle_t *handle);
+    psa_key_id_t *key);
 
 /** Abort a key derivation operation.
  *
@@ -3627,7 +3574,8 @@
  *                                (\c PSA_ALG_XXX value such that
  *                                #PSA_ALG_IS_RAW_KEY_AGREEMENT(\p alg)
  *                                is true).
- * \param private_key             Handle to the private key to use.
+ * \param private_key             Identifier of the private key to use. It must
+ *                                allow the usage #PSA_KEY_USAGE_DERIVE.
  * \param[in] peer_key            Public key of the peer. It must be
  *                                in the same format that psa_import_key()
  *                                accepts. The standard formats for public
@@ -3665,7 +3613,7 @@
  *         results in this error code.
  */
 psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
-                                   psa_key_handle_t private_key,
+                                   psa_key_id_t private_key,
                                    const uint8_t *peer_key,
                                    size_t peer_key_length,
                                    uint8_t *output,
@@ -3721,7 +3669,9 @@
  *   attributes.
  *
  * \param[in] attributes    The attributes for the new key.
- * \param[out] handle       On success, a handle to the newly created key.
+ * \param[out] key          On success, an identifier for the newly created
+ *                          key. For persistent keys, this is the key
+ *                          identifier defined in \p attributes.
  *                          \c 0 on failure.
  *
  * \retval #PSA_SUCCESS
@@ -3746,7 +3696,7 @@
  *         results in this error code.
  */
 psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
-                              psa_key_handle_t *handle);
+                              psa_key_id_t *key);
 
 /**@}*/
 
diff --git a/interface/include/psa/crypto_client_struct.h b/interface/include/psa/crypto_client_struct.h
index 959f573..98f7bfe 100644
--- a/interface/include/psa/crypto_client_struct.h
+++ b/interface/include/psa/crypto_client_struct.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -32,7 +32,7 @@
 struct psa_client_key_attributes_s
 {
     uint32_t lifetime;
-    uint32_t id;
+    psa_key_id_t id;
     uint32_t alg;
     uint32_t usage;
     size_t bits;
diff --git a/interface/include/psa/crypto_compat.h b/interface/include/psa/crypto_compat.h
index 26c205a..8ca1f6a 100644
--- a/interface/include/psa/crypto_compat.h
+++ b/interface/include/psa/crypto_compat.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -24,6 +24,25 @@
 extern "C" {
 #endif
 
+/*
+ * To support both openless APIs and psa_open_key() temporarily, define
+ * psa_key_handle_t to be equal to psa_key_id_t. Do not mark the
+ * type and its utility macros and functions deprecated yet. This will be done
+ * in a subsequent phase.
+ */
+typedef psa_key_id_t psa_key_handle_t;
+
+/** Check whether an handle is null.
+ *
+ * \param handle  Handle
+ *
+ * \return Non-zero if the handle is null, zero otherwise.
+ */
+static inline int psa_key_handle_is_null(psa_key_handle_t handle)
+{
+    return(handle == 0);
+}
+
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
 
 /*
@@ -42,6 +61,7 @@
 typedef MBEDTLS_PSA_DEPRECATED psa_dh_family_t mbedtls_deprecated_psa_dh_family_t;
 typedef MBEDTLS_PSA_DEPRECATED psa_ecc_family_t psa_ecc_curve_t;
 typedef MBEDTLS_PSA_DEPRECATED psa_dh_family_t psa_dh_group_t;
+typedef MBEDTLS_PSA_DEPRECATED psa_algorithm_t mbedtls_deprecated_psa_algorithm_t;
 
 #define PSA_KEY_TYPE_GET_CURVE PSA_KEY_TYPE_ECC_GET_FAMILY
 #define PSA_KEY_TYPE_GET_GROUP PSA_KEY_TYPE_DH_GET_FAMILY
@@ -97,7 +117,6 @@
                               const uint8_t *signature,
                               size_t signature_length );
 
-#endif /* MBEDTLS_DEPRECATED_REMOVED */
 
 /*
  * Size-specific elliptic curve families.
@@ -205,6 +224,117 @@
 #define PSA_DH_GROUP_CUSTOM \
     MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_CUSTOM )
 
+/*
+ * Deprecated PSA Crypto stream cipher algorithms (PSA Crypto API  <= 1.0 beta3)
+ */
+#define PSA_ALG_ARC4 \
+    MBEDTLS_DEPRECATED_CONSTANT(psa_algorithm_t, PSA_ALG_STREAM_CIPHER)
+#define PSA_ALG_CHACHA20 \
+    MBEDTLS_DEPRECATED_CONSTANT(psa_algorithm_t, PSA_ALG_STREAM_CIPHER)
+
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/** Open a handle to an existing persistent key.
+ *
+ * Open a handle to a persistent key. A key is persistent if it was created
+ * with a lifetime other than #PSA_KEY_LIFETIME_VOLATILE. A persistent key
+ * always has a nonzero key identifier, set with psa_set_key_id() when
+ * creating the key. Implementations may provide additional pre-provisioned
+ * keys that can be opened with psa_open_key(). Such keys have an application
+ * key identifier in the vendor range, as documented in the description of
+ * #psa_key_id_t.
+ *
+ * The application must eventually close the handle with psa_close_key() or
+ * psa_destroy_key() to release associated resources. If the application dies
+ * without calling one of these functions, the implementation should perform
+ * the equivalent of a call to psa_close_key().
+ *
+ * Some implementations permit an application to open the same key multiple
+ * times. If this is successful, each call to psa_open_key() will return a
+ * different key handle.
+ *
+ * \note This API is not part of the PSA Cryptography API Release 1.0.0
+ * specification. It was defined in the 1.0 Beta 3 version of the
+ * specification but was removed in the 1.0.0 released version. This API is
+ * kept for the time being to not break applications relying on it. It is not
+ * deprecated yet but will be in the near future.
+ *
+ * \note Applications that rely on opening a key multiple times will not be
+ * portable to implementations that only permit a single key handle to be
+ * opened. See also :ref:\`key-handles\`.
+ *
+ *
+ * \param id           The persistent identifier of the key.
+ * \param[out] key     On success, a handle to the key.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success. The application can now use the value of `*handle`
+ *         to access the key.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ *         The implementation does not have sufficient resources to open the
+ *         key. This can be due to reaching an implementation limit on the
+ *         number of open keys, the number of open key handles, or available
+ *         memory.
+ * \retval #PSA_ERROR_DOES_NOT_EXIST
+ *         There is no persistent key with key identifier \p id.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         \p id is not a valid persistent key identifier.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ *         The specified key exists, but the application does not have the
+ *         permission to access it. Note that this specification does not
+ *         define any way to create such a key, but it may be possible
+ *         through implementation-specific means.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \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_open_key(psa_key_id_t id,
+                          psa_key_id_t *key);
+
+/** Close a key handle.
+ *
+ * If the handle designates a volatile key, this will destroy the key material
+ * and free all associated resources, just like psa_destroy_key().
+ *
+ * If this is the last open handle to a persistent key, then closing the handle
+ * will free all resources associated with the key in volatile memory. The key
+ * data in persistent storage is not affected and can be opened again later
+ * with a call to psa_open_key().
+ *
+ * Closing the key handle makes the handle invalid, and the key handle
+ * must not be used again by the application.
+ *
+ * \note This API is not part of the PSA Cryptography API Release 1.0.0
+ * specification. It was defined in the 1.0 Beta 3 version of the
+ * specification but was removed in the 1.0.0 released version. This API is
+ * kept for the time being to not break applications relying on it. It is not
+ * deprecated yet but will be in the near future.
+ *
+ * \note If the key handle was used to set up an active
+ * :ref:\`multipart operation <multipart-operations>\`, then closing the
+ * key handle can cause the multipart operation to fail. Applications should
+ * maintain the key handle until after the multipart operation has finished.
+ *
+ * \param key           The key to close.
+ *                      If this is \c 0, do nothing and return \c PSA_SUCCESS.
+ *
+ * \retval #PSA_SUCCESS
+ *         \p handle was a valid handle or \c 0. It is now closed.
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ *         \p handle is not a valid handle nor \c 0.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \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_close_key(psa_key_id_t key);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/interface/include/psa/crypto_sizes.h b/interface/include/psa/crypto_sizes.h
index cbdf597..4d13e41 100644
--- a/interface/include/psa/crypto_sizes.h
+++ b/interface/include/psa/crypto_sizes.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -605,4 +605,94 @@
      PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
      0)
 
+/** The default nonce size for an AEAD algorithm, in bytes.
+ *
+ * This macro can be used to allocate a buffer of sufficient size to
+ * store the nonce output from #psa_aead_generate_nonce().
+ *
+ * See also #PSA_AEAD_NONCE_MAX_SIZE.
+ *
+ * \note This is not the maximum size of nonce supported as input to #psa_aead_set_nonce(),
+ *       #psa_aead_encrypt() or #psa_aead_decrypt(), just the default size that is generated by
+ *       #psa_aead_generate_nonce().
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ *          zero times, so you should not pass arguments that contain
+ *          side effects.
+ *
+ * \param key_type  A symmetric key type that is compatible with algorithm \p alg.
+ *
+ * \param alg       An AEAD algorithm (\c PSA_ALG_XXX value such that
+ *                  #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \return The default nonce size for the specified key type and algorithm.
+ *         If the key type or AEAD algorithm is not recognized,
+ *         or the parameters are incompatible, return 0.
+ *         An implementation can return either 0 or a correct size for a key type
+ *         and AEAD algorithm that it recognizes, but does not support.
+ */
+#define PSA_AEAD_NONCE_LENGTH(key_type, alg) \
+    (PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) == 16 && \
+         (PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_CCM || \
+          PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_GCM) ? 12 : \
+     (key_type) == PSA_KEY_TYPE_CHACHA20 && \
+          PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_CHACHA20_POLY1305 ? 12 : \
+     0)
+
+/** The maximum default nonce size among all supported pairs of key types and
+ *  AEAD algorithms, in bytes.
+ *
+ * This is equal to or greater than any value that #PSA_AEAD_NONCE_LENGTH() may return.
+ *
+ * \note This is not the maximum size of nonce supported as input to #psa_aead_set_nonce(),
+ *       #psa_aead_encrypt() or #psa_aead_decrypt(), just the largest size that may be generated by
+ *       #psa_aead_generate_nonce().
+ */
+#define PSA_AEAD_NONCE_MAX_SIZE 12
+
+/** The default IV size for a cipher algorithm, in bytes.
+ *
+ * The IV that is generated as part of a call to #psa_cipher_encrypt() is always
+ * the default IV length for the algorithm.
+ *
+ * This macro can be used to allocate a buffer of sufficient size to
+ * store the IV output from #psa_cipher_generate_iv() when using
+ * a multi-part cipher operation.
+ *
+ * See also #PSA_CIPHER_IV_MAX_SIZE.
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ *          zero times, so you should not pass arguments that contain
+ *          side effects.
+ *
+ * \param key_type  A symmetric key type that is compatible with algorithm \p alg.
+ *
+ * \param alg       A cipher algorithm (\c PSA_ALG_XXX value such that
+ *                  #PSA_ALG_IS_CIPHER(\p alg) is true).
+ *
+ * \return The default IV size for the specified key type and algorithm.
+ *         If the algorithm does not use an IV, return 0.
+ *         If the key type or cipher algorithm is not recognized,
+ *         or the parameters are incompatible, return 0.
+ *         An implementation can return either 0 or a correct size for a key type
+ *         and cipher algorithm that it recognizes, but does not support.
+ */
+#define PSA_CIPHER_IV_LENGTH(key_type, alg) \
+    (PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) > 1 && \
+        ((alg) == PSA_ALG_CTR || \
+         (alg) == PSA_ALG_CFB || \
+         (alg) == PSA_ALG_OFB || \
+         (alg) == PSA_ALG_XTS || \
+         (alg) == PSA_ALG_CBC_NO_PADDING || \
+         (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \
+     (key_type) == PSA_KEY_TYPE_CHACHA20 && \
+         (alg) == PSA_ALG_STREAM_CIPHER ? 12 : \
+     0)
+
+/** The maximum IV size for all supported cipher algorithms, in bytes.
+ *
+ * See also #PSA_CIPHER_IV_LENGTH().
+ */
+#define PSA_CIPHER_IV_MAX_SIZE 16
+
 #endif /* PSA_CRYPTO_SIZES_H */
diff --git a/interface/include/psa/crypto_struct.h b/interface/include/psa/crypto_struct.h
index ac08987..e0ceb2f 100644
--- a/interface/include/psa/crypto_struct.h
+++ b/interface/include/psa/crypto_struct.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -126,11 +126,19 @@
 }
 
 static inline void psa_set_key_id(psa_key_attributes_t *attributes,
-                                  psa_key_id_t id)
+                                  psa_key_id_t key)
 {
-    attributes->id = id;
-    if( attributes->lifetime == PSA_KEY_LIFETIME_VOLATILE )
-        attributes->lifetime = PSA_KEY_LIFETIME_PERSISTENT;
+    psa_key_lifetime_t lifetime = attributes->lifetime;
+
+    attributes->id = key;
+
+    if( PSA_KEY_LIFETIME_IS_VOLATILE(lifetime))
+    {
+        attributes->lifetime =
+            PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
+                PSA_KEY_LIFETIME_PERSISTENT,
+                PSA_KEY_LIFETIME_GET_LOCATION(lifetime));
+    }
 }
 
 static inline psa_key_id_t psa_get_key_id(
@@ -143,7 +151,7 @@
                                         psa_key_lifetime_t lifetime)
 {
     attributes->lifetime = lifetime;
-    if( lifetime == PSA_KEY_LIFETIME_VOLATILE )
+    if(PSA_KEY_LIFETIME_IS_VOLATILE(lifetime))
     {
         attributes->id = 0;
     }
diff --git a/interface/include/psa/crypto_types.h b/interface/include/psa/crypto_types.h
index 540e49a..bf51a2f 100644
--- a/interface/include/psa/crypto_types.h
+++ b/interface/include/psa/crypto_types.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -49,10 +49,6 @@
  * @{
  */
 
-/* Integral type representing a key handle. */
-typedef uint16_t psa_key_handle_t;
-
-
 /** \brief Encoding of a key type.
  */
 typedef uint16_t psa_key_type_t;
@@ -328,7 +324,7 @@
  * -# Call a key creation function: psa_import_key(), psa_generate_key(),
  *    psa_key_derivation_output_key() or psa_copy_key(). This function reads
  *    the attribute structure, creates a key with these attributes, and
- *    outputs a handle to the newly created key.
+ *    outputs a key identifier to the newly created key.
  * -# The attribute structure is now no longer necessary.
  *    You may call psa_reset_key_attributes(), although this is optional
  *    with the workflow presented here because the attributes currently
diff --git a/interface/include/psa/crypto_values.h b/interface/include/psa/crypto_values.h
index 75e3050..9cca6b2 100644
--- a/interface/include/psa/crypto_values.h
+++ b/interface/include/psa/crypto_values.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -100,7 +100,7 @@
  * as applicable.
  *
  * Implementations shall not return this error code to indicate that a
- * key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
+ * key identifier is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
  * instead. */
 #define PSA_ERROR_BAD_STATE             ((psa_status_t)-137)
 
@@ -110,7 +110,7 @@
  * combination of parameters are recognized as invalid.
  *
  * Implementations shall not return this error code to indicate that a
- * key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
+ * key identifier is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
  * instead.
  */
 #define PSA_ERROR_INVALID_ARGUMENT      ((psa_status_t)-135)
@@ -258,7 +258,7 @@
  * to read from a resource. */
 #define PSA_ERROR_INSUFFICIENT_DATA     ((psa_status_t)-143)
 
-/** The key handle is not valid. See also :ref:\`key-handles\`.
+/** The key identifier is not valid. See also :ref:\`key-handles\`.
  */
 #define PSA_ERROR_INVALID_HANDLE        ((psa_status_t)-136)
 
@@ -601,14 +601,14 @@
 #define PSA_ALG_VENDOR_FLAG                     ((psa_algorithm_t)0x80000000)
 
 #define PSA_ALG_CATEGORY_MASK                   ((psa_algorithm_t)0x7f000000)
-#define PSA_ALG_CATEGORY_HASH                   ((psa_algorithm_t)0x01000000)
-#define PSA_ALG_CATEGORY_MAC                    ((psa_algorithm_t)0x02000000)
+#define PSA_ALG_CATEGORY_HASH                   ((psa_algorithm_t)0x02000000)
+#define PSA_ALG_CATEGORY_MAC                    ((psa_algorithm_t)0x03000000)
 #define PSA_ALG_CATEGORY_CIPHER                 ((psa_algorithm_t)0x04000000)
-#define PSA_ALG_CATEGORY_AEAD                   ((psa_algorithm_t)0x06000000)
-#define PSA_ALG_CATEGORY_SIGN                   ((psa_algorithm_t)0x10000000)
-#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION  ((psa_algorithm_t)0x12000000)
-#define PSA_ALG_CATEGORY_KEY_DERIVATION         ((psa_algorithm_t)0x20000000)
-#define PSA_ALG_CATEGORY_KEY_AGREEMENT          ((psa_algorithm_t)0x30000000)
+#define PSA_ALG_CATEGORY_AEAD                   ((psa_algorithm_t)0x05000000)
+#define PSA_ALG_CATEGORY_SIGN                   ((psa_algorithm_t)0x06000000)
+#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION  ((psa_algorithm_t)0x07000000)
+#define PSA_ALG_CATEGORY_KEY_DERIVATION         ((psa_algorithm_t)0x08000000)
+#define PSA_ALG_CATEGORY_KEY_AGREEMENT          ((psa_algorithm_t)0x09000000)
 
 /** Whether an algorithm is vendor-defined.
  *
@@ -710,35 +710,35 @@
 
 #define PSA_ALG_HASH_MASK                       ((psa_algorithm_t)0x000000ff)
 /** MD2 */
-#define PSA_ALG_MD2                             ((psa_algorithm_t)0x01000001)
+#define PSA_ALG_MD2                             ((psa_algorithm_t)0x02000001)
 /** MD4 */
-#define PSA_ALG_MD4                             ((psa_algorithm_t)0x01000002)
+#define PSA_ALG_MD4                             ((psa_algorithm_t)0x02000002)
 /** MD5 */
-#define PSA_ALG_MD5                             ((psa_algorithm_t)0x01000003)
+#define PSA_ALG_MD5                             ((psa_algorithm_t)0x02000003)
 /** PSA_ALG_RIPEMD160 */
-#define PSA_ALG_RIPEMD160                       ((psa_algorithm_t)0x01000004)
+#define PSA_ALG_RIPEMD160                       ((psa_algorithm_t)0x02000004)
 /** SHA1 */
-#define PSA_ALG_SHA_1                           ((psa_algorithm_t)0x01000005)
+#define PSA_ALG_SHA_1                           ((psa_algorithm_t)0x02000005)
 /** SHA2-224 */
-#define PSA_ALG_SHA_224                         ((psa_algorithm_t)0x01000008)
+#define PSA_ALG_SHA_224                         ((psa_algorithm_t)0x02000008)
 /** SHA2-256 */
-#define PSA_ALG_SHA_256                         ((psa_algorithm_t)0x01000009)
+#define PSA_ALG_SHA_256                         ((psa_algorithm_t)0x02000009)
 /** SHA2-384 */
-#define PSA_ALG_SHA_384                         ((psa_algorithm_t)0x0100000a)
+#define PSA_ALG_SHA_384                         ((psa_algorithm_t)0x0200000a)
 /** SHA2-512 */
-#define PSA_ALG_SHA_512                         ((psa_algorithm_t)0x0100000b)
+#define PSA_ALG_SHA_512                         ((psa_algorithm_t)0x0200000b)
 /** SHA2-512/224 */
-#define PSA_ALG_SHA_512_224                     ((psa_algorithm_t)0x0100000c)
+#define PSA_ALG_SHA_512_224                     ((psa_algorithm_t)0x0200000c)
 /** SHA2-512/256 */
-#define PSA_ALG_SHA_512_256                     ((psa_algorithm_t)0x0100000d)
+#define PSA_ALG_SHA_512_256                     ((psa_algorithm_t)0x0200000d)
 /** SHA3-224 */
-#define PSA_ALG_SHA3_224                        ((psa_algorithm_t)0x01000010)
+#define PSA_ALG_SHA3_224                        ((psa_algorithm_t)0x02000010)
 /** SHA3-256 */
-#define PSA_ALG_SHA3_256                        ((psa_algorithm_t)0x01000011)
+#define PSA_ALG_SHA3_256                        ((psa_algorithm_t)0x02000011)
 /** SHA3-384 */
-#define PSA_ALG_SHA3_384                        ((psa_algorithm_t)0x01000012)
+#define PSA_ALG_SHA3_384                        ((psa_algorithm_t)0x02000012)
 /** SHA3-512 */
-#define PSA_ALG_SHA3_512                        ((psa_algorithm_t)0x01000013)
+#define PSA_ALG_SHA3_512                        ((psa_algorithm_t)0x02000013)
 
 /** In a hash-and-sign algorithm policy, allow any hash algorithm.
  *
@@ -761,9 +761,9 @@
  *   an algorithm built from `PSA_xxx_SIGNATURE` and a specific hash. Each
  *   call to sign or verify a message may use a different hash.
  *   ```
- *   psa_sign_hash(handle, PSA_xxx_SIGNATURE(PSA_ALG_SHA_256), ...);
- *   psa_sign_hash(handle, PSA_xxx_SIGNATURE(PSA_ALG_SHA_512), ...);
- *   psa_sign_hash(handle, PSA_xxx_SIGNATURE(PSA_ALG_SHA3_256), ...);
+ *   psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA_256), ...);
+ *   psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA_512), ...);
+ *   psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA3_256), ...);
  *   ```
  *
  * This value may not be used to build other algorithms that are
@@ -773,10 +773,10 @@
  * This value may not be used to build an algorithm specification to
  * perform an operation. It is only valid to build policies.
  */
-#define PSA_ALG_ANY_HASH                        ((psa_algorithm_t)0x010000ff)
+#define PSA_ALG_ANY_HASH                        ((psa_algorithm_t)0x020000ff)
 
 #define PSA_ALG_MAC_SUBCATEGORY_MASK            ((psa_algorithm_t)0x00c00000)
-#define PSA_ALG_HMAC_BASE                       ((psa_algorithm_t)0x02800000)
+#define PSA_ALG_HMAC_BASE                       ((psa_algorithm_t)0x03800000)
 /** Macro to build an HMAC algorithm.
  *
  * For example, #PSA_ALG_HMAC(#PSA_ALG_SHA_256) is HMAC-SHA-256.
@@ -815,8 +815,8 @@
  * reach up to 63; the largest MAC is 64 bytes so its trivial truncation
  * to full length is correctly encoded as 0 and any non-trivial truncation
  * is correctly encoded as a value between 1 and 63. */
-#define PSA_ALG_MAC_TRUNCATION_MASK             ((psa_algorithm_t)0x00003f00)
-#define PSA_MAC_TRUNCATION_OFFSET 8
+#define PSA_ALG_MAC_TRUNCATION_MASK             ((psa_algorithm_t)0x003f0000)
+#define PSA_MAC_TRUNCATION_OFFSET 16
 
 /** Macro to build a truncated MAC algorithm.
  *
@@ -884,15 +884,15 @@
 #define PSA_MAC_TRUNCATED_LENGTH(mac_alg)                               \
     (((mac_alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET)
 
-#define PSA_ALG_CIPHER_MAC_BASE                 ((psa_algorithm_t)0x02c00000)
+#define PSA_ALG_CIPHER_MAC_BASE                 ((psa_algorithm_t)0x03c00000)
 /** The CBC-MAC construction over a block cipher
  *
  * \warning CBC-MAC is insecure in many cases.
  * A more secure mode, such as #PSA_ALG_CMAC, is recommended.
  */
-#define PSA_ALG_CBC_MAC                         ((psa_algorithm_t)0x02c00001)
+#define PSA_ALG_CBC_MAC                         ((psa_algorithm_t)0x03c00100)
 /** The CMAC construction over a block cipher */
-#define PSA_ALG_CMAC                            ((psa_algorithm_t)0x02c00002)
+#define PSA_ALG_CMAC                            ((psa_algorithm_t)0x03c00200)
 
 /** Whether the specified algorithm is a MAC algorithm based on a block cipher.
  *
@@ -925,21 +925,13 @@
     (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_CIPHER_STREAM_FLAG)) == \
         (PSA_ALG_CATEGORY_CIPHER | PSA_ALG_CIPHER_STREAM_FLAG))
 
-/** The ARC4 stream cipher algorithm.
+/** The stream cipher mode of a stream cipher algorithm.
+ *
+ * The underlying stream cipher is determined by the key type.
+ * - To use ChaCha20, use a key type of #PSA_KEY_TYPE_CHACHA20.
+ * - To use ARC4, use a key type of #PSA_KEY_TYPE_ARC4.
  */
-#define PSA_ALG_ARC4                            ((psa_algorithm_t)0x04800001)
-
-/** The ChaCha20 stream cipher.
- *
- * ChaCha20 is defined in RFC 7539.
- *
- * The nonce size for psa_cipher_set_iv() or psa_cipher_generate_iv()
- * must be 12.
- *
- * The initial block counter is always 0.
- *
- */
-#define PSA_ALG_CHACHA20                        ((psa_algorithm_t)0x04800005)
+#define PSA_ALG_STREAM_CIPHER                   ((psa_algorithm_t)0x04800100)
 
 /** The CTR stream cipher mode.
  *
@@ -948,19 +940,19 @@
  * For example, to use AES-128-CTR, use this algorithm with
  * a key of type #PSA_KEY_TYPE_AES and a length of 128 bits (16 bytes).
  */
-#define PSA_ALG_CTR                             ((psa_algorithm_t)0x04c00001)
+#define PSA_ALG_CTR                             ((psa_algorithm_t)0x04c01000)
 
 /** The CFB stream cipher mode.
  *
  * The underlying block cipher is determined by the key type.
  */
-#define PSA_ALG_CFB                             ((psa_algorithm_t)0x04c00002)
+#define PSA_ALG_CFB                             ((psa_algorithm_t)0x04c01100)
 
 /** The OFB stream cipher mode.
  *
  * The underlying block cipher is determined by the key type.
  */
-#define PSA_ALG_OFB                             ((psa_algorithm_t)0x04c00003)
+#define PSA_ALG_OFB                             ((psa_algorithm_t)0x04c01200)
 
 /** The XTS cipher mode.
  *
@@ -968,7 +960,27 @@
  * least one full block of input, but beyond this minimum the input
  * does not need to be a whole number of blocks.
  */
-#define PSA_ALG_XTS                             ((psa_algorithm_t)0x044000ff)
+#define PSA_ALG_XTS                             ((psa_algorithm_t)0x0440ff00)
+
+/** The Electronic Code Book (ECB) mode of a block cipher, with no padding.
+ *
+ * \warning ECB mode does not protect the confidentiality of the encrypted data
+ * except in extremely narrow circumstances. It is recommended that applications
+ * only use ECB if they need to construct an operating mode that the
+ * implementation does not provide. Implementations are encouraged to provide
+ * the modes that applications need in preference to supporting direct access
+ * to ECB.
+ *
+ * The underlying block cipher is determined by the key type.
+ *
+ * This symmetric cipher mode can only be used with messages whose lengths are a
+ * multiple of the block size of the chosen block cipher.
+ *
+ * ECB mode does not accept an initialization vector (IV). When using a
+ * multi-part cipher operation with this algorithm, psa_cipher_generate_iv()
+ * and psa_cipher_set_iv() must not be called.
+ */
+#define PSA_ALG_ECB_NO_PADDING                  ((psa_algorithm_t)0x04404400)
 
 /** The CBC block cipher chaining mode, with no padding.
  *
@@ -977,7 +989,7 @@
  * This symmetric cipher mode can only be used with messages whose lengths
  * are whole number of blocks for the chosen block cipher.
  */
-#define PSA_ALG_CBC_NO_PADDING                  ((psa_algorithm_t)0x04600100)
+#define PSA_ALG_CBC_NO_PADDING                  ((psa_algorithm_t)0x04404000)
 
 /** The CBC block cipher chaining mode with PKCS#7 padding.
  *
@@ -985,7 +997,7 @@
  *
  * This is the padding method defined by PKCS#7 (RFC 2315) &sect;10.3.
  */
-#define PSA_ALG_CBC_PKCS7                       ((psa_algorithm_t)0x04600101)
+#define PSA_ALG_CBC_PKCS7                       ((psa_algorithm_t)0x04404100)
 
 #define PSA_ALG_AEAD_FROM_BLOCK_FLAG            ((psa_algorithm_t)0x00400000)
 
@@ -1006,13 +1018,13 @@
  *
  * The underlying block cipher is determined by the key type.
  */
-#define PSA_ALG_CCM                             ((psa_algorithm_t)0x06401001)
+#define PSA_ALG_CCM                             ((psa_algorithm_t)0x05500100)
 
 /** The GCM authenticated encryption algorithm.
  *
  * The underlying block cipher is determined by the key type.
  */
-#define PSA_ALG_GCM                             ((psa_algorithm_t)0x06401002)
+#define PSA_ALG_GCM                             ((psa_algorithm_t)0x05500200)
 
 /** The Chacha20-Poly1305 AEAD algorithm.
  *
@@ -1023,14 +1035,14 @@
  *
  * Implementations must support 16-byte tags and should reject other sizes.
  */
-#define PSA_ALG_CHACHA20_POLY1305               ((psa_algorithm_t)0x06001005)
+#define PSA_ALG_CHACHA20_POLY1305               ((psa_algorithm_t)0x05100500)
 
 /* In the encoding of a AEAD algorithm, the bits corresponding to
  * PSA_ALG_AEAD_TAG_LENGTH_MASK encode the length of the AEAD tag.
  * The constants for default lengths follow this encoding.
  */
-#define PSA_ALG_AEAD_TAG_LENGTH_MASK            ((psa_algorithm_t)0x00003f00)
-#define PSA_AEAD_TAG_LENGTH_OFFSET 8
+#define PSA_ALG_AEAD_TAG_LENGTH_MASK            ((psa_algorithm_t)0x003f0000)
+#define PSA_AEAD_TAG_LENGTH_OFFSET 16
 
 /** Macro to build a shortened AEAD algorithm.
  *
@@ -1074,7 +1086,7 @@
     PSA_ALG_AEAD_WITH_TAG_LENGTH(ref, 0) ?                               \
     ref :
 
-#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE          ((psa_algorithm_t)0x10020000)
+#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE          ((psa_algorithm_t)0x06000200)
 /** RSA PKCS#1 v1.5 signature with hashing.
  *
  * This is the signature scheme defined by RFC 8017
@@ -1102,7 +1114,7 @@
 #define PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)                               \
     (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PKCS1V15_SIGN_BASE)
 
-#define PSA_ALG_RSA_PSS_BASE               ((psa_algorithm_t)0x10030000)
+#define PSA_ALG_RSA_PSS_BASE               ((psa_algorithm_t)0x06000300)
 /** RSA PSS signature with hashing.
  *
  * This is the signature scheme defined by RFC 8017
@@ -1126,7 +1138,7 @@
 #define PSA_ALG_IS_RSA_PSS(alg)                                 \
     (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE)
 
-#define PSA_ALG_ECDSA_BASE                      ((psa_algorithm_t)0x10060000)
+#define PSA_ALG_ECDSA_BASE                      ((psa_algorithm_t)0x06000600)
 /** ECDSA signature with hashing.
  *
  * This is the ECDSA signature scheme defined by ANSI X9.62,
@@ -1159,7 +1171,7 @@
  * the curve size.
  */
 #define PSA_ALG_ECDSA_ANY PSA_ALG_ECDSA_BASE
-#define PSA_ALG_DETERMINISTIC_ECDSA_BASE        ((psa_algorithm_t)0x10070000)
+#define PSA_ALG_DETERMINISTIC_ECDSA_BASE        ((psa_algorithm_t)0x06000700)
 /** Deterministic ECDSA signature with hashing.
  *
  * This is the deterministic ECDSA signature scheme defined by RFC 6979.
@@ -1184,7 +1196,7 @@
  */
 #define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg)                           \
     (PSA_ALG_DETERMINISTIC_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
-#define PSA_ALG_ECDSA_DETERMINISTIC_FLAG        ((psa_algorithm_t)0x00010000)
+#define PSA_ALG_ECDSA_DETERMINISTIC_FLAG        ((psa_algorithm_t)0x00000100)
 #define PSA_ALG_IS_ECDSA(alg)                                           \
     (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_ECDSA_DETERMINISTIC_FLAG) ==  \
      PSA_ALG_ECDSA_BASE)
@@ -1238,9 +1250,9 @@
 
 /** RSA PKCS#1 v1.5 encryption.
  */
-#define PSA_ALG_RSA_PKCS1V15_CRYPT              ((psa_algorithm_t)0x12020000)
+#define PSA_ALG_RSA_PKCS1V15_CRYPT              ((psa_algorithm_t)0x07000200)
 
-#define PSA_ALG_RSA_OAEP_BASE                   ((psa_algorithm_t)0x12030000)
+#define PSA_ALG_RSA_OAEP_BASE                   ((psa_algorithm_t)0x07000300)
 /** RSA OAEP encryption.
  *
  * This is the encryption scheme defined by RFC 8017
@@ -1264,7 +1276,7 @@
      ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH :      \
      0)
 
-#define PSA_ALG_HKDF_BASE                       ((psa_algorithm_t)0x20000100)
+#define PSA_ALG_HKDF_BASE                       ((psa_algorithm_t)0x08000100)
 /** Macro to build an HKDF algorithm.
  *
  * For example, `PSA_ALG_HKDF(PSA_ALG_SHA256)` is HKDF using HMAC-SHA-256.
@@ -1303,7 +1315,7 @@
 #define PSA_ALG_HKDF_GET_HASH(hkdf_alg)                         \
     (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
 
-#define PSA_ALG_TLS12_PRF_BASE                  ((psa_algorithm_t)0x20000200)
+#define PSA_ALG_TLS12_PRF_BASE                  ((psa_algorithm_t)0x08000200)
 /** Macro to build a TLS-1.2 PRF algorithm.
  *
  * TLS 1.2 uses a custom pseudorandom function (PRF) for key schedule,
@@ -1346,7 +1358,7 @@
 #define PSA_ALG_TLS12_PRF_GET_HASH(hkdf_alg)                         \
     (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
 
-#define PSA_ALG_TLS12_PSK_TO_MS_BASE            ((psa_algorithm_t)0x20000300)
+#define PSA_ALG_TLS12_PSK_TO_MS_BASE            ((psa_algorithm_t)0x08000300)
 /** Macro to build a TLS-1.2 PSK-to-MasterSecret algorithm.
  *
  * In a pure-PSK handshake in TLS 1.2, the master secret is derived
@@ -1392,8 +1404,8 @@
 #define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg)                         \
     (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
 
-#define PSA_ALG_KEY_DERIVATION_MASK             ((psa_algorithm_t)0x0803ffff)
-#define PSA_ALG_KEY_AGREEMENT_MASK              ((psa_algorithm_t)0x10fc0000)
+#define PSA_ALG_KEY_DERIVATION_MASK             ((psa_algorithm_t)0xfe00ffff)
+#define PSA_ALG_KEY_AGREEMENT_MASK              ((psa_algorithm_t)0xffff0000)
 
 /** Macro to build a combined algorithm that chains a key agreement with
  * a key derivation.
@@ -1424,7 +1436,7 @@
  * a key derivation function.
  * Usually, raw key agreement algorithms are constructed directly with
  * a \c PSA_ALG_xxx macro while non-raw key agreement algorithms are
- * constructed with PSA_ALG_KEY_AGREEMENT().
+ * constructed with #PSA_ALG_KEY_AGREEMENT().
  *
  * \param alg An algorithm identifier (value of type #psa_algorithm_t).
  *
@@ -1446,7 +1458,7 @@
  * It is `ceiling(m / 8)` bytes long where `m` is the size of the prime `p`
  * in bits.
  */
-#define PSA_ALG_FFDH                            ((psa_algorithm_t)0x30100000)
+#define PSA_ALG_FFDH                            ((psa_algorithm_t)0x09010000)
 
 /** Whether the specified algorithm is a finite field Diffie-Hellman algorithm.
  *
@@ -1488,7 +1500,7 @@
  *   in big-endian byte order.
  *   The bit size is `m` for the field `F_{2^m}`.
  */
-#define PSA_ALG_ECDH                            ((psa_algorithm_t)0x30200000)
+#define PSA_ALG_ECDH                            ((psa_algorithm_t)0x09020000)
 
 /** Whether the specified algorithm is an elliptic curve Diffie-Hellman
  * algorithm.
@@ -1533,7 +1545,7 @@
 
 /** The default lifetime for volatile keys.
  *
- * A volatile key only exists as long as the handle to it is not closed.
+ * A volatile key only exists as long as the identifier to it is not destroyed.
  * The key material is guaranteed to be erased on a power reset.
  *
  * A key with this lifetime is typically stored in the RAM area of the
@@ -1704,7 +1716,7 @@
  *
  * For a key pair, this concerns the private key.
  */
-#define PSA_KEY_USAGE_SIGN_HASH                 ((psa_key_usage_t)0x00000400)
+#define PSA_KEY_USAGE_SIGN_HASH                 ((psa_key_usage_t)0x00001000)
 
 /** Whether the key may be used to verify a message signature.
  *
@@ -1714,11 +1726,11 @@
  *
  * For a key pair, this concerns the public key.
  */
-#define PSA_KEY_USAGE_VERIFY_HASH               ((psa_key_usage_t)0x00000800)
+#define PSA_KEY_USAGE_VERIFY_HASH               ((psa_key_usage_t)0x00002000)
 
 /** Whether the key may be used to derive other keys.
  */
-#define PSA_KEY_USAGE_DERIVE                    ((psa_key_usage_t)0x00001000)
+#define PSA_KEY_USAGE_DERIVE                    ((psa_key_usage_t)0x00004000)
 
 /**@}*/
 
diff --git a/interface/include/tfm_crypto_defs.h b/interface/include/tfm_crypto_defs.h
index 53c03ce..b4c771f 100644
--- a/interface/include/tfm_crypto_defs.h
+++ b/interface/include/tfm_crypto_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -38,7 +38,7 @@
                                   *   request
                                   */
     uint16_t step;               /*!< Key derivation step */
-    psa_key_handle_t key_handle; /*!< Key handle */
+    psa_key_id_t key_id;         /*!< Key id */
     psa_algorithm_t alg;         /*!< Algorithm */
     uint32_t op_handle;          /*!< Frontend context handle associated to a
                                   *   multipart operation
@@ -64,6 +64,7 @@
     TFM_CRYPTO_DESTROY_KEY_SID,
     TFM_CRYPTO_EXPORT_KEY_SID,
     TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID,
+    TFM_CRYPTO_PURGE_KEY_SID,
     TFM_CRYPTO_COPY_KEY_SID,
     TFM_CRYPTO_HASH_COMPUTE_SID,
     TFM_CRYPTO_HASH_COMPARE_SID,
diff --git a/interface/src/tfm_crypto_func_api.c b/interface/src/tfm_crypto_func_api.c
index 6ddbb6b..dd6a90a 100644
--- a/interface/src/tfm_crypto_func_api.c
+++ b/interface/src/tfm_crypto_func_api.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -31,7 +31,7 @@
 }
 
 psa_status_t psa_open_key(psa_key_id_t id,
-                          psa_key_handle_t *handle)
+                          psa_key_id_t *key)
 {
     const struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_OPEN_KEY_SID,
@@ -41,18 +41,18 @@
         {.base = &id, .len = sizeof(psa_key_id_t)},
     };
     psa_outvec out_vec[] = {
-        {.base = handle, .len = sizeof(psa_key_handle_t)},
+        {.base = key, .len = sizeof(psa_key_id_t)},
     };
 
     return API_DISPATCH(tfm_crypto_open_key,
                         TFM_CRYPTO_OPEN_KEY);
 }
 
-psa_status_t psa_close_key(psa_key_handle_t handle)
+psa_status_t psa_close_key(psa_key_id_t key)
 {
     const struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_CLOSE_KEY_SID,
-        .key_handle = handle,
+        .key_id = key,
     };
     psa_invec in_vec[] = {
         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -65,7 +65,7 @@
 psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
                             const uint8_t *data,
                             size_t data_length,
-                            psa_key_handle_t *handle)
+                            psa_key_id_t *key)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
@@ -77,7 +77,7 @@
         {.base = data, .len = data_length}
     };
     psa_outvec out_vec[] = {
-        {.base = handle, .len = sizeof(psa_key_handle_t)}
+        {.base = key, .len = sizeof(psa_key_id_t)}
     };
 
     status = API_DISPATCH(tfm_crypto_import_key,
@@ -86,12 +86,12 @@
     return status;
 }
 
-psa_status_t psa_destroy_key(psa_key_handle_t handle)
+psa_status_t psa_destroy_key(psa_key_id_t key)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_DESTROY_KEY_SID,
-        .key_handle = handle,
+        .key_id = key,
     };
     psa_invec in_vec[] = {
         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -103,13 +103,13 @@
     return status;
 }
 
-psa_status_t psa_get_key_attributes(psa_key_handle_t handle,
+psa_status_t psa_get_key_attributes(psa_key_id_t key,
                                     psa_key_attributes_t *attributes)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID,
-        .key_handle = handle,
+        .key_id = key,
     };
     psa_invec in_vec[] = {
         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -140,7 +140,7 @@
     return;
 }
 
-psa_status_t psa_export_key(psa_key_handle_t handle,
+psa_status_t psa_export_key(psa_key_id_t key,
                             uint8_t *data,
                             size_t data_size,
                             size_t *data_length)
@@ -148,7 +148,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_EXPORT_KEY_SID,
-        .key_handle = handle,
+        .key_id = key,
     };
     psa_invec in_vec[] = {
         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -165,7 +165,7 @@
     return status;
 }
 
-psa_status_t psa_export_public_key(psa_key_handle_t handle,
+psa_status_t psa_export_public_key(psa_key_id_t key,
                                    uint8_t *data,
                                    size_t data_size,
                                    size_t *data_length)
@@ -173,7 +173,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID,
-        .key_handle = handle,
+        .key_id = key,
     };
 
     psa_invec in_vec[] = {
@@ -191,14 +191,30 @@
     return status;
 }
 
-psa_status_t psa_copy_key(psa_key_handle_t source_handle,
+psa_status_t psa_purge_key(psa_key_id_t key)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_PURGE_KEY_SID,
+        .key_id = key,
+    };
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_purge_key,
+                                    TFM_CRYPTO_PURGE_KEY);
+    return status;
+}
+
+psa_status_t psa_copy_key(psa_key_id_t source_key,
                           const psa_key_attributes_t *attributes,
-                          psa_key_handle_t *target_handle)
+                          psa_key_id_t *target_key)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_COPY_KEY_SID,
-        .key_handle = source_handle,
+        .key_id = source_key,
     };
 
     psa_invec in_vec[] = {
@@ -207,7 +223,7 @@
     };
 
     psa_outvec out_vec[] = {
-        {.base = target_handle, .len = sizeof(psa_key_handle_t)},
+        {.base = target_key, .len = sizeof(psa_key_id_t)},
     };
 
     status = API_DISPATCH(tfm_crypto_copy_key,
@@ -268,13 +284,13 @@
 }
 
 psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
-                                      psa_key_handle_t handle,
+                                      psa_key_id_t key,
                                       psa_algorithm_t alg)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
         .op_handle = operation->handle,
     };
@@ -293,13 +309,13 @@
 }
 
 psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
-                                      psa_key_handle_t handle,
+                                      psa_key_id_t key,
                                       psa_algorithm_t alg)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
         .op_handle = operation->handle,
     };
@@ -595,13 +611,13 @@
 }
 
 psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
-                                psa_key_handle_t handle,
+                                psa_key_id_t key,
                                 psa_algorithm_t alg)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_MAC_SIGN_SETUP_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
         .op_handle = operation->handle,
     };
@@ -620,13 +636,13 @@
 }
 
 psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation,
-                                  psa_key_handle_t handle,
+                                  psa_key_id_t key,
                                   psa_algorithm_t alg)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_MAC_VERIFY_SETUP_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
         .op_handle = operation->handle,
     };
@@ -740,7 +756,7 @@
     return status;
 }
 
-psa_status_t psa_aead_encrypt(psa_key_handle_t handle,
+psa_status_t psa_aead_encrypt(psa_key_id_t key,
                               psa_algorithm_t alg,
                               const uint8_t *nonce,
                               size_t nonce_length,
@@ -755,7 +771,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_AEAD_ENCRYPT_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
         .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
     };
@@ -793,7 +809,7 @@
     return status;
 }
 
-psa_status_t psa_aead_decrypt(psa_key_handle_t handle,
+psa_status_t psa_aead_decrypt(psa_key_id_t key,
                               psa_algorithm_t alg,
                               const uint8_t *nonce,
                               size_t nonce_length,
@@ -808,7 +824,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_AEAD_DECRYPT_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
         .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
     };
@@ -846,7 +862,7 @@
     return status;
 }
 
-psa_status_t psa_asymmetric_sign(psa_key_handle_t handle,
+psa_status_t psa_asymmetric_sign(psa_key_id_t key,
                                  psa_algorithm_t alg,
                                  const uint8_t *hash,
                                  size_t hash_length,
@@ -854,11 +870,11 @@
                                  size_t signature_size,
                                  size_t *signature_length)
 {
-    return psa_sign_hash(handle, alg, hash, hash_length, signature,
+    return psa_sign_hash(key, alg, hash, hash_length, signature,
                          signature_size, signature_length);
 }
 
-psa_status_t psa_sign_hash(psa_key_handle_t handle,
+psa_status_t psa_sign_hash(psa_key_id_t key,
                            psa_algorithm_t alg,
                            const uint8_t *hash,
                            size_t hash_length,
@@ -869,7 +885,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_SIGN_HASH_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
     };
 
@@ -889,18 +905,18 @@
     return status;
 }
 
-psa_status_t psa_asymmetric_verify(psa_key_handle_t handle,
+psa_status_t psa_asymmetric_verify(psa_key_id_t key,
                                    psa_algorithm_t alg,
                                    const uint8_t *hash,
                                    size_t hash_length,
                                    const uint8_t *signature,
                                    size_t signature_length)
 {
-    return psa_verify_hash(handle, alg, hash, hash_length,
+    return psa_verify_hash(key, alg, hash, hash_length,
                            signature, signature_length);
 }
 
-psa_status_t psa_verify_hash(psa_key_handle_t handle,
+psa_status_t psa_verify_hash(psa_key_id_t key,
                              psa_algorithm_t alg,
                              const uint8_t *hash,
                              size_t hash_length,
@@ -910,7 +926,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_VERIFY_HASH_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg
     };
 
@@ -926,7 +942,7 @@
     return status;
 }
 
-psa_status_t psa_asymmetric_encrypt(psa_key_handle_t handle,
+psa_status_t psa_asymmetric_encrypt(psa_key_id_t key,
                                     psa_algorithm_t alg,
                                     const uint8_t *input,
                                     size_t input_length,
@@ -939,7 +955,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg
     };
 
@@ -966,7 +982,7 @@
     return status;
 }
 
-psa_status_t psa_asymmetric_decrypt(psa_key_handle_t handle,
+psa_status_t psa_asymmetric_decrypt(psa_key_id_t key,
                                     psa_algorithm_t alg,
                                     const uint8_t *input,
                                     size_t input_length,
@@ -979,7 +995,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_ASYMMETRIC_DECRYPT_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg
     };
 
@@ -1058,12 +1074,12 @@
 psa_status_t psa_key_derivation_input_key(
                                       psa_key_derivation_operation_t *operation,
                                       psa_key_derivation_step_t step,
-                                      psa_key_handle_t handle)
+                                      psa_key_id_t key)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_KEY_SID,
-        .key_handle = handle,
+        .key_id = key,
         .step = step,
         .op_handle = operation->handle,
     };
@@ -1103,14 +1119,14 @@
 psa_status_t psa_key_derivation_key_agreement(
                                       psa_key_derivation_operation_t *operation,
                                       psa_key_derivation_step_t step,
-                                      psa_key_handle_t private_key,
+                                      psa_key_id_t private_key,
                                       const uint8_t *peer_key,
                                       size_t peer_key_length)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT_SID,
-        .key_handle = private_key,
+        .key_id = private_key,
         .step = step,
         .op_handle = operation->handle,
     };
@@ -1153,7 +1169,7 @@
 }
 
 psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
-                              psa_key_handle_t *handle)
+                              psa_key_id_t *key)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
@@ -1166,7 +1182,7 @@
     };
 
     psa_outvec out_vec[] = {
-        {.base = handle, .len = sizeof(psa_key_handle_t)},
+        {.base = key, .len = sizeof(psa_key_id_t)},
     };
 
     status = API_DISPATCH(tfm_crypto_generate_key,
@@ -1249,7 +1265,7 @@
     return status;
 }
 
-psa_status_t psa_mac_compute(psa_key_handle_t handle,
+psa_status_t psa_mac_compute(psa_key_id_t key,
                              psa_algorithm_t alg,
                              const uint8_t *input,
                              size_t input_length,
@@ -1264,7 +1280,7 @@
     return status;
 }
 
-psa_status_t psa_mac_verify(psa_key_handle_t handle,
+psa_status_t psa_mac_verify(psa_key_id_t key,
                             psa_algorithm_t alg,
                             const uint8_t *input,
                             size_t input_length,
@@ -1278,7 +1294,7 @@
     return status;
 }
 
-psa_status_t psa_cipher_encrypt(psa_key_handle_t handle,
+psa_status_t psa_cipher_encrypt(psa_key_id_t key,
                                 psa_algorithm_t alg,
                                 const uint8_t *input,
                                 size_t input_length,
@@ -1293,7 +1309,7 @@
     return status;
 }
 
-psa_status_t psa_cipher_decrypt(psa_key_handle_t handle,
+psa_status_t psa_cipher_decrypt(psa_key_id_t key,
                                 psa_algorithm_t alg,
                                 const uint8_t *input,
                                 size_t input_length,
@@ -1309,7 +1325,7 @@
 }
 
 psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
-                                   psa_key_handle_t private_key,
+                                   psa_key_id_t private_key,
                                    const uint8_t *peer_key,
                                    size_t peer_key_length,
                                    uint8_t *output,
@@ -1320,7 +1336,7 @@
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_RAW_KEY_AGREEMENT_SID,
         .alg = alg,
-        .key_handle = private_key
+        .key_id = private_key
     };
 
     psa_invec in_vec[] = {
@@ -1408,7 +1424,7 @@
 psa_status_t psa_key_derivation_output_key(
                                       const psa_key_attributes_t *attributes,
                                       psa_key_derivation_operation_t *operation,
-                                      psa_key_handle_t *handle)
+                                      psa_key_id_t *key)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
@@ -1422,7 +1438,7 @@
     };
 
     psa_outvec out_vec[] = {
-        {.base = handle, .len = sizeof(psa_key_handle_t)}
+        {.base = key, .len = sizeof(psa_key_id_t)}
     };
 
     status = API_DISPATCH(tfm_crypto_key_derivation_output_key,
@@ -1431,7 +1447,7 @@
 }
 
 psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
-                                    psa_key_handle_t handle,
+                                    psa_key_id_t key,
                                     psa_algorithm_t alg)
 {
     psa_status_t status;
@@ -1442,7 +1458,7 @@
 }
 
 psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
-                                    psa_key_handle_t handle,
+                                    psa_key_id_t key,
                                     psa_algorithm_t alg)
 {
     psa_status_t status;
diff --git a/interface/src/tfm_crypto_ipc_api.c b/interface/src/tfm_crypto_ipc_api.c
index 166e051..a89dd2b 100644
--- a/interface/src/tfm_crypto_ipc_api.c
+++ b/interface/src/tfm_crypto_ipc_api.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -41,7 +41,7 @@
 }
 
 psa_status_t psa_open_key(psa_key_id_t id,
-                          psa_key_handle_t *handle)
+                          psa_key_id_t *key)
 {
     psa_status_t status;
     const struct tfm_crypto_pack_iovec iov = {
@@ -52,7 +52,7 @@
         {.base = &id, .len = sizeof(psa_key_id_t)},
     };
     psa_outvec out_vec[] = {
-        {.base = handle, .len = sizeof(psa_key_handle_t)},
+        {.base = key, .len = sizeof(psa_key_id_t)},
     };
 
     PSA_CONNECT(TFM_CRYPTO);
@@ -65,12 +65,12 @@
     return status;
 }
 
-psa_status_t psa_close_key(psa_key_handle_t handle)
+psa_status_t psa_close_key(psa_key_id_t key)
 {
     psa_status_t status;
     const struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_CLOSE_KEY_SID,
-        .key_handle = handle,
+        .key_id = key,
     };
     psa_invec in_vec[] = {
         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -89,7 +89,7 @@
 psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
                             const uint8_t *data,
                             size_t data_length,
-                            psa_key_handle_t *handle)
+                            psa_key_id_t *key)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
@@ -101,7 +101,7 @@
         {.base = data, .len = data_length}
     };
     psa_outvec out_vec[] = {
-        {.base = handle, .len = sizeof(psa_key_handle_t)}
+        {.base = key, .len = sizeof(psa_key_id_t)}
     };
 
     PSA_CONNECT(TFM_CRYPTO);
@@ -113,12 +113,12 @@
     return status;
 }
 
-psa_status_t psa_destroy_key(psa_key_handle_t handle)
+psa_status_t psa_destroy_key(psa_key_id_t key)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_DESTROY_KEY_SID,
-        .key_handle = handle,
+        .key_id = key,
     };
     psa_invec in_vec[] = {
         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -133,13 +133,13 @@
     return status;
 }
 
-psa_status_t psa_get_key_attributes(psa_key_handle_t handle,
+psa_status_t psa_get_key_attributes(psa_key_id_t key,
                                     psa_key_attributes_t *attributes)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID,
-        .key_handle = handle,
+        .key_id = key,
     };
     psa_invec in_vec[] = {
         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -182,7 +182,7 @@
     return;
 }
 
-psa_status_t psa_export_key(psa_key_handle_t handle,
+psa_status_t psa_export_key(psa_key_id_t key,
                             uint8_t *data,
                             size_t data_size,
                             size_t *data_length)
@@ -190,7 +190,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_EXPORT_KEY_SID,
-        .key_handle = handle,
+        .key_id = key,
     };
     psa_invec in_vec[] = {
         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -211,7 +211,7 @@
     return status;
 }
 
-psa_status_t psa_export_public_key(psa_key_handle_t handle,
+psa_status_t psa_export_public_key(psa_key_id_t key,
                                    uint8_t *data,
                                    size_t data_size,
                                    size_t *data_length)
@@ -219,7 +219,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID,
-        .key_handle = handle,
+        .key_id = key,
     };
 
     psa_invec in_vec[] = {
@@ -241,14 +241,35 @@
     return status;
 }
 
-psa_status_t psa_copy_key(psa_key_handle_t source_handle,
+psa_status_t psa_purge_key(psa_key_id_t key)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_PURGE_KEY_SID,
+        .key_id = key,
+    };
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+
+    PSA_CONNECT(TFM_CRYPTO);
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_purge_key,
+                                    TFM_CRYPTO_PURGE_KEY);
+
+    PSA_CLOSE();
+
+    return status;
+}
+
+psa_status_t psa_copy_key(psa_key_id_t source_key,
                           const psa_key_attributes_t *attributes,
-                          psa_key_handle_t *target_handle)
+                          psa_key_id_t *target_key)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_COPY_KEY_SID,
-        .key_handle = source_handle,
+        .key_id = source_key,
     };
 
     psa_invec in_vec[] = {
@@ -258,7 +279,7 @@
     };
 
     psa_outvec out_vec[] = {
-        {.base = target_handle, .len = sizeof(psa_key_handle_t)},
+        {.base = target_key, .len = sizeof(psa_key_id_t)},
     };
 
     PSA_CONNECT(TFM_CRYPTO);
@@ -331,13 +352,13 @@
 }
 
 psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
-                                      psa_key_handle_t handle,
+                                      psa_key_id_t key,
                                       psa_algorithm_t alg)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
         .op_handle = operation->handle,
     };
@@ -360,13 +381,13 @@
 }
 
 psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
-                                      psa_key_handle_t handle,
+                                      psa_key_id_t key,
                                       psa_algorithm_t alg)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
         .op_handle = operation->handle,
     };
@@ -710,13 +731,13 @@
 }
 
 psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
-                                psa_key_handle_t handle,
+                                psa_key_id_t key,
                                 psa_algorithm_t alg)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_MAC_SIGN_SETUP_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
         .op_handle = operation->handle,
     };
@@ -739,13 +760,13 @@
 }
 
 psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation,
-                                  psa_key_handle_t handle,
+                                  psa_key_id_t key,
                                   psa_algorithm_t alg)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_MAC_VERIFY_SETUP_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
         .op_handle = operation->handle,
     };
@@ -879,7 +900,7 @@
     return status;
 }
 
-psa_status_t psa_aead_encrypt(psa_key_handle_t handle,
+psa_status_t psa_aead_encrypt(psa_key_id_t key,
                               psa_algorithm_t alg,
                               const uint8_t *nonce,
                               size_t nonce_length,
@@ -894,7 +915,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_AEAD_ENCRYPT_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
         .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
     };
@@ -940,7 +961,7 @@
     return status;
 }
 
-psa_status_t psa_aead_decrypt(psa_key_handle_t handle,
+psa_status_t psa_aead_decrypt(psa_key_id_t key,
                               psa_algorithm_t alg,
                               const uint8_t *nonce,
                               size_t nonce_length,
@@ -955,7 +976,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_AEAD_DECRYPT_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
         .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
     };
@@ -1001,7 +1022,7 @@
     return status;
 }
 
-psa_status_t psa_asymmetric_sign(psa_key_handle_t handle,
+psa_status_t psa_asymmetric_sign(psa_key_id_t key,
                                  psa_algorithm_t alg,
                                  const uint8_t *hash,
                                  size_t hash_length,
@@ -1009,10 +1030,10 @@
                                  size_t signature_size,
                                  size_t *signature_length)
 {
-    return psa_sign_hash(handle, alg, hash, hash_length, signature, signature_size, signature_length);
+    return psa_sign_hash(key, alg, hash, hash_length, signature, signature_size, signature_length);
 }
 
-psa_status_t psa_sign_hash(psa_key_handle_t handle,
+psa_status_t psa_sign_hash(psa_key_id_t key,
                            psa_algorithm_t alg,
                            const uint8_t *hash,
                            size_t hash_length,
@@ -1023,7 +1044,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_SIGN_HASH_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg,
     };
 
@@ -1047,17 +1068,17 @@
     return status;
 }
 
-psa_status_t psa_asymmetric_verify(psa_key_handle_t handle,
+psa_status_t psa_asymmetric_verify(psa_key_id_t key,
                                    psa_algorithm_t alg,
                                    const uint8_t *hash,
                                    size_t hash_length,
                                    const uint8_t *signature,
                                    size_t signature_length)
 {
-    return psa_verify_hash(handle, alg, hash, hash_length, signature, signature_length);
+    return psa_verify_hash(key, alg, hash, hash_length, signature, signature_length);
 }
 
-psa_status_t psa_verify_hash(psa_key_handle_t handle,
+psa_status_t psa_verify_hash(psa_key_id_t key,
                              psa_algorithm_t alg,
                              const uint8_t *hash,
                              size_t hash_length,
@@ -1067,7 +1088,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_VERIFY_HASH_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg
     };
 
@@ -1087,7 +1108,7 @@
     return status;
 }
 
-psa_status_t psa_asymmetric_encrypt(psa_key_handle_t handle,
+psa_status_t psa_asymmetric_encrypt(psa_key_id_t key,
                                     psa_algorithm_t alg,
                                     const uint8_t *input,
                                     size_t input_length,
@@ -1100,7 +1121,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg
     };
 
@@ -1135,7 +1156,7 @@
     return status;
 }
 
-psa_status_t psa_asymmetric_decrypt(psa_key_handle_t handle,
+psa_status_t psa_asymmetric_decrypt(psa_key_id_t key,
                                     psa_algorithm_t alg,
                                     const uint8_t *input,
                                     size_t input_length,
@@ -1148,7 +1169,7 @@
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_ASYMMETRIC_DECRYPT_SID,
-        .key_handle = handle,
+        .key_id = key,
         .alg = alg
     };
 
@@ -1243,12 +1264,12 @@
 psa_status_t psa_key_derivation_input_key(
                                       psa_key_derivation_operation_t *operation,
                                       psa_key_derivation_step_t step,
-                                      psa_key_handle_t handle)
+                                      psa_key_id_t key)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_KEY_SID,
-        .key_handle = handle,
+        .key_id = key,
         .step = step,
         .op_handle = operation->handle,
     };
@@ -1297,14 +1318,14 @@
 psa_status_t psa_key_derivation_key_agreement(
                                       psa_key_derivation_operation_t *operation,
                                       psa_key_derivation_step_t step,
-                                      psa_key_handle_t private_key,
+                                      psa_key_id_t private_key,
                                       const uint8_t *peer_key,
                                       size_t peer_key_length)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT_SID,
-        .key_handle = private_key,
+        .key_id = private_key,
         .step = step,
         .op_handle = operation->handle,
     };
@@ -1355,7 +1376,7 @@
 }
 
 psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
-                              psa_key_handle_t *handle)
+                              psa_key_id_t *key)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
@@ -1368,7 +1389,7 @@
     };
 
     psa_outvec out_vec[] = {
-        {.base = handle, .len = sizeof(psa_key_handle_t)},
+        {.base = key, .len = sizeof(psa_key_id_t)},
     };
 
     PSA_CONNECT(TFM_CRYPTO);
@@ -1454,7 +1475,7 @@
     return status;
 }
 
-psa_status_t psa_mac_compute(psa_key_handle_t handle,
+psa_status_t psa_mac_compute(psa_key_id_t key,
                              psa_algorithm_t alg,
                              const uint8_t *input,
                              size_t input_length,
@@ -1469,7 +1490,7 @@
     return status;
 }
 
-psa_status_t psa_mac_verify(psa_key_handle_t handle,
+psa_status_t psa_mac_verify(psa_key_id_t key,
                             psa_algorithm_t alg,
                             const uint8_t *input,
                             size_t input_length,
@@ -1483,7 +1504,7 @@
     return status;
 }
 
-psa_status_t psa_cipher_encrypt(psa_key_handle_t handle,
+psa_status_t psa_cipher_encrypt(psa_key_id_t key,
                                 psa_algorithm_t alg,
                                 const uint8_t *input,
                                 size_t input_length,
@@ -1498,7 +1519,7 @@
     return status;
 }
 
-psa_status_t psa_cipher_decrypt(psa_key_handle_t handle,
+psa_status_t psa_cipher_decrypt(psa_key_id_t key,
                                 psa_algorithm_t alg,
                                 const uint8_t *input,
                                 size_t input_length,
@@ -1514,7 +1535,7 @@
 }
 
 psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
-                                   psa_key_handle_t private_key,
+                                   psa_key_id_t private_key,
                                    const uint8_t *peer_key,
                                    size_t peer_key_length,
                                    uint8_t *output,
@@ -1525,7 +1546,7 @@
     struct tfm_crypto_pack_iovec iov = {
         .sfn_id = TFM_CRYPTO_RAW_KEY_AGREEMENT_SID,
         .alg = alg,
-        .key_handle = private_key
+        .key_id = private_key
     };
 
     psa_invec in_vec[] = {
@@ -1629,7 +1650,7 @@
 psa_status_t psa_key_derivation_output_key(
                                       const psa_key_attributes_t *attributes,
                                       psa_key_derivation_operation_t *operation,
-                                      psa_key_handle_t *handle)
+                                      psa_key_id_t *key)
 {
     psa_status_t status;
     struct tfm_crypto_pack_iovec iov = {
@@ -1643,7 +1664,7 @@
     };
 
     psa_outvec out_vec[] = {
-        {.base = handle, .len = sizeof(psa_key_handle_t)}
+        {.base = key, .len = sizeof(psa_key_id_t)}
     };
 
     PSA_CONNECT(TFM_CRYPTO);
@@ -1656,7 +1677,7 @@
 }
 
 psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
-                                    psa_key_handle_t handle,
+                                    psa_key_id_t key,
                                     psa_algorithm_t alg)
 {
     psa_status_t status;
@@ -1667,7 +1688,7 @@
 }
 
 psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
-                                    psa_key_handle_t handle,
+                                    psa_key_id_t key,
                                     psa_algorithm_t alg)
 {
     psa_status_t status;