Interface: Interface provided to NS side
These files provide a reference interface mplementation for integration
with OS running on the NS side. This has been tested to work with
RTX scheduler.
Modifications may be required while integrating other OS.
Change-Id: I4845584465c5df0bc574de31564a0789154c0dd5
Signed-off-by: Ashutosh Singh <ashutosh.singh@arm.com>
Co-Authored-By: Marc Moreno Berengue <marc.morenoberengue@arm.com>
Co-Authored-By: Antonio de Angelis <antonio.deangelis@arm.com>
diff --git a/interface/include/tfm_api.h b/interface/include/tfm_api.h
new file mode 100644
index 0000000..d911f0c
--- /dev/null
+++ b/interface/include/tfm_api.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_API_H__
+#define __TFM_API_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* FixMe: sort out DEBUG compile option and limit return value options
+ * on external interfaces */
+/* Note:
+ * TFM will only return values recognized and parsed by TFM core.
+ * Service return codes are not automatically passed on to REE.
+ * Any non-zero return value is interpreted as an error that may trigger
+ * TEE error handling flow.
+ */
+enum tfm_status_e
+{
+ TFM_SUCCESS = 0,
+ TFM_SERVICE_PENDED,
+ TFM_SERVICE_BUSY,
+ TFM_ERROR_SERVICE_ALREADY_PENDED,
+ TFM_ERROR_SECURE_DOMAIN_LOCKED,
+ TFM_ERROR_INVALID_PARAMETER,
+ TFM_ERROR_SERVICE_NON_REENTRANT,
+ TFM_ERROR_NS_THREAD_MODE_CALL,
+ TFM_ERROR_INVALID_EXC_MODE,
+ TFM_SECURE_LOCK_FAILED,
+ TFM_SECURE_UNLOCK_FAILED,
+ TFM_ERROR_GENERIC = 0x1F,
+ TFM_SERVICE_SPECIFIC_ERROR_MIN,
+};
+
+//==================== Secure function declarations ==========================//
+
+/* Placeholder for secure function declarations defined by TF-M in the future */
+
+//================ End Secure function declarations ==========================//
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_API_H__ */
diff --git a/interface/include/tfm_id_mngr.h b/interface/include/tfm_id_mngr.h
new file mode 100644
index 0000000..dafe133
--- /dev/null
+++ b/interface/include/tfm_id_mngr.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_ID_MNGR_H__
+#define __TFM_ID_MNGR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+/**
+ * \brief Gets SST current application ID
+ *
+ * \return Returns the SST current application ID
+ */
+uint32_t tfm_sst_get_cur_id(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_ID_MNGR_H__ */
diff --git a/interface/include/tfm_ns_lock.h b/interface/include/tfm_ns_lock.h
new file mode 100644
index 0000000..7361aac
--- /dev/null
+++ b/interface/include/tfm_ns_lock.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#ifndef __TFM_NS_LOCK_H__
+#define __TFM_NS_LOCK_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "tfm_ns_svc.h"
+
+/**
+ * \brief NS world, NS lock based dispatcher
+ *
+ * \details To be called from the SVC wrapper API interface
+ */
+uint32_t tfm_ns_lock_svc_dispatch(enum tfm_svc_num svc_num,
+ uint32_t arg0,
+ uint32_t arg1,
+ uint32_t arg2,
+ uint32_t arg3);
+
+/**
+ * \brief NS world, Init NS lock
+ *
+ * \details Needs to be called during non-secure app init
+ * to initialize the TFM NS lock object
+ */
+uint32_t tfm_ns_lock_init();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_NS_LOCK_H__ */
diff --git a/interface/include/tfm_ns_svc.h b/interface/include/tfm_ns_svc.h
new file mode 100644
index 0000000..e83b076
--- /dev/null
+++ b/interface/include/tfm_ns_svc.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdio.h>
+#include <cmsis_compiler.h>
+
+#ifndef __TFM_NS_SVC_H__
+#define __TFM_NS_SVC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Macro to encode an svc instruction
+ *
+ */
+#define SVC(code) __ASM("svc %0" : : "I" (code))
+
+/**
+ * \brief Numbers associated to each SVC available
+ *
+ * \details Start from 1 as 0 is reserved by RTX
+ */
+enum tfm_svc_num {
+ SVC_INVALID = 0,
+
+/* SVC API for SST */
+ SVC_TFM_SST_GET_HANDLE,
+ SVC_TFM_SST_CREATE,
+ SVC_TFM_SST_GET_ATTRIBUTES,
+ SVC_TFM_SST_READ,
+ SVC_TFM_SST_WRITE,
+ SVC_TFM_SST_DELETE,
+
+#if defined(CORE_TEST_INTERACTIVE)
+ SVC_SECURE_DECREMENT_NS_LOCK_1,
+ SVC_SECURE_DECREMENT_NS_LOCK_2,
+#endif /* CORE_TEST_INTERACTIVE */
+
+#if defined(CORE_TEST_SERVICES)
+ SVC_TFM_CORE_TEST,
+ SVC_TFM_CORE_TEST_MULTIPLE_CALLS,
+#endif /* CORE_TEST_SERVICES */
+
+ /* add all the new entries above this line */
+ SVC_TFM_MAX,
+};
+
+/* number of user SVC functions */
+#define USER_SVC_COUNT (SVC_TFM_MAX - 1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_NS_SVC_H__ */
diff --git a/interface/include/tfm_sst_api.h b/interface/include/tfm_sst_api.h
new file mode 100644
index 0000000..3cdb64e
--- /dev/null
+++ b/interface/include/tfm_sst_api.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_SST_API__
+#define __TFM_SST_API__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Gets handler for the given asset UUID. If an asset is deleted, the
+ * linked asset handle reference is no longer valid and will give
+ * TFM_SST_ERR_ASSET_REF_INVALID if used.
+ *
+ * \param[in] asset_uuid Asset UUID
+ * \param[out] hdl Pointer to store the asset's handler
+ *
+ * \return Returns TFM_SST_ERR_SUCCESS if asset is found. Otherwise, error code
+ * as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_get_handle(uint16_t asset_uuid,
+ uint32_t* hdl);
+
+/**
+ * \brief Allocates space for the asset, referenced by asset handler,
+ * without setting any data in the asset.
+ *
+ * \param[in] asset_uuid Asset UUID
+ *
+ * \return Returns an TFM_SST_ERR_SUCCESS if asset is created correctly.
+ * Otherwise, error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_create(uint16_t asset_uuid);
+
+/**
+ * \brief Gets asset's attributes referenced by asset handler.
+ * Uses cached metadata to return the size and write offset of an asset.
+ *
+ * \param[in] asset_handle Asset handler
+ * \param[out] attrib_struct Pointer to store the asset's attribute
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_get_attributes(uint32_t asset_handle,
+ struct tfm_sst_attribs_t* attrib_struct);
+
+/**
+ * \brief Reads asset's data from asset referenced by asset handler.
+ *
+ * \param[in] asset_handle Asset handler
+ * \param[out] data Pointer to data vector \ref tfm_sst_buf_t to store
+ * data, size and offset
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_read(uint32_t asset_handle,
+ struct tfm_sst_buf_t* data);
+
+/**
+ * \brief Writes data into an asset referenced by asset handler.
+ *
+ * \param[in] asset_handle Asset handler
+ * \param[in] data Pointer to data vector \ref tfm_sst_buf_t which
+ * contains the data to write
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_write(uint32_t asset_handle,
+ struct tfm_sst_buf_t* data);
+
+/**
+ * \brief Deletes the asset referenced by the asset handler.
+ *
+ * \param[in] asset_handle Asset handler
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_delete(uint32_t asset_handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_SST_API__ */
diff --git a/interface/include/tfm_sst_defs.h b/interface/include/tfm_sst_defs.h
new file mode 100644
index 0000000..75e2a16
--- /dev/null
+++ b/interface/include/tfm_sst_defs.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_SST_DEFS_H__
+#define __TFM_SST_DEFS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <limits.h>
+#include "tfm_api.h"
+
+/* FIXME: the secure APP ID should not be share with the non-secure code
+ * as it is revealing information about secure code implementation.
+ */
+#define S_APP_ID 0xF0000000
+
+/* FIXME:
+ * Very descriptive error codes can leak implementation
+ * information to caller and may allow exploitation
+ * of implementation weaknesses by malicious actors.
+ * Potential approaches-
+ * a. Just return generic error for any kind of failure
+ *
+ * OR
+ *
+ * b. Non-secure callers get the generic failure, the
+ * secure side callers get a bit more detailed error
+ * codes.
+ */
+
+/* The return value is shared with the TFM service status value. The SST return
+ * codes shouldn't overlap with predefined TFM status values.
+ */
+#define TFM_SST_ERR_OFFSET (TFM_SERVICE_SPECIFIC_ERROR_MIN)
+
+enum tfm_sst_err_t {
+ TFM_SST_ERR_SUCCESS = 0,
+ TFM_SST_ERR_ASSET_NOT_PREPARED = TFM_SST_ERR_OFFSET,
+ TFM_SST_ERR_ASSET_NOT_FOUND,
+ TFM_SST_ERR_PARAM_ERROR,
+ TFM_SST_ERR_INVALID_HANDLE,
+ TFM_SST_ERR_STORAGE_SYSTEM_FULL,
+ TFM_SST_ERR_SYSTEM_ERROR,
+ /* Following entry is only to ensure the error code of int size */
+ TFM_SST_ERR_FORCE_INT_SIZE = INT_MAX
+};
+
+struct tfm_sst_attribs_t {
+ uint32_t size_current; /*!< The current size of the asset */
+ uint32_t size_max; /*!< The maximum size of the asset in bytes */
+};
+
+/* Structure to store data information to read/write from/to asset */
+struct tfm_sst_buf_t {
+ uint8_t* data; /*!< Address of input/output data */
+ uint32_t size; /*!< Size of input/output data */
+ uint32_t offset; /*!< Offset within asset */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_SST_DEFS_H__ */
diff --git a/interface/include/tfm_sst_svc_handler.h b/interface/include/tfm_sst_svc_handler.h
new file mode 100644
index 0000000..808c0ea
--- /dev/null
+++ b/interface/include/tfm_sst_svc_handler.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_SST_SVC_HANDLER_H__
+#define __TFM_SST_SVC_HANDLER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "tfm_sst_defs.h"
+
+/**
+ * \brief SVC funtion to get handler for the given asset UUID. If an asset is
+ * deleted, the linked asset handle reference is no longer valid and
+ * will give TFM_SST_ERR_ASSET_REF_INVALID if used.
+ *
+ * \param[in] asset_uuid Asset UUID
+ * \param[out] hdl Pointer to store the asset's handler
+ *
+ * \return Returns TFM_SST_ERR_SUCCESS if asset is found. Otherwise, error code
+ * as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_svc_get_handle(uint16_t asset_uuid,
+ uint32_t* hdl);
+
+/**
+ * \brief SVC funtion to allocate space for the asset, referenced by asset
+ * handler, without setting any data in the asset.
+ *
+ * \param[in] asset_uuid Asset UUID
+ *
+ * \return Returns an TFM_SST_ERR_SUCCESS if asset is created correctly.
+ * Otherwise, error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_svc_create(uint16_t asset_uuid);
+
+/**
+ * \brief SVC funtion to get asset's attributes referenced by asset handler.
+ * Uses cached metadata to return the size and write offset of an asset.
+ *
+ * \param[in] asset_handle Asset handler
+ * \param[out] attrib_struct Pointer to store asset's attribute
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_svc_get_attributes(uint32_t asset_handle,
+ struct tfm_sst_attribs_t* attrib_struct);
+
+/**
+ * \brief SVC funtion to read asset's data from asset referenced by asset
+ * handler.
+ *
+ * \param[in] asset_handle Asset handler
+ * \param[out] data Pointer to data vector \ref tfm_sst_buf_t to store
+ * data, size and offset
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_svc_read(uint32_t asset_handle,
+ struct tfm_sst_buf_t* data);
+
+/**
+ * \brief SVC funtion to write data into an asset referenced by asset handler.
+ *
+ * \param[in] asset_handle Asset handler
+ * \param[in] data Pointer to data vector \ref tfm_sst_buf_t which
+ * contains the data to write
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_svc_write(uint32_t asset_handle,
+ struct tfm_sst_buf_t* data);
+
+/**
+ * \brief SVC funtion to delete the asset referenced by the asset handler.
+ *
+ * \param[in] asset_handle Asset handler
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_svc_delete(uint32_t asset_handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_SST_SVC_HANDLER_H__ */
diff --git a/interface/include/tfm_sst_veneers.h b/interface/include/tfm_sst_veneers.h
new file mode 100644
index 0000000..791bbb0
--- /dev/null
+++ b/interface/include/tfm_sst_veneers.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_SST_VENEERS_H__
+#define __TFM_SST_VENEERS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "tfm_sst_defs.h"
+
+#define __cmse_secure_gateway \
+ __attribute__((cmse_nonsecure_entry, noinline, section("SFN")))
+
+/**
+ * \brief Gets handler for the given asset uuid. If an asset is deleted, the
+ * linked asset handle reference is no longer valid and will give
+ * TFM_SST_ERR_ASSET_REF_INVALID if used.
+ *
+ * \param[in] app_id Application ID
+ * \param[in] asset_uuid Asset UUID
+ * \param[out] hdl Handle to be returned
+ *
+ * \return Returns asset handle. If asset is not found, it returns
+ * TFM_SST_ERR_ASSET_NOT_FOUND. If SST area is not prepared, it returns
+ * TFM_SST_ERR_ASSET_NOT_PREPARED.
+ */
+enum tfm_sst_err_t tfm_sst_veneer_get_handle(uint32_t app_id,
+ uint16_t asset_uuid,
+ uint32_t *hdl)
+__cmse_secure_gateway;
+
+/**
+ * \brief Allocates space for the asset, referenced by asset handler,
+ * without setting any data in the asset.
+ *
+ * \param[in] app_id Application ID
+ * \param[in] asset_uuid Asset UUID
+ *
+ * \return Returns an asset handle. If SST area is not prepared, it returns
+ * TFM_SST_ERR_ASSET_NOT_PREPARED. If SST area is full, it returns
+ * TFM_SST_ERR_STORAGE_SYSTEM_FULL. If application id doesn't have the
+ * write rights, it returns TFM_SST_ERR_PERMS_NOT_ALLOWED.
+ */
+enum tfm_sst_err_t tfm_sst_veneer_create(uint32_t app_id, uint16_t asset_uuid)
+__cmse_secure_gateway;
+
+/**
+ * \brief Gets asset's attributes referenced by asset handler.
+ * Uses cached metadata to return the size and write offset of an asset.
+ *
+ * \param[in] app_id Application ID
+ * \param[in] asset_handle Asset handler
+ * \param[out] attrib_struct Pointer to asset attribute struct
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+extern enum tfm_sst_err_t tfm_sst_veneer_get_attributes(
+ uint32_t app_id,
+ uint32_t asset_handle,
+ struct tfm_sst_attribs_t *attrib_struct)
+__cmse_secure_gateway;
+
+/**
+ * \brief Reads asset's data from asset referenced by asset handler.
+ *
+ * \param[in] app_id Application ID
+ * \param[in] asset_handle Asset handler
+ * \param[in/out] data Pointer to data vector \ref tfm_sst_buf_t to
+ * store data, size and offset
+ *
+ * \return Returns the number of bytes written or a castable \ref tfm_sst_err_t
+ * value
+ */
+enum tfm_sst_err_t tfm_sst_veneer_read(uint32_t app_id,
+ uint32_t asset_handle,
+ struct tfm_sst_buf_t *data)
+__cmse_secure_gateway;
+
+/**
+ * \brief Writes data into an asset referenced by asset handler.
+ *
+ * \param[in] app_id Application ID
+ * \param[in] asset_handle Asset handler
+ * \param[in] data Pointer to data vector \ref tfm_sst_buf_t which
+ * contains the data to write
+ *
+ * \return Returns the number of bytes written or a castable \ref tfm_sst_err_t
+ * value
+ */
+enum tfm_sst_err_t tfm_sst_veneer_write(uint32_t app_id,
+ uint32_t asset_handle,
+ struct tfm_sst_buf_t *data)
+__cmse_secure_gateway;
+
+/**
+ * \brief Deletes the asset referenced by the asset handler.
+ *
+ * \param[in] app_id Application ID
+ * \param[in] asset_handle Asset handler
+ *
+ * \return Returns TFM_SST_ERR_PERMS_NOT_ALLOWED if the asset can't be deleted
+ * to by this app ID. Returns TFM_SST_ERR_ASSET_REF_INVALID, if asset
+ * no longer exists. Otherwise, TFM_SST_ERR_SUCCESS.
+ */
+enum tfm_sst_err_t tfm_sst_veneer_delete(uint32_t app_id,
+ uint32_t asset_handle)
+__cmse_secure_gateway;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_SST_VENEERS_H__ */
diff --git a/interface/src/tfm_id_mngr_dummy.c b/interface/src/tfm_id_mngr_dummy.c
new file mode 100644
index 0000000..c882c8a
--- /dev/null
+++ b/interface/src/tfm_id_mngr_dummy.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* FIXME: this TFM ID manager is only a stub implementation. It is system
+ * integrators responsibility to define a way of identifying the app id and
+ * based on their non secure side of the threat model. The secure side only
+ * checks if this is an ID belonging to NS side entities. The secure side
+ * doesn't make any attempt to challenge the app id value, this is left for NS
+ * side privileged code to implement.
+ */
+
+#include "tfm_id_mngr.h"
+
+#include <string.h>
+#include "cmsis_os2.h"
+
+#define INVALID_APP_ID 0
+
+/* FIXME: following two functions are meant to be internally
+ * available to RTX. The header file containing prototype of
+ * these functions has complex header inclusion which leads
+ * to compiler specific paths in CMSIS, which currently doesn't have
+ * clang variant. To simplify this, following functions are directly
+ * declared here (as opposed to header inclusion). After clear
+ * separation of S and NS builds this will require to be revisited
+ */
+extern osThreadId_t svcRtxThreadGetId(void);
+extern const char *svcRtxThreadGetName(osThreadId_t thread_id);
+
+/* Translation table pair between OS threads and SST app IDs */
+struct thread_sst_appid_pair {
+ const char* t_name; /*!< Task/Thread name */
+ uint32_t app_id; /*!< Application ID used in assets definition */
+};
+
+static struct thread_sst_appid_pair sst_ns_policy_table[] =
+{
+ {"Thread_A", 9},
+ {"Thread_B", 10},
+ {"Thread_C", 11},
+};
+
+static const char* get_active_task_name(void)
+{
+ const char* thread_name;
+
+ thread_name = svcRtxThreadGetName(svcRtxThreadGetId());
+
+ return thread_name;
+}
+
+uint32_t tfm_sst_get_cur_id(void)
+{
+ uint32_t i;
+ static uint32_t sst_table_size = (sizeof(sst_ns_policy_table) /
+ sizeof(sst_ns_policy_table[0]));
+ const char* p_thread_name;
+
+ p_thread_name = get_active_task_name();
+
+ for (i = 0; i < sst_table_size; i++) {
+ if (strcmp(sst_ns_policy_table[i].t_name, p_thread_name) == 0) {
+ return sst_ns_policy_table[i].app_id;
+ }
+ }
+
+ return INVALID_APP_ID;
+}
diff --git a/interface/src/tfm_ns_lock_rtx.c b/interface/src/tfm_ns_lock_rtx.c
new file mode 100644
index 0000000..cf5fd6d
--- /dev/null
+++ b/interface/src/tfm_ns_lock_rtx.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "cmsis.h"
+#include "cmsis_os2.h"
+
+#include "tfm_api.h"
+#include "tfm_ns_svc.h"
+
+/**
+ * \brief struct ns_lock_state type
+ */
+struct ns_lock_state
+{
+ bool init;
+ osMutexId_t id;
+};
+
+/**
+ * \brief ns_lock status
+ */
+static struct ns_lock_state ns_lock = {.init=false, .id=NULL};
+
+/**
+ * \brief Mutex properties, NS lock
+ */
+static const osMutexAttr_t ns_lock_attrib = {
+ .name = "ns_lock",
+ .attr_bits = osMutexPrioInherit
+};
+
+/**
+ * \def NUM_SVC_DISPATCHERS
+ *
+ */
+#define NUM_SVC_DISPATCHERS (6)
+
+/**
+ * \brief Naked functions associated to each
+ * SVC needed
+ */
+__attribute__((naked))
+static uint32_t tfm_svc_dispatch_SST_GET_HANDLE(uint32_t arg0, uint32_t arg1,
+ uint32_t arg2, uint32_t arg3)
+{
+ SVC(SVC_TFM_SST_GET_HANDLE);
+ __ASM("BX LR");
+}
+
+__attribute__((naked))
+static uint32_t tfm_svc_dispatch_SST_CREATE(uint32_t arg0, uint32_t arg1,
+ uint32_t arg2, uint32_t arg3)
+{
+ SVC(SVC_TFM_SST_CREATE);
+ __ASM("BX LR");
+}
+
+__attribute__((naked))
+static uint32_t tfm_svc_dispatch_SST_GET_ATTRIBUTES(uint32_t arg0,uint32_t arg1,
+ uint32_t arg2,uint32_t arg3)
+{
+ SVC(SVC_TFM_SST_GET_ATTRIBUTES);
+ __ASM("BX LR");
+}
+
+__attribute__((naked))
+static uint32_t tfm_svc_dispatch_SST_READ(uint32_t arg0, uint32_t arg1,
+ uint32_t arg2, uint32_t arg3)
+{
+ SVC(SVC_TFM_SST_READ);
+ __ASM("BX LR");
+}
+
+__attribute__((naked))
+static uint32_t tfm_svc_dispatch_SST_WRITE(uint32_t arg0, uint32_t arg1,
+ uint32_t arg2, uint32_t arg3)
+{
+ SVC(SVC_TFM_SST_WRITE);
+ __ASM("BX LR");
+}
+
+__attribute__((naked))
+static uint32_t tfm_svc_dispatch_SST_DELETE(uint32_t arg0, uint32_t arg1,
+ uint32_t arg2, uint32_t arg3)
+{
+ SVC(SVC_TFM_SST_DELETE);
+ __ASM("BX LR");
+}
+
+/**
+ * \brief Array with function pointers to the
+ * naked functions. Entry 0 is treated
+* as invalid
+ */
+static void *tfm_svc_dispatch_functions[NUM_SVC_DISPATCHERS+1] = {
+ (void *) NULL, /* SVC_INVALID */
+ (void *) tfm_svc_dispatch_SST_GET_HANDLE,
+ (void *) tfm_svc_dispatch_SST_CREATE,
+ (void *) tfm_svc_dispatch_SST_GET_ATTRIBUTES,
+ (void *) tfm_svc_dispatch_SST_READ,
+ (void *) tfm_svc_dispatch_SST_WRITE,
+ (void *) tfm_svc_dispatch_SST_DELETE
+};
+
+/**
+ * \brief NS world, NS lock based dispatcher
+ */
+uint32_t tfm_ns_lock_svc_dispatch(enum tfm_svc_num svc_num,
+ uint32_t arg0,
+ uint32_t arg1,
+ uint32_t arg2,
+ uint32_t arg3)
+{
+ uint32_t result;
+ uint32_t (*tfm_svc_dispatch_function_p)(uint32_t, uint32_t,
+ uint32_t, uint32_t);
+
+ /* Check the NS lock has been initialized */
+ if (ns_lock.init == false) {
+ return TFM_ERROR_GENERIC;
+ }
+
+ /* Validate the SVC number requested */
+ if ((svc_num > SVC_INVALID) && (svc_num < (NUM_SVC_DISPATCHERS+1))) {
+ tfm_svc_dispatch_function_p = tfm_svc_dispatch_functions[svc_num];
+
+ /* TFM request protected by NS lock */
+ osMutexAcquire(ns_lock.id,osWaitForever);
+ result = (*tfm_svc_dispatch_function_p)(arg0, arg1, arg2, arg3);
+ osMutexRelease(ns_lock.id);
+
+ return result;
+ }
+ else {
+ return TFM_ERROR_GENERIC;
+ }
+}
+
+/**
+ * \brief NS world, Init NS lock
+ */
+uint32_t tfm_ns_lock_init()
+{
+ if (ns_lock.init == false) {
+ ns_lock.id = osMutexNew(&ns_lock_attrib);
+ ns_lock.init = true;
+ return TFM_SUCCESS;
+ }
+ else {
+ return TFM_ERROR_GENERIC;
+ }
+}
diff --git a/interface/src/tfm_sst_api.c b/interface/src/tfm_sst_api.c
new file mode 100644
index 0000000..fb13ed0
--- /dev/null
+++ b/interface/src/tfm_sst_api.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_sst_defs.h"
+#include "tfm_ns_lock.h"
+
+enum tfm_sst_err_t tfm_sst_get_handle(uint16_t asset_uuid, uint32_t* hdl)
+{
+ return tfm_ns_lock_svc_dispatch(SVC_TFM_SST_GET_HANDLE,
+ (uint32_t)asset_uuid,
+ (uint32_t)hdl,
+ 0,
+ 0);
+}
+
+enum tfm_sst_err_t tfm_sst_create(uint16_t asset_uuid)
+{
+ return tfm_ns_lock_svc_dispatch(SVC_TFM_SST_CREATE,
+ (uint32_t) asset_uuid,
+ 0,
+ 0,
+ 0);
+}
+
+enum tfm_sst_err_t tfm_sst_get_attributes(uint32_t asset_handle,
+ struct tfm_sst_attribs_t* attrib_struct)
+{
+ return tfm_ns_lock_svc_dispatch(SVC_TFM_SST_GET_ATTRIBUTES,
+ (uint32_t)asset_handle,
+ (uint32_t)attrib_struct,
+ 0,
+ 0);
+}
+
+enum tfm_sst_err_t tfm_sst_read(uint32_t asset_handle, struct tfm_sst_buf_t* data)
+{
+ return tfm_ns_lock_svc_dispatch(SVC_TFM_SST_READ,
+ (uint32_t)asset_handle,
+ (uint32_t)data,
+ 0,
+ 0);
+}
+
+enum tfm_sst_err_t tfm_sst_write(uint32_t asset_handle, struct tfm_sst_buf_t* data)
+{
+ return tfm_ns_lock_svc_dispatch(SVC_TFM_SST_WRITE,
+ (uint32_t)asset_handle,
+ (uint32_t)data,
+ 0,
+ 0);
+}
+
+enum tfm_sst_err_t tfm_sst_delete(uint32_t asset_handle)
+{
+ return tfm_ns_lock_svc_dispatch(SVC_TFM_SST_DELETE,
+ (uint32_t)asset_handle,
+ 0,
+ 0,
+ 0);
+}
diff --git a/interface/src/tfm_sst_svc_handler.c b/interface/src/tfm_sst_svc_handler.c
new file mode 100644
index 0000000..c10432e
--- /dev/null
+++ b/interface/src/tfm_sst_svc_handler.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <string.h>
+#include "tfm_ns_svc.h"
+#include "tfm_sst_veneers.h"
+#include "tfm_id_mngr.h"
+
+/* SVC function implementations */
+enum tfm_sst_err_t tfm_sst_svc_get_handle(uint16_t asset_uuid,
+ uint32_t* hdl)
+{
+ uint32_t app_id;
+
+ app_id = tfm_sst_get_cur_id();
+
+ return tfm_sst_veneer_get_handle(app_id, asset_uuid, hdl);
+}
+
+enum tfm_sst_err_t tfm_sst_svc_create(uint16_t asset_uuid)
+{
+ uint32_t app_id;
+
+ app_id = tfm_sst_get_cur_id();
+
+ return tfm_sst_veneer_create(app_id, asset_uuid);
+}
+
+enum tfm_sst_err_t tfm_sst_svc_get_attributes(uint32_t asset_handle,
+ struct tfm_sst_attribs_t* attrib_struct)
+{
+ uint32_t app_id;
+
+ app_id = tfm_sst_get_cur_id();
+
+ return tfm_sst_veneer_get_attributes(app_id, asset_handle, attrib_struct);
+}
+
+enum tfm_sst_err_t tfm_sst_svc_read(uint32_t asset_handle,
+ struct tfm_sst_buf_t* data)
+{
+ uint32_t app_id;
+
+ app_id = tfm_sst_get_cur_id();
+
+ return tfm_sst_veneer_read(app_id, asset_handle, data);
+}
+
+enum tfm_sst_err_t tfm_sst_svc_write(uint32_t asset_handle,
+ struct tfm_sst_buf_t* data)
+{
+ uint32_t app_id;
+
+ app_id = tfm_sst_get_cur_id();
+
+ return tfm_sst_veneer_write(app_id, asset_handle, data);
+}
+
+enum tfm_sst_err_t tfm_sst_svc_delete(uint32_t asset_handle)
+{
+ uint32_t app_id;
+
+ app_id = tfm_sst_get_cur_id();
+
+ return tfm_sst_veneer_delete(app_id, asset_handle);
+}