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/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);
+}
+