TF-M Reference Manual  1.2.0
TrustedFirmware-M
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ipc_ns_interface_testsuite.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <stdio.h>
9 #include "ipc_ns_tests.h"
10 #include "psa/client.h"
11 #include "test_framework_helpers.h"
12 #ifdef TFM_PSA_API
13 #include "psa_manifest/sid.h"
14 #endif
15 
16 /* List of tests */
17 static void tfm_ipc_test_1001(struct test_result_t *ret);
18 static void tfm_ipc_test_1002(struct test_result_t *ret);
19 static void tfm_ipc_test_1003(struct test_result_t *ret);
20 static void tfm_ipc_test_1004(struct test_result_t *ret);
21 static void tfm_ipc_test_1005(struct test_result_t *ret);
22 static void tfm_ipc_test_1006(struct test_result_t *ret);
23 
24 #ifdef TFM_IPC_ISOLATION_2_TEST_READ_ONLY_MEM
25 static void tfm_ipc_test_1007(struct test_result_t *ret);
26 #endif
27 
28 #ifdef TFM_IPC_ISOLATION_2_APP_ACCESS_PSA_MEM
29 static void tfm_ipc_test_1008(struct test_result_t *ret);
30 #endif
31 
32 #ifdef TFM_IPC_ISOLATION_2_MEM_CHECK
33 static void tfm_ipc_test_1009(struct test_result_t *ret);
34 #endif
35 
36 static void tfm_ipc_test_1010(struct test_result_t *ret);
37 
38 static struct test_t ipc_veneers_tests[] = {
39  {&tfm_ipc_test_1001, "TFM_IPC_TEST_1001",
40  "Get PSA framework version", {TEST_PASSED}},
41  {&tfm_ipc_test_1002, "TFM_IPC_TEST_1002",
42  "Get version of an RoT Service", {TEST_PASSED}},
43  {&tfm_ipc_test_1003, "TFM_IPC_TEST_1003",
44  "Connect to an RoT Service", {TEST_PASSED}},
45  {&tfm_ipc_test_1004, "TFM_IPC_TEST_1004",
46  "Call an RoT Service", {TEST_PASSED}},
47  {&tfm_ipc_test_1005, "TFM_IPC_TEST_1005",
48  "Call IPC_INIT_BASIC_TEST service", {TEST_PASSED}},
49  {&tfm_ipc_test_1006, "TFM_IPC_TEST_1006",
50  "Call PSA RoT access APP RoT memory test service", {TEST_PASSED}},
51 #ifdef TFM_IPC_ISOLATION_2_TEST_READ_ONLY_MEM
52  {&tfm_ipc_test_1007, "TFM_IPC_TEST_1007",
53  "Call PSA RoT access APP RoT readonly memory test service", {TEST_PASSED}},
54 #endif
55 #ifdef TFM_IPC_ISOLATION_2_APP_ACCESS_PSA_MEM
56  {&tfm_ipc_test_1008, "TFM_IPC_TEST_1008",
57  "Call APP RoT access PSA RoT memory test service", {TEST_PASSED}},
58 #endif
59 #ifdef TFM_IPC_ISOLATION_2_MEM_CHECK
60  {&tfm_ipc_test_1009, "TFM_IPC_TEST_1009",
61  "Call APP RoT memory check test service", {TEST_PASSED}},
62 #endif
63  {&tfm_ipc_test_1010, "TFM_IPC_TEST_1010",
64  "Test psa_call with the status of PSA_ERROR_PROGRAMMER_ERROR", {TEST_PASSED}},
65 };
66 
68 {
69  uint32_t list_size;
70 
71  list_size = (sizeof(ipc_veneers_tests) / sizeof(ipc_veneers_tests[0]));
72 
73  set_testsuite("IPC non-secure interface test (TFM_IPC_TEST_1XXX)",
74  ipc_veneers_tests, list_size, p_test_suite);
75 }
76 
84 static void tfm_ipc_test_1001(struct test_result_t *ret)
85 {
86  uint32_t version;
87 
88  version = psa_framework_version();
89  if (version == PSA_FRAMEWORK_VERSION) {
90  TEST_LOG("The version of the PSA Framework API is %d.\r\n", version);
91  } else {
92  TEST_FAIL("The version of the PSA Framework API is not valid!\r\n");
93  return;
94  }
95 }
96 
100 static void tfm_ipc_test_1002(struct test_result_t *ret)
101 {
102  uint32_t version;
103 
105  if (version == PSA_VERSION_NONE) {
106  TEST_FAIL("RoT Service is not implemented or caller is not authorized" \
107  "to access it!\r\n");
108  return;
109  } else {
110  /* Valid version number */
111  TEST_LOG("The service version is %d.\r\n", version);
112  }
113  ret->val = TEST_PASSED;
114 }
115 
119 static void tfm_ipc_test_1003(struct test_result_t *ret)
120 {
121  psa_handle_t handle;
122 
125  if (handle > 0) {
126  TEST_LOG("Connect success!\r\n");
127  } else {
128  TEST_FAIL("The RoT Service has refused the connection!\r\n");
129  return;
130  }
131  psa_close(handle);
132  ret->val = TEST_PASSED;
133 }
134 
138 static void tfm_ipc_test_1004(struct test_result_t *ret)
139 {
140  char str1[] = "str1";
141  char str2[] = "str2";
142  char str3[128], str4[128];
143  struct psa_invec invecs[2] = {{str1, sizeof(str1)/sizeof(char)},
144  {str2, sizeof(str2)/sizeof(char)}};
145  struct psa_outvec outvecs[2] = {{str3, sizeof(str3)/sizeof(char)},
146  {str4, sizeof(str4)/sizeof(char)}};
147  psa_handle_t handle;
148  psa_status_t status;
149  uint32_t version;
150 
152  TEST_LOG("TFM service support version is %d.\r\n", version);
155  status = psa_call(handle, PSA_IPC_CALL, invecs, 2, outvecs, 2);
156  if (status >= 0) {
157  TEST_LOG("psa_call is successful!\r\n");
158  } else {
159  TEST_FAIL("psa_call is failed!\r\n");
160  return;
161  }
162 
163  TEST_LOG("outvec1 is: %s\r\n", outvecs[0].base);
164  TEST_LOG("outvec2 is: %s\r\n", outvecs[1].base);
165  psa_close(handle);
166  ret->val = TEST_PASSED;
167 }
168 
172 static void tfm_ipc_test_1005(struct test_result_t *ret)
173 {
174  psa_handle_t handle;
175  psa_status_t status;
176  int test_result;
177  struct psa_outvec outvecs[1] = {{&test_result, sizeof(test_result)}};
178 
181  if (handle > 0) {
182  TEST_LOG("Connect success!\r\n");
183  } else {
184  TEST_LOG("The RoT Service has refused the connection!\r\n");
185  ret->val = TEST_FAILED;
186  return;
187  }
188 
189  status = psa_call(handle, PSA_IPC_CALL, NULL, 0, outvecs, 1);
190  if (status >= 0) {
191  TEST_LOG("Call success!\r\n");
192  if (test_result > 0) {
193  ret->val = TEST_PASSED;
194  } else {
195  ret->val = TEST_FAILED;
196  }
197  } else {
198  TEST_LOG("Call failed!\r\n");
199  ret->val = TEST_FAILED;
200  }
201 
202  psa_close(handle);
203 }
204 
209 static void tfm_ipc_test_1006(struct test_result_t *ret)
210 {
211  psa_handle_t handle;
212  psa_status_t status;
213  int test_result;
214  struct psa_outvec outvecs[1] = {{&test_result, sizeof(test_result)}};
215 
218  if (handle > 0) {
219  TEST_LOG("Connect success!\r\n");
220  } else {
221  TEST_LOG("The RoT Service has refused the connection!\r\n");
222  ret->val = TEST_FAILED;
223  return;
224  }
225 
226  status = psa_call(handle, PSA_IPC_CALL, NULL, 0, outvecs, 1);
227  if (status >= 0) {
228  TEST_LOG("Call success!\r\n");
229  if (test_result > 0) {
230  ret->val = TEST_PASSED;
231  } else {
232  ret->val = TEST_FAILED;
233  }
234  } else {
235  TEST_LOG("Call failed!\r\n");
236  ret->val = TEST_FAILED;
237  }
238 
239  psa_close(handle);
240 }
241 
242 #ifdef TFM_IPC_ISOLATION_2_TEST_READ_ONLY_MEM
243 
247 static void tfm_ipc_test_1007(struct test_result_t *ret)
248 {
249  psa_handle_t handle;
250  int test_result;
251  struct psa_outvec outvecs[1] = {{&test_result, sizeof(test_result)}};
252 
255  if (handle > 0) {
256  TEST_LOG("Connect success!\r\n");
257  } else {
258  TEST_LOG("The RoT Service has refused the connection!\r\n");
259  ret->val = TEST_FAILED;
260  return;
261  }
262 
263  psa_call(handle, PSA_IPC_CALL, NULL, 0, outvecs, 1);
264 
265  /* The system should panic in psa_call. If runs here, the test fails. */
266  ret->val = TEST_FAILED;
267  psa_close(handle);
268 }
269 #endif
270 
271 #ifdef TFM_IPC_ISOLATION_2_APP_ACCESS_PSA_MEM
272 
276 static void tfm_ipc_test_1008(struct test_result_t *ret)
277 {
278  psa_handle_t handle;
279  int test_result;
280  struct psa_outvec outvecs[1] = {{&test_result, sizeof(test_result)}};
281 
284  if (handle > 0) {
285  TEST_LOG("Connect success!\r\n");
286  } else {
287  TEST_LOG("The RoT Service has refused the connection!\r\n");
288  ret->val = TEST_FAILED;
289  return;
290  }
291 
292  psa_call(handle, PSA_IPC_CALL, NULL, 0, outvecs, 1);
293 
294  /* The system should panic in psa_call. If runs here, the test fails. */
295  ret->val = TEST_FAILED;
296  psa_close(handle);
297 }
298 #endif
299 
300 #ifdef TFM_IPC_ISOLATION_2_MEM_CHECK
301 
305 static void tfm_ipc_test_1009(struct test_result_t *ret)
306 {
307  psa_handle_t handle;
308  int test_result;
309  struct psa_outvec outvecs[1] = {{&test_result, sizeof(test_result)}};
310 
313  if (handle > 0) {
314  TEST_LOG("Connect success!\r\n");
315  } else {
316  TEST_LOG("The RoT Service has refused the connection!\r\n");
317  ret->val = TEST_FAILED;
318  return;
319  }
320 
321  psa_call(handle, PSA_IPC_CALL, NULL, 0, outvecs, 1);
322 
323  /* The system should panic in psa_call. If runs here, the test fails. */
324  ret->val = TEST_FAILED;
325  psa_close(handle);
326 }
327 #endif
328 
333 static void tfm_ipc_test_1010(struct test_result_t *ret)
334 {
335  psa_handle_t handle;
336  psa_status_t status;
339  if (handle > 0) {
340  TEST_LOG("Connect success!\r\n");
341  } else {
342  TEST_LOG("The RoT Service has refused the connection!\r\n");
343  ret->val = TEST_FAILED;
344  return;
345  }
346  status = psa_call(handle, PSA_IPC_CALL, NULL, 0, NULL, 0);
347  if (status == PSA_ERROR_PROGRAMMER_ERROR) {
348  TEST_LOG("The first time call success!\r\n");
349  } else {
350  TEST_LOG("The first time call failed!\r\n");
351  ret->val = TEST_FAILED;
352  }
353  status = psa_call(handle, PSA_IPC_CALL, NULL, 0, NULL, 0);
354  if (status == PSA_ERROR_PROGRAMMER_ERROR) {
355  TEST_LOG("The second time call success!\r\n");
356  } else {
357  TEST_LOG("The second time call failed!\r\n");
358  ret->val = TEST_FAILED;
359  }
360 
361  psa_close(handle);
362 }
#define PSA_FRAMEWORK_VERSION
Definition: client.h:26
void * base
Definition: client.h:75
#define IPC_CLIENT_TEST_APP_ACCESS_PSA_MEM_VERSION
Definition: sid.h:119
#define TEST_FAIL(info_msg)
#define IPC_SERVICE_TEST_CLIENT_PROGRAMMER_ERROR_VERSION
Definition: sid.h:109
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.
#define IPC_CLIENT_TEST_APP_ACCESS_PSA_MEM_SID
Definition: sid.h:118
void psa_close(psa_handle_t handle)
Close a connection to an RoT Service.
Definition: psa_client.c:63
#define IPC_CLIENT_TEST_BASIC_SID
Definition: sid.h:112
#define IPC_CLIENT_TEST_BASIC_VERSION
Definition: sid.h:113
uint32_t psa_framework_version(void)
Retrieve the version of the PSA Framework API that is implemented.
Definition: psa_client.c:14
#define IPC_CLIENT_TEST_PSA_ACCESS_APP_MEM_SID
Definition: sid.h:114
#define IPC_CLIENT_TEST_PSA_ACCESS_APP_READ_ONLY_MEM_VERSION
Definition: sid.h:117
psa_handle_t psa_connect(uint32_t sid, uint32_t version)
Connect to an RoT Service by its SID.
Definition: psa_client.c:30
#define IPC_CLIENT_TEST_MEM_CHECK_SID
Definition: sid.h:120
struct test_result_t ret
#define IPC_CLIENT_TEST_PSA_ACCESS_APP_READ_ONLY_MEM_SID
Definition: sid.h:116
#define PSA_ERROR_PROGRAMMER_ERROR
Definition: error.h:32
#define PSA_VERSION_NONE
Definition: client.h:32
void register_testsuite_ns_ipc_interface(struct test_suite_t *p_test_suite)
Register testsuite for ipc non-secure interface.
#define IPC_SERVICE_TEST_BASIC_SID
Definition: sid.h:100
int32_t psa_handle_t
Definition: client.h:61
#define TEST_LOG(...)
enum test_status_t val
uint32_t psa_version(uint32_t sid)
Retrieve the version of an RoT Service or indicate that it is not present on this system...
Definition: psa_client.c:22
#define IPC_SERVICE_TEST_BASIC_VERSION
Definition: sid.h:101
#define PSA_IPC_CALL
Definition: client.h:59
#define IPC_CLIENT_TEST_MEM_CHECK_VERSION
Definition: sid.h:121
int32_t psa_status_t
Function return status.
Definition: crypto_types.h:43
#define IPC_SERVICE_TEST_CLIENT_PROGRAMMER_ERROR_SID
Definition: sid.h:108
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
#define IPC_CLIENT_TEST_PSA_ACCESS_APP_MEM_VERSION
Definition: sid.h:115