Crypto: Add support for key APIs for HUK

Adds support for the psa_open_key and psa_close_key APIs only when the
key identifier corresponds to the HUK. Also makes it possible to derive
another key from the HUK by calling the PSA key derivation functions
with the HUK key handle as the input key.

Change-Id: I6992daaca76b87412b334a852383b2221a5181a9
Signed-off-by: Jamie Fox <jamie.fox@arm.com>
diff --git a/interface/include/tfm_crypto_defs.h b/interface/include/tfm_crypto_defs.h
index 91af175..5a380c6 100644
--- a/interface/include/tfm_crypto_defs.h
+++ b/interface/include/tfm_crypto_defs.h
@@ -59,6 +59,8 @@
  */
 enum {
     TFM_CRYPTO_ALLOCATE_KEY_SID = (0u),
+    TFM_CRYPTO_OPEN_KEY_SID,
+    TFM_CRYPTO_CLOSE_KEY_SID,
     TFM_CRYPTO_IMPORT_KEY_SID,
     TFM_CRYPTO_DESTROY_KEY_SID,
     TFM_CRYPTO_GET_KEY_INFORMATION_SID,
@@ -117,6 +119,19 @@
 #define TFM_CRYPTO_INVALID_HANDLE (0x0u)
 
 /**
+ * \brief The persistent key identifier that refers to the hardware unique key.
+ *
+ */
+#define TFM_CRYPTO_KEY_ID_HUK (0xFFFF815Bu)
+
+/**
+ * \brief The algorithm identifier that refers to key derivation from the
+ *        hardware unique key.
+ *
+ */
+#define TFM_CRYPTO_ALG_HUK_DERIVATION ((psa_algorithm_t)0xB0000F00)
+
+/**
  * \brief Define miscellaneous literal constants that are used in the service
  *
  */
diff --git a/interface/include/tfm_veneers.h b/interface/include/tfm_veneers.h
index 23b4f8d..5b0e2bf 100644
--- a/interface/include/tfm_veneers.h
+++ b/interface/include/tfm_veneers.h
@@ -40,6 +40,8 @@
 
 /******** TFM_SP_CRYPTO ********/
 psa_status_t tfm_tfm_crypto_allocate_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_open_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_close_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_import_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_destroy_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_get_key_information_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
diff --git a/interface/src/tfm_crypto_func_api.c b/interface/src/tfm_crypto_func_api.c
index 176c192..87c1a64 100644
--- a/interface/src/tfm_crypto_func_api.c
+++ b/interface/src/tfm_crypto_func_api.c
@@ -53,12 +53,20 @@
                           psa_key_id_t id,
                           psa_key_handle_t *handle)
 {
-    (void)lifetime;
-    (void)id;
-    (void)handle;
+    const struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_OPEN_KEY_SID,
+        .lifetime = lifetime,
+    };
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = &id, .len = sizeof(psa_key_id_t)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = handle, .len = sizeof(psa_key_handle_t)},
+    };
 
-    /* TODO: Persistent key APIs are not supported yet */
-    return PSA_ERROR_NOT_SUPPORTED;
+    return API_DISPATCH(tfm_crypto_open_key,
+                        TFM_CRYPTO_OPEN_KEY);
 }
 
 psa_status_t psa_create_key(psa_key_lifetime_t lifetime,
@@ -75,10 +83,16 @@
 
 psa_status_t psa_close_key(psa_key_handle_t handle)
 {
-    (void)handle;
+    const struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CLOSE_KEY_SID,
+        .key_handle = handle,
+    };
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
 
-    /* TODO: Persistent key APIs are not supported yet */
-    return PSA_ERROR_NOT_SUPPORTED;
+    return API_DISPATCH_NO_OUTVEC(tfm_crypto_close_key,
+                                  TFM_CRYPTO_CLOSE_KEY);
 }
 
 psa_status_t psa_import_key(psa_key_handle_t handle,
diff --git a/interface/src/tfm_crypto_ipc_api.c b/interface/src/tfm_crypto_ipc_api.c
index cf6152c..21f7816 100644
--- a/interface/src/tfm_crypto_ipc_api.c
+++ b/interface/src/tfm_crypto_ipc_api.c
@@ -75,12 +75,27 @@
 #if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
     return PSA_ERROR_NOT_SUPPORTED;
 #else
-    (void)lifetime;
-    (void)id;
-    (void)handle;
+    psa_status_t status;
+    const struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_OPEN_KEY_SID,
+        .lifetime = lifetime,
+    };
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = &id, .len = sizeof(psa_key_id_t)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = handle, .len = sizeof(psa_key_handle_t)},
+    };
 
-    /* TODO: Persistent key APIs are not supported yet */
-    return PSA_ERROR_NOT_SUPPORTED;
+    PSA_CONNECT(TFM_CRYPTO);
+
+    status = API_DISPATCH(tfm_crypto_open_key,
+                          TFM_CRYPTO_OPEN_KEY);
+
+    PSA_CLOSE();
+
+    return status;
 #endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
 }
 
@@ -105,10 +120,23 @@
 #if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
     return PSA_ERROR_NOT_SUPPORTED;
 #else
-    (void)handle;
+    psa_status_t status;
+    const struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CLOSE_KEY_SID,
+        .key_handle = handle,
+    };
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
 
-    /* TODO: Persistent key APIs are not supported yet */
-    return PSA_ERROR_NOT_SUPPORTED;
+    PSA_CONNECT(TFM_CRYPTO);
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_close_key,
+                                    TFM_CRYPTO_CLOSE_KEY);;
+
+    PSA_CLOSE();
+
+    return status;
 #endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
 }