TF-M Reference Manual  1.2.0
TrustedFirmware-M
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
core_ns_positive_testsuite.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2020, Arm Limited. All rights reserved.
3  * Copyright (c) 2020, Cypress Semiconductor Corporation. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  */
8 
9 #include <stdio.h>
10 #include <string.h>
11 
12 #include "core_ns_tests.h"
13 #include CMSIS_device_header
14 #include "tfm_api.h"
15 #include "tfm_plat_test.h"
16 #include "core_test_api.h"
17 #include "core_test_defs.h"
18 #ifdef TFM_PSA_API
19 #include "psa_manifest/sid.h"
20 #else /* TFM_PSA_API */
21 #include "tfm_veneers.h"
22 #endif /* TFM_PSA_API */
23 #ifdef TFM_ENABLE_IRQ_TEST
24 #include "tfm_peripherals_def.h"
25 #endif
26 
27 /* Define test suite for core tests */
28 /* List of tests */
29 
30 #define TOSTRING(x) #x
31 #define CORE_TEST_DESCRIPTION(number, fn, description) \
32  {fn, "TFM_CORE_TEST_"TOSTRING(number),\
33  description, {TEST_PASSED} }
34 
35 #ifndef TFM_PSA_API
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);
38 #endif /* TFM_PSA_API */
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);
43 #endif
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);
49 #endif
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
53 static void tfm_core_test_irq(struct test_result_t *ret);
54 
55 static enum irq_test_scenario_t executing_irq_test_scenario = IRQ_TEST_SCENARIO_NONE;
56 static struct irq_test_execution_data_t irq_test_execution_data = {0};
57 #endif
58 
59 static struct test_t core_tests[] = {
60 CORE_TEST_DESCRIPTION(CORE_TEST_ID_NS_THREAD, tfm_core_test_ns_thread,
61  "Test service request from NS thread mode"),
62 CORE_TEST_DESCRIPTION(CORE_TEST_ID_CHECK_INIT, tfm_core_test_check_init,
63  "Test the success of service init"),
64 #ifdef ENABLE_TFM_CORE_RECURSION_TESTS
65 CORE_TEST_DESCRIPTION(CORE_TEST_ID_RECURSION, tfm_core_test_recursion,
66  "Test direct recursion of secure services"),
67 #endif
68 #ifdef TFM_ENABLE_IRQ_TEST
70  tfm_core_test_irq,
71  "Test secure irq"),
72 #endif
73 CORE_TEST_DESCRIPTION(CORE_TEST_ID_BUFFER_CHECK, tfm_core_test_buffer_check,
74  "Test secure service buffer accesses"),
75 CORE_TEST_DESCRIPTION(CORE_TEST_ID_SS_TO_SS, tfm_core_test_ss_to_ss,
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"),
84 #endif
85 #ifndef TFM_PSA_API
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"),
92 #endif /* TFM_PSA_API */
94  tfm_core_test_iovec_sanitization,
95  "Test service parameter sanitization"),
97  tfm_core_test_outvec_write,
98  "Test outvec write"),
99 };
100 
102 {
103  uint32_t list_size;
104 
105  list_size = (sizeof(core_tests) / sizeof(core_tests[0]));
106 
107  set_testsuite("Core non-secure positive tests (TFM_CORE_TEST_1XXX)",
108  core_tests, list_size, p_test_suite);
109 }
110 
111 #ifdef TFM_PSA_API
112 static psa_status_t psa_test_common(uint32_t sid, uint32_t version,
113  const psa_invec *in_vecs, size_t in_len,
114  psa_outvec *out_vecs, size_t out_len)
115 {
116  psa_handle_t handle;
117  psa_status_t status;
118 
119  handle = psa_connect(sid, version);
120  if (handle <= 0) {
122  }
123 
124  status = psa_call(handle, PSA_IPC_CALL, in_vecs, in_len, out_vecs, out_len);
125  if (status < 0) {
127  }
128 
129  psa_close(handle);
130  return status;
131 }
132 #endif /* TFM_PSA_API */
133 
134 static void tfm_core_test_ns_thread(struct test_result_t *ret)
135 {
136  int32_t err;
137 #ifndef TFM_PSA_API
138  int32_t test_case_id = CORE_TEST_ID_NS_THREAD;
139  psa_invec in_vec[] = { {&test_case_id, sizeof(int32_t)} };
140 
141  err = tfm_spm_core_test_sfn_veneer(in_vec, 1, NULL, 0);
142 #else /* TFM_PSA_API */
143  err = psa_test_common(SPM_CORE_TEST_NS_THREAD_SID,
145  NULL, 0, NULL, 0);
146 #endif /* TFM_PSA_API */
147 
148  if (err != CORE_TEST_ERRNO_SUCCESS) {
149  TEST_FAIL("Secure function call from thread mode should be successful");
150  return;
151  }
152 
153  ret->val = TEST_PASSED;
154 }
155 
156 #ifdef TFM_ENABLE_PERIPH_ACCESS_TEST
157 static void tfm_core_test_peripheral_access(struct test_result_t *ret)
158 {
159  int32_t err;
160 
161 #ifndef TFM_PSA_API
162  int32_t test_case_id = CORE_TEST_ID_PERIPHERAL_ACCESS;
163  psa_invec in_vec[] = { {&test_case_id, sizeof(int32_t)} };
164  struct tfm_core_test_call_args_t args = {in_vec, 1, NULL, 0};
165 
166  err = tfm_core_test_call(tfm_spm_core_test_sfn_veneer, &args);
167 #else /* TFM_PSA_API */
168  err = psa_test_common(SPM_CORE_TEST_PERIPHERAL_ACCESS_SID,
170  NULL, 0, NULL, 0);
171 #endif /* TFM_PSA_API */
172 
173  switch (err) {
175  ret->val = TEST_PASSED;
176  return;
178  TEST_FAIL("Service peripheral access failed.");
179  return;
180  default:
181  TEST_FAIL("Unexpected return value received.");
182  return;
183  }
184 }
185 #endif
186 
187 static void empty_iovecs(psa_invec invec[], psa_outvec outvec[])
188 {
189  int i = 0;
190 
191  for (i = 0; i < PSA_MAX_IOVEC; ++i) {
192  invec[i].len = 0;
193  invec[i].base = NULL;
194  outvec[i].len = 0;
195  outvec[i].base = NULL;
196  }
197 }
198 
199 static void full_iovecs(psa_invec invec[], psa_outvec outvec[])
200 {
201  int i = 0;
202 
203  for (i = 0; i < PSA_MAX_IOVEC; ++i) {
204  invec[i].len = sizeof(psa_invec);
205  invec[i].base = invec + i;
206  outvec[i].len = PSA_MAX_IOVEC * sizeof(psa_outvec);
207  outvec[i].base = outvec;
208  }
209 }
210 
211 static void tfm_core_test_iovec_sanitization(struct test_result_t *ret)
212 {
213  int32_t err;
214  psa_invec in_vec[PSA_MAX_IOVEC] = {
215  {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0} };
217  {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0} };
218 
219 #ifndef TFM_PSA_API
220  struct tfm_core_test_call_args_t args = {NULL, 0, NULL, 0};
221 #endif /* TFM_PSA_API */
222 
223  /* Check a few valid cases */
224 
225  /* Execute a call with valid iovecs (empty) */
226  empty_iovecs(in_vec, out_vec);
227 
228 #ifndef TFM_PSA_API
229  args.in_vec = NULL;
230  args.in_len = 0;
231  args.out_vec = NULL;
232  args.out_len = 0;
233  err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
234 #else /* TFM_PSA_API */
235  err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
237  NULL, 0, NULL, 0);
238 #endif /* TFM_PSA_API */
239  if (err != CORE_TEST_ERRNO_SUCCESS_2) {
240  TEST_FAIL("iovec sanitization failed on empty vectors.");
241  return;
242  }
243 
244  /* Execute a call with valid iovecs (full) */
245  full_iovecs(in_vec, out_vec);
246 #ifndef TFM_PSA_API
247  args.in_vec = in_vec;
248  args.in_len = 2;
249  args.out_vec = out_vec;
250  args.out_len = PSA_MAX_IOVEC - args.in_len;
251  err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
252 #else /* TFM_PSA_API */
253  err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
255  in_vec, 2, out_vec, 2);
256 #endif /* TFM_PSA_API */
257  if (err != CORE_TEST_ERRNO_SUCCESS_2) {
258  TEST_FAIL("iovec sanitization failed on full vectors.");
259  return;
260  }
261 
262  /* Execute a call with valid iovecs (different number of vectors) */
263  full_iovecs(in_vec, out_vec);
264 #ifndef TFM_PSA_API
265  args.in_vec = in_vec;
266  args.in_len = 2;
267  args.out_vec = out_vec;
268  args.out_len = 1;
269  err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
270 #else /* TFM_PSA_API */
271  err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
273  in_vec, 2, out_vec, 1);
274 #endif /* TFM_PSA_API */
275  if (err != CORE_TEST_ERRNO_SUCCESS_2) {
276  TEST_FAIL(
277  "iovec sanitization failed on valid, partially full vectors.");
278  return;
279  }
280 
281  /* Check some further valid cases to be sure that checks happen only iovecs
282  * that specified valid by the parameters
283  */
284 
285  /* Execute a call with base = 0 in single vector in outvec that is out of
286  * range
287  */
288  full_iovecs(in_vec, out_vec);
289  out_vec[1].base = NULL;
290 #ifndef TFM_PSA_API
291  args.in_vec = in_vec;
292  args.in_len = 2;
293  args.out_vec = out_vec;
294  args.out_len = 1;
295  err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
296 #else /* TFM_PSA_API */
297  err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
299  in_vec, 2, out_vec, 1);
300 #endif /* TFM_PSA_API */
301  if (err != CORE_TEST_ERRNO_SUCCESS_2) {
302  TEST_FAIL("content of an outvec out of range should not be checked");
303  return;
304  }
305 
306  /* Execute a call with len = 0 in single vector in invec that is out of
307  * range
308  */
309  full_iovecs(in_vec, out_vec);
310  in_vec[2].len = 0;
311 #ifndef TFM_PSA_API
312  args.in_vec = in_vec;
313  args.in_len = 2;
314  args.out_vec = out_vec;
315  args.out_len = 1;
316  err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
317 #else /* TFM_PSA_API */
318  err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
320  in_vec, 2, out_vec, 1);
321 #endif /* TFM_PSA_API */
322  if (err != CORE_TEST_ERRNO_SUCCESS_2) {
323  TEST_FAIL("content of an outvec out of range should not be checked");
324  return;
325  }
326 
327  /* Execute a call with len = 0 in single vector in invec */
328  full_iovecs(in_vec, out_vec);
329  in_vec[1].len = 0;
330  in_vec[1].base = NULL;
331 #ifndef TFM_PSA_API
332  args.in_vec = in_vec;
333  args.in_len = 2;
334  args.out_vec = out_vec;
335  args.out_len = 2;
336  err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
337 #else /* TFM_PSA_API */
338  err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
340  in_vec, 2, out_vec, 2);
341 #endif /* TFM_PSA_API */
342  if (err != CORE_TEST_ERRNO_SUCCESS_2) {
343  TEST_FAIL("If the len of an invec is 0, the base should be ignored");
344  return;
345  }
346 
347  /* Execute a call with len = 0 in single vector in outvec */
348  full_iovecs(in_vec, out_vec);
349  out_vec[1].len = 0;
350  out_vec[1].base = NULL;
351 #ifndef TFM_PSA_API
352  args.in_vec = in_vec;
353  args.in_len = 2;
354  args.out_vec = out_vec;
355  args.out_len = 2;
356  err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
357 #else /* TFM_PSA_API */
358  err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
360  in_vec, 2, out_vec, 2);
361 #endif /* TFM_PSA_API */
362  if (err != CORE_TEST_ERRNO_SUCCESS_2) {
363  TEST_FAIL("If the len of an outvec is 0, the base should be ignored");
364  return;
365  }
366 
367  ret->val = TEST_PASSED;
368 }
369 
370 static void tfm_core_test_outvec_write(struct test_result_t *ret)
371 {
372  int32_t err;
373  int i;
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)];
378 
379  psa_invec in_vec[PSA_MAX_IOVEC] = { {in_buf_0, sizeof(in_buf_0)},
380  {in_buf_1, sizeof(in_buf_1)} };
381  psa_outvec out_vec[PSA_MAX_IOVEC] = { {out_buf_0, sizeof(out_buf_0) },
382  {out_buf_1, sizeof(out_buf_1)} };
383 #ifndef TFM_PSA_API
384  int32_t test_case_id = CORE_TEST_ID_OUTVEC_WRITE;
385  struct tfm_core_test_call_args_t args1 = {in_vec, 2, out_vec, 2};
386  struct tfm_core_test_call_args_t args2 = {in_vec, 1, NULL, 0};
387 
388  err = tfm_core_test_call(tfm_spm_core_test_2_get_every_second_byte_veneer,
389  &args1);
390 #else /* TFM_PSA_API */
391  err = psa_test_common(SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SID,
393  in_vec, 2, out_vec, 2);
394 #endif /* TFM_PSA_API */
395 
396  if (err != CORE_TEST_ERRNO_SUCCESS) {
397  TEST_FAIL("call to secure function should be successful");
398  return;
399  }
400 
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");
404  return;
405  }
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]) {
408  TEST_FAIL("result is not correct");
409  return;
410  }
411  }
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]) {
414  TEST_FAIL("result is not correct");
415  return;
416  }
417  }
418 
419  /* do the same test on the secure side */
420 #ifndef TFM_PSA_API
421  in_vec[0].base = &test_case_id;
422  in_vec[0].len = sizeof(int32_t);
423  err = tfm_core_test_call(tfm_spm_core_test_sfn_veneer, &args2);
424 #else /* TFM_PSA_API */
425  err = psa_test_common(SPM_CORE_TEST_OUTVEC_WRITE_SID,
427  in_vec, 0, out_vec, 0);
428 #endif /* TFM_PSA_API */
429 
430  if (err != CORE_TEST_ERRNO_SUCCESS) {
431  TEST_FAIL("Failed to execute secure side test");
432  return;
433  }
434 
435  ret->val = TEST_PASSED;
436 }
437 
438 #ifdef TFM_ENABLE_IRQ_TEST
439 static int32_t prepare_test_scenario_ns(
440  enum irq_test_scenario_t test_scenario,
441  struct irq_test_execution_data_t *execution_data)
442 {
443  executing_irq_test_scenario = test_scenario;
444  switch (test_scenario) {
447  case IRQ_TEST_SCENARIO_1:
448  case IRQ_TEST_SCENARIO_2:
449  case IRQ_TEST_SCENARIO_3:
450  case IRQ_TEST_SCENARIO_4:
451  /* nothing to be done here */
452  break;
453  case IRQ_TEST_SCENARIO_5:
454  execution_data->timer1_triggered = 0;
455  tfm_plat_test_non_secure_timer_start();
456  break;
457  default:
459  }
460 
462 }
463 
464 static int32_t execute_test_scenario_ns(
465  enum irq_test_scenario_t test_scenario,
466  struct irq_test_execution_data_t *execution_data)
467 {
468 
469  switch (test_scenario) {
472  case IRQ_TEST_SCENARIO_1:
473  if (execution_data->timer0_triggered) {
475  }
476  while (!execution_data->timer0_triggered) {
477  ;
478  }
479  break;
480  case IRQ_TEST_SCENARIO_2:
481  case IRQ_TEST_SCENARIO_3:
482  case IRQ_TEST_SCENARIO_4:
483  case IRQ_TEST_SCENARIO_5:
484  /* nothing to be done here */
485  break;
486  default:
488  }
489 
491 }
492 
493 void TIMER1_Handler (void)
494 {
495  tfm_plat_test_non_secure_timer_stop();
496 
497  switch (executing_irq_test_scenario) {
499  case IRQ_TEST_SCENARIO_1:
500  case IRQ_TEST_SCENARIO_2:
501  case IRQ_TEST_SCENARIO_3:
502  case IRQ_TEST_SCENARIO_4:
503  while (1) {}
504  /* shouldn't happen */
505  break;
506  case IRQ_TEST_SCENARIO_5:
507  irq_test_execution_data.timer1_triggered = 1;
508  break;
509  default:
510  while (1) {}
511  /* shouldn't happen */
512  break;
513  }
514 }
515 
516 static int32_t tfm_core_test_irq_scenario(
517  enum irq_test_scenario_t test_scenario)
518 {
519  struct irq_test_execution_data_t *execution_data_address =
520  &irq_test_execution_data;
521  uint32_t scenario = test_scenario;
522 
523  psa_invec in_vec[] = {
524  {&scenario, sizeof(uint32_t)},
525  {&execution_data_address,
526  sizeof(struct irq_test_execution_data_t *)} };
527  int32_t err;
528 
529 #ifdef TFM_PSA_API
530  err = psa_test_common(SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_SID,
532  in_vec, 2, NULL, 0);
533 #else
534  err = tfm_spm_irq_test_1_prepare_test_scenario_veneer(in_vec, 2, NULL, 0);
535 #endif
536  if (err != CORE_TEST_ERRNO_SUCCESS) {
537  return err;
538  }
539 
540 #ifdef TFM_PSA_API
541  err = psa_test_common(SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_SID,
543  in_vec, 2, NULL, 0);
544 #else
545  err = tfm_spm_core_test_2_prepare_test_scenario_veneer(in_vec, 2, NULL, 0);
546 #endif
547  if (err != CORE_TEST_ERRNO_SUCCESS) {
548  return err;
549  }
550 
551  err = prepare_test_scenario_ns(test_scenario, &irq_test_execution_data);
552  if (err != CORE_TEST_ERRNO_SUCCESS) {
553  return err;
554  }
555 
556 #ifdef TFM_PSA_API
557  err = psa_test_common(SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SID,
559  in_vec, 2, NULL, 0);
560 #else
561  err = tfm_spm_irq_test_1_execute_test_scenario_veneer(in_vec, 1, NULL, 0);
562 #endif
563  if (err != CORE_TEST_ERRNO_SUCCESS) {
564  return err;
565  }
566 
567 #ifdef TFM_PSA_API
568  err = psa_test_common(SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_SID,
570  in_vec, 2, NULL, 0);
571 #else
572  err = tfm_spm_core_test_2_execute_test_scenario_veneer(in_vec, 1, NULL, 0);
573 #endif
574  if (err != CORE_TEST_ERRNO_SUCCESS) {
575  return err;
576  }
577 
578  err = execute_test_scenario_ns(test_scenario, &irq_test_execution_data);
579  if (err != CORE_TEST_ERRNO_SUCCESS) {
580  return err;
581  }
582 
584 }
585 
586 static void tfm_core_test_irq(struct test_result_t *ret)
587 {
588  int32_t err;
589 
590  struct irq_test_execution_data_t *execution_data_address =
591  &irq_test_execution_data;
592  uint32_t scenario = IRQ_TEST_SCENARIO_NONE;
593 
594  psa_invec in_vec[] = {
595  {&scenario, sizeof(uint32_t)},
596  {&execution_data_address,
597  sizeof(struct irq_test_execution_data_t *)} };
598 
599  NVIC_EnableIRQ(TFM_TIMER1_IRQ);
600 
601  err = tfm_core_test_irq_scenario(IRQ_TEST_SCENARIO_1);
602  if (err != CORE_TEST_ERRNO_SUCCESS) {
603  TEST_FAIL("Failed to execute IRQ test scenario 1.");
604  return;
605  }
606 
607  err = tfm_core_test_irq_scenario(IRQ_TEST_SCENARIO_2);
608  if (err != CORE_TEST_ERRNO_SUCCESS) {
609  TEST_FAIL("Failed to execute IRQ test scenario 2.");
610  return;
611  }
612 
613  err = tfm_core_test_irq_scenario(IRQ_TEST_SCENARIO_3);
614  if (err != CORE_TEST_ERRNO_SUCCESS) {
615  TEST_FAIL("Failed to execute IRQ test scenario 3.");
616  return;
617  }
618 
619  err = tfm_core_test_irq_scenario(IRQ_TEST_SCENARIO_4);
620  if (err != CORE_TEST_ERRNO_SUCCESS) {
621  TEST_FAIL("Failed to execute IRQ test scenario 4.");
622  return;
623  }
624 
625  err = tfm_core_test_irq_scenario(IRQ_TEST_SCENARIO_5);
626  if (err != CORE_TEST_ERRNO_SUCCESS) {
627  TEST_FAIL("Failed to execute IRQ test scenario 5.");
628  return;
629  }
630 
631  /* finally call prepare with scenario none as a teardown */
632 #ifdef TFM_PSA_API
633  err = psa_test_common(SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_SID,
635  in_vec, 2, NULL, 0);
636 #else
637  err = tfm_spm_irq_test_1_prepare_test_scenario_veneer(in_vec, 2, NULL, 0);
638 #endif
639  if (err != CORE_TEST_ERRNO_SUCCESS) {
640  TEST_FAIL("Failed to tear down IRQ tests");
641  return;
642  }
643 
644  ret->val = TEST_PASSED;
645 }
646 #endif
647 
648 /*
649  * \brief Tests whether the initialisation of the service was successful.
650  *
651  */
652 static void tfm_core_test_check_init(struct test_result_t *ret)
653 {
654  int32_t err;
655 #ifndef TFM_PSA_API
656  struct tfm_core_test_call_args_t args = {NULL, 0, NULL, 0};
657 
658  err = tfm_core_test_call(tfm_spm_core_test_sfn_init_success_veneer, &args);
659 #else /* TFM_PSA_API */
660  err = psa_test_common(SPM_CORE_TEST_INIT_SUCCESS_SID,
662  NULL, 0, NULL, 0);
663 #endif /* TFM_PSA_API */
664 
665  if (err != CORE_TEST_ERRNO_SUCCESS) {
666  TEST_FAIL("Failed to initialise test service.");
667  return;
668  }
669 
670  ret->val = TEST_PASSED;
671 }
672 
673 #ifdef ENABLE_TFM_CORE_RECURSION_TESTS
674 
677 static void tfm_core_test_recursion(struct test_result_t *ret)
678 {
679  /*
680  * TODO
681  * Recursive calls will trigger a fatal error. Current test framework cannot
682  * recover from that error.
683  * Leave a test case stub here for further implementation.
684  */
685  TEST_FAIL("The test case is not implemented yet.");
686 }
687 #endif
688 
689 static void tfm_core_test_buffer_check(struct test_result_t *ret)
690 {
691  int32_t res, i;
692 
693  uint32_t inbuf[] = {1, 2, 3, 4, 0xAAAFFF, 0xFFFFFFFF};
694  uint32_t outbuf[16] = {0};
695  int32_t result = 1;
696  psa_invec in_vec[] = { {inbuf, sizeof(inbuf)} };
697  psa_outvec outvec[] = { {outbuf, sizeof(outbuf)},
698  {&result, sizeof(int32_t)} };
699 #ifndef TFM_PSA_API
700  struct tfm_core_test_call_args_t args = {in_vec, 1, outvec, 2};
701 
702  res = tfm_core_test_call(tfm_spm_core_test_2_sfn_invert_veneer, &args);
703 #else /* TFM_PSA_API */
704  res = psa_test_common(SPM_CORE_TEST_2_INVERT_SID,
706  in_vec, 1, outvec, 2);
707 #endif /* TFM_PSA_API */
708  if (res != CORE_TEST_ERRNO_SUCCESS) {
709  TEST_FAIL("Call to secure service should be successful.");
710  return;
711  }
712  if (result == 0) {
713  for (i = 0; i < sizeof(inbuf) >> 2; i++) {
714  if (outbuf[i] != ~inbuf[i]) {
715  TEST_FAIL("Secure function failed to modify buffer.");
716  return;
717  }
718  }
719  for (; i < sizeof(outbuf) >> 2; i++) {
720  if (outbuf[i] != 0) {
721  TEST_FAIL("Secure function buffer access overflow.");
722  return;
723  }
724  }
725  } else {
726  TEST_FAIL("Secure service returned error.");
727  return;
728  }
729 
730  ret->val = TEST_PASSED;
731 }
732 
733 static void tfm_core_test_ss_to_ss(struct test_result_t *ret)
734 {
735  int32_t err;
736 
737 #ifndef TFM_PSA_API
738  int32_t test_case_id = CORE_TEST_ID_SS_TO_SS;
739  psa_invec in_vec[] = { {&test_case_id, sizeof(int32_t)} };
740  struct tfm_core_test_call_args_t args = {in_vec, 1, NULL, 0};
741 
742  err = tfm_core_test_call(tfm_spm_core_test_sfn_veneer, &args);
743 #else /* TFM_PSA_API */
744  err = psa_test_common(SPM_CORE_TEST_SS_TO_SS_SID,
746  NULL, 0, NULL, 0);
747 #endif /* TFM_PSA_API */
748 
749  if (err != CORE_TEST_ERRNO_SUCCESS) {
750  TEST_FAIL("The internal service call failed.");
751  return;
752  }
753 
754  ret->val = TEST_PASSED;
755 }
756 
757 static void tfm_core_test_ss_to_ss_buffer(struct test_result_t *ret)
758 {
759  int32_t res, i;
760 
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)} };
765 #ifndef TFM_PSA_API
766  int32_t test_case_id = CORE_TEST_ID_SS_TO_SS_BUFFER;
767  psa_invec in_vec[] = { {&test_case_id, sizeof(int32_t)},
768  {inbuf, sizeof(inbuf)},
769  {&len, sizeof(int32_t)} };
770  struct tfm_core_test_call_args_t args = {in_vec, 3, out_vec, 1};
771 
772  res = tfm_core_test_call(tfm_spm_core_test_sfn_veneer, &args);
773 #else /* TFM_PSA_API */
774  psa_invec in_vec[] = {{inbuf, sizeof(inbuf)},
775  {&len, sizeof(int32_t)} };
776 
777  res = psa_test_common(SPM_CORE_TEST_SS_TO_SS_BUFFER_SID,
779  in_vec, 2, out_vec, 1);
780 #endif /* TFM_PSA_API */
781  switch (res) {
783  for (i = 0; i < sizeof(inbuf) >> 2; i++) {
784  if (outbuf[i] != ~inbuf[i]) {
785  TEST_FAIL("Secure function failed to modify buffer.");
786  return;
787  }
788  }
789  for (; i < sizeof(outbuf) >> 2; i++) {
790  if (outbuf[i] != 0) {
791  TEST_FAIL("Secure function buffer access overflow.");
792  return;
793  }
794  }
795  ret->val = TEST_PASSED;
796  return;
798  TEST_FAIL("NS buffer rejected by TF-M core.");
799  return;
801  TEST_FAIL("Slave service call failed.");
802  return;
804  TEST_FAIL("Slave secure function failed to modify buffer.");
805  return;
806  default:
807  TEST_FAIL("Secure service returned error.");
808  return;
809  }
810 }
811 
812 #ifndef TFM_PSA_API
813 static void tfm_core_test_get_caller_client_id(struct test_result_t *ret)
814 {
815  int32_t err;
816  int32_t test_case_id = CORE_TEST_ID_GET_CALLER_CLIENT_ID;
817  psa_invec in_vec[] = { {&test_case_id, sizeof(int32_t)} };
818  struct tfm_core_test_call_args_t args = {in_vec, 1, NULL, 0};
819 
820  err = tfm_core_test_call(tfm_spm_core_test_sfn_veneer, &args);
821 
822  if (err != CORE_TEST_ERRNO_SUCCESS) {
823  TEST_FAIL("The internal service call failed.");
824  return;
825  }
826 
827  ret->val = TEST_PASSED;
828 }
829 
830 static void tfm_core_test_spm_request(struct test_result_t *ret)
831 {
832  int32_t err;
833 #ifndef TFM_PSA_API
834  int32_t test_case_id = CORE_TEST_ID_SPM_REQUEST;
835  psa_invec in_vec[] = { {&test_case_id, sizeof(int32_t)} };
836  struct tfm_core_test_call_args_t args = {in_vec, 1, NULL, 0};
837 
838  err = tfm_core_test_call(tfm_spm_core_test_sfn_veneer, &args);
839 #else /* TFM_PSA_API */
840  err = psa_test_common(SPM_CORE_TEST_SPM_REQUEST_SID,
842  NULL, 0, NULL, 0);
843 #endif /* TFM_PSA_API */
844 
845  if (err != CORE_TEST_ERRNO_SUCCESS) {
846  TEST_FAIL("The SPM request failed.");
847  return;
848  }
849 
850  ret->val = TEST_PASSED;
851 }
852 
853 #endif /* TFM_PSA_API */
#define CORE_TEST_ID_RECURSION
#define SPM_CORE_TEST_SPM_REQUEST_VERSION
Definition: sid.h:75
#define SPM_CORE_TEST_2_INVERT_SID
Definition: sid.h:88
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)
Definition: core_test_api.c:11
void * base
Definition: client.h:75
struct psa_invec psa_invec
#define SPM_CORE_TEST_SS_TO_SS_BUFFER_VERSION
Definition: sid.h:67
#define SPM_CORE_TEST_INIT_SUCCESS_SID
Definition: sid.h:60
#define CORE_TEST_ID_SECURE_IRQ
#define TEST_FAIL(info_msg)
size_t len
Definition: client.h:68
#define SPM_CORE_TEST_NS_THREAD_SID
Definition: sid.h:78
#define SPM_CORE_TEST_PERIPHERAL_ACCESS_SID
Definition: sid.h:70
#define CORE_TEST_ID_PERIPHERAL_ACCESS
volatile int32_t timer1_triggered
#define SPM_CORE_TEST_OUTVEC_WRITE_VERSION
Definition: sid.h:69
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.
Definition: core_test_api.h:22
#define SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_SID
Definition: sid.h:124
#define SPM_CORE_TEST_SS_TO_SS_VERSION
Definition: sid.h:65
void psa_close(psa_handle_t handle)
Close a connection to an RoT Service.
Definition: psa_client.c:63
#define CORE_TEST_ID_BUFFER_CHECK
#define CORE_TEST_ID_CHECK_INIT
#define SPM_CORE_TEST_2_SLAVE_SERVICE_VERSION
Definition: sid.h:83
#define PSA_MAX_IOVEC
Definition: client.h:54
#define CORE_TEST_DESCRIPTION(number, fn, description)
#define CORE_TEST_ID_IOVEC_SANITIZATION
#define CORE_TEST_ID_NS_THREAD
irq_test_scenario_t
psa_handle_t psa_connect(uint32_t sid, uint32_t version)
Connect to an RoT Service by its SID.
Definition: psa_client.c:30
struct psa_outvec psa_outvec
#define SPM_CORE_TEST_SS_TO_SS_SID
Definition: sid.h:64
#define CORE_TEST_ID_SS_TO_SS
#define SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_VERSION
Definition: sid.h:93
#define SPM_CORE_TEST_SPM_REQUEST_SID
Definition: sid.h:74
struct test_result_t ret
#define SPM_CORE_TEST_SS_TO_SS_BUFFER_SID
Definition: sid.h:66
#define SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_VERSION
Definition: sid.h:125
#define SPM_CORE_TEST_2_SLAVE_SERVICE_SID
Definition: sid.h:82
struct psa_outvec * out_vec
Definition: core_test_api.h:25
#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SID
Definition: sid.h:86
#define SPM_CORE_TEST_NS_THREAD_VERSION
Definition: sid.h:79
#define SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_VERSION
Definition: sid.h:91
#define CORE_TEST_ID_GET_CALLER_CLIENT_ID
size_t len
Definition: client.h:76
int32_t psa_handle_t
Definition: client.h:61
struct psa_invec * in_vec
Definition: core_test_api.h:23
#define SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_SID
Definition: sid.h:90
enum test_status_t val
#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_VERSION
Definition: sid.h:87
#define SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SID
Definition: sid.h:126
#define PSA_IPC_CALL
Definition: client.h:59
#define CORE_TEST_ID_SPM_REQUEST
#define SPM_CORE_TEST_2_INVERT_VERSION
Definition: sid.h:89
#define SPM_CORE_TEST_INIT_SUCCESS_VERSION
Definition: sid.h:61
const void * base
Definition: client.h:67
#define SPM_CORE_TEST_OUTVEC_WRITE_SID
Definition: sid.h:68
int32_t psa_status_t
Function return status.
Definition: crypto_types.h:43
#define SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_VERSION
Definition: sid.h:127
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.
Definition: psa_client.c:47
volatile int32_t timer0_triggered
#define SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_SID
Definition: sid.h:92
#define SPM_CORE_TEST_PERIPHERAL_ACCESS_VERSION
Definition: sid.h:71
#define CORE_TEST_ID_SS_TO_SS_BUFFER
#define CORE_TEST_ID_OUTVEC_WRITE