summaryrefslogtreecommitdiff
path: root/nrfdemo/builddk/tfm/api_ns/interface/src
diff options
context:
space:
mode:
authorMichal Hanus <mikehanus@protonmail.com>2025-04-14 22:04:32 +0200
committerMichal Hanus <mikehanus@protonmail.com>2025-04-14 22:04:32 +0200
commit2e13c372f1419f08dab7797b244681f889dd9bcf (patch)
tree995a31c40f13068c4135c213e938e0a2a9ed05a3 /nrfdemo/builddk/tfm/api_ns/interface/src
parent620dfd94019f3c7e3022fa5a5fb9c9b51491062d (diff)
nrfdemo
Diffstat (limited to 'nrfdemo/builddk/tfm/api_ns/interface/src')
-rw-r--r--nrfdemo/builddk/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_bare_metal.c23
-rw-r--r--nrfdemo/builddk/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_rtos.c56
-rw-r--r--nrfdemo/builddk/tfm/api_ns/interface/src/tfm_crypto_api.c1849
-rw-r--r--nrfdemo/builddk/tfm/api_ns/interface/src/tfm_ioctl_core_ns_api.c68
-rw-r--r--nrfdemo/builddk/tfm/api_ns/interface/src/tfm_platform_api.c109
-rw-r--r--nrfdemo/builddk/tfm/api_ns/interface/src/tfm_tz_psa_ns_api.c63
6 files changed, 2168 insertions, 0 deletions
diff --git a/nrfdemo/builddk/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_bare_metal.c b/nrfdemo/builddk/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_bare_metal.c
new file mode 100644
index 0000000..01da8b8
--- /dev/null
+++ b/nrfdemo/builddk/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_bare_metal.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company)
+ * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* This file provides implementation of TF-M NS os wrapper functions for the
+ * bare metal use case.
+ *
+ * \note This implementation does not provide multithread safety, so it
+ * shouldn't be used in RTOS environment.
+ */
+
+#include "tfm_ns_interface.h"
+
+int32_t tfm_ns_interface_dispatch(veneer_fn fn,
+ uint32_t arg0, uint32_t arg1,
+ uint32_t arg2, uint32_t arg3)
+{
+ return fn(arg0, arg1, arg2, arg3);
+}
diff --git a/nrfdemo/builddk/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_rtos.c b/nrfdemo/builddk/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_rtos.c
new file mode 100644
index 0000000..a1f7727
--- /dev/null
+++ b/nrfdemo/builddk/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_rtos.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company)
+ * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* This file provides implementation of TF-M NS os wrapper functions for the
+ * RTOS use case. This implementation provides multithread safety, so it
+ * can be used in RTOS environment.
+ */
+
+#include <stdint.h>
+
+#include "os_wrapper/mutex.h"
+
+#include "tfm_ns_interface.h"
+
+/**
+ * \brief the ns_lock ID
+ */
+static void *ns_lock_handle = NULL;
+
+int32_t tfm_ns_interface_dispatch(veneer_fn fn,
+ uint32_t arg0, uint32_t arg1,
+ uint32_t arg2, uint32_t arg3)
+{
+ int32_t result;
+
+ /* TFM request protected by NS lock */
+ while (os_wrapper_mutex_acquire(ns_lock_handle, OS_WRAPPER_WAIT_FOREVER)
+ != OS_WRAPPER_SUCCESS) {
+ }
+
+ result = fn(arg0, arg1, arg2, arg3);
+
+ while (os_wrapper_mutex_release(ns_lock_handle) != OS_WRAPPER_SUCCESS) {
+ }
+
+ return result;
+}
+
+uint32_t tfm_ns_interface_init(void)
+{
+ void *handle;
+
+ handle = os_wrapper_mutex_create();
+ if (!handle) {
+ return OS_WRAPPER_ERROR;
+ }
+
+ ns_lock_handle = handle;
+ return OS_WRAPPER_SUCCESS;
+}
diff --git a/nrfdemo/builddk/tfm/api_ns/interface/src/tfm_crypto_api.c b/nrfdemo/builddk/tfm/api_ns/interface/src/tfm_crypto_api.c
new file mode 100644
index 0000000..4dc7ea8
--- /dev/null
+++ b/nrfdemo/builddk/tfm/api_ns/interface/src/tfm_crypto_api.c
@@ -0,0 +1,1849 @@
+/*
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_crypto_defs.h"
+#include "psa/crypto.h"
+#include "psa/client.h"
+#include "psa_manifest/sid.h"
+
+#define API_DISPATCH(in_vec, out_vec) \
+ psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, \
+ in_vec, IOVEC_LEN(in_vec), \
+ out_vec, IOVEC_LEN(out_vec))
+#define API_DISPATCH_NO_OUTVEC(in_vec) \
+ psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, \
+ in_vec, IOVEC_LEN(in_vec), \
+ (psa_outvec *)NULL, 0)
+
+/*!
+ * \def CONFIG_TFM_CRYPTO_API_RENAME
+ *
+ * \brief By setting this to 1, system integrators can rename the symbols of the
+ * PSA Crypto APIs available in the TF-M interface. It allows flexibility
+ * for some integration setups where multiple providers of the PSA Crypto
+ * APIs are available at link time. Normally this configuration option
+ * should not be enabled when building the Secure interface because the
+ * secure partitions will just use the standard function names. By default
+ * it prepends the "tfm_crypto__" prefix.
+ *
+ * \note This config option is not available through the TF-M configuration as
+ * it's for NS applications and system integrators to enable.
+ */
+
+/*!
+ * \def TFM_CRYPTO_API(ret, fun)
+ *
+ * \brief Define the function signature of a TF-M Crypto API with return
+ * type \a ret and PSA Crypto API function name \a fun
+ *
+ * \param ret return type associated to the API
+ * \param fun API name (e.g. a PSA Crypto API function name)
+ *
+ * \returns Function signature
+ */
+
+#if CONFIG_TFM_CRYPTO_API_RENAME == 1
+#define TFM_CRYPTO_API(ret, fun) ret tfm_crypto__##fun
+#else
+#define TFM_CRYPTO_API(ret, fun) ret fun
+#endif /* CONFIG_TFM_CRYPTO_API_RENAME */
+
+TFM_CRYPTO_API(psa_status_t, psa_crypto_init)(void)
+{
+ /* Service init is performed during TFM boot up,
+ * so application level initialisation is empty
+ */
+ return PSA_SUCCESS;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_open_key)(psa_key_id_t id,
+ psa_key_id_t *key)
+{
+ const struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_OPEN_KEY_SID,
+ .key_id = id,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = key, .len = sizeof(psa_key_id_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_close_key)(psa_key_id_t key)
+{
+ const struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CLOSE_KEY_SID,
+ .key_id = key,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_import_key)(const psa_key_attributes_t *attributes,
+ const uint8_t *data,
+ size_t data_length,
+ psa_key_id_t *key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_IMPORT_KEY_SID,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ {.base = data, .len = data_length}
+ };
+ psa_outvec out_vec[] = {
+ {.base = key, .len = sizeof(psa_key_id_t)}
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_destroy_key)(psa_key_id_t key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_DESTROY_KEY_SID,
+ .key_id = key,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_get_key_attributes)(psa_key_id_t key,
+ psa_key_attributes_t *attributes)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID,
+ .key_id = key,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(void, psa_reset_key_attributes)(psa_key_attributes_t *attributes)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_RESET_KEY_ATTRIBUTES_SID,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ };
+
+ (void)API_DISPATCH(in_vec, out_vec);
+ return;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_export_key)(psa_key_id_t key,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_EXPORT_KEY_SID,
+ .key_id = key,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = data, .len = data_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *data_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_export_public_key)(psa_key_id_t key,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID,
+ .key_id = key,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = data, .len = data_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *data_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_purge_key)(psa_key_id_t key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PURGE_KEY_SID,
+ .key_id = key,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_copy_key)(psa_key_id_t source_key,
+ const psa_key_attributes_t *attributes,
+ psa_key_id_t *target_key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_COPY_KEY_SID,
+ .key_id = source_key,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = target_key, .len = sizeof(psa_key_id_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_generate_iv)(psa_cipher_operation_t *operation,
+ unsigned char *iv,
+ size_t iv_size,
+ size_t *iv_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_GENERATE_IV_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = iv, .len = iv_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *iv_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_set_iv)(psa_cipher_operation_t *operation,
+ const unsigned char *iv,
+ size_t iv_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_SET_IV_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = iv, .len = iv_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_encrypt_setup)(psa_cipher_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_decrypt_setup)(psa_cipher_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_update)(psa_cipher_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length,
+ unsigned char *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_UPDATE_SID,
+ .op_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 = output, .len = output_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *output_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_abort)(psa_cipher_operation_t *operation)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_ABORT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_finish)(psa_cipher_operation_t *operation,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_FINISH_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = output, .len = output_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *output_length = out_vec[1].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_setup)(psa_hash_operation_t *operation,
+ psa_algorithm_t alg)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_SETUP_SID,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_update)(psa_hash_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_UPDATE_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_finish)(psa_hash_operation_t *operation,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_FINISH_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = hash, .len = hash_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *hash_length = out_vec[1].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_verify)(psa_hash_operation_t *operation,
+ const uint8_t *hash,
+ size_t hash_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_VERIFY_SID,
+ .op_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->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_abort)(psa_hash_operation_t *operation)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_ABORT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_clone)(const psa_hash_operation_t *source_operation,
+ psa_hash_operation_t *target_operation)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_CLONE_SID,
+ .op_handle = source_operation->handle,
+ };
+
+ if (target_operation && (target_operation->handle != 0)) {
+ return PSA_ERROR_BAD_STATE;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = &(target_operation->handle),
+ .len = sizeof(target_operation->handle)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(target_operation->handle),
+ .len = sizeof(target_operation->handle)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_compute)(psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_COMPUTE_SID,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = hash, .len = hash_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *hash_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_compare)(psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *hash,
+ size_t hash_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_COMPARE_SID,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = hash, .len = hash_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_sign_setup)(psa_mac_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_SIGN_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_verify_setup)(psa_mac_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_VERIFY_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_update)(psa_mac_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_UPDATE_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_sign_finish)(psa_mac_operation_t *operation,
+ uint8_t *mac,
+ size_t mac_size,
+ size_t *mac_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_SIGN_FINISH_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = mac, .len = mac_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *mac_length = out_vec[1].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_verify_finish)(psa_mac_operation_t *operation,
+ const uint8_t *mac,
+ size_t mac_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_VERIFY_FINISH_SID,
+ .op_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->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_abort)(psa_mac_operation_t *operation)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_ABORT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_encrypt)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *nonce,
+ size_t nonce_length,
+ const uint8_t *additional_data,
+ size_t additional_data_length,
+ const uint8_t *plaintext,
+ size_t plaintext_length,
+ uint8_t *ciphertext,
+ size_t ciphertext_size,
+ size_t *ciphertext_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_ENCRYPT_SID,
+ .key_id = key,
+ .alg = alg,
+ .aead_in = {.nonce = {0}, .nonce_length = 0}
+ };
+
+ /* Sanitize the optional input */
+ if ((additional_data == NULL) && (additional_data_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = NULL, .len = 0},
+ {.base = plaintext, .len = plaintext_length},
+ {.base = additional_data, .len = additional_data_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = ciphertext, .len = ciphertext_size},
+ };
+
+ if (nonce_length > TFM_CRYPTO_MAX_NONCE_LENGTH) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (nonce != NULL) {
+ for (size_t idx = 0; idx < nonce_length; idx++) {
+ iov.aead_in.nonce[idx] = nonce[idx];
+ }
+ iov.aead_in.nonce_length = nonce_length;
+ }
+
+ in_vec[0].base = &iov;
+ in_vec[0].len = sizeof(struct tfm_crypto_pack_iovec);
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (additional_data == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, IOVEC_LEN(out_vec));
+
+ *ciphertext_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_decrypt)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *nonce,
+ size_t nonce_length,
+ const uint8_t *additional_data,
+ size_t additional_data_length,
+ const uint8_t *ciphertext,
+ size_t ciphertext_length,
+ uint8_t *plaintext,
+ size_t plaintext_size,
+ size_t *plaintext_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_DECRYPT_SID,
+ .key_id = key,
+ .alg = alg,
+ .aead_in = {.nonce = {0}, .nonce_length = 0}
+ };
+
+ /* Sanitize the optional input */
+ if ((additional_data == NULL) && (additional_data_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = NULL, .len = 0},
+ {.base = ciphertext, .len = ciphertext_length},
+ {.base = additional_data, .len = additional_data_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = plaintext, .len = plaintext_size},
+ };
+
+ if (nonce_length > TFM_CRYPTO_MAX_NONCE_LENGTH) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (nonce != NULL) {
+ for (size_t idx = 0; idx < nonce_length; idx++) {
+ iov.aead_in.nonce[idx] = nonce[idx];
+ }
+ iov.aead_in.nonce_length = nonce_length;
+ }
+
+ in_vec[0].base = &iov;
+ in_vec[0].len = sizeof(struct tfm_crypto_pack_iovec);
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (additional_data == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, IOVEC_LEN(out_vec));
+
+ *plaintext_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_encrypt_setup)(psa_aead_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_ENCRYPT_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_decrypt_setup)(psa_aead_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_DECRYPT_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_generate_nonce)(psa_aead_operation_t *operation,
+ uint8_t *nonce,
+ size_t nonce_size,
+ size_t *nonce_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_GENERATE_NONCE_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = nonce, .len = nonce_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *nonce_length = out_vec[0].len;
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_set_nonce)(psa_aead_operation_t *operation,
+ const uint8_t *nonce,
+ size_t nonce_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_SET_NONCE_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = nonce, .len = nonce_length}
+ };
+
+ status = API_DISPATCH_NO_OUTVEC(in_vec);
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_set_lengths)(psa_aead_operation_t *operation,
+ size_t ad_length,
+ size_t plaintext_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_SET_LENGTHS_SID,
+ .ad_length = ad_length,
+ .plaintext_length = plaintext_length,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ status = API_DISPATCH_NO_OUTVEC(in_vec);
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_update_ad)(psa_aead_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_UPDATE_AD_SID,
+ .op_handle = operation->handle,
+ };
+
+ /* Sanitize the optional input */
+ if ((input == NULL) && (input_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length}
+ };
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (input == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ NULL, 0);
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_update)(psa_aead_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_UPDATE_SID,
+ .op_handle = operation->handle,
+ };
+
+ /* Sanitize the optional input */
+ if ((input == NULL) && (input_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length}
+ };
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (input == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, IOVEC_LEN(out_vec));
+
+ *output_length = out_vec[0].len;
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_finish)(psa_aead_operation_t *operation,
+ uint8_t *ciphertext,
+ size_t ciphertext_size,
+ size_t *ciphertext_length,
+ uint8_t *tag,
+ size_t tag_size,
+ size_t *tag_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_FINISH_SID,
+ .op_handle = operation->handle,
+ };
+
+ /* Sanitize the optional output */
+ if ((ciphertext == NULL) && (ciphertext_size != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = tag, .len = tag_size},
+ {.base = ciphertext, .len = ciphertext_size}
+ };
+
+ size_t out_len = IOVEC_LEN(out_vec);
+
+ if (ciphertext == NULL || ciphertext_size == 0) {
+ out_len--;
+ }
+ if ((out_len == 3) && (ciphertext_length == NULL)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL,
+ in_vec, IOVEC_LEN(in_vec),
+ out_vec, out_len);
+
+ if (out_len == 3) {
+ *ciphertext_length = out_vec[2].len;
+ } else {
+ *ciphertext_length = 0;
+ }
+
+ *tag_length = out_vec[1].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_verify)(psa_aead_operation_t *operation,
+ uint8_t *plaintext,
+ size_t plaintext_size,
+ size_t *plaintext_length,
+ const uint8_t *tag,
+ size_t tag_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_VERIFY_SID,
+ .op_handle = operation->handle,
+ };
+
+ /* Sanitize the optional output */
+ if ((plaintext == NULL) && (plaintext_size != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = tag, .len = tag_length}
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = plaintext, .len = plaintext_size}
+ };
+
+ size_t out_len = IOVEC_LEN(out_vec);
+
+ if (plaintext == NULL || plaintext_size == 0) {
+ out_len--;
+ }
+ if ((out_len == 2) && (plaintext_length == NULL)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL,
+ in_vec, IOVEC_LEN(in_vec),
+ out_vec, out_len);
+
+ if (out_len == 2) {
+ *plaintext_length = out_vec[1].len;
+ } else {
+ *plaintext_length = 0;
+ }
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_abort)(psa_aead_operation_t *operation)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_ABORT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_sign_message)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *signature,
+ size_t signature_size,
+ size_t *signature_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_ASYMMETRIC_SIGN_MESSAGE_SID,
+ .key_id = key,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = signature, .len = signature_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *signature_length = out_vec[0].len;
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_verify_message)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *signature,
+ size_t signature_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_ASYMMETRIC_VERIFY_MESSAGE_SID,
+ .key_id = key,
+ .alg = alg
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = signature, .len = signature_length}
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_sign_hash)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ uint8_t *signature,
+ size_t signature_size,
+ size_t *signature_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_ASYMMETRIC_SIGN_HASH_SID,
+ .key_id = key,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = hash, .len = hash_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = signature, .len = signature_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *signature_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_verify_hash)(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)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_ASYMMETRIC_VERIFY_HASH_SID,
+ .key_id = key,
+ .alg = alg
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = hash, .len = hash_length},
+ {.base = signature, .len = signature_length}
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_asymmetric_encrypt)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *salt,
+ size_t salt_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SID,
+ .key_id = key,
+ .alg = alg
+ };
+
+ /* Sanitize the optional input */
+ if ((salt == NULL) && (salt_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = salt, .len = salt_length}
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (salt == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, IOVEC_LEN(out_vec));
+
+ *output_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_asymmetric_decrypt)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *salt,
+ size_t salt_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_ASYMMETRIC_DECRYPT_SID,
+ .key_id = key,
+ .alg = alg
+ };
+
+ /* Sanitize the optional input */
+ if ((salt == NULL) && (salt_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = salt, .len = salt_length}
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (salt == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, IOVEC_LEN(out_vec));
+
+ *output_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_get_capacity)(
+ const psa_key_derivation_operation_t *operation,
+ size_t *capacity)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_GET_CAPACITY_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = capacity, .len = sizeof(size_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_output_bytes)(
+ psa_key_derivation_operation_t *operation,
+ uint8_t *output,
+ size_t output_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_length},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_input_key)(
+ psa_key_derivation_operation_t *operation,
+ psa_key_derivation_step_t step,
+ psa_key_id_t key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_KEY_SID,
+ .key_id = key,
+ .step = step,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_abort)(psa_key_derivation_operation_t *operation)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_ABORT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_key_agreement)(
+ psa_key_derivation_operation_t *operation,
+ psa_key_derivation_step_t step,
+ psa_key_id_t private_key,
+ const uint8_t *peer_key,
+ size_t peer_key_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT_SID,
+ .key_id = private_key,
+ .step = step,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = peer_key, .len = peer_key_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_generate_random)(uint8_t *output,
+ size_t output_size)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_GENERATE_RANDOM_SID,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+ if (output_size == 0) {
+ return PSA_SUCCESS;
+ }
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_generate_key)(const psa_key_attributes_t *attributes,
+ psa_key_id_t *key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_GENERATE_KEY_SID,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = key, .len = sizeof(psa_key_id_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_compute)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *mac,
+ size_t mac_size,
+ size_t *mac_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_COMPUTE_SID,
+ .key_id = key,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = mac, .len = mac_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *mac_length = out_vec[0].len;
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_verify)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *mac,
+ const size_t mac_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_VERIFY_SID,
+ .key_id = key,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = mac, .len = mac_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_encrypt)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_ENCRYPT_SID,
+ .key_id = key,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *output_length = out_vec[0].len;
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_decrypt)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_DECRYPT_SID,
+ .key_id = key,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *output_length = out_vec[0].len;
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_raw_key_agreement)(psa_algorithm_t alg,
+ psa_key_id_t private_key,
+ const uint8_t *peer_key,
+ size_t peer_key_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_RAW_KEY_AGREEMENT_SID,
+ .alg = alg,
+ .key_id = private_key
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = peer_key, .len = peer_key_length},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *output_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_setup)(psa_key_derivation_operation_t *operation,
+ psa_algorithm_t alg)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_SETUP_SID,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_set_capacity)(
+ psa_key_derivation_operation_t *operation,
+ size_t capacity)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_SET_CAPACITY_SID,
+ .capacity = capacity,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_input_bytes)(
+ psa_key_derivation_operation_t *operation,
+ psa_key_derivation_step_t step,
+ const uint8_t *data,
+ size_t data_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_BYTES_SID,
+ .step = step,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = data, .len = data_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_output_key)(
+ const psa_key_attributes_t *attributes,
+ psa_key_derivation_operation_t *operation,
+ psa_key_id_t *key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_OUTPUT_KEY_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = key, .len = sizeof(psa_key_id_t)}
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_setup)
+(psa_pake_operation_t *operation, psa_key_id_t password_key,
+ const psa_pake_cipher_suite_t *cipher_suite) {
+ struct tfm_crypto_pack_iovec iov = {.function_id = TFM_CRYPTO_PAKE_SETUP_SID,
+ .op_handle = operation->handle,
+ .key_id = password_key};
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = cipher_suite, .len = sizeof(psa_pake_cipher_suite_t)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_set_role)
+(psa_pake_operation_t *operation, psa_pake_role_t role) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_SET_ROLE_SID,
+ .op_handle = operation->handle,
+ .role = role,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_set_user)
+(psa_pake_operation_t *operation, const uint8_t *user_id, size_t user_id_len) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_SET_USER_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = user_id, .len = user_id_len},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_set_peer)
+(psa_pake_operation_t *operation, const uint8_t *peer_id, size_t peer_id_len) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_SET_PEER_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = peer_id, .len = peer_id_len},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_set_context)
+(psa_pake_operation_t *operation, const uint8_t *context, size_t context_len) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_SET_CONTEXT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = context, .len = context_len},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_output)
+(psa_pake_operation_t *operation, psa_pake_step_t step, uint8_t *output,
+ size_t output_size, size_t *output_length) {
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_OUTPUT_SID,
+ .op_handle = operation->handle,
+ .step = step,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {{.base = output, .len = output_size}};
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *output_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_input)
+(psa_pake_operation_t *operation, psa_pake_step_t step, const uint8_t *input,
+ size_t input_length) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_INPUT_SID,
+ .op_handle = operation->handle,
+ .step = step,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_get_shared_key)
+(psa_pake_operation_t *operation, const psa_key_attributes_t *attributes,
+ mbedtls_svc_key_id_t *key) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_GET_SHARED_KEY_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = key, .len = sizeof(mbedtls_svc_key_id_t)}};
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_abort)(psa_pake_operation_t *operation) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_ABORT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_input_integer)(
+ psa_key_derivation_operation_t *operation,
+ psa_key_derivation_step_t step,
+ uint64_t value)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_INTEGER_SID,
+ .step = step,
+ .value = value,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_verify_bytes)(
+ psa_key_derivation_operation_t *operation,
+ const uint8_t *expected_output,
+ size_t output_length)
+{
+ /* To be implemented when the PSA backend supports it */
+ return PSA_ERROR_NOT_SUPPORTED;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_verify_key)(
+ psa_key_derivation_operation_t *operation,
+ psa_key_id_t expected)
+{
+ /* To be implemented when the PSA backend supports it */
+ return PSA_ERROR_NOT_SUPPORTED;
+}
diff --git a/nrfdemo/builddk/tfm/api_ns/interface/src/tfm_ioctl_core_ns_api.c b/nrfdemo/builddk/tfm/api_ns/interface/src/tfm_ioctl_core_ns_api.c
new file mode 100644
index 0000000..2370988
--- /dev/null
+++ b/nrfdemo/builddk/tfm/api_ns/interface/src/tfm_ioctl_core_ns_api.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2021 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "nrf.h"
+#include <stdint.h>
+#include <tfm_platform_api.h>
+#include <tfm_ioctl_core_api.h>
+
+enum tfm_platform_err_t tfm_platform_mem_read(void *destination, uint32_t addr,
+ size_t len, uint32_t *result)
+{
+ enum tfm_platform_err_t ret;
+ psa_invec in_vec;
+ psa_outvec out_vec;
+ struct tfm_read_service_args_t args;
+ struct tfm_read_service_out_t out;
+
+ in_vec.base = (const void *)&args;
+ in_vec.len = sizeof(args);
+
+ out_vec.base = (void *)&out;
+ out_vec.len = sizeof(out);
+
+ args.destination = destination;
+ args.addr = addr;
+ args.len = len;
+
+ ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_READ_SERVICE, &in_vec,
+ &out_vec);
+
+ *result = out.result;
+
+ return ret;
+}
+
+enum tfm_platform_err_t tfm_platform_gpio_pin_mcu_select(uint32_t pin_number, uint32_t mcu,
+ uint32_t *result)
+{
+#if defined(GPIO_PIN_CNF_MCUSEL_Msk)
+ enum tfm_platform_err_t ret;
+ psa_invec in_vec;
+ psa_outvec out_vec;
+ struct tfm_gpio_service_args args;
+ struct tfm_gpio_service_out out;
+
+ args.type = TFM_GPIO_SERVICE_TYPE_PIN_MCU_SELECT;
+ args.mcu_select.pin_number = pin_number;
+ args.mcu_select.mcu = mcu;
+
+ in_vec.base = (const void *)&args;
+ in_vec.len = sizeof(args);
+
+ out_vec.base = (void *)&out;
+ out_vec.len = sizeof(out);
+
+ ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_GPIO_SERVICE, &in_vec,
+ &out_vec);
+
+ *result = out.result;
+
+ return ret;
+#else
+ return TFM_PLATFORM_ERR_NOT_SUPPORTED;
+#endif
+}
diff --git a/nrfdemo/builddk/tfm/api_ns/interface/src/tfm_platform_api.c b/nrfdemo/builddk/tfm/api_ns/interface/src/tfm_platform_api.c
new file mode 100644
index 0000000..4fc564b
--- /dev/null
+++ b/nrfdemo/builddk/tfm/api_ns/interface/src/tfm_platform_api.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdbool.h>
+#include "tfm_platform_api.h"
+#include "psa/client.h"
+#include "psa_manifest/sid.h"
+
+enum tfm_platform_err_t tfm_platform_system_reset(void)
+{
+ psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+
+ status = psa_call(TFM_PLATFORM_SERVICE_HANDLE,
+ TFM_PLATFORM_API_ID_SYSTEM_RESET,
+ NULL, 0, NULL, 0);
+
+ if (status < PSA_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ } else {
+ return (enum tfm_platform_err_t)status;
+ }
+
+}
+
+enum tfm_platform_err_t
+tfm_platform_ioctl(tfm_platform_ioctl_req_t request,
+ psa_invec *input, psa_outvec *output)
+{
+ tfm_platform_ioctl_req_t req = request;
+ struct psa_invec in_vec[2] = { {0} };
+ size_t inlen, outlen;
+ psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+
+ in_vec[0].base = &req;
+ in_vec[0].len = sizeof(req);
+ if (input != NULL) {
+ in_vec[1].base = input->base;
+ in_vec[1].len = input->len;
+ inlen = 2;
+ } else {
+ inlen = 1;
+ }
+
+ if (output != NULL) {
+ outlen = 1;
+ } else {
+ outlen = 0;
+ }
+
+ status = psa_call(TFM_PLATFORM_SERVICE_HANDLE,
+ TFM_PLATFORM_API_ID_IOCTL,
+ in_vec, inlen,
+ output, outlen);
+
+ if (status < PSA_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ } else {
+ return (enum tfm_platform_err_t)status;
+ }
+}
+
+enum tfm_platform_err_t
+tfm_platform_nv_counter_increment(uint32_t counter_id)
+{
+ psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+ struct psa_invec in_vec[1];
+
+ in_vec[0].base = &counter_id;
+ in_vec[0].len = sizeof(counter_id);
+
+ status = psa_call(TFM_PLATFORM_SERVICE_HANDLE,
+ TFM_PLATFORM_API_ID_NV_INCREMENT,
+ in_vec, 1, (psa_outvec *)NULL, 0);
+
+ if (status < PSA_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ } else {
+ return (enum tfm_platform_err_t)status;
+ }
+}
+
+enum tfm_platform_err_t
+tfm_platform_nv_counter_read(uint32_t counter_id,
+ uint32_t size, uint8_t *val)
+{
+ psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+ struct psa_invec in_vec[1];
+ struct psa_outvec out_vec[1];
+
+ in_vec[0].base = &counter_id;
+ in_vec[0].len = sizeof(counter_id);
+
+ out_vec[0].base = val;
+ out_vec[0].len = size;
+
+ status = psa_call(TFM_PLATFORM_SERVICE_HANDLE,
+ TFM_PLATFORM_API_ID_NV_READ,
+ in_vec, 1, out_vec, 1);
+
+ if (status < PSA_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ } else {
+ return (enum tfm_platform_err_t)status;
+ }
+}
diff --git a/nrfdemo/builddk/tfm/api_ns/interface/src/tfm_tz_psa_ns_api.c b/nrfdemo/builddk/tfm/api_ns/interface/src/tfm_tz_psa_ns_api.c
new file mode 100644
index 0000000..1f9fbe4
--- /dev/null
+++ b/nrfdemo/builddk/tfm/api_ns/interface/src/tfm_tz_psa_ns_api.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "psa/client.h"
+#include "tfm_ns_interface.h"
+#include "tfm_psa_call_pack.h"
+
+/**** API functions ****/
+
+uint32_t psa_framework_version(void)
+{
+ return tfm_ns_interface_dispatch(
+ (veneer_fn)tfm_psa_framework_version_veneer,
+ 0,
+ 0,
+ 0,
+ 0);
+}
+
+uint32_t psa_version(uint32_t sid)
+{
+ return tfm_ns_interface_dispatch(
+ (veneer_fn)tfm_psa_version_veneer,
+ sid,
+ 0,
+ 0,
+ 0);
+}
+
+psa_status_t psa_call(psa_handle_t handle, int32_t type,
+ const psa_invec *in_vec,
+ size_t in_len,
+ psa_outvec *out_vec,
+ size_t out_len)
+{
+ if ((type > PSA_CALL_TYPE_MAX) ||
+ (type < PSA_CALL_TYPE_MIN) ||
+ (in_len > PSA_MAX_IOVEC) ||
+ (out_len > PSA_MAX_IOVEC)) {
+ return PSA_ERROR_PROGRAMMER_ERROR;
+ }
+
+ return tfm_ns_interface_dispatch(
+ (veneer_fn)tfm_psa_call_veneer,
+ (uint32_t)handle,
+ PARAM_PACK(type, in_len, out_len),
+ (uint32_t)in_vec,
+ (uint32_t)out_vec);
+}
+
+psa_handle_t psa_connect(uint32_t sid, uint32_t version)
+{
+ return tfm_ns_interface_dispatch((veneer_fn)tfm_psa_connect_veneer, sid, version, 0, 0);
+}
+
+void psa_close(psa_handle_t handle)
+{
+ (void)tfm_ns_interface_dispatch((veneer_fn)tfm_psa_close_veneer, (uint32_t)handle, 0, 0, 0);
+}