13 #include CMSIS_device_header
15 #include "tfm_plat_test.h"
23 #ifdef TFM_ENABLE_IRQ_TEST
24 #include "tfm_peripherals_def.h"
30 #define TOSTRING(x) #x
31 #define CORE_TEST_DESCRIPTION(number, fn, description) \
32 {fn, "TFM_CORE_TEST_"TOSTRING(number),\
33 description, {TEST_PASSED} }
36 static void tfm_core_test_get_caller_client_id(
struct test_result_t *ret);
37 static void tfm_core_test_spm_request(
struct test_result_t *ret);
39 static void tfm_core_test_ns_thread(
struct test_result_t *ret);
40 static void tfm_core_test_check_init(
struct test_result_t *ret);
41 #ifdef ENABLE_TFM_CORE_RECURSION_TESTS
42 static void tfm_core_test_recursion(
struct test_result_t *ret);
44 static void tfm_core_test_buffer_check(
struct test_result_t *ret);
45 static void tfm_core_test_ss_to_ss(
struct test_result_t *ret);
46 static void tfm_core_test_ss_to_ss_buffer(
struct test_result_t *ret);
47 #ifdef TFM_ENABLE_PERIPH_ACCESS_TEST
48 static void tfm_core_test_peripheral_access(
struct test_result_t *ret);
50 static void tfm_core_test_iovec_sanitization(
struct test_result_t *ret);
51 static void tfm_core_test_outvec_write(
struct test_result_t *ret);
52 #ifdef TFM_ENABLE_IRQ_TEST
59 static struct test_t core_tests[] = {
61 "Test service request from NS thread mode"),
63 "Test the success of service init"),
64 #ifdef ENABLE_TFM_CORE_RECURSION_TESTS
66 "Test direct recursion of secure services"),
68 #ifdef TFM_ENABLE_IRQ_TEST
74 "Test secure service buffer accesses"),
76 "Test secure service to service call"),
78 tfm_core_test_ss_to_ss_buffer,
79 "Test secure service to service call with buffer handling"),
80 #ifdef TFM_ENABLE_PERIPH_ACCESS_TEST
82 tfm_core_test_peripheral_access,
83 "Test service peripheral access"),
87 tfm_core_test_get_caller_client_id,
88 "Test get caller client ID function"),
90 tfm_core_test_spm_request,
91 "Test SPM request function"),
94 tfm_core_test_iovec_sanitization,
95 "Test service parameter sanitization"),
97 tfm_core_test_outvec_write,
105 list_size = (
sizeof(core_tests) /
sizeof(core_tests[0]));
107 set_testsuite(
"Core non-secure positive tests (TFM_CORE_TEST_1XXX)",
108 core_tests, list_size, p_test_suite);
112 static psa_status_t psa_test_common(uint32_t sid, uint32_t version,
139 psa_invec in_vec[] = { {&test_case_id,
sizeof(int32_t)} };
141 err = tfm_spm_core_test_sfn_veneer(in_vec, 1, NULL, 0);
149 TEST_FAIL(
"Secure function call from thread mode should be successful");
156 #ifdef TFM_ENABLE_PERIPH_ACCESS_TEST
157 static void tfm_core_test_peripheral_access(
struct test_result_t *ret)
163 psa_invec in_vec[] = { {&test_case_id,
sizeof(int32_t)} };
178 TEST_FAIL(
"Service peripheral access failed.");
181 TEST_FAIL(
"Unexpected return value received.");
193 invec[i].
base = NULL;
195 outvec[i].
base = NULL;
205 invec[i].
base = invec + i;
207 outvec[i].
base = outvec;
211 static void tfm_core_test_iovec_sanitization(
struct test_result_t *ret)
215 {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0} };
217 {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0} };
226 empty_iovecs(in_vec, out_vec);
240 TEST_FAIL(
"iovec sanitization failed on empty vectors.");
245 full_iovecs(in_vec, out_vec);
255 in_vec, 2, out_vec, 2);
258 TEST_FAIL(
"iovec sanitization failed on full vectors.");
263 full_iovecs(in_vec, out_vec);
273 in_vec, 2, out_vec, 1);
277 "iovec sanitization failed on valid, partially full vectors.");
288 full_iovecs(in_vec, out_vec);
289 out_vec[1].
base = NULL;
299 in_vec, 2, out_vec, 1);
302 TEST_FAIL(
"content of an outvec out of range should not be checked");
309 full_iovecs(in_vec, out_vec);
320 in_vec, 2, out_vec, 1);
323 TEST_FAIL(
"content of an outvec out of range should not be checked");
328 full_iovecs(in_vec, out_vec);
330 in_vec[1].
base = NULL;
340 in_vec, 2, out_vec, 2);
343 TEST_FAIL(
"If the len of an invec is 0, the base should be ignored");
348 full_iovecs(in_vec, out_vec);
350 out_vec[1].
base = NULL;
360 in_vec, 2, out_vec, 2);
363 TEST_FAIL(
"If the len of an outvec is 0, the base should be ignored");
370 static void tfm_core_test_outvec_write(
struct test_result_t *ret)
374 uint8_t in_buf_0[] = {0, 1, 2, 3, 4};
375 uint8_t in_buf_1[] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89};
376 uint8_t out_buf_0[
sizeof(in_buf_0)];
377 uint8_t out_buf_1[
sizeof(in_buf_1)];
380 {in_buf_1,
sizeof(in_buf_1)} };
382 {out_buf_1,
sizeof(out_buf_1)} };
393 in_vec, 2, out_vec, 2);
397 TEST_FAIL(
"call to secure function should be successful");
401 if (out_vec[0].len !=
sizeof(in_buf_0)/2 ||
402 out_vec[1].len !=
sizeof(in_buf_1)/2) {
403 TEST_FAIL(
"Number of elements in outvec is not set properly");
406 for (i = 1; i <
sizeof(in_buf_0); i += 2) {
407 if (((uint8_t *)out_vec[0].base)[i/2] != in_buf_0[i]) {
412 for (i = 1; i <
sizeof(in_buf_1); i += 2) {
413 if (((uint8_t *)out_vec[1].base)[i/2] != in_buf_1[i]) {
421 in_vec[0].base = &test_case_id;
422 in_vec[0].len =
sizeof(int32_t);
427 in_vec, 0, out_vec, 0);
431 TEST_FAIL(
"Failed to execute secure side test");
438 #ifdef TFM_ENABLE_IRQ_TEST
439 static int32_t prepare_test_scenario_ns(
443 executing_irq_test_scenario = test_scenario;
444 switch (test_scenario) {
455 tfm_plat_test_non_secure_timer_start();
464 static int32_t execute_test_scenario_ns(
469 switch (test_scenario) {
493 void TIMER1_Handler (
void)
495 tfm_plat_test_non_secure_timer_stop();
497 switch (executing_irq_test_scenario) {
516 static int32_t tfm_core_test_irq_scenario(
520 &irq_test_execution_data;
521 uint32_t scenario = test_scenario;
524 {&scenario,
sizeof(uint32_t)},
525 {&execution_data_address,
534 err = tfm_spm_irq_test_1_prepare_test_scenario_veneer(in_vec, 2, NULL, 0);
545 err = tfm_spm_core_test_2_prepare_test_scenario_veneer(in_vec, 2, NULL, 0);
551 err = prepare_test_scenario_ns(test_scenario, &irq_test_execution_data);
561 err = tfm_spm_irq_test_1_execute_test_scenario_veneer(in_vec, 1, NULL, 0);
572 err = tfm_spm_core_test_2_execute_test_scenario_veneer(in_vec, 1, NULL, 0);
578 err = execute_test_scenario_ns(test_scenario, &irq_test_execution_data);
591 &irq_test_execution_data;
595 {&scenario,
sizeof(uint32_t)},
596 {&execution_data_address,
599 NVIC_EnableIRQ(TFM_TIMER1_IRQ);
603 TEST_FAIL(
"Failed to execute IRQ test scenario 1.");
609 TEST_FAIL(
"Failed to execute IRQ test scenario 2.");
615 TEST_FAIL(
"Failed to execute IRQ test scenario 3.");
621 TEST_FAIL(
"Failed to execute IRQ test scenario 4.");
627 TEST_FAIL(
"Failed to execute IRQ test scenario 5.");
637 err = tfm_spm_irq_test_1_prepare_test_scenario_veneer(in_vec, 2, NULL, 0);
640 TEST_FAIL(
"Failed to tear down IRQ tests");
652 static void tfm_core_test_check_init(
struct test_result_t *ret)
666 TEST_FAIL(
"Failed to initialise test service.");
673 #ifdef ENABLE_TFM_CORE_RECURSION_TESTS
677 static void tfm_core_test_recursion(
struct test_result_t *ret)
685 TEST_FAIL(
"The test case is not implemented yet.");
689 static void tfm_core_test_buffer_check(
struct test_result_t *ret)
693 uint32_t inbuf[] = {1, 2, 3, 4, 0xAAAFFF, 0xFFFFFFFF};
694 uint32_t outbuf[16] = {0};
696 psa_invec in_vec[] = { {inbuf,
sizeof(inbuf)} };
697 psa_outvec outvec[] = { {outbuf,
sizeof(outbuf)},
698 {&result,
sizeof(int32_t)} };
706 in_vec, 1, outvec, 2);
709 TEST_FAIL(
"Call to secure service should be successful.");
713 for (i = 0; i < sizeof(inbuf) >> 2; i++) {
714 if (outbuf[i] != ~inbuf[i]) {
715 TEST_FAIL(
"Secure function failed to modify buffer.");
719 for (; i < sizeof(outbuf) >> 2; i++) {
720 if (outbuf[i] != 0) {
721 TEST_FAIL(
"Secure function buffer access overflow.");
726 TEST_FAIL(
"Secure service returned error.");
733 static void tfm_core_test_ss_to_ss(
struct test_result_t *ret)
739 psa_invec in_vec[] = { {&test_case_id,
sizeof(int32_t)} };
750 TEST_FAIL(
"The internal service call failed.");
757 static void tfm_core_test_ss_to_ss_buffer(
struct test_result_t *ret)
761 uint32_t inbuf[] = {1, 2, 3, 4, 0xAAAFFF, 0xFFFFFFFF};
762 uint32_t outbuf[16] = {0};
763 int32_t len = (int32_t)
sizeof(inbuf) >> 2;
764 psa_outvec out_vec[] = { {outbuf,
sizeof(outbuf)} };
767 psa_invec in_vec[] = { {&test_case_id,
sizeof(int32_t)},
768 {inbuf,
sizeof(inbuf)},
769 {&len,
sizeof(int32_t)} };
774 psa_invec in_vec[] = {{inbuf,
sizeof(inbuf)},
775 {&len,
sizeof(int32_t)} };
779 in_vec, 2, out_vec, 1);
783 for (i = 0; i < sizeof(inbuf) >> 2; i++) {
784 if (outbuf[i] != ~inbuf[i]) {
785 TEST_FAIL(
"Secure function failed to modify buffer.");
789 for (; i < sizeof(outbuf) >> 2; i++) {
790 if (outbuf[i] != 0) {
791 TEST_FAIL(
"Secure function buffer access overflow.");
798 TEST_FAIL(
"NS buffer rejected by TF-M core.");
804 TEST_FAIL(
"Slave secure function failed to modify buffer.");
807 TEST_FAIL(
"Secure service returned error.");
813 static void tfm_core_test_get_caller_client_id(
struct test_result_t *ret)
817 psa_invec in_vec[] = { {&test_case_id,
sizeof(int32_t)} };
823 TEST_FAIL(
"The internal service call failed.");
830 static void tfm_core_test_spm_request(
struct test_result_t *ret)
835 psa_invec in_vec[] = { {&test_case_id,
sizeof(int32_t)} };
#define CORE_TEST_ID_RECURSION
#define SPM_CORE_TEST_SPM_REQUEST_VERSION
#define SPM_CORE_TEST_2_INVERT_SID
void register_testsuite_ns_core_positive(struct test_suite_t *p_test_suite)
Register testsuite for the core positive tests.
int32_t tfm_core_test_call(int32_t(*fn_ptr)(struct psa_invec *, size_t, struct psa_outvec *, size_t), struct tfm_core_test_call_args_t *args)
struct psa_invec psa_invec
#define SPM_CORE_TEST_SS_TO_SS_BUFFER_VERSION
#define SPM_CORE_TEST_INIT_SUCCESS_SID
#define CORE_TEST_ID_SECURE_IRQ
#define TEST_FAIL(info_msg)
#define SPM_CORE_TEST_NS_THREAD_SID
#define SPM_CORE_TEST_PERIPHERAL_ACCESS_SID
#define CORE_TEST_ID_PERIPHERAL_ACCESS
volatile int32_t timer1_triggered
#define SPM_CORE_TEST_OUTVEC_WRITE_VERSION
enum test_suite_err_t set_testsuite(const char *name, struct test_t *test_list, uint32_t size, struct test_suite_t *p_ts)
Sets test suite parameters.
This structure is to pass iovec arguments to the tfm_core_test_call function.
#define SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_SID
#define SPM_CORE_TEST_SS_TO_SS_VERSION
void psa_close(psa_handle_t handle)
Close a connection to an RoT Service.
#define CORE_TEST_ID_BUFFER_CHECK
#define CORE_TEST_ID_CHECK_INIT
#define SPM_CORE_TEST_2_SLAVE_SERVICE_VERSION
#define CORE_TEST_DESCRIPTION(number, fn, description)
#define CORE_TEST_ID_IOVEC_SANITIZATION
#define CORE_TEST_ID_NS_THREAD
psa_handle_t psa_connect(uint32_t sid, uint32_t version)
Connect to an RoT Service by its SID.
struct psa_outvec psa_outvec
#define SPM_CORE_TEST_SS_TO_SS_SID
#define CORE_TEST_ID_SS_TO_SS
#define SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_VERSION
#define SPM_CORE_TEST_SPM_REQUEST_SID
#define SPM_CORE_TEST_SS_TO_SS_BUFFER_SID
#define SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_VERSION
#define SPM_CORE_TEST_2_SLAVE_SERVICE_SID
struct psa_outvec * out_vec
#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SID
#define SPM_CORE_TEST_NS_THREAD_VERSION
#define SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_VERSION
#define CORE_TEST_ID_GET_CALLER_CLIENT_ID
struct psa_invec * in_vec
#define SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_SID
#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_VERSION
#define SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SID
#define CORE_TEST_ID_SPM_REQUEST
#define SPM_CORE_TEST_2_INVERT_VERSION
#define SPM_CORE_TEST_INIT_SUCCESS_VERSION
#define SPM_CORE_TEST_OUTVEC_WRITE_SID
int32_t psa_status_t
Function return status.
#define SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_VERSION
psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len)
Call an RoT Service on an established connection.
volatile int32_t timer0_triggered
#define SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_SID
#define SPM_CORE_TEST_PERIPHERAL_ACCESS_VERSION
#define CORE_TEST_ID_SS_TO_SS_BUFFER
#define CORE_TEST_ID_OUTVEC_WRITE