Core: Add unpriv API to get caller client ID
Add tfm_core_get_caller_client_id(void) function to the unprivileged
TF-M core API. This function can only be called from secure partition.
Also add test case to test this function in the positive core test
suite.
Change-Id: I8dcd07b62f7bf8e43258695283cbb719a9357e48
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
diff --git a/platform/ext/target/mps2/an519/partition/region_defs.h b/platform/ext/target/mps2/an519/partition/region_defs.h
index 0dfd62a..dbf55aa 100644
--- a/platform/ext/target/mps2/an519/partition/region_defs.h
+++ b/platform/ext/target/mps2/an519/partition/region_defs.h
@@ -67,7 +67,7 @@
#define IMAGE_CODE_SIZE \
(FLASH_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)
-#define CMSE_VENEER_REGION_SIZE (0x000000E0)
+#define CMSE_VENEER_REGION_SIZE (0x00000100)
/* Use SRAM1 memory to store Code data */
#define S_ROM_ALIAS_BASE (0x10000000)
diff --git a/platform/ext/target/mps2/an521/partition/region_defs.h b/platform/ext/target/mps2/an521/partition/region_defs.h
index 82d96b6..3487d2f 100644
--- a/platform/ext/target/mps2/an521/partition/region_defs.h
+++ b/platform/ext/target/mps2/an521/partition/region_defs.h
@@ -67,7 +67,7 @@
#define IMAGE_CODE_SIZE \
(FLASH_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)
-#define CMSE_VENEER_REGION_SIZE (0x000000E0)
+#define CMSE_VENEER_REGION_SIZE (0x00000100)
/* Use SRAM1 memory to store Code data */
#define S_ROM_ALIAS_BASE (0x10000000)
diff --git a/platform/ext/target/musca_a/partition/region_defs.h b/platform/ext/target/musca_a/partition/region_defs.h
index 203ef74..013a76d 100755
--- a/platform/ext/target/musca_a/partition/region_defs.h
+++ b/platform/ext/target/musca_a/partition/region_defs.h
@@ -51,7 +51,7 @@
#define IMAGE_CODE_SIZE \
(FLASH_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)
-#define CMSE_VENEER_REGION_SIZE (0x000000E0)
+#define CMSE_VENEER_REGION_SIZE (0x00000100)
/*
* Since we enable/disable flash during s/ns code copy to code sram we cannot
diff --git a/secure_fw/core/tfm_handler.c b/secure_fw/core/tfm_handler.c
index 2e8b805..3085d7b 100644
--- a/secure_fw/core/tfm_handler.c
+++ b/secure_fw/core/tfm_handler.c
@@ -27,6 +27,9 @@
tfm_core_validate_secure_caller_handler(const uint32_t svc_args[]);
extern void
+ tfm_core_get_caller_client_id_handler(const uint32_t svc_args[]);
+
+extern void
tfm_core_memory_permission_check_handler(const uint32_t svc_args[]);
/* This SVC handler is called when a secure partition requests access to a
@@ -169,6 +172,9 @@
case TFM_SVC_VALIDATE_SECURE_CALLER:
tfm_core_validate_secure_caller_handler(svc_args);
break;
+ case TFM_SVC_GET_CALLER_CLIENT_ID:
+ tfm_core_get_caller_client_id_handler(svc_args);
+ break;
case TFM_SVC_MEMORY_CHECK:
tfm_core_memory_permission_check_handler(svc_args);
break;
diff --git a/secure_fw/core/tfm_secure_api.c b/secure_fw/core/tfm_secure_api.c
index 34af9a8..5491386 100644
--- a/secure_fw/core/tfm_secure_api.c
+++ b/secure_fw/core/tfm_secure_api.c
@@ -10,6 +10,7 @@
#include <stdbool.h>
#include "cmsis.h"
#include "tfm_secure_api.h"
+#include "tfm_nspm.h"
#include "secure_utilities.h"
#include "uart_stdout.h"
#include "secure_fw/spm/spm_api.h"
@@ -89,6 +90,8 @@
uint32_t partition_state;
uint32_t partition_flags;
struct tfm_exc_stack_t *svc_ctx = (struct tfm_exc_stack_t *)psp;
+ uint32_t caller_partition_id;
+ int32_t client_id;
/* Check partition idx validity */
if (caller_partition_idx == SPM_INVALID_PARTITION_IDX) {
@@ -119,10 +122,11 @@
curr_part_data = tfm_spm_partition_get_runtime_data(partition_idx);
partition_state = curr_part_data->partition_state;
partition_flags = tfm_spm_partition_get_flags(partition_idx);
+ caller_partition_id = tfm_spm_partition_get_partition_id(
+ caller_partition_idx);
if ((tfm_secure_api_initializing) &&
- (tfm_spm_partition_get_partition_id(caller_partition_idx)
- == TFM_SP_CORE_ID) &&
+ (caller_partition_id == TFM_SP_CORE_ID) &&
(partition_state == SPM_PARTITION_STATE_UNINIT)) {
#if TFM_LVL != 1
/* Make thread mode unprivileged while untrusted partition init is
@@ -163,6 +167,18 @@
caller_partition_idx);
tfm_spm_partition_store_context(caller_partition_idx, psp, excReturn);
+ if ((caller_flags&SPM_PART_FLAG_SECURE)) {
+ tfm_spm_partition_set_caller_client_id(partition_idx,
+ caller_partition_id);
+ } else {
+ client_id = tfm_nspm_get_current_client_id();
+ if (client_id >= 0)
+ {
+ return TFM_SECURE_LOCK_FAILED;
+ }
+ tfm_spm_partition_set_caller_client_id(partition_idx, client_id);
+ }
+
#if (TFM_LVL != 1) && (TFM_LVL != 2)
/* Dynamic partitioning is only done is TFM level 3 */
tfm_spm_partition_sandbox_deconfig(caller_partition_idx);
@@ -461,6 +477,115 @@
}
svc_args[0] = res;
}
+/**
+ * \brief Check whether a buffer is ok for writing to by the privileged API
+ * function.
+ *
+ * This function checks whether the caller partition owns the buffer, can write
+ * to it, and the buffer has proper alignment.
+ *
+ * \param[in] partition_idx Partition index
+ * \param[in] start_addr The start address of the buffer
+ * \param[in] len The length of the buffer
+ * \param[in] alignment The expected alignment (in bits)
+ *
+ * \return 1 if the check passes, 0 otherwise.
+ *
+ * \note For a 0 long buffer the check fails.
+ */
+static int32_t check_buffer_access(uint32_t partition_idx,
+ void* start_addr, size_t len,
+ uint32_t alignment)
+{
+ uintptr_t start_addr_value = (uintptr_t)start_addr;
+ uintptr_t end_addr_value = (uintptr_t)start_addr + len;
+ uintptr_t alignment_mask;
+
+ alignment_mask = (((uintptr_t)1) << alignment) - 1;
+
+ /* Check that the pointer is aligned properly */
+ if (start_addr_value & alignment_mask) {
+ /* not aligned, return error */
+ return 0;
+ }
+
+ /* Protect against overflow (and zero len) */
+ if (end_addr_value <= start_addr_value)
+ {
+ return 0;
+ }
+
+#if TFM_LVL == 1
+ /* For privileged partition execution, all secure data memory and stack
+ * is accessible
+ */
+ if (start_addr_value >= S_DATA_START &&
+ end_addr_value <= (S_DATA_START + S_DATA_SIZE)) {
+ return 1;
+ }
+#else
+ /* For non-privileged execution the partition's data and stack is
+ * accessible
+ */
+ if (start_addr_value >=
+ tfm_spm_partition_get_stack_bottom(partition_idx) &&
+ end_addr_value <=
+ tfm_spm_partition_get_stack_top(partition_idx)) {
+ return 1;
+ }
+ if (start_addr_value >=
+ tfm_spm_partition_get_rw_start(partition_idx) &&
+ end_addr_value <=
+ tfm_spm_partition_get_rw_limit(partition_idx)) {
+ return 1;
+ }
+ if (start_addr_value >=
+ tfm_spm_partition_get_zi_start(partition_idx) &&
+ end_addr_value <=
+ tfm_spm_partition_get_zi_limit(partition_idx)) {
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+void tfm_core_get_caller_client_id_handler(uint32_t *svc_args)
+{
+ uintptr_t result_ptr_value = svc_args[0];
+ uint32_t running_partition_idx =
+ tfm_spm_partition_get_running_partition_idx();
+ const uint32_t running_partition_flags =
+ tfm_spm_partition_get_flags(running_partition_idx);
+ const struct spm_partition_runtime_data_t *curr_part_data =
+ tfm_spm_partition_get_runtime_data(running_partition_idx);
+ int res = 0;
+
+ if (!(running_partition_flags&SPM_PART_FLAG_SECURE)) {
+ /* This handler shouldn't be called from outside partition context.
+ * Partitions are only allowed to run while S domain is locked.
+ */
+ svc_args[0] = TFM_ERROR_INVALID_PARAMETER;
+ return;
+ }
+
+ /* Make sure that the output pointer points to a memory area that is owned
+ * by the partition
+ */
+ res = check_buffer_access(running_partition_idx,
+ (void*)result_ptr_value,
+ sizeof(curr_part_data->caller_client_id),
+ 2);
+ if (!res) {
+ /* Not in accessible range, return error */
+ svc_args[0] = TFM_ERROR_INVALID_PARAMETER;
+ return;
+ }
+
+ *((int32_t *)result_ptr_value) = curr_part_data->caller_client_id;
+
+ /* Store return value in r0 */
+ svc_args[0] = TFM_SUCCESS;
+}
void tfm_core_memory_permission_check_handler(uint32_t *svc_args)
{
diff --git a/secure_fw/core/tfm_secure_api.h b/secure_fw/core/tfm_secure_api.h
index 3d4a9ae..25e76f8 100644
--- a/secure_fw/core/tfm_secure_api.h
+++ b/secure_fw/core/tfm_secure_api.h
@@ -73,6 +73,8 @@
extern int32_t tfm_core_validate_secure_caller(void);
+extern int32_t tfm_core_get_caller_client_id(int32_t *caller_client_id);
+
extern int32_t tfm_core_memory_permission_check(
void *ptr, uint32_t size, int32_t access);
diff --git a/secure_fw/core/tfm_svc.h b/secure_fw/core/tfm_svc.h
index 419ee66..9c4d1a5 100644
--- a/secure_fw/core/tfm_svc.h
+++ b/secure_fw/core/tfm_svc.h
@@ -14,6 +14,7 @@
TFM_SVC_SFN_REQUEST = 0,
TFM_SVC_SFN_RETURN,
TFM_SVC_VALIDATE_SECURE_CALLER,
+ TFM_SVC_GET_CALLER_CLIENT_ID,
TFM_SVC_MEMORY_CHECK,
TFM_SVC_SET_SHARE_AREA,
TFM_SVC_PRINT,
diff --git a/secure_fw/core/tfm_unpriv_api.c b/secure_fw/core/tfm_unpriv_api.c
index ceac806..6817c36 100644
--- a/secure_fw/core/tfm_unpriv_api.c
+++ b/secure_fw/core/tfm_unpriv_api.c
@@ -109,6 +109,15 @@
}
__attribute__((naked))
+int32_t tfm_core_get_caller_client_id(int32_t *caller_client_id)
+{
+ __ASM(
+ "SVC %0\n"
+ "BX LR\n"
+ : : "I" (TFM_SVC_GET_CALLER_CLIENT_ID));
+}
+
+__attribute__((naked))
int32_t tfm_core_validate_secure_caller(void)
{
__ASM(
diff --git a/secure_fw/spm/spm_api.c b/secure_fw/spm/spm_api.c
index ff68245..77bf5be 100644
--- a/secure_fw/spm/spm_api.c
+++ b/secure_fw/spm/spm_api.c
@@ -210,6 +210,30 @@
return g_spm_partition_db.partitions[partition_idx].memory_data.stack_top;
}
+uint32_t tfm_spm_partition_get_zi_start(uint32_t partition_idx)
+{
+ return g_spm_partition_db.partitions[partition_idx].
+ memory_data.zi_start;
+}
+
+uint32_t tfm_spm_partition_get_zi_limit(uint32_t partition_idx)
+{
+ return g_spm_partition_db.partitions[partition_idx].
+ memory_data.zi_limit;
+}
+
+uint32_t tfm_spm_partition_get_rw_start(uint32_t partition_idx)
+{
+ return g_spm_partition_db.partitions[partition_idx].
+ memory_data.rw_start;
+}
+
+uint32_t tfm_spm_partition_get_rw_limit(uint32_t partition_idx)
+{
+ return g_spm_partition_db.partitions[partition_idx].
+ memory_data.rw_limit;
+}
+
void tfm_spm_partition_set_stack(uint32_t partition_idx, uint32_t stack_ptr)
{
g_spm_partition_db.partitions[partition_idx].
@@ -260,6 +284,13 @@
caller_partition_idx = caller_partition_idx;
}
+void tfm_spm_partition_set_caller_client_id(uint32_t partition_idx,
+ int32_t caller_client_id)
+{
+ g_spm_partition_db.partitions[partition_idx].runtime_data.
+ caller_client_id = caller_client_id;
+}
+
enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
uint32_t share)
{
diff --git a/secure_fw/spm/spm_api.h b/secure_fw/spm/spm_api.h
index 67cbfbf..f0034af 100644
--- a/secure_fw/spm/spm_api.h
+++ b/secure_fw/spm/spm_api.h
@@ -42,6 +42,7 @@
struct spm_partition_runtime_data_t {
uint32_t partition_state;
uint32_t caller_partition_idx;
+ int32_t caller_client_id;
uint32_t share;
uint32_t stack_ptr;
uint32_t lr;
@@ -125,6 +126,52 @@
uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx);
/**
+ * \brief Get the start of the zero-initialised region for a partition
+ *
+ * \param[in] partition_idx Partition idx
+ *
+ * \return Start of the zero-initialised region
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ */
+uint32_t tfm_spm_partition_get_zi_start(uint32_t partition_idx);
+
+/**
+ * \brief Get the limit of the zero-initialised region for a partition
+ *
+ * \param[in] partition_idx Partition idx
+ *
+ * \return Limit of the zero-initialised region
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ * \note The address returned is not part of the region.
+ */
+uint32_t tfm_spm_partition_get_zi_limit(uint32_t partition_idx);
+
+/**
+ * \brief Get the start of the read-write region for a partition
+ *
+ * \param[in] partition_idx Partition idx
+ *
+ * \return Start of the read-write region
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ */
+uint32_t tfm_spm_partition_get_rw_start(uint32_t partition_idx);
+
+/**
+ * \brief Get the limit of the read-write region for a partition
+ *
+ * \param[in] partition_idx Partition idx
+ *
+ * \return Limit of the read-write region
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ * \note The address returned is not part of the region.
+ */
+uint32_t tfm_spm_partition_get_rw_limit(uint32_t partition_idx);
+
+/**
* \brief Get the current runtime data of a partition
*
* \param[in] partition_idx Partition index
@@ -189,6 +236,17 @@
uint32_t caller_partition_idx);
/**
+* \brief Set the caller client ID for a given partition
+*
+* \param[in] partition_idx Partition index
+* \param[in] caller_client_id The ID of the calling client
+*
+* \note This function doesn't check if any of the partition_idxs are valid.
+*/
+void tfm_spm_partition_set_caller_client_id(uint32_t partition_idx,
+ int32_t caller_client_id);
+
+/**
* \brief Set the buffer share region of the partition
*
* \param[in] partition_idx Partition index
diff --git a/test/suites/core/non_secure/core_ns_positive_testsuite.c b/test/suites/core/non_secure/core_ns_positive_testsuite.c
index ac5711b..9accf53 100644
--- a/test/suites/core/non_secure/core_ns_positive_testsuite.c
+++ b/test/suites/core/non_secure/core_ns_positive_testsuite.c
@@ -33,6 +33,7 @@
static void tfm_core_test_share_change(struct test_result_t *ret);
static void tfm_core_test_ss_to_ss_buffer(struct test_result_t *ret);
static void tfm_core_test_peripheral_access(struct test_result_t *ret);
+static void tfm_core_test_get_caller_client_id(struct test_result_t *ret);
static struct test_t core_tests[] = {
CORE_TEST_DESCRIPTION(CORE_TEST_ID_NS_THREAD, tfm_core_test_ns_thread,
@@ -59,6 +60,9 @@
CORE_TEST_DESCRIPTION(CORE_TEST_ID_PERIPHERAL_ACCESS,
tfm_core_test_peripheral_access,
"Test service peripheral access"),
+CORE_TEST_DESCRIPTION(CORE_TEST_ID_GET_CALLER_CLIENT_ID,
+ tfm_core_test_get_caller_client_id,
+ "Test get caller client ID function"),
};
void register_testsuite_ns_core_positive(struct test_suite_t *p_test_suite)
@@ -330,3 +334,23 @@
return;
}
}
+
+static void tfm_core_test_get_caller_client_id(struct test_result_t *ret)
+{
+ int32_t err;
+
+ args[0] = CORE_TEST_ID_GET_CALLER_CLIENT_ID;
+ err = tfm_core_test_call(tfm_core_test_sfn, args);
+
+ if (err != TFM_SUCCESS && err < TFM_PARTITION_SPECIFIC_ERROR_MIN) {
+ TEST_FAIL("Call to secure service should be successful.");
+ return;
+ }
+
+ if (err != CORE_TEST_ERRNO_SUCCESS) {
+ TEST_FAIL("The internal service call failed.");
+ return;
+ }
+
+ ret->val = TEST_PASSED;
+}
diff --git a/test/test_services/tfm_core_test/core_test_defs.h b/test/test_services/tfm_core_test/core_test_defs.h
index 4b36a44..9a44972 100644
--- a/test/test_services/tfm_core_test/core_test_defs.h
+++ b/test/test_services/tfm_core_test/core_test_defs.h
@@ -17,17 +17,18 @@
#include "tfm_api.h"
/* These definitions are used in symbols, only digits are permitted */
-#define CORE_TEST_ID_NS_THREAD 1001
-#define CORE_TEST_ID_CHECK_INIT 1003
-#define CORE_TEST_ID_RECURSION 1004
-#define CORE_TEST_ID_MEMORY_PERMISSIONS 1005
-#define CORE_TEST_ID_MPU_ACCESS 1006
-#define CORE_TEST_ID_BUFFER_CHECK 1007
-#define CORE_TEST_ID_SS_TO_SS 1008
-#define CORE_TEST_ID_SHARE_REDIRECTION 1009
-#define CORE_TEST_ID_SS_TO_SS_BUFFER 1010
-#define CORE_TEST_ID_PERIPHERAL_ACCESS 1012
-#define CORE_TEST_ID_BLOCK 2001
+#define CORE_TEST_ID_NS_THREAD 1001
+#define CORE_TEST_ID_CHECK_INIT 1003
+#define CORE_TEST_ID_RECURSION 1004
+#define CORE_TEST_ID_MEMORY_PERMISSIONS 1005
+#define CORE_TEST_ID_MPU_ACCESS 1006
+#define CORE_TEST_ID_BUFFER_CHECK 1007
+#define CORE_TEST_ID_SS_TO_SS 1008
+#define CORE_TEST_ID_SHARE_REDIRECTION 1009
+#define CORE_TEST_ID_SS_TO_SS_BUFFER 1010
+#define CORE_TEST_ID_PERIPHERAL_ACCESS 1012
+#define CORE_TEST_ID_GET_CALLER_CLIENT_ID 1013
+#define CORE_TEST_ID_BLOCK 2001
/* Use lower 16 bits in return value for error code, upper 16 for line number
* in test service
diff --git a/test/test_services/tfm_core_test/tfm_ss_core_test.c b/test/test_services/tfm_core_test/tfm_ss_core_test.c
index f10fd8c..27e1ea9 100644
--- a/test/test_services/tfm_core_test/tfm_ss_core_test.c
+++ b/test/test_services/tfm_core_test/tfm_ss_core_test.c
@@ -13,11 +13,27 @@
#include "test/test_services/tfm_core_test_2/tfm_ss_core_test_2_veneers.h"
#include "secure_fw/core/secure_utilities.h"
#include "tfm_secure_api.h"
+#include "spm_partition_defs.h"
#include "smm_mps2.h"
static int32_t partition_init_done;
+#define INVALID_NS_CLIENT_ID 0x49abcdef
+#define EXPECTED_NS_CLIENT_ID (-1)
+
+/* Don't initialise caller_partition_id_zi and expect it to be linked in the
+ * zero-initialised data area
+ */
+static int32_t caller_client_id_zi;
+
+/* Initialise caller_partition_id_rw and expect it to be linked in the
+ * read-write data area
+ */
+static int32_t caller_client_id_rw = INVALID_NS_CLIENT_ID;
+
+static int32_t* invalid_addresses [] = {(int32_t*)0x0, (int32_t*)0xFFF12000};
+
int32_t core_test_init(void)
{
partition_init_done = 1;
@@ -252,6 +268,49 @@
}
}
+static int32_t test_get_caller_client_id(void)
+{
+ /* Call to a special service that checks the caller service ID */
+ size_t i;
+ int32_t ret;
+ int32_t caller_client_id_stack = INVALID_NS_CLIENT_ID;
+
+ caller_client_id_zi = INVALID_NS_CLIENT_ID;
+
+ ret = tfm_core_test_2_check_caller_client_id();
+ if (ret != TFM_SUCCESS) {
+ return CORE_TEST_ERRNO_SLAVE_SP_CALL_FAILURE;
+ }
+
+ /* test with invalid output pointers */
+ for (i = 0; i < sizeof(invalid_addresses)/sizeof(invalid_addresses[0]); ++i)
+ {
+ ret = tfm_core_get_caller_client_id(invalid_addresses[i]);
+ if (ret != TFM_ERROR_INVALID_PARAMETER) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+ }
+
+ /* test with valid output pointers */
+ ret = tfm_core_get_caller_client_id(&caller_client_id_zi);
+ if (ret != TFM_SUCCESS || caller_client_id_zi != EXPECTED_NS_CLIENT_ID) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+
+ ret = tfm_core_get_caller_client_id(&caller_client_id_rw);
+ if (ret != TFM_SUCCESS || caller_client_id_rw != EXPECTED_NS_CLIENT_ID) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+
+ ret = tfm_core_get_caller_client_id(&caller_client_id_stack);
+ if (ret != TFM_SUCCESS ||
+ caller_client_id_stack != EXPECTED_NS_CLIENT_ID) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+
+ return TFM_SUCCESS;
+}
+
#ifdef CORE_TEST_INTERACTIVE
#define MPS2_USERPB0_BASE (0x50302008)
#define MPS2_USERPB0_MASK (0x1)
@@ -315,6 +374,8 @@
return test_ss_to_ss_buffer((uint32_t *)arg1, (uint32_t *)arg2, arg3);
case CORE_TEST_ID_PERIPHERAL_ACCESS:
return test_peripheral_access();
+ case CORE_TEST_ID_GET_CALLER_CLIENT_ID:
+ return test_get_caller_client_id();
case CORE_TEST_ID_BLOCK:
return test_block(arg1, arg2, arg3);
case CORE_TEST_ID_NS_THREAD:
diff --git a/test/test_services/tfm_core_test_2/manifest.yaml b/test/test_services/tfm_core_test_2/manifest.yaml
index cb4230e..8cf94c1 100644
--- a/test/test_services/tfm_core_test_2/manifest.yaml
+++ b/test/test_services/tfm_core_test_2/manifest.yaml
@@ -31,6 +31,14 @@
"non_secure_clients": true,
"minor_version": 1,
"minor_policy": "strict"
+ },
+ {
+ "sfid": "TFM_CORE_TEST_2_SFN_CHECK_CALLER_CLIENT_ID_SFID",
+ "signal": "TFM_CORE_TEST_2_SFN_CHECK_CALLER_CLIENT_ID",
+ "tfm_symbol": "spm_core_test_2_check_caller_client_id",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
}
],
"source_files": [
diff --git a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.c b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.c
index 165fbfe..052c0b0 100644
--- a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.c
+++ b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.c
@@ -9,8 +9,23 @@
#include "tfm_ss_core_test_2.h"
#include "tfm_api.h"
#include "tfm_secure_api.h"
+#include "spm_partition_defs.h"
#include "test/test_services/tfm_core_test/core_test_defs.h"
+#define INVALID_NS_CLIENT_ID 0x49abcdef
+
+/* Don't initialise caller_partition_id_zi and expect it to be linked in the
+ * zero-initialised data area
+ */
+static int32_t caller_client_id_zi;
+
+/* Initialise caller_partition_id_rw and expect it to be linked in the
+ * read-write data area
+ */
+static int32_t caller_client_id_rw = INVALID_NS_CLIENT_ID;
+
+static int32_t* invalid_addresses [] = {(int32_t*)0x0, (int32_t*)0xFFF12000};
+
/* FIXME: Add a testcase to test that a failed init makes the secure partition
* closed, and none of its functions can be called.
* A new test service for this purpose is to be added.
@@ -25,6 +40,43 @@
return TFM_SUCCESS;
}
+int32_t spm_core_test_2_check_caller_client_id(void)
+{
+ size_t i;
+ int32_t caller_client_id_stack = INVALID_NS_CLIENT_ID;
+ int32_t ret;
+
+ caller_client_id_zi = INVALID_NS_CLIENT_ID;
+
+ /* test with invalid output pointers */
+ for (i = 0; i < sizeof(invalid_addresses)/sizeof(invalid_addresses[0]); ++i)
+ {
+ ret = tfm_core_get_caller_client_id(invalid_addresses[i]);
+ if (ret != TFM_ERROR_INVALID_PARAMETER) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+ }
+
+ /* test with valid output pointers */
+ ret = tfm_core_get_caller_client_id(&caller_client_id_zi);
+ if (ret != TFM_SUCCESS || caller_client_id_zi != TFM_SP_CORE_TEST_ID) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+
+ ret = tfm_core_get_caller_client_id(&caller_client_id_rw);
+ if (ret != TFM_SUCCESS || caller_client_id_rw != TFM_SP_CORE_TEST_ID) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+
+ ret = tfm_core_get_caller_client_id(&caller_client_id_stack);
+ if (ret != TFM_SUCCESS ||
+ caller_client_id_stack != TFM_SP_CORE_TEST_ID) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+
+ return TFM_SUCCESS;
+}
+
/* Invert function */
#define SFN_INVERT_MAX_LEN 128
diff --git a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.h b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.h
index 8981694..e1d7bc0 100644
--- a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.h
+++ b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.h
@@ -36,6 +36,16 @@
int32_t spm_core_test_2_sfn_invert(
int32_t *res_ptr, uint32_t *in_ptr, uint32_t *out_ptr, int32_t len);
+/**
+ * \brief A minimal test secure function to be called from another partition.
+ *
+ * Checks the functionality of querying the client ID of the caller service.
+ *
+ * \return Returns \ref TFM_SUCCESS on success, \ref CORE_TEST_ERRNO_TEST_FAULT
+ * othervise.
+ */
+int32_t spm_core_test_2_check_caller_client_id(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_veneers.c b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_veneers.c
index 6ac3585..3ec7e38 100644
--- a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_veneers.c
+++ b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_veneers.c
@@ -27,3 +27,11 @@
spm_core_test_2_sfn_invert,
res_ptr, in_ptr, out_ptr, len);
}
+
+__tfm_secure_gateway_attributes__
+int32_t tfm_core_test_2_check_caller_client_id(void)
+{
+ TFM_CORE_SFN_REQUEST(TFM_SP_CORE_TEST_2_ID,
+ spm_core_test_2_check_caller_client_id,
+ 0, 0, 0, 0);
+}
diff --git a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_veneers.h b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_veneers.h
index a483a98..b556bdd 100644
--- a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_veneers.h
+++ b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_veneers.h
@@ -36,6 +36,17 @@
uint32_t *in_ptr,
uint32_t *out_ptr,
int32_t len);
+
+/**
+ * \brief A minimal test secure function to be called from another partition.
+ *
+ * Checks the functionality of querying the client ID of the caller service.
+ *
+ * \return Returns \ref TFM_SUCCESS on success, \ref CORE_TEST_ERRNO_TEST_FAULT
+ * othervise.
+ */
+int32_t tfm_core_test_2_check_caller_client_id(void);
+
#ifdef __cplusplus
}
#endif