SST: IPC compatibility for Protected Storage
- Add IPC implementation for both secure and non-secure PS APIs.
- Update Secure Storage manifest to support IPC model.
- Add wrapper function for IPC model in tfm_sst_req_mngr.c.
- Increase the stack size to pass the test cases.
- Skip some test cases which are not supported in IPC model.
Change-Id: I80ba50fb6d46af773bbda2519e76c20776984951
Signed-off-by: Summer Qin <summer.qin@arm.com>
diff --git a/interface/include/tfm_sst_defs.h b/interface/include/tfm_sst_defs.h
index 9132cce..c997d64 100644
--- a/interface/include/tfm_sst_defs.h
+++ b/interface/include/tfm_sst_defs.h
@@ -15,6 +15,23 @@
/* Invalid UID */
#define TFM_SST_INVALID_UID 0
+#ifdef TFM_PSA_API
+/*
+ * Defines for SID and minor version number. These SIDs should align with the
+ * value in service manifest file.
+ */
+#define TFM_SST_SET_SID (0x00002000)
+#define TFM_SST_SET_MIN_VER (0x0001)
+#define TFM_SST_GET_SID (0x00002001)
+#define TFM_SST_GET_MIN_VER (0x0001)
+#define TFM_SST_GET_INFO_SID (0x00002002)
+#define TFM_SST_GET_INFO_MIN_VER (0x0001)
+#define TFM_SST_REMOVE_SID (0x00002003)
+#define TFM_SST_REMOVE_MIN_VER (0x0001)
+#define TFM_SST_GET_SUPPORT_SID (0x00002004)
+#define TFM_SST_GET_SUPPORT_MIN_VER (0x0001)
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/interface/src/tfm_sst_api.c b/interface/src/tfm_sst_api.c
index 260dbc2..0da82d0 100644
--- a/interface/src/tfm_sst_api.c
+++ b/interface/src/tfm_sst_api.c
@@ -9,8 +9,11 @@
#include "tfm_ns_lock.h"
#include "tfm_veneers.h"
+#include "tfm_sst_defs.h"
#define IOVEC_LEN(x) (uint32_t)(sizeof(x)/sizeof(x[0]))
+/* FixMe: Check if PSA framework header would provide similar macro. */
+#define TFM_PSA_HANDLE_IS_VALID(handle) ((handle) > (psa_handle_t)0)
psa_ps_status_t psa_ps_set(psa_ps_uid_t uid,
uint32_t data_length,
@@ -19,6 +22,9 @@
{
psa_status_t status;
psa_ps_status_t err;
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+#endif
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) },
@@ -30,12 +36,32 @@
{ .base = &err , .len = sizeof(err) }
};
+#ifdef TFM_PSA_API
+ if (p_data == NULL) {
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ handle = psa_connect(TFM_SST_SET_SID, TFM_SST_SET_MIN_VER);
+ if (!TFM_PSA_HANDLE_IS_VALID(handle)) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+
+ status = psa_call(handle, in_vec, IOVEC_LEN(in_vec), out_vec,
+ IOVEC_LEN(out_vec));
+
+ psa_close(handle);
+
+ if (status != PSA_SUCCESS) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+#else
status = tfm_ns_lock_dispatch((veneer_fn)tfm_tfm_sst_set_req_veneer,
(uint32_t)in_vec, IOVEC_LEN(in_vec),
(uint32_t)out_vec, IOVEC_LEN(out_vec));
if (status != PSA_SUCCESS) {
return PSA_PS_ERROR_OPERATION_FAILED;
}
+#endif
return err;
}
@@ -47,6 +73,9 @@
{
psa_status_t status;
psa_ps_status_t err;
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+#endif
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) },
@@ -58,6 +87,25 @@
{ .base = p_data, .len = data_length }
};
+#ifdef TFM_PSA_API
+ if (p_data == NULL) {
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ handle = psa_connect(TFM_SST_GET_SID, TFM_SST_GET_MIN_VER);
+ if (!TFM_PSA_HANDLE_IS_VALID(handle)) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+
+ status = psa_call(handle, in_vec, IOVEC_LEN(in_vec), out_vec,
+ IOVEC_LEN(out_vec));
+
+ psa_close(handle);
+
+ if (status != PSA_SUCCESS) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+#else
status = tfm_ns_lock_dispatch((veneer_fn)tfm_tfm_sst_get_req_veneer,
(uint32_t)in_vec, IOVEC_LEN(in_vec),
(uint32_t)out_vec, IOVEC_LEN(out_vec));
@@ -65,6 +113,7 @@
if (status != PSA_SUCCESS) {
return PSA_PS_ERROR_OPERATION_FAILED;
}
+#endif
return err;
}
@@ -73,6 +122,9 @@
{
psa_status_t status;
psa_ps_status_t err;
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+#endif
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) }
@@ -83,6 +135,21 @@
{ .base = p_info, .len = sizeof(*p_info) }
};
+#ifdef TFM_PSA_API
+ handle = psa_connect(TFM_SST_GET_INFO_SID, TFM_SST_GET_INFO_MIN_VER);
+ if (!TFM_PSA_HANDLE_IS_VALID(handle)) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+
+ status = psa_call(handle, in_vec, IOVEC_LEN(in_vec), out_vec,
+ IOVEC_LEN(out_vec));
+
+ psa_close(handle);
+
+ if (status != PSA_SUCCESS) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+#else
status = tfm_ns_lock_dispatch((veneer_fn)tfm_tfm_sst_get_info_req_veneer,
(uint32_t)in_vec, IOVEC_LEN(in_vec),
(uint32_t)out_vec, IOVEC_LEN(out_vec));
@@ -90,6 +157,7 @@
if (status != PSA_SUCCESS) {
return PSA_PS_ERROR_OPERATION_FAILED;
}
+#endif
return err;
}
@@ -98,6 +166,9 @@
{
psa_status_t status;
psa_ps_status_t err;
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+#endif
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) }
@@ -107,6 +178,21 @@
{ .base = &err, .len = sizeof(err) }
};
+#ifdef TFM_PSA_API
+ handle = psa_connect(TFM_SST_REMOVE_SID, TFM_SST_REMOVE_MIN_VER);
+ if (!TFM_PSA_HANDLE_IS_VALID(handle)) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+
+ status = psa_call(handle, in_vec, IOVEC_LEN(in_vec), out_vec,
+ IOVEC_LEN(out_vec));
+
+ psa_close(handle);
+
+ if (status != PSA_SUCCESS) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+#else
status = tfm_ns_lock_dispatch((veneer_fn)tfm_tfm_sst_remove_req_veneer,
(uint32_t)in_vec, IOVEC_LEN(in_vec),
(uint32_t)out_vec, IOVEC_LEN(out_vec));
@@ -114,6 +200,7 @@
if (status != PSA_SUCCESS) {
return PSA_PS_ERROR_OPERATION_FAILED;
}
+#endif
return err;
}
@@ -145,6 +232,9 @@
* uninitialised value in case the secure function fails.
*/
uint32_t support_flags = 0;
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+#endif
psa_outvec out_vec[] = {
{ .base = &support_flags, .len = sizeof(support_flags) }
@@ -153,9 +243,20 @@
/* The PSA API does not return an error, so any error from TF-M is
* ignored.
*/
+#ifdef TFM_PSA_API
+ handle = psa_connect(TFM_SST_GET_SUPPORT_SID, TFM_SST_GET_SUPPORT_MIN_VER);
+ if (!TFM_PSA_HANDLE_IS_VALID(handle)) {
+ return support_flags;
+ }
+
+ (void)psa_call(handle, NULL, 0, out_vec, IOVEC_LEN(out_vec));
+
+ psa_close(handle);
+#else
(void)tfm_ns_lock_dispatch((veneer_fn)tfm_tfm_sst_get_support_req_veneer,
(uint32_t)NULL, 0,
(uint32_t)out_vec, IOVEC_LEN(out_vec));
+#endif
return support_flags;
}
diff --git a/secure_fw/core/ipc/include/tfm_spm_signal_defs.h b/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
index 924de1f..0c1f01f 100644
--- a/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
+++ b/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
@@ -10,5 +10,6 @@
#include "test/test_services/tfm_ipc_service/tfm_ipc_service_partition.h"
#include "test/test_services/tfm_core_test/tfm_ss_core_test_signal.h"
#include "test/test_services/tfm_core_test_2/tfm_ss_core_test_2_signal.h"
+#include "secure_fw/services/secure_storage/tfm_sst_signal.h"
#endif
diff --git a/secure_fw/services/secure_storage/manifest.yaml b/secure_fw/services/secure_storage/manifest.yaml
index cc65894..86cefe0 100644
--- a/secure_fw/services/secure_storage/manifest.yaml
+++ b/secure_fw/services/secure_storage/manifest.yaml
@@ -10,9 +10,10 @@
"type": "PSA-ROT",
"priority": "NORMAL",
"id": "0x00000100",
- "entry_point": "tfm_sst_init",
+ "entry_point": "tfm_sst_req_mngr_init",
"stack_size": "0x2000",
"heap_size": "0x0400",
+ "tfm_partition_ipc": true,
"secure_functions": [
{
"sfid": "TFM_SST_SET_SFID",
@@ -55,6 +56,47 @@
"minor_policy": "strict"
}
],
+ "services" : [{
+ "name": "TFM_SST_SET_SID",
+ "sid": "0x00002000",
+ "signal": "TFM_SST_SET_SIG",
+ "non_secure_clients": "true",
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ },
+ {
+ "name": "TFM_SST_GET_SID",
+ "sid": "0x00002001",
+ "signal": "TFM_SST_GET_SIG",
+ "non_secure_clients": "true",
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ },
+ {
+ "name": "TFM_SST_GET_INFO_SID",
+ "sid": "0x00002002",
+ "signal": "TFM_SST_GET_INFO_SIG",
+ "non_secure_clients": "true",
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ },
+ {
+ "name": "TFM_SST_REMOVE_SID",
+ "sid": "0x00002003",
+ "signal": "TFM_SST_REMOVE_SIG",
+ "non_secure_clients": "true",
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ },
+ {
+ "name": "TFM_SST_GET_SUPPORT_SID",
+ "sid": "0x00002004",
+ "signal": "TFM_SST_GET_SUPPORT_SIG",
+ "non_secure_clients": "true",
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ }
+ ],
"source_files": [
"sst_encrypted_object.c",
"sst_object_system.c",
diff --git a/secure_fw/services/secure_storage/tfm_sst_req_mngr.c b/secure_fw/services/secure_storage/tfm_sst_req_mngr.c
index e00ab7c..8c7e577 100644
--- a/secure_fw/services/secure_storage/tfm_sst_req_mngr.c
+++ b/secure_fw/services/secure_storage/tfm_sst_req_mngr.c
@@ -10,6 +10,12 @@
#include "secure_fw/core/tfm_secure_api.h"
#include "tfm_api.h"
#include "tfm_protected_storage.h"
+#ifdef TFM_PSA_API
+#include "psa_client.h"
+#include "psa_service.h"
+#include "tfm_sst_signal.h"
+#include "flash_layout.h"
+#endif
psa_status_t tfm_sst_set_req(struct psa_invec *in_vec, size_t in_len,
struct psa_outvec *out_vec, size_t out_len)
@@ -219,3 +225,232 @@
return PSA_SUCCESS;
}
+
+#ifdef TFM_PSA_API
+typedef psa_status_t (*sst_func_t)(const psa_msg_t *msg);
+static uint8_t asset_data[SST_MAX_ASSET_SIZE] = {0};
+
+static psa_status_t tfm_sst_set_ipc(const psa_msg_t *msg)
+{
+ psa_ps_uid_t uid;
+ int32_t client_id;
+ psa_ps_create_flags_t create_flags;
+ size_t in_size[3], out_size, num = 0;
+ psa_ps_status_t err;
+
+ client_id = msg->client_id;
+ in_size[0] = msg->in_size[0];
+ in_size[1] = msg->in_size[1];
+ in_size[2] = msg->in_size[2];
+ out_size = msg->out_size[0];
+ if (in_size[0] != sizeof(psa_ps_uid_t) ||
+ in_size[2] != sizeof(psa_ps_create_flags_t) ||
+ out_size != sizeof(psa_ps_status_t)) {
+ /* The size of one of the arguments is incorrect */
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ num = psa_read(msg->handle, 0, &uid, in_size[0]);
+ if (num != in_size[0]) {
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (in_size[1] > SST_MAX_ASSET_SIZE) {
+ num = psa_read(msg->handle, 1, &asset_data, SST_MAX_ASSET_SIZE);
+ if (num != SST_MAX_ASSET_SIZE) {
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+ } else {
+ num = psa_read(msg->handle, 1, &asset_data, in_size[1]);
+ if (num != in_size[1]) {
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+ }
+
+ num = psa_read(msg->handle, 2, &create_flags, in_size[2]);
+ if (num != in_size[2]) {
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ err = tfm_sst_set(client_id, uid, in_size[1], asset_data, create_flags);
+ psa_write(msg->handle, 0, &err, out_size);
+ return PSA_SUCCESS;
+}
+
+static psa_status_t tfm_sst_get_ipc(const psa_msg_t *msg)
+{
+ psa_ps_uid_t uid;
+ int32_t client_id;
+ uint32_t data_offset;
+ size_t in_size[2], out_size[2], num = 0;
+ psa_ps_status_t err;
+
+ client_id = msg->client_id;
+ in_size[0] = msg->in_size[0];
+ in_size[1] = msg->in_size[1];
+ out_size[0] = msg->out_size[0];
+ out_size[1] = msg->out_size[1];
+ if (in_size[0] != sizeof(psa_ps_uid_t) ||
+ in_size[1] != sizeof(uint32_t) ||
+ out_size[0] != sizeof(psa_ps_status_t)) {
+ /* The size of one of the arguments is incorrect */
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ num = psa_read(msg->handle, 0, &uid, in_size[0]);
+ if (num != in_size[0]) {
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ num = psa_read(msg->handle, 1, &data_offset, in_size[1]);
+ if (num != in_size[1]) {
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ err = tfm_sst_get(client_id, uid, data_offset, out_size[1], asset_data);
+ psa_write(msg->handle, 0, &err, out_size[0]);
+ if (err == PSA_PS_SUCCESS) {
+ psa_write(msg->handle, 1, asset_data, out_size[1]);
+ }
+ return PSA_SUCCESS;
+}
+
+static psa_status_t tfm_sst_get_info_ipc(const psa_msg_t *msg)
+{
+ psa_ps_uid_t uid;
+ int32_t client_id;
+ struct psa_ps_info_t info;
+ size_t in_size, out_size[2], num = 0;
+ psa_ps_status_t err;
+
+ client_id = msg->client_id;
+ in_size = msg->in_size[0];
+ out_size[0] = msg->out_size[0];
+ out_size[1] = msg->out_size[1];
+ if (in_size != sizeof(psa_ps_uid_t) ||
+ out_size[0] != sizeof(psa_ps_status_t) ||
+ out_size[1] != sizeof(struct psa_ps_info_t)) {
+ /* The size of one of the arguments is incorrect */
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ num = psa_read(msg->handle, 0, &uid, in_size);
+ if (num != in_size) {
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ err = tfm_sst_get_info(client_id, uid, &info);
+ psa_write(msg->handle, 0, &err, out_size[0]);
+ if (err == PSA_PS_SUCCESS) {
+ psa_write(msg->handle, 1, &info, out_size[1]);
+ }
+ return PSA_SUCCESS;
+}
+
+static psa_status_t tfm_sst_remove_ipc(const psa_msg_t *msg)
+{
+ psa_ps_uid_t uid;
+ int32_t client_id;
+ size_t in_size, out_size, num = 0;
+ psa_ps_status_t err;
+
+ client_id = msg->client_id;
+ in_size = msg->in_size[0];
+ out_size = msg->out_size[0];
+ if (in_size != sizeof(psa_ps_uid_t) ||
+ out_size != sizeof(psa_ps_status_t)) {
+ /* The size of one of the arguments is incorrect */
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ num = psa_read(msg->handle, 0, &uid, in_size);
+ if (num != in_size) {
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ err = tfm_sst_remove(client_id, uid);
+ psa_write(msg->handle, 0, &err, out_size);
+ return PSA_SUCCESS;
+}
+
+static psa_status_t tfm_sst_get_support_ipc(const psa_msg_t *msg)
+{
+ size_t out_size;
+ uint32_t support_flags;
+
+ out_size = msg->out_size[0];
+ if (out_size != sizeof(support_flags)) {
+ /* The output argument size is incorrect */
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ support_flags = tfm_sst_get_support();
+ psa_write(msg->handle, 0, &support_flags, out_size);
+ return PSA_SUCCESS;
+}
+
+/*
+ * Fixme: Temporarily implement abort as infinite loop,
+ * will replace it later.
+ */
+static void tfm_abort(void)
+{
+ while (1)
+ ;
+}
+
+static void ps_signal_handle(psa_signal_t signal, sst_func_t pfn)
+{
+ psa_msg_t msg;
+ psa_status_t status;
+
+ status = psa_get(signal, &msg);
+ switch (msg.type) {
+ case PSA_IPC_CONNECT:
+ psa_reply(msg.handle, PSA_SUCCESS);
+ break;
+ case PSA_IPC_CALL:
+ status = pfn(&msg);
+ psa_reply(msg.handle, status);
+ break;
+ case PSA_IPC_DISCONNECT:
+ psa_reply(msg.handle, PSA_SUCCESS);
+ break;
+ default:
+ tfm_abort();
+ }
+}
+#endif /* TFM_PSA_API */
+
+psa_ps_status_t tfm_sst_req_mngr_init(void)
+{
+ psa_ps_status_t err;
+#ifdef TFM_PSA_API
+ psa_signal_t signals = 0;
+#endif
+
+ err = tfm_sst_init();
+ if (err != PSA_PS_SUCCESS) {
+ return err;
+ }
+
+#ifdef TFM_PSA_API
+ while (1) {
+ signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
+ if (signals & TFM_SST_SET_SIG) {
+ ps_signal_handle(TFM_SST_SET_SIG, tfm_sst_set_ipc);
+ } else if (signals & TFM_SST_GET_SIG) {
+ ps_signal_handle(TFM_SST_GET_SIG, tfm_sst_get_ipc);
+ } else if (signals & TFM_SST_GET_INFO_SIG) {
+ ps_signal_handle(TFM_SST_GET_INFO_SIG, tfm_sst_get_info_ipc);
+ } else if (signals & TFM_SST_REMOVE_SIG) {
+ ps_signal_handle(TFM_SST_REMOVE_SIG, tfm_sst_remove_ipc);
+ } else if (signals & TFM_SST_GET_SUPPORT_SIG) {
+ ps_signal_handle(TFM_SST_GET_SUPPORT_SIG, tfm_sst_get_support_ipc);
+ } else {
+ tfm_abort();
+ }
+ }
+#endif
+ return err;
+}
diff --git a/secure_fw/services/secure_storage/tfm_sst_secure_api.c b/secure_fw/services/secure_storage/tfm_sst_secure_api.c
index 905767e..d38bc5f 100644
--- a/secure_fw/services/secure_storage/tfm_sst_secure_api.c
+++ b/secure_fw/services/secure_storage/tfm_sst_secure_api.c
@@ -7,8 +7,11 @@
#include "psa_protected_storage.h"
#include "tfm_veneers.h"
+#include "tfm_sst_defs.h"
#define IOVEC_LEN(x) (sizeof(x)/sizeof(x[0]))
+/* FixMe: Check if PSA framework header would provide similar macro. */
+#define TFM_PSA_HANDLE_IS_VALID(handle) ((handle) > (psa_handle_t)0)
__attribute__((section("SFN")))
psa_ps_status_t psa_ps_set(psa_ps_uid_t uid,
@@ -18,6 +21,9 @@
{
psa_status_t status;
psa_ps_status_t err;
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+#endif
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) },
@@ -29,11 +35,31 @@
{ .base = &err , .len = sizeof(err) }
};
+#ifdef TFM_PSA_API
+ if (p_data == NULL) {
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ handle = psa_connect(TFM_SST_SET_SID, TFM_SST_SET_MIN_VER);
+ if (!TFM_PSA_HANDLE_IS_VALID(handle)) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+
+ status = psa_call(handle, in_vec, IOVEC_LEN(in_vec), out_vec,
+ IOVEC_LEN(out_vec));
+
+ psa_close(handle);
+
+ if (status != PSA_SUCCESS) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+#else
status = tfm_tfm_sst_set_req_veneer(in_vec, IOVEC_LEN(in_vec),
out_vec, IOVEC_LEN(out_vec));
if (status != PSA_SUCCESS) {
return PSA_PS_ERROR_OPERATION_FAILED;
}
+#endif
return err;
}
@@ -46,6 +72,9 @@
{
psa_status_t status;
psa_ps_status_t err;
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+#endif
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) },
@@ -57,11 +86,31 @@
{ .base = p_data, .len = data_length }
};
+#ifdef TFM_PSA_API
+ if (p_data == NULL) {
+ return PSA_PS_ERROR_INVALID_ARGUMENT;
+ }
+
+ handle = psa_connect(TFM_SST_GET_SID, TFM_SST_GET_MIN_VER);
+ if (!TFM_PSA_HANDLE_IS_VALID(handle)) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+
+ status = psa_call(handle, in_vec, IOVEC_LEN(in_vec), out_vec,
+ IOVEC_LEN(out_vec));
+
+ psa_close(handle);
+
+ if (status != PSA_SUCCESS) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+#else
status = tfm_tfm_sst_get_req_veneer(in_vec, IOVEC_LEN(in_vec),
out_vec, IOVEC_LEN(out_vec));
if (status != PSA_SUCCESS) {
return PSA_PS_ERROR_OPERATION_FAILED;
}
+#endif
return err;
}
@@ -71,6 +120,9 @@
{
psa_status_t status;
psa_ps_status_t err;
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+#endif
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) }
@@ -81,12 +133,28 @@
{ .base = p_info, .len = sizeof(*p_info) }
};
+#ifdef TFM_PSA_API
+ handle = psa_connect(TFM_SST_GET_INFO_SID, TFM_SST_GET_INFO_MIN_VER);
+ if (!TFM_PSA_HANDLE_IS_VALID(handle)) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+
+ status = psa_call(handle, in_vec, IOVEC_LEN(in_vec), out_vec,
+ IOVEC_LEN(out_vec));
+
+ psa_close(handle);
+
+ if (status != PSA_SUCCESS) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+#else
status = tfm_tfm_sst_get_info_req_veneer(in_vec, IOVEC_LEN(in_vec),
out_vec, IOVEC_LEN(out_vec));
if (status != PSA_SUCCESS) {
return PSA_PS_ERROR_OPERATION_FAILED;
}
+#endif
return err;
}
@@ -96,6 +164,9 @@
{
psa_status_t status;
psa_ps_status_t err;
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+#endif
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) }
@@ -105,12 +176,28 @@
{ .base = &err, .len = sizeof(err) }
};
+#ifdef TFM_PSA_API
+ handle = psa_connect(TFM_SST_REMOVE_SID, TFM_SST_REMOVE_MIN_VER);
+ if (!TFM_PSA_HANDLE_IS_VALID(handle)) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+
+ status = psa_call(handle, in_vec, IOVEC_LEN(in_vec), out_vec,
+ IOVEC_LEN(out_vec));
+
+ psa_close(handle);
+
+ if (status != PSA_SUCCESS) {
+ return PSA_PS_ERROR_OPERATION_FAILED;
+ }
+#else
status = tfm_tfm_sst_remove_req_veneer(in_vec, IOVEC_LEN(in_vec),
out_vec, IOVEC_LEN(out_vec));
if (status != PSA_SUCCESS) {
return PSA_PS_ERROR_OPERATION_FAILED;
}
+#endif
return err;
}
@@ -145,6 +232,9 @@
* uninitialised value in case the secure function fails.
*/
uint32_t support_flags = 0;
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+#endif
psa_outvec out_vec[] = {
{ .base = &support_flags, .len = sizeof(support_flags) }
@@ -153,8 +243,19 @@
/* The PSA API does not return an error, so any error from TF-M is
* ignored.
*/
+#ifdef TFM_PSA_API
+ handle = psa_connect(TFM_SST_GET_SUPPORT_SID, TFM_SST_GET_SUPPORT_MIN_VER);
+ if (!TFM_PSA_HANDLE_IS_VALID(handle)) {
+ return support_flags;
+ }
+
+ (void)psa_call(handle, NULL, 0, out_vec, IOVEC_LEN(out_vec));
+
+ psa_close(handle);
+#else
(void)tfm_tfm_sst_get_support_req_veneer(NULL, 0,
out_vec, IOVEC_LEN(out_vec));
+#endif
return support_flags;
}
diff --git a/secure_fw/services/secure_storage/tfm_sst_signal.h b/secure_fw/services/secure_storage/tfm_sst_signal.h
new file mode 100644
index 0000000..3e7eb1b
--- /dev/null
+++ b/secure_fw/services/secure_storage/tfm_sst_signal.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_SST_SIGNAL_H__
+#define __TFM_SST_SIGNAL_H__
+
+/*
+ * FixMe: hardcode it now, will add support to autogenerate these signal
+ * definitons later.
+ */
+/*
+ * Each Secure Partition has up to 32 different signals. A signal is represented
+ * as a single-bit value within a 32-bit integer.
+ * The following signals are reserved in all Secure Partitions:
+ * - 0x00000001U
+ * - 0x00000002U
+ * - 0x00000004U
+ * - 0x00000008U
+ * The remaining 28 general signals can be associated with other inputs to the
+ * Secure Partition.
+ */
+#define TFM_SST_SET_SIG (1 << (0 + 4))
+#define TFM_SST_GET_SIG (1 << (1 + 4))
+#define TFM_SST_GET_INFO_SIG (1 << (2 + 4))
+#define TFM_SST_REMOVE_SIG (1 << (3 + 4))
+#define TFM_SST_GET_SUPPORT_SIG (1 << (4 + 4))
+
+#endif /* __TFM_SST_SIGNAL_H__ */
diff --git a/secure_fw/services/tfm_partition_list.inc b/secure_fw/services/tfm_partition_list.inc
index 72da66f..228336b 100644
--- a/secure_fw/services/tfm_partition_list.inc
+++ b/secure_fw/services/tfm_partition_list.inc
@@ -12,8 +12,9 @@
/******** TFM_SP_STORAGE ********/
PARTITION_DECLARE(TFM_SP_STORAGE, 0
+ | SPM_PART_FLAG_IPC
, "PSA-ROT", 0x00000100, NORMAL);
-PARTITION_ADD_INIT_FUNC(TFM_SP_STORAGE, tfm_sst_init);
+PARTITION_ADD_INIT_FUNC(TFM_SP_STORAGE, tfm_sst_req_mngr_init);
/******** TFM_SP_AUDIT_LOG ********/
PARTITION_DECLARE(TFM_SP_AUDIT_LOG, 0
diff --git a/secure_fw/services/tfm_service_list.inc b/secure_fw/services/tfm_service_list.inc
index 696724b..1486c76 100644
--- a/secure_fw/services/tfm_service_list.inc
+++ b/secure_fw/services/tfm_service_list.inc
@@ -11,6 +11,11 @@
#define __TFM_SERVICE_LIST_INC__
/******** TFM_SP_STORAGE ********/
+{"TFM_SST_SET_SID", TFM_SP_STORAGE_ID, TFM_SST_SET_SIG, 0x00002000, true, 1, TFM_VERSION_POLICY_STRICT},
+{"TFM_SST_GET_SID", TFM_SP_STORAGE_ID, TFM_SST_GET_SIG, 0x00002001, true, 1, TFM_VERSION_POLICY_STRICT},
+{"TFM_SST_GET_INFO_SID", TFM_SP_STORAGE_ID, TFM_SST_GET_INFO_SIG, 0x00002002, true, 1, TFM_VERSION_POLICY_STRICT},
+{"TFM_SST_REMOVE_SID", TFM_SP_STORAGE_ID, TFM_SST_REMOVE_SIG, 0x00002003, true, 1, TFM_VERSION_POLICY_STRICT},
+{"TFM_SST_GET_SUPPORT_SID", TFM_SP_STORAGE_ID, TFM_SST_GET_SUPPORT_SIG, 0x00002004, true, 1, TFM_VERSION_POLICY_STRICT},
/******** TFM_SP_AUDIT_LOG ********/
diff --git a/secure_fw/spm/spm_db.h b/secure_fw/spm/spm_db.h
index 6b28f94..7bfaa3c 100644
--- a/secure_fw/spm/spm_db.h
+++ b/secure_fw/spm/spm_db.h
@@ -21,7 +21,7 @@
#define TFM_PARTITION_TYPE_APP "APPLICATION-ROT"
#define TFM_PARTITION_TYPE_PSA "PSA-ROT"
-#define TFM_STACK_SIZE 1024
+#define TFM_STACK_SIZE (1024 * 5)
#ifdef TFM_PSA_API
enum tfm_partition_priority {
diff --git a/test/suites/sst/secure/psa_ps_s_interface_testsuite.c b/test/suites/sst/secure/psa_ps_s_interface_testsuite.c
index 4993604..d8950eb 100644
--- a/test/suites/sst/secure/psa_ps_s_interface_testsuite.c
+++ b/test/suites/sst/secure/psa_ps_s_interface_testsuite.c
@@ -227,6 +227,7 @@
*/
static void tfm_sst_test_2003(struct test_result_t *ret)
{
+#ifndef TFM_PSA_API
psa_ps_status_t status;
const psa_ps_uid_t uid = TEST_UID_3;
const psa_ps_create_flags_t flags = PSA_PS_FLAG_NONE;
@@ -245,6 +246,7 @@
return;
}
+#endif
ret->val = TEST_PASSED;
}
@@ -254,6 +256,7 @@
*/
static void tfm_sst_test_2004(struct test_result_t *ret)
{
+#ifndef TFM_PSA_API
psa_ps_status_t status;
const psa_ps_uid_t uid = TEST_UID_1;
const psa_ps_create_flags_t flags = PSA_PS_FLAG_NONE;
@@ -274,6 +277,7 @@
return;
}
+#endif
ret->val = TEST_PASSED;
}
@@ -570,6 +574,7 @@
return;
}
+#ifndef TFM_PSA_API
/* Get with data length and offset set to invalid values */
read_len = INVALID_DATA_LEN;
offset = INVALID_OFFSET;
@@ -592,6 +597,7 @@
TEST_FAIL("Read data should be equal to original read data");
return;
}
+#endif
/* Call remove to clean up storage for the next test */
status = psa_ps_remove(uid);
@@ -613,7 +619,9 @@
const psa_ps_uid_t uid = TEST_UID_3;
const psa_ps_create_flags_t flags = PSA_PS_FLAG_NONE;
const uint32_t data_len = WRITE_DATA_SIZE;
+#ifndef TFM_PSA_API
const uint32_t offset = 0;
+#endif
uint8_t write_data[] = WRITE_DATA;
status = psa_ps_set(uid, data_len, write_data, flags);
@@ -629,11 +637,13 @@
*/
/* Get with NULL data pointer */
+#ifndef TFM_PSA_API
status = psa_ps_get(uid, offset, data_len, NULL);
if (status != PSA_PS_ERROR_OPERATION_FAILED) {
TEST_FAIL("Get should not succeed with NULL data pointer");
return;
}
+#endif
/* Call remove to clean up storage for the next test */
status = psa_ps_remove(uid);
@@ -798,11 +808,13 @@
*/
/* Get info with NULL info pointer */
+#ifndef TFM_PSA_API
status = psa_ps_get_info(uid, NULL);
if (status != PSA_PS_ERROR_OPERATION_FAILED) {
TEST_FAIL("Get info should not succeed with NULL info pointer");
return;
}
+#endif
/* Call remove to clean up storage for the next test */
status = psa_ps_remove(uid);