Crypto: Add IPC compatibility

This patch introduces compatibility in the Crypto
service with the IPC infrastructure of TF-M.

Change-Id: I5a095780e1f2bd489c83cfbca138ca6dd0bfe9ba
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
diff --git a/interface/src/tfm_crypto_api.c b/interface/src/tfm_crypto_api.c
index 3b70d49..19dc6f4 100644
--- a/interface/src/tfm_crypto_api.c
+++ b/interface/src/tfm_crypto_api.c
@@ -10,24 +10,44 @@
 #include "psa_crypto.h"
 #include "tfm_ns_lock.h"
 
-#define NS_LOCK_DISPATCH(sfn_name)                                   \
-    tfm_ns_lock_dispatch((veneer_fn)tfm_##sfn_name##_veneer,         \
-        (uint32_t)in_vec, sizeof(in_vec)/sizeof(in_vec[0]),          \
-        (uint32_t)out_vec, sizeof(out_vec)/sizeof(out_vec[0]))
+#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
 
-#define NS_LOCK_DISPATCH_NO_INVEC(sfn_name)                          \
-    tfm_ns_lock_dispatch((veneer_fn)tfm_##sfn_name##_veneer,         \
-        (uint32_t)NULL, 0,                                           \
-        (uint32_t)out_vec, sizeof(out_vec)/sizeof(out_vec[0]))
+#ifdef TFM_PSA_API
+#include "psa_client.h"
 
-#define NS_LOCK_DISPATCH_NO_OUTVEC(sfn_name)                         \
-    tfm_ns_lock_dispatch((veneer_fn)tfm_##sfn_name##_veneer,         \
-        (uint32_t)in_vec, sizeof(in_vec)/sizeof(in_vec[0]),          \
+/* Macro to check for a valid PSA handle */
+/* FixMe: Here temporarily until it's added to the framework headers */
+#define PSA_IS_HANDLE_VALID(handle) ((handle) > (psa_handle_t)0)
+
+#define PSA_CONNECT(service)                                \
+    psa_handle_t handle;                                    \
+    handle = psa_connect(service##_SID, service##_MIN_VER); \
+    if (!PSA_IS_HANDLE_VALID(handle)) {                     \
+        return PSA_ERROR_UNKNOWN_ERROR;                     \
+    }                                                       \
+
+#define PSA_CLOSE() psa_close(handle)
+
+#define API_DISPATCH(sfn_name, sfn_id)                     \
+    psa_call(handle, /*PSA_IPC_CALL,*/                     \
+        in_vec, ARRAY_SIZE(in_vec),                        \
+        out_vec, ARRAY_SIZE(out_vec))
+
+#define API_DISPATCH_NO_OUTVEC(sfn_name, sfn_id)           \
+    psa_call(handle, /*PSA_IPC_CALL,*/                     \
+        in_vec, ARRAY_SIZE(in_vec),                        \
+        (psa_outvec *)NULL, 0)
+#else
+#define API_DISPATCH(sfn_name, sfn_id)                         \
+    tfm_ns_lock_dispatch((veneer_fn)tfm_##sfn_name##_veneer,   \
+        (uint32_t)in_vec, ARRAY_SIZE(in_vec),                  \
+        (uint32_t)out_vec, ARRAY_SIZE(out_vec))
+
+#define API_DISPATCH_NO_OUTVEC(sfn_name, sfn_id)               \
+    tfm_ns_lock_dispatch((veneer_fn)tfm_##sfn_name##_veneer,   \
+        (uint32_t)in_vec, ARRAY_SIZE(in_vec),                  \
         (uint32_t)NULL, 0)
-
-#define API_DISPATCH(sfn_name) NS_LOCK_DISPATCH(sfn_name)
-#define API_DISPATCH_NO_INVEC(sfn_name) NS_LOCK_DISPATCH_NO_INVEC(sfn_name)
-#define API_DISPATCH_NO_OUTVEC(sfn_name) NS_LOCK_DISPATCH_NO_OUTVEC(sfn_name)
+#endif
 
 psa_status_t psa_crypto_init(void)
 {
@@ -43,13 +63,25 @@
                             size_t data_length)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_IMPORT_KEY_SFID,
+        .key = key,
+        .type = type,
+    };
     psa_invec in_vec[] = {
-        {.base = &key, .len = sizeof(psa_key_slot_t)},
-        {.base = &type, .len = sizeof(psa_key_type_t)},
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
         {.base = data, .len = data_length}
     };
 
-    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_import_key);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_import_key,
+                                    TFM_CRYPTO_IMPORT_KEY);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -57,11 +89,23 @@
 psa_status_t psa_destroy_key(psa_key_slot_t key)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_DESTROY_KEY_SFID,
+        .key = key,
+    };
     psa_invec in_vec[] = {
-        {.base = &key, .len = sizeof(psa_key_slot_t)},
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
     };
 
-    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_destroy_key);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_destroy_key,
+                                    TFM_CRYPTO_DESTROY_KEY);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -71,15 +115,27 @@
                                      size_t *bits)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GET_KEY_INFORMATION_SFID,
+        .key = key,
+    };
     psa_invec in_vec[] = {
-        {.base = &key, .len = sizeof(psa_key_slot_t)},
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
     };
     psa_outvec out_vec[] = {
         {.base = type, .len = sizeof(psa_key_type_t)},
         {.base = bits, .len = sizeof(size_t)}
     };
 
-    status = API_DISPATCH(tfm_crypto_get_key_information);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_get_key_information,
+                          TFM_CRYPTO_GET_KEY_INFORMATION);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -90,17 +146,30 @@
                             size_t *data_length)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_EXPORT_KEY_SFID,
+        .key = key,
+    };
     psa_invec in_vec[] = {
-        {.base = &key, .len = sizeof(psa_key_slot_t)},
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
     };
     psa_outvec out_vec[] = {
         {.base = data, .len = data_size}
     };
 
-    status = API_DISPATCH(tfm_crypto_export_key);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_export_key,
+                          TFM_CRYPTO_EXPORT_KEY);
 
     *data_length = out_vec[0].len;
 
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
     return status;
 }
 
@@ -121,12 +190,31 @@
 void psa_key_policy_init(psa_key_policy_t *policy)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_KEY_POLICY_INIT_SFID,
+    };
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
     psa_outvec out_vec[] = {
         {.base = policy, .len = sizeof(psa_key_policy_t)},
     };
 
+#ifdef TFM_PSA_API
+    psa_handle_t handle;
+    handle = psa_connect(TFM_CRYPTO_SID,
+                         TFM_CRYPTO_MIN_VER);
+    if (!PSA_IS_HANDLE_VALID(handle)) {
+        return;
+    }
+#endif
+
     /* PSA API returns void so just ignore error value returned */
-    status = API_DISPATCH_NO_INVEC(tfm_crypto_key_policy_init);
+    status = API_DISPATCH(tfm_crypto_key_policy_init,
+                          TFM_CRYPTO_KEY_POLICY_INIT);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 }
 
 void psa_key_policy_set_usage(psa_key_policy_t *policy,
@@ -134,16 +222,33 @@
                               psa_algorithm_t alg)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_KEY_POLICY_SET_USAGE_SFID,
+        .usage = usage,
+        .alg = alg,
+    };
     psa_invec in_vec[] = {
-        {.base = &usage, .len = sizeof(psa_key_usage_t)},
-        {.base = &alg, .len = sizeof(psa_algorithm_t)}
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
     };
     psa_outvec out_vec[] = {
         {.base = policy, .len = sizeof(psa_key_policy_t)},
     };
 
+#ifdef TFM_PSA_API
+    psa_handle_t handle;
+    handle = psa_connect(TFM_CRYPTO_SID,
+                         TFM_CRYPTO_MIN_VER);
+    if (!PSA_IS_HANDLE_VALID(handle)) {
+        return;
+    }
+#endif
+
     /* PSA API returns void so just ignore error value returned */
-    status = API_DISPATCH(tfm_crypto_key_policy_set_usage);
+    status = API_DISPATCH(tfm_crypto_key_policy_set_usage,
+                          TFM_CRYPTO_KEY_POLICY_SET_USAGE);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 }
 
 psa_key_usage_t psa_key_policy_get_usage(const psa_key_policy_t *policy)
@@ -151,20 +256,33 @@
     psa_status_t status;
     psa_key_usage_t usage;
 
-    /* Initialise to a sensible default to avoid returning an uninitialised
-     * value in case the secure function fails.
-     */
-    usage = 0;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_KEY_POLICY_GET_USAGE_SFID,
+    };
 
     psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
         {.base = policy, .len = sizeof(psa_key_policy_t)},
     };
     psa_outvec out_vec[] = {
         {.base = &usage, .len = sizeof(psa_key_usage_t)},
     };
 
+    /* Initialise to a sensible default to avoid returning an uninitialised
+     * value in case the secure function fails.
+     */
+    usage = 0;
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
     /* The PSA API does not return an error, so ignore any error from TF-M */
-    status = API_DISPATCH(tfm_crypto_key_policy_get_usage);
+    status = API_DISPATCH(tfm_crypto_key_policy_get_usage,
+                          TFM_CRYPTO_KEY_POLICY_GET_USAGE);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return usage;
 }
@@ -174,20 +292,33 @@
     psa_status_t status;
     psa_algorithm_t alg;
 
-    /* Initialise to a sensible default to avoid returning an uninitialised
-     * value in case the secure function fails.
-     */
-    alg = 0;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_KEY_POLICY_GET_ALGORITHM_SFID,
+    };
 
     psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
         {.base = policy, .len = sizeof(psa_key_policy_t)},
     };
     psa_outvec out_vec[] = {
         {.base = &alg, .len = sizeof(psa_algorithm_t)},
     };
 
+    /* Initialise to a sensible default to avoid returning an uninitialised
+     * value in case the secure function fails.
+     */
+    alg = 0;
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
     /* The PSA API does not return an error, so ignore any error from TF-M */
-    status = API_DISPATCH(tfm_crypto_key_policy_get_algorithm);
+    status = API_DISPATCH(tfm_crypto_key_policy_get_algorithm,
+                          TFM_CRYPTO_KEY_POLICY_GET_ALGORITHM);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return alg;
 }
@@ -196,12 +327,25 @@
                                 const psa_key_policy_t *policy)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_SET_KEY_POLICY_SFID,
+        .key = key,
+    };
+
     psa_invec in_vec[] = {
-        {.base = &key, .len = sizeof(psa_key_slot_t)},
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
         {.base = policy, .len = sizeof(psa_key_policy_t)},
     };
 
-    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_set_key_policy);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_set_key_policy,
+                                    TFM_CRYPTO_SET_KEY_POLICY);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -210,14 +354,27 @@
                                 psa_key_policy_t *policy)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GET_KEY_POLICY_SFID,
+        .key = key,
+    };
+
     psa_invec in_vec[] = {
-        {.base = &key, .len = sizeof(psa_key_slot_t)},
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
     };
     psa_outvec out_vec[] = {
         {.base = policy, .len = sizeof(psa_key_policy_t)},
     };
 
-    status = API_DISPATCH(tfm_crypto_get_key_policy);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_get_key_policy,
+                          TFM_CRYPTO_GET_KEY_POLICY);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -226,12 +383,25 @@
                                   psa_key_lifetime_t lifetime)
 {
     psa_status_t status;
-    psa_invec in_vec[] = {
-        {.base = &key, .len = sizeof(psa_key_slot_t)},
-        {.base = &lifetime, .len = sizeof(psa_key_lifetime_t)},
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_SET_KEY_LIFETIME_SFID,
+        .key = key,
+        .lifetime = lifetime,
     };
 
-    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_set_key_lifetime);
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_set_key_lifetime,
+                                    TFM_CRYPTO_SET_KEY_LIFETIME);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -240,14 +410,27 @@
                                   psa_key_lifetime_t *lifetime)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GET_KEY_LIFETIME_SFID,
+        .key = key,
+    };
+
     psa_invec in_vec[] = {
-        {.base = &key, .len = sizeof(psa_key_slot_t)},
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
     };
     psa_outvec out_vec[] = {
         {.base = lifetime, .len = sizeof(psa_key_lifetime_t)},
     };
 
-    status = API_DISPATCH(tfm_crypto_get_key_lifetime);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_get_key_lifetime,
+                          TFM_CRYPTO_GET_KEY_LIFETIME);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -257,14 +440,28 @@
                                size_t iv_length)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_SET_IV_SFID,
+        .handle = operation->handle,
+    };
+
     psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
         {.base = iv, .len = iv_length},
     };
     psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
     };
 
-    status = API_DISPATCH(tfm_crypto_cipher_set_iv);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_cipher_set_iv,
+                          TFM_CRYPTO_CIPHER_SET_IV);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -274,15 +471,29 @@
                                       psa_algorithm_t alg)
 {
     psa_status_t status;
-    psa_invec in_vec[] = {
-        {.base = &key, .len = sizeof(psa_key_slot_t)},
-        {.base = &alg, .len = sizeof(psa_algorithm_t)},
-    };
-    psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SFID,
+        .key = key,
+        .alg = alg,
+        .handle = operation->handle,
     };
 
-    status = API_DISPATCH(tfm_crypto_cipher_encrypt_setup);
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_cipher_encrypt_setup,
+                          TFM_CRYPTO_CIPHER_ENCRYPT_SETUP);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -292,15 +503,29 @@
                                       psa_algorithm_t alg)
 {
     psa_status_t status;
-    psa_invec in_vec[] = {
-        {.base = &key, .len = sizeof(psa_key_slot_t)},
-        {.base = &alg, .len = sizeof(psa_algorithm_t)},
-    };
-    psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SFID,
+        .key = key,
+        .alg = alg,
+        .handle = operation->handle,
     };
 
-    status = API_DISPATCH(tfm_crypto_cipher_decrypt_setup);
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_cipher_decrypt_setup,
+                          TFM_CRYPTO_CIPHER_DECRYPT_SETUP);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -313,29 +538,60 @@
                                size_t *output_length)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_UPDATE_SFID,
+        .handle = operation->handle,
+    };
+
     psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
         {.base = input, .len = input_length},
     };
     psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
         {.base = output, .len = output_size}
     };
 
-    status = API_DISPATCH(tfm_crypto_cipher_update);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_cipher_update,
+                          TFM_CRYPTO_CIPHER_UPDATE);
 
     *output_length = out_vec[1].len;
 
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
     return status;
 }
 
 psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation)
 {
     psa_status_t status;
-    psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_ABORT_SFID,
+        .handle = operation->handle,
     };
 
-    status = API_DISPATCH_NO_INVEC(tfm_crypto_cipher_abort);
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_cipher_abort,
+                          TFM_CRYPTO_CIPHER_ABORT);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -346,15 +602,32 @@
                                size_t *output_length)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_FINISH_SFID,
+        .handle = operation->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
     psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
         {.base = output, .len = output_size},
     };
 
-    status = API_DISPATCH_NO_INVEC(tfm_crypto_cipher_finish);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_cipher_finish,
+                          TFM_CRYPTO_CIPHER_FINISH);
 
     *output_length = out_vec[1].len;
 
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
     return status;
 }
 
@@ -362,14 +635,29 @@
                             psa_algorithm_t alg)
 {
     psa_status_t status;
-    psa_invec in_vec[] = {
-        {.base = &alg, .len = sizeof(psa_algorithm_t)},
-    };
-    psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_hash_operation_t)},
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_HASH_SETUP_SFID,
+        .alg = alg,
+        .handle = operation->handle,
     };
 
-    status = API_DISPATCH(tfm_crypto_hash_setup);
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_hash_setup,
+                          TFM_CRYPTO_HASH_SETUP);
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -379,14 +667,29 @@
                              size_t input_length)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_HASH_UPDATE_SFID,
+        .handle = operation->handle,
+    };
+
     psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
         {.base = input, .len = input_length},
     };
     psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_hash_operation_t)},
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
     };
 
-    status = API_DISPATCH(tfm_crypto_hash_update);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_hash_update,
+                          TFM_CRYPTO_HASH_UPDATE);
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -397,15 +700,32 @@
                              size_t *hash_length)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_HASH_FINISH_SFID,
+        .handle = operation->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
     psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_hash_operation_t)},
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
         {.base = hash, .len = hash_size},
     };
 
-    status = API_DISPATCH_NO_INVEC(tfm_crypto_hash_finish);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_hash_finish,
+                          TFM_CRYPTO_HASH_FINISH);
 
     *hash_length = out_vec[1].len;
 
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
     return status;
 }
 
@@ -414,14 +734,28 @@
                              size_t hash_length)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_HASH_VERIFY_SFID,
+        .handle = operation->handle,
+    };
+
     psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
         {.base = hash, .len = hash_length},
     };
     psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_hash_operation_t)},
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
     };
 
-    status = API_DISPATCH(tfm_crypto_hash_verify);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_hash_verify,
+                          TFM_CRYPTO_HASH_VERIFY);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -429,11 +763,27 @@
 psa_status_t psa_hash_abort(psa_hash_operation_t *operation)
 {
     psa_status_t status;
-    psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_hash_operation_t)},
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_HASH_ABORT_SFID,
+        .handle = operation->handle,
     };
 
-    status = API_DISPATCH_NO_INVEC(tfm_crypto_hash_abort);
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_hash_abort,
+                          TFM_CRYPTO_HASH_ABORT);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -443,15 +793,29 @@
                                 psa_algorithm_t alg)
 {
     psa_status_t status;
-    psa_invec in_vec[] = {
-        {.base = &key, .len = sizeof(psa_key_slot_t)},
-        {.base = &alg, .len = sizeof(psa_algorithm_t)}
-    };
-    psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_mac_operation_t)},
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_MAC_SIGN_SETUP_SFID,
+        .key = key,
+        .alg = alg,
+        .handle = operation->handle,
     };
 
-    status = API_DISPATCH(tfm_crypto_mac_sign_setup);
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_mac_sign_setup,
+                          TFM_CRYPTO_MAC_SIGN_SETUP);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -461,15 +825,29 @@
                                   psa_algorithm_t alg)
 {
     psa_status_t status;
-    psa_invec in_vec[] = {
-        {.base = &key, .len = sizeof(psa_key_slot_t)},
-        {.base = &alg, .len = sizeof(psa_algorithm_t)}
-    };
-    psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_mac_operation_t)},
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_MAC_VERIFY_SETUP_SFID,
+        .key = key,
+        .alg = alg,
+        .handle = operation->handle,
     };
 
-    status = API_DISPATCH(tfm_crypto_mac_verify_setup);
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_mac_verify_setup,
+                          TFM_CRYPTO_MAC_VERIFY_SETUP);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -479,14 +857,28 @@
                             size_t input_length)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_MAC_UPDATE_SFID,
+        .handle = operation->handle,
+    };
+
     psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
         {.base = input, .len = input_length},
     };
     psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_mac_operation_t)},
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
     };
 
-    status = API_DISPATCH(tfm_crypto_mac_update);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_mac_update,
+                          TFM_CRYPTO_MAC_UPDATE);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -497,15 +889,32 @@
                                  size_t *mac_length)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_MAC_SIGN_FINISH_SFID,
+        .handle = operation->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
     psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_mac_operation_t)},
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
         {.base = mac, .len = mac_size},
     };
 
-    status = API_DISPATCH_NO_INVEC(tfm_crypto_mac_sign_finish);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_mac_sign_finish,
+                          TFM_CRYPTO_MAC_SIGN_FINISH);
 
     *mac_length = out_vec[1].len;
 
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
     return status;
 }
 
@@ -514,14 +923,29 @@
                                    size_t mac_length)
 {
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_MAC_VERIFY_FINISH_SFID,
+        .handle = operation->handle,
+    };
+
     psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
         {.base = mac, .len = mac_length},
     };
     psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_mac_operation_t)},
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
     };
 
-    status = API_DISPATCH(tfm_crypto_mac_verify_finish);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_mac_verify_finish,
+                          TFM_CRYPTO_MAC_VERIFY_FINISH);
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -529,11 +953,27 @@
 psa_status_t psa_mac_abort(psa_mac_operation_t *operation)
 {
     psa_status_t status;
-    psa_outvec out_vec[] = {
-        {.base = operation, .len = sizeof(psa_mac_operation_t)},
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_MAC_ABORT_SFID,
+        .handle = operation->handle,
     };
 
-    status = API_DISPATCH_NO_INVEC(tfm_crypto_mac_abort);
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_mac_abort,
+                          TFM_CRYPTO_MAC_ABORT);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
 
     return status;
 }
@@ -551,17 +991,18 @@
                               size_t *ciphertext_length)
 {
     psa_status_t status;
-    struct tfm_crypto_aead_pack_input input_s = {
-      .key = key,
-      .alg = alg,
-      .nonce = {0},
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_AEAD_ENCRYPT_SFID,
+        .key = key,
+        .alg = alg,
+        .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
     };
+
     size_t idx = 0;
     psa_invec in_vec[] = {
-        {.base = &input_s, .len = nonce_length + sizeof(psa_key_slot_t)
-                                               + sizeof(psa_algorithm_t)},
-        {.base = additional_data, .len = additional_data_length},
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
         {.base = plaintext, .len = plaintext_length},
+        {.base = additional_data, .len = additional_data_length},
     };
     psa_outvec out_vec[] = {
         {.base = ciphertext, .len = ciphertext_size},
@@ -573,14 +1014,32 @@
 
     if (nonce != NULL) {
         for (idx = 0; idx < nonce_length; idx++) {
-            input_s.nonce[idx] = nonce[idx];
+            iov.aead_in.nonce[idx] = nonce[idx];
         }
     }
 
-    status = API_DISPATCH(tfm_crypto_aead_encrypt);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+    size_t in_len = sizeof(in_vec)/sizeof(in_vec[0]);
+    if (additional_data == NULL) {
+      in_len--;
+    }
+    status = psa_call(handle, in_vec, in_len,
+                      out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+#else
+    status = API_DISPATCH(tfm_crypto_aead_encrypt,
+                          TFM_CRYPTO_AEAD_ENCRYPT);
+#endif
 
     *ciphertext_length = out_vec[0].len;
 
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
     return status;
 }
 
@@ -597,17 +1056,18 @@
                               size_t *plaintext_length)
 {
     psa_status_t status;
-    struct tfm_crypto_aead_pack_input input_s = {
-      .key = key,
-      .alg = alg,
-      .nonce = {0},
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_AEAD_DECRYPT_SFID,
+        .key = key,
+        .alg = alg,
+        .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
     };
+
     size_t idx = 0;
     psa_invec in_vec[] = {
-        {.base = &input_s, .len = nonce_length + sizeof(psa_key_slot_t)
-                                               + sizeof(psa_algorithm_t)},
-        {.base = additional_data, .len = additional_data_length},
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
         {.base = ciphertext, .len = ciphertext_length},
+        {.base = additional_data, .len = additional_data_length},
     };
     psa_outvec out_vec[] = {
         {.base = plaintext, .len = plaintext_size},
@@ -619,13 +1079,31 @@
 
     if (nonce != NULL) {
         for (idx = 0; idx < nonce_length; idx++) {
-            input_s.nonce[idx] = nonce[idx];
+            iov.aead_in.nonce[idx] = nonce[idx];
         }
     }
 
-    status = API_DISPATCH(tfm_crypto_aead_decrypt);
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+    size_t in_len = sizeof(in_vec)/sizeof(in_vec[0]);
+    if (additional_data == NULL) {
+      in_len--;
+    }
+    status = psa_call(handle, in_vec, in_len,
+                      out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+#else
+    status = API_DISPATCH(tfm_crypto_aead_decrypt,
+                          TFM_CRYPTO_AEAD_DECRYPT);
+#endif
 
     *plaintext_length = out_vec[0].len;
 
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
     return status;
 }