Core: add PSA client API functions
NS client infrastructure for PSA API created in
conformance with v8M secure gateway call restrictions
and TF-M rules.
Note:
- S SVC handlers TBD
- Buffer read/write funtions TBD
- Sanity checks in S SVC handlers TBD
Change-Id: Ia2947c28247af699d337754db2f22e2e25235c41
Signed-off-by: Miklos Balint <miklos.balint@arm.com>
diff --git a/CommonConfig.cmake b/CommonConfig.cmake
index 964a51c..858126a 100644
--- a/CommonConfig.cmake
+++ b/CommonConfig.cmake
@@ -103,6 +103,8 @@
set (SERVICES_TEST_ENABLED OFF)
set (TEST_FRAMEWORK_S OFF)
set (TEST_FRAMEWORK_NS OFF)
+set (TFM_PSA_API ON)
+set (TFM_LEGACY_API ON)
if(${TARGET_PLATFORM} STREQUAL "AN521" OR ${TARGET_PLATFORM} STREQUAL "AN519")
set (REFERENCE_PLATFORM ON)
@@ -115,6 +117,14 @@
set(SERVICES_TEST_ENABLED ON)
endif()
+if (TFM_PSA_API)
+ add_definitions(-DTFM_PSA_API)
+endif()
+
+if (TFM_LEGACY_API)
+ add_definitions(-DTFM_LEGACY_API)
+endif()
+
if (SERVICES_TEST_ENABLED)
set(SERVICE_TEST_S ON)
set(SERVICE_TEST_NS ON)
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 59d1713..d7b3665 100755
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -60,6 +60,12 @@
)
endif()
+if (NOT DEFINED TFM_PSA_API)
+ message(FATAL_ERROR "Incomplete build configuration: TFM_PSA_API is undefined. ")
+elseif (TFM_PSA_API)
+ list(APPEND NS_APP_SRC "${INTERFACE_DIR}/src/tfm_psa_ns_api.c")
+endif()
+
set(BUILD_CMSIS_CORE On)
set(BUILD_RETARGET On)
set(BUILD_NATIVE_DRIVERS On)
diff --git a/interface/include/tfm_api.h b/interface/include/tfm_api.h
index fea137a..527a433 100644
--- a/interface/include/tfm_api.h
+++ b/interface/include/tfm_api.h
@@ -13,6 +13,7 @@
#endif
#include <stdint.h>
+#include "interface/include/psa_client.h"
#define TFM_INVALID_CLIENT_ID 0
@@ -73,6 +74,47 @@
*/
enum tfm_status_e tfm_register_client_id (int32_t ns_client_id);
+/**
+ * \brief Return version of secure function provided by secure binary
+ *
+ * \param[in] sid ID of secure service
+ *
+ * \return Version number of secure function
+ */
+uint32_t tfm_psa_version_veneer(uint32_t sid);
+
+/**
+ * \brief Connect to secure function
+ *
+ * \param[in] sid ID of secure service
+ * \param[in] minor_version Minor version of SF requested by client
+ *
+ * \return Returns handle to connection
+ */
+psa_handle_t tfm_psa_connect_veneer(uint32_t sid, uint32_t minor_version);
+
+/**
+ * \brief Call a secure function referenced by a connection handle
+ *
+ * \param[in] handle Handle to connection
+ * \param[in] in_vecs invec containing pointer/count of input vectors
+ * \param[in] out_vecs invec containing pointer/count of output vectors
+ *
+ * \return Returns \ref psa_error_t error code
+ */
+psa_error_t tfm_psa_call_veneer(psa_handle_t handle,
+ const psa_invec *in_vecs,
+ const psa_invec *out_vecs);
+
+/**
+ * \brief Close connection to secure function referenced by a connection handle
+ *
+ * \param[in] handle Handle to connection
+ *
+ * \return Returns \ref psa_error_t error code
+ */
+psa_error_t tfm_psa_close_veneer(psa_handle_t handle);
+
//================ End Secure function declarations ==========================//
#ifdef __cplusplus
diff --git a/interface/include/tfm_ns_psa_svc.h b/interface/include/tfm_ns_psa_svc.h
new file mode 100644
index 0000000..a1032f6
--- /dev/null
+++ b/interface/include/tfm_ns_psa_svc.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_NS_PSA_SVC_H__
+#define __TFM_NS_PSA_SVC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "interface/include/psa_client.h"
+
+uint32_t tfm_psa_ns_version(uint32_t sid);
+
+psa_handle_t tfm_psa_ns_connect(uint32_t sid, uint32_t minor_version);
+
+psa_error_t tfm_psa_ns_call(psa_handle_t handle,
+ const psa_invec *in_vecs,
+ const psa_invec *out_vecs);
+
+psa_error_t tfm_psa_ns_close(psa_handle_t handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_NS_PSA_SVC_H__ */
diff --git a/interface/src/tfm_psa_ns_api.c b/interface/src/tfm_psa_ns_api.c
new file mode 100644
index 0000000..80c3af8
--- /dev/null
+++ b/interface/src/tfm_psa_ns_api.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "interface/include/psa_client.h"
+#include "tfm_ns_lock.h"
+#include "tfm_api.h"
+
+/**** API functions ****/
+
+uint32_t psa_version(uint32_t sid)
+{
+ return tfm_ns_lock_dispatch((veneer_fn)tfm_psa_version_veneer,
+ sid,
+ 0,
+ 0,
+ 0);
+}
+
+psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version)
+{
+ return tfm_ns_lock_dispatch((veneer_fn)tfm_psa_connect_veneer,
+ sid,
+ minor_version,
+ 0,
+ 0);
+}
+
+psa_error_t psa_call(psa_handle_t handle,
+ const psa_invec *in_vec,
+ size_t in_len,
+ const psa_outvec *out_vec,
+ size_t out_len)
+{
+ /* Due to v8M restrictions, TF-M NS API needs to add another layer of
+ * serialization in order for NS to pass arguments to S
+ */
+ psa_invec in_vecs, out_vecs;
+ in_vecs.base = in_vec;
+ in_vecs.len = in_len;
+ out_vecs.base = out_vec;
+ out_vecs.len = out_len;
+ return tfm_ns_lock_dispatch((veneer_fn)tfm_psa_call_veneer,
+ (uint32_t)handle,
+ (uint32_t)&in_vecs,
+ (uint32_t)&out_vecs,
+ 0);
+}
+
+void psa_close(psa_handle_t handle)
+{
+ tfm_ns_lock_dispatch((veneer_fn)tfm_psa_close_veneer,
+ (uint32_t)handle,
+ 0,
+ 0,
+ 0);
+}
+
diff --git a/secure_fw/core/CMakeLists.inc b/secure_fw/core/CMakeLists.inc
index c7e4392..564209c 100644
--- a/secure_fw/core/CMakeLists.inc
+++ b/secure_fw/core/CMakeLists.inc
@@ -39,6 +39,12 @@
"${SS_CORE_DIR}/tfm_boot_data.c"
)
+if (NOT DEFINED TFM_PSA_API)
+ message(FATAL_ERROR "Incomplete build configuration: TFM_PSA_API is undefined. ")
+elseif (TFM_PSA_API)
+ list(APPEND SS_CORE_C_SRC "${SS_CORE_DIR}/tfm_psa_api_client.c")
+endif()
+
#Append all our source files to global lists.
list(APPEND ALL_SRC_C ${SS_CORE_C_SRC})
unset(SS_CORE_C_SRC)
diff --git a/secure_fw/core/tfm_psa_api_client.c b/secure_fw/core/tfm_psa_api_client.c
new file mode 100644
index 0000000..56bda99
--- /dev/null
+++ b/secure_fw/core/tfm_psa_api_client.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "secure_utilities.h"
+#include "tfm_secure_api.h"
+#include "tfm_api.h"
+
+/* FixMe: check if this is really needed */
+extern int32_t tfm_secure_lock;
+
+__attribute__ ((always_inline)) __STATIC_INLINE
+int32_t tfm_psa_veneer_sanity_check(void)
+{
+ int32_t ns_caller = cmse_nonsecure_caller();
+ uint32_t exc_num = __get_active_exc_num();
+
+ if (exc_num != EXC_NUM_SVCALL) {
+ return TFM_ERROR_INVALID_EXC_MODE;
+ }
+
+ if (ns_caller) {
+ if (tfm_secure_lock != 0) {
+ /* Secure domain is already locked!
+ * FixMe: Decide if this is a fault or permitted in case of PSA
+ * API usage
+ */
+ return TFM_ERROR_SECURE_DOMAIN_LOCKED;
+ }
+ } else {
+ /* Secure partition should not call a different secure partition
+ * using TFM PSA veneers
+ */
+ return TFM_ERROR_INVALID_EXC_MODE;
+ }
+ return TFM_SUCCESS;
+}
+
+/* Veneer implementation */
+
+/* FixMe: these functions need to have different attributes compared to those
+ * legacy veneers which may be called by secure partitions.
+ * They won't call legacy SFN but instead will be handlers for TF-M
+ */
+
+__tfm_secure_gateway_attributes__
+uint32_t tfm_psa_version_veneer(uint32_t sid)
+{
+ /* perform sanity check */
+ /* FixMe: pattern should follow guides on tfm core veneer return values */
+ if(tfm_psa_veneer_sanity_check() != TFM_SUCCESS) {
+ return TFM_ERROR_GENERIC;
+ }
+ /* return version number registered in manifest for given SID */
+ return TFM_SUCCESS;
+}
+
+__tfm_secure_gateway_attributes__
+psa_handle_t tfm_psa_connect_veneer(uint32_t sid, uint32_t minor_version)
+{
+ /* perform sanity check */
+ /* decide whether a connection can be established to a given SID.
+ * In case of library model, this function always returns a valid handle.
+ * In thread model, it needs to perform the procedures outlined in PSA IPC
+ */
+ return TFM_SUCCESS;
+}
+
+__tfm_secure_gateway_attributes__
+psa_error_t tfm_psa_call_veneer(psa_handle_t handle,
+ const psa_invec *in_vecs,
+ const psa_invec *out_vecs)
+{
+ /* perform sanity check */
+ /* In case of library model, call the function referenced by the handle
+ * In thread model, it needs to perform the procedures outlined in PSA IPC
+ */
+ return TFM_SUCCESS;
+}
+
+__tfm_secure_gateway_attributes__
+psa_error_t tfm_psa_close_veneer(psa_handle_t handle)
+{
+ /* perform sanity check */
+ /* Close connection referenced by handle */
+ return TFM_SUCCESS;
+}
diff --git a/secure_fw/core/tfm_secure_api.c b/secure_fw/core/tfm_secure_api.c
index 0b66ba5..863643b 100644
--- a/secure_fw/core/tfm_secure_api.c
+++ b/secure_fw/core/tfm_secure_api.c
@@ -36,7 +36,7 @@
/* This is the "Big Lock" on the secure side, to guarantee single entry
* to SPE
*/
-static int32_t tfm_secure_lock;
+int32_t tfm_secure_lock;
static int32_t tfm_secure_api_initializing = 1;
static int32_t *prepare_partition_ctx(