1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2020, ARM Limited. All rights reserved.
4 * Copyright (c) 2014, STMicroelectronics International N.V.
5 */
6
7 #include <errno.h>
8 #include <limits.h>
9 #include <pthread.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/stat.h>
14 #include <sys/types.h>
15 #include <unistd.h>
16
17 #include "xtest_test.h"
18 #include "xtest_helpers.h"
19 #include "xtest_uuid_helpers.h"
20 #include <signed_hdr.h>
21 #include <util.h>
22
23 #include <pta_invoke_tests.h>
24 #include <ta_crypt.h>
25 #include <ta_os_test.h>
26 #include <ta_create_fail_test.h>
27 #include <ta_rpc_test.h>
28 #include <ta_sims_test.h>
29 #include <ta_miss_test.h>
30 #include <ta_sims_keepalive_test.h>
31 #include <ta_concurrent.h>
32 #include <ta_tpm_log_test.h>
33 #include <ta_supp_plugin.h>
34 #include <sdp_basic.h>
35 #include <pta_secstor_ta_mgmt.h>
36
37 #include <test_supp_plugin.h>
38
39 #ifndef MIN
40 #define MIN(a, b) ((a) < (b) ? (a) : (b))
41 #endif
42
43 struct xtest_crypto_session {
44 ADBG_Case_t *c;
45 TEEC_Session *session;
46 uint32_t cmd_id_sha256;
47 uint32_t cmd_id_aes256ecb_encrypt;
48 uint32_t cmd_id_aes256ecb_decrypt;
49 };
50
xtest_crypto_test(struct xtest_crypto_session * cs)51 static void xtest_crypto_test(struct xtest_crypto_session *cs)
52 {
53 uint32_t ret_orig = 0;
54 uint8_t crypt_out[16] = { };
55 uint8_t crypt_in[16] = { 22, 17 };
56
57 crypt_in[15] = 60;
58
59 Do_ADBG_BeginSubCase(cs->c, "AES encrypt");
60 {
61 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
62
63 op.params[0].tmpref.buffer = crypt_in;
64 op.params[0].tmpref.size = sizeof(crypt_in);
65 op.params[1].tmpref.buffer = crypt_out;
66 op.params[1].tmpref.size = sizeof(crypt_out);
67 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
68 TEEC_MEMREF_TEMP_OUTPUT,
69 TEEC_NONE, TEEC_NONE);
70
71 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
72 TEEC_InvokeCommand(cs->session,
73 cs->
74 cmd_id_aes256ecb_encrypt,
75 &op,
76 &ret_orig));
77 }
78 Do_ADBG_EndSubCase(cs->c, "AES encrypt");
79
80 Do_ADBG_BeginSubCase(cs->c, "AES decrypt");
81 {
82 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
83 uint8_t out[16] = { };
84
85 op.params[0].tmpref.buffer = crypt_out;
86 op.params[0].tmpref.size = sizeof(crypt_out);
87 op.params[1].tmpref.buffer = out;
88 op.params[1].tmpref.size = sizeof(out);
89 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
90 TEEC_MEMREF_TEMP_OUTPUT,
91 TEEC_NONE, TEEC_NONE);
92
93 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
94 TEEC_InvokeCommand(cs->session,
95 cs->
96 cmd_id_aes256ecb_decrypt,
97 &op,
98 &ret_orig));
99
100 if (!ADBG_EXPECT(cs->c, 0,
101 memcmp(crypt_in, out, sizeof(crypt_in)))) {
102 Do_ADBG_Log("crypt_in:");
103 Do_ADBG_HexLog(crypt_in, sizeof(crypt_in), 16);
104 Do_ADBG_Log("out:");
105 Do_ADBG_HexLog(out, sizeof(out), 16);
106 }
107 }
108 Do_ADBG_EndSubCase(cs->c, "AES decrypt");
109
110 Do_ADBG_BeginSubCase(cs->c, "SHA-256 test, 3 bytes input");
111 {
112 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
113 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
114 static const uint8_t sha256_out[] = {
115 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
116 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
117 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
118 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
119 };
120 uint8_t out[32] = { };
121
122 op.params[0].tmpref.buffer = (void *)sha256_in;
123 op.params[0].tmpref.size = sizeof(sha256_in);
124 op.params[1].tmpref.buffer = out;
125 op.params[1].tmpref.size = sizeof(out);
126 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
127 TEEC_MEMREF_TEMP_OUTPUT,
128 TEEC_NONE, TEEC_NONE);
129
130 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
131 TEEC_InvokeCommand(cs->session,
132 cs->
133 cmd_id_sha256,
134 &op,
135 &ret_orig));
136
137 if (!ADBG_EXPECT(cs->c, 0, memcmp(sha256_out, out,
138 sizeof(sha256_out)))) {
139 Do_ADBG_Log("sha256_out:");
140 Do_ADBG_HexLog(sha256_out, sizeof(sha256_out), 16);
141 Do_ADBG_Log("out:");
142 Do_ADBG_HexLog(out, sizeof(out), 16);
143 }
144 }
145 Do_ADBG_EndSubCase(cs->c, "SHA-256 test, 3 bytes input");
146
147 Do_ADBG_BeginSubCase(cs->c, "AES-256 ECB encrypt (32B, fixed key)");
148 {
149 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
150 static const uint8_t in[] = {
151 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
152 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
153 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
154 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
155 };
156 static const uint8_t exp_out[] = {
157 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
158 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
159 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
160 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
161 };
162 uint8_t out[sizeof(exp_out)] = { };
163
164 op.params[0].tmpref.buffer = (void *)in;
165 op.params[0].tmpref.size = sizeof(in);
166 op.params[1].tmpref.buffer = out;
167 op.params[1].tmpref.size = sizeof(out);
168 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
169 TEEC_MEMREF_TEMP_OUTPUT,
170 TEEC_NONE, TEEC_NONE);
171
172 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
173 TEEC_InvokeCommand(cs->session,
174 cs->
175 cmd_id_aes256ecb_encrypt,
176 &op,
177 &ret_orig));
178
179 if (!ADBG_EXPECT(cs->c, 0,
180 memcmp(exp_out, out, sizeof(exp_out)))) {
181 Do_ADBG_Log("exp_out:");
182 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
183 Do_ADBG_Log("out:");
184 Do_ADBG_HexLog(out, sizeof(out), 16);
185 }
186 }
187 Do_ADBG_EndSubCase(cs->c, "AES-256 ECB encrypt (32B, fixed key)");
188
189 Do_ADBG_BeginSubCase(cs->c, "AES-256 ECB decrypt (32B, fixed key)");
190 {
191 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
192 static const uint8_t in[] = {
193 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
194 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
195 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
196 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
197 };
198 static const uint8_t exp_out[] = {
199 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
200 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
201 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
202 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
203 };
204 uint8_t out[sizeof(exp_out)] = { };
205
206 op.params[0].tmpref.buffer = (void *)in;
207 op.params[0].tmpref.size = sizeof(in);
208 op.params[1].tmpref.buffer = out;
209 op.params[1].tmpref.size = sizeof(out);
210 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
211 TEEC_MEMREF_TEMP_OUTPUT,
212 TEEC_NONE, TEEC_NONE);
213
214 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
215 TEEC_InvokeCommand(cs->session,
216 cs->
217 cmd_id_aes256ecb_decrypt,
218 &op,
219 &ret_orig));
220
221 if (!ADBG_EXPECT(cs->c, 0,
222 memcmp(exp_out, out, sizeof(exp_out)))) {
223 Do_ADBG_Log("exp_out:");
224 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
225 Do_ADBG_Log("out:");
226 Do_ADBG_HexLog(out, sizeof(out), 16);
227 }
228 }
229 Do_ADBG_EndSubCase(cs->c, "AES-256 ECB decrypt (32B, fixed key)");
230 }
231
xtest_tee_test_1001(ADBG_Case_t * c)232 static void xtest_tee_test_1001(ADBG_Case_t *c)
233 {
234 TEEC_Result res = TEEC_ERROR_GENERIC;
235 TEEC_Session session = { };
236 uint32_t ret_orig = 0;
237
238 /* Pseudo TA is optional: warn and nicely exit if not found */
239 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
240 &ret_orig);
241 if (res == TEEC_ERROR_ITEM_NOT_FOUND) {
242 Do_ADBG_Log(" - 1001 - skip test, pseudo TA not found");
243 return;
244 }
245 ADBG_EXPECT_TEEC_SUCCESS(c, res);
246
247 (void)ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
248 &session, PTA_INVOKE_TESTS_CMD_SELF_TESTS, NULL, &ret_orig));
249 TEEC_CloseSession(&session);
250 }
251 ADBG_CASE_DEFINE(regression, 1001, xtest_tee_test_1001, "Core self tests");
252
xtest_tee_test_1002(ADBG_Case_t * c)253 static void xtest_tee_test_1002(ADBG_Case_t *c)
254 {
255 TEEC_Result res = TEEC_ERROR_GENERIC;
256 TEEC_Session session = { };
257 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
258 uint32_t ret_orig = 0;
259 uint8_t buf[16 * 1024] = { };
260 uint8_t exp_sum = 0;
261 size_t n = 0;
262
263 /* Pseudo TA is optional: warn and nicely exit if not found */
264 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
265 &ret_orig);
266 if (res == TEEC_ERROR_ITEM_NOT_FOUND) {
267 Do_ADBG_Log(" - 1002 - skip test, pseudo TA not found");
268 return;
269 }
270 ADBG_EXPECT_TEEC_SUCCESS(c, res);
271
272 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE,
273 TEEC_NONE, TEEC_NONE);
274 op.params[0].tmpref.size = sizeof(buf);
275 op.params[0].tmpref.buffer = buf;
276
277 for (n = 0; n < sizeof(buf); n++)
278 buf[n] = n + 1;
279 for (n = 0; n < sizeof(buf); n++)
280 exp_sum += buf[n];
281
282 if (!ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
283 &session, PTA_INVOKE_TESTS_CMD_PARAMS, &op, &ret_orig)))
284 goto out;
285
286 ADBG_EXPECT_COMPARE_SIGNED(c, exp_sum, ==, buf[0]);
287 out:
288 TEEC_CloseSession(&session);
289 }
290 ADBG_CASE_DEFINE(regression, 1002, xtest_tee_test_1002, "PTA parameters");
291
292 struct test_1003_arg {
293 uint32_t test_type;
294 size_t repeat;
295 size_t max_before_lockers;
296 size_t max_during_lockers;
297 size_t before_lockers;
298 size_t during_lockers;
299 TEEC_Result res;
300 uint32_t error_orig;
301 };
302
test_1003_thread(void * arg)303 static void *test_1003_thread(void *arg)
304 {
305 struct test_1003_arg *a = arg;
306 TEEC_Session session = { };
307 size_t rounds = 64 * 1024;
308 size_t n = 0;
309
310 a->res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid,
311 NULL, &a->error_orig);
312 if (a->res != TEEC_SUCCESS)
313 return NULL;
314
315 for (n = 0; n < a->repeat; n++) {
316 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
317
318 op.params[0].value.a = a->test_type;
319 op.params[0].value.b = rounds;
320
321 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
322 TEEC_VALUE_OUTPUT,
323 TEEC_NONE, TEEC_NONE);
324 a->res = TEEC_InvokeCommand(&session,
325 PTA_INVOKE_TESTS_CMD_MUTEX,
326 &op, &a->error_orig);
327 if (a->test_type == PTA_MUTEX_TEST_WRITER &&
328 op.params[1].value.b != 1) {
329 Do_ADBG_Log("n %zu %" PRIu32, n, op.params[1].value.b);
330 a->res = TEEC_ERROR_BAD_STATE;
331 a->error_orig = 42;
332 break;
333 }
334
335 if (a->test_type == PTA_MUTEX_TEST_READER) {
336 if (op.params[1].value.a > a->max_before_lockers)
337 a->max_before_lockers = op.params[1].value.a;
338
339 if (op.params[1].value.b > a->max_during_lockers)
340 a->max_during_lockers = op.params[1].value.b;
341
342 a->before_lockers += op.params[1].value.a;
343 a->during_lockers += op.params[1].value.b;
344 }
345 }
346 TEEC_CloseSession(&session);
347
348 return NULL;
349 }
350
351 #define TEST_1003_THREAD_COUNT (3 * 2)
352
xtest_tee_test_1003(ADBG_Case_t * c)353 static void xtest_tee_test_1003(ADBG_Case_t *c)
354 {
355 TEEC_Result res = TEEC_ERROR_GENERIC;
356 TEEC_Session session = { };
357 uint32_t ret_orig = 0;
358 size_t repeat = 20;
359 struct test_1003_arg arg[TEST_1003_THREAD_COUNT] = { };
360 size_t max_read_concurrency = 0;
361 size_t max_read_waiters = 0;
362 size_t num_concurrent_read_lockers = 0;
363 size_t num_concurrent_read_waiters = 0;
364 size_t n = 0;
365 size_t nt = TEST_1003_THREAD_COUNT;
366 double mean_read_concurrency = 0;
367 double mean_read_waiters = 0;
368 size_t num_writers = 0;
369 size_t num_readers = 0;
370 pthread_t thr[TEST_1003_THREAD_COUNT] = { };
371
372 /* Pseudo TA is optional: warn and nicely exit if not found */
373 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
374 &ret_orig);
375 if (res == TEEC_ERROR_ITEM_NOT_FOUND) {
376 Do_ADBG_Log(" - 1003 - skip test, pseudo TA not found");
377 return;
378 }
379 ADBG_EXPECT_TEEC_SUCCESS(c, res);
380 TEEC_CloseSession(&session);
381
382 for (n = 0; n < nt; n++) {
383 if (n % 3) {
384 arg[n].test_type = PTA_MUTEX_TEST_READER;
385 num_readers++;
386 } else {
387 arg[n].test_type = PTA_MUTEX_TEST_WRITER;
388 num_writers++;
389 }
390 arg[n].repeat = repeat;
391 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
392 test_1003_thread, arg + n)))
393 nt = n; /* break loop and start cleanup */
394 }
395
396 for (n = 0; n < nt; n++) {
397 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
398 if (!ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
399 Do_ADBG_Log("error origin %" PRIu32,
400 arg[n].error_orig);
401 if (arg[n].test_type == PTA_MUTEX_TEST_READER) {
402 if (arg[n].max_during_lockers > max_read_concurrency)
403 max_read_concurrency =
404 arg[n].max_during_lockers;
405
406 if (arg[n].max_before_lockers > max_read_waiters)
407 max_read_waiters = arg[n].max_before_lockers;
408
409 num_concurrent_read_lockers += arg[n].during_lockers;
410 num_concurrent_read_waiters += arg[n].before_lockers;
411 }
412 }
413
414 mean_read_concurrency = (double)num_concurrent_read_lockers /
415 (double)(repeat * num_readers);
416 mean_read_waiters = (double)num_concurrent_read_waiters /
417 (double)(repeat * num_readers);
418
419 Do_ADBG_Log(" Number of parallel threads: %d (%zu writers and %zu readers)",
420 TEST_1003_THREAD_COUNT, num_writers, num_readers);
421 Do_ADBG_Log(" Max read concurrency: %zu", max_read_concurrency);
422 Do_ADBG_Log(" Max read waiters: %zu", max_read_waiters);
423 Do_ADBG_Log(" Mean read concurrency: %g", mean_read_concurrency);
424 Do_ADBG_Log(" Mean read waiting: %g", mean_read_waiters);
425 }
426 ADBG_CASE_DEFINE(regression, 1003, xtest_tee_test_1003,
427 "Core internal read/write mutex");
428
xtest_tee_test_1004(ADBG_Case_t * c)429 static void xtest_tee_test_1004(ADBG_Case_t *c)
430 {
431 TEEC_Session session = { };
432 uint32_t ret_orig = 0;
433 struct xtest_crypto_session cs = { c, &session, TA_CRYPT_CMD_SHA256,
434 TA_CRYPT_CMD_AES256ECB_ENC,
435 TA_CRYPT_CMD_AES256ECB_DEC };
436
437 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
438 &session, &crypt_user_ta_uuid,
439 NULL, &ret_orig)))
440 return;
441
442 /* Run the "complete crypto test suite" */
443 xtest_crypto_test(&cs);
444
445 TEEC_CloseSession(&session);
446 }
447 ADBG_CASE_DEFINE(regression, 1004, xtest_tee_test_1004, "Test User Crypt TA");
448
xtest_tee_test_invalid_mem_access(ADBG_Case_t * c,unsigned int n)449 static void xtest_tee_test_invalid_mem_access(ADBG_Case_t *c, unsigned int n)
450 {
451 TEEC_Session session = { };
452 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
453 uint32_t ret_orig = 0;
454
455 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
456 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
457 &ret_orig)))
458 return;
459
460 op.params[0].value.a = n;
461 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
462 TEEC_NONE);
463
464 (void)ADBG_EXPECT_TEEC_RESULT(c,
465 TEEC_ERROR_TARGET_DEAD,
466 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
467 &ret_orig));
468
469 (void)ADBG_EXPECT_TEEC_RESULT(c,
470 TEEC_ERROR_TARGET_DEAD,
471 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
472 &ret_orig));
473
474 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
475
476 TEEC_CloseSession(&session);
477 }
478
xtest_tee_test_invalid_mem_access2(ADBG_Case_t * c,unsigned int n,size_t size)479 static void xtest_tee_test_invalid_mem_access2(ADBG_Case_t *c, unsigned int n,
480 size_t size)
481 {
482 TEEC_Session session = { };
483 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
484 uint32_t ret_orig = 0;
485 TEEC_SharedMemory shm = { };
486
487 shm.size = size;
488 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
489 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
490 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
491 return;
492
493 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
494 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
495 &ret_orig)))
496 goto rel_shm;
497
498 op.params[0].value.a = (uint32_t)n;
499 op.params[1].memref.parent = &shm;
500 op.params[1].memref.size = size;
501 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_WHOLE,
502 TEEC_NONE, TEEC_NONE);
503
504 (void)ADBG_EXPECT_TEEC_RESULT(c,
505 TEEC_ERROR_TARGET_DEAD,
506 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
507 &ret_orig));
508
509 (void)ADBG_EXPECT_TEEC_RESULT(c,
510 TEEC_ERROR_TARGET_DEAD,
511 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
512 &ret_orig));
513
514 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
515
516 TEEC_CloseSession(&session);
517 rel_shm:
518 TEEC_ReleaseSharedMemory(&shm);
519 }
520
xtest_tee_test_1005(ADBG_Case_t * c)521 static void xtest_tee_test_1005(ADBG_Case_t *c)
522 {
523 uint32_t ret_orig = 0;
524 #define MAX_SESSIONS 3
525 TEEC_Session sessions[MAX_SESSIONS];
526 int i = 0;
527
528 for (i = 0; i < MAX_SESSIONS; i++) {
529 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
530 xtest_teec_open_session(&sessions[i],
531 &concurrent_ta_uuid,
532 NULL, &ret_orig)))
533 break;
534 }
535
536 for (; --i >= 0; )
537 TEEC_CloseSession(&sessions[i]);
538 }
539 ADBG_CASE_DEFINE(regression, 1005, xtest_tee_test_1005, "Many sessions");
540
xtest_tee_test_1006(ADBG_Case_t * c)541 static void xtest_tee_test_1006(ADBG_Case_t *c)
542 {
543 TEEC_Session session = { };
544 uint32_t ret_orig = 0;
545 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
546 uint8_t buf[32] = { };
547
548 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
549 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
550 &ret_orig)))
551 return;
552
553 op.params[0].tmpref.buffer = buf;
554 op.params[0].tmpref.size = sizeof(buf);
555 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
556 TEEC_NONE, TEEC_NONE);
557
558 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
559 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
560 &ret_orig));
561
562 TEEC_CloseSession(&session);
563 }
564 ADBG_CASE_DEFINE(regression, 1006, xtest_tee_test_1006,
565 "Test Basic OS features");
566
xtest_tee_test_1007(ADBG_Case_t * c)567 static void xtest_tee_test_1007(ADBG_Case_t *c)
568 {
569 TEEC_Session session = { };
570 uint32_t ret_orig = 0;
571
572 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
573 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
574 &ret_orig)))
575 return;
576
577 (void)ADBG_EXPECT_TEEC_RESULT(c,
578 TEEC_ERROR_TARGET_DEAD,
579 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
580 &ret_orig));
581
582 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
583
584 (void)ADBG_EXPECT_TEEC_RESULT(c,
585 TEEC_ERROR_TARGET_DEAD,
586 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
587 &ret_orig));
588
589 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
590
591 TEEC_CloseSession(&session);
592 }
593 ADBG_CASE_DEFINE(regression, 1007, xtest_tee_test_1007, "Test Panic");
594
595 #ifndef TA_DIR
596 # ifdef __ANDROID__
597 #define TA_DIR "/vendor/lib/optee_armtz"
598 # else
599 #define TA_DIR "/lib/optee_armtz"
600 # endif
601 #endif
602
open_ta_file(const TEEC_UUID * uuid,const char * mode)603 static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode)
604 {
605 char buf[PATH_MAX] = { };
606
607 snprintf(buf, sizeof(buf),
608 "%s/%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x.ta",
609 TA_DIR, uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
610 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
611 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
612 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
613 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
614
615 return fopen(buf, mode);
616 }
617
load_corrupt_ta(ADBG_Case_t * c,size_t offs,uint8_t mask)618 static bool load_corrupt_ta(ADBG_Case_t *c, size_t offs, uint8_t mask)
619 {
620 TEEC_Session session = { };
621 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
622 TEEC_UUID uuid = PTA_SECSTOR_TA_MGMT_UUID;
623 TEEC_Result res = TEEC_ERROR_GENERIC;
624 uint32_t ret_orig = 0;
625 FILE *f = NULL;
626 bool r = false;
627 uint8_t *buf = NULL;
628 size_t sz = 0;
629 size_t fread_res = 0;
630
631 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
632 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
633 goto out;
634
635 f = open_ta_file(&create_fail_test_ta_uuid, "rb");
636 if (!ADBG_EXPECT_NOT_NULL(c, f))
637 goto out;
638 if (!ADBG_EXPECT_TRUE(c, !fseek(f, 0, SEEK_END)))
639 goto out;
640 sz = ftell(f);
641 rewind(f);
642
643 buf = malloc(sz);
644 if (!ADBG_EXPECT_NOT_NULL(c, buf))
645 goto out;
646
647 fread_res = fread(buf, 1, sz, f);
648 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, fread_res, ==, sz))
649 goto out;
650
651 fclose(f);
652 f = NULL;
653
654 buf[MIN(offs, sz)] ^= mask;
655
656 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
657 TEEC_NONE, TEEC_NONE);
658 op.params[0].tmpref.buffer = buf;
659 op.params[0].tmpref.size = sz;
660
661 res = TEEC_InvokeCommand(&session, PTA_SECSTOR_TA_MGMT_BOOTSTRAP, &op,
662 &ret_orig);
663 r = ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
664 out:
665 free(buf);
666 if (f)
667 fclose(f);
668 TEEC_CloseSession(&session);
669 return r;
670 }
671
test_1008_corrupt_ta(ADBG_Case_t * c)672 static void test_1008_corrupt_ta(ADBG_Case_t *c)
673 {
674 TEEC_UUID uuid = PTA_SECSTOR_TA_MGMT_UUID;
675 TEEC_Result res = TEEC_ERROR_GENERIC;
676 TEEC_Session session = { };
677 uint32_t ret_orig = 0;
678
679 res = xtest_teec_open_session(&session, &uuid, NULL, &ret_orig);
680 if (res) {
681 if (ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_ITEM_NOT_FOUND,
682 res))
683 Do_ADBG_Log("PTA Secure Storage TA Management not found: skip test");
684 return;
685 }
686 TEEC_CloseSession(&session);
687
688 ADBG_EXPECT_TRUE(c,
689 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
690 ADBG_EXPECT_TRUE(c,
691 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
692 ADBG_EXPECT_TRUE(c,
693 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
694 ADBG_EXPECT_TRUE(c,
695 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
696 ADBG_EXPECT_TRUE(c,
697 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
698 ADBG_EXPECT_TRUE(c,
699 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
700 ADBG_EXPECT_TRUE(c,
701 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
702 ADBG_EXPECT_TRUE(c,
703 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
704 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
705 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 8000, 1)); /* payload */
706 }
707
xtest_tee_test_1008(ADBG_Case_t * c)708 static void xtest_tee_test_1008(ADBG_Case_t *c)
709 {
710 TEEC_Session session = { };
711 TEEC_Session session_crypt = { };
712 uint32_t ret_orig = 0;
713
714 Do_ADBG_BeginSubCase(c, "Invoke command");
715 {
716 if (ADBG_EXPECT_TEEC_SUCCESS(c,
717 xtest_teec_open_session(&session, &os_test_ta_uuid,
718 NULL, &ret_orig))) {
719
720 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
721 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
722 NULL, &ret_orig));
723 TEEC_CloseSession(&session);
724 }
725
726 }
727 Do_ADBG_EndSubCase(c, "Invoke command");
728
729 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
730 {
731 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
732
733 op.params[0].value.a = 2000;
734 op.paramTypes = TEEC_PARAM_TYPES(
735 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
736
737 if (ADBG_EXPECT_TEEC_SUCCESS(c,
738 xtest_teec_open_session(&session,
739 &os_test_ta_uuid,
740 NULL,
741 &ret_orig))) {
742
743 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
744 TEEC_InvokeCommand(&session,
745 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
746 &op, &ret_orig));
747 TEEC_CloseSession(&session);
748 }
749 }
750 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
751
752 Do_ADBG_BeginSubCase(c, "Create session fail");
753 {
754 size_t n = 0;
755
756 for (n = 0; n < 100; n++) {
757 Do_ADBG_Log("n = %zu", n);
758 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
759 xtest_teec_open_session(&session_crypt,
760 &create_fail_test_ta_uuid,
761 NULL, &ret_orig));
762 /* level > 0 may be used to detect/debug memory leaks */
763 if (!level)
764 break;
765 }
766 }
767 Do_ADBG_EndSubCase(c, "Create session fail");
768
769 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
770 test_1008_corrupt_ta(c);
771 Do_ADBG_EndSubCase(c, "Load corrupt TA");
772 }
773 ADBG_CASE_DEFINE(regression, 1008, xtest_tee_test_1008,
774 "TEE internal client API");
775
cancellation_thread(void * arg)776 static void *cancellation_thread(void *arg)
777 {
778 /*
779 * Sleep 0.5 seconds before cancellation to make sure that the other
780 * thread is in RPC_WAIT.
781 */
782 (void)usleep(500000);
783 TEEC_RequestCancellation(arg);
784 return NULL;
785 }
786
xtest_tee_test_1009_subcase(ADBG_Case_t * c,const char * subcase,uint32_t timeout,bool cancel)787 static void xtest_tee_test_1009_subcase(ADBG_Case_t *c, const char *subcase,
788 uint32_t timeout, bool cancel)
789 {
790 TEEC_Session session = { };
791 uint32_t ret_orig = 0;
792 pthread_t thr;
793
794 memset(&thr, 0, sizeof(thr));
795
796 Do_ADBG_BeginSubCase(c, "%s", subcase);
797 {
798 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
799
800 if (ADBG_EXPECT_TEEC_SUCCESS(c,
801 xtest_teec_open_session(&session, &os_test_ta_uuid,
802 NULL, &ret_orig))) {
803
804 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c,
805 TEEC_ORIGIN_TRUSTED_APP,
806 ret_orig);
807
808 op.params[0].value.a = timeout;
809 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
810 TEEC_NONE,
811 TEEC_NONE, TEEC_NONE);
812 if (cancel) {
813 (void)ADBG_EXPECT(c, 0,
814 pthread_create(&thr, NULL,
815 cancellation_thread, &op));
816
817 (void)ADBG_EXPECT_TEEC_RESULT(c,
818 TEEC_ERROR_CANCEL,
819 TEEC_InvokeCommand(&session,
820 TA_OS_TEST_CMD_WAIT,
821 &op,
822 &ret_orig));
823 } else
824
825 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
826 TEEC_InvokeCommand(&session,
827 TA_OS_TEST_CMD_WAIT,
828 &op,
829 &ret_orig));
830 if (cancel)
831 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
832
833 TEEC_CloseSession(&session);
834 }
835 }
836 Do_ADBG_EndSubCase(c, "%s", subcase);
837 }
838
xtest_tee_test_1009(ADBG_Case_t * c)839 static void xtest_tee_test_1009(ADBG_Case_t *c)
840 {
841 xtest_tee_test_1009_subcase(c, "TEE Wait 0.1s", 100, false);
842 xtest_tee_test_1009_subcase(c, "TEE Wait 0.5s", 500, false);
843 xtest_tee_test_1009_subcase(c, "TEE Wait 2s cancel", 2000, true);
844 xtest_tee_test_1009_subcase(c, "TEE Wait 2s", 2000, false);
845 }
846 ADBG_CASE_DEFINE(regression, 1009, xtest_tee_test_1009, "TEE Wait");
847
xtest_tee_test_1010(ADBG_Case_t * c)848 static void xtest_tee_test_1010(ADBG_Case_t *c)
849 {
850 unsigned int n = 0;
851 unsigned int idx = 0;
852 size_t memref_sz[] = { 1024, 65536 };
853
854 for (n = 1; n <= 5; n++) {
855 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
856 xtest_tee_test_invalid_mem_access(c, n);
857 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
858 }
859
860 for (idx = 0; idx < ARRAY_SIZE(memref_sz); idx++) {
861 for (n = 1; n <= 5; n++) {
862 Do_ADBG_BeginSubCase(c,
863 "Invalid memory access %u with %zu bytes memref",
864 n, memref_sz[idx]);
865 xtest_tee_test_invalid_mem_access2(c, n, memref_sz[idx]);
866 Do_ADBG_EndSubCase(c,
867 "Invalid memory access %u with %zu bytes memref",
868 n, memref_sz[idx]);
869 }
870 }
871 }
872 ADBG_CASE_DEFINE(regression, 1010, xtest_tee_test_1010,
873 "Invalid memory access");
874
xtest_tee_test_1011(ADBG_Case_t * c)875 static void xtest_tee_test_1011(ADBG_Case_t *c)
876 {
877 TEEC_Session session = { };
878 uint32_t ret_orig = 0;
879 struct xtest_crypto_session cs = {
880 c, &session, TA_RPC_CMD_CRYPT_SHA256,
881 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
882 TA_RPC_CMD_CRYPT_AES256ECB_DEC
883 };
884 struct xtest_crypto_session cs_privmem = {
885 c, &session,
886 TA_RPC_CMD_CRYPT_PRIVMEM_SHA256,
887 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_ENC,
888 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_DEC
889 };
890 TEEC_UUID uuid = rpc_test_ta_uuid;
891
892 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
893 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
894 return;
895
896 Do_ADBG_BeginSubCase(c, "TA-to-TA via non-secure shared memory");
897 /*
898 * Run the "complete crypto test suite" using TA-to-TA
899 * communication
900 */
901 xtest_crypto_test(&cs);
902 Do_ADBG_EndSubCase(c, "TA-to-TA via non-secure shared memory");
903
904 Do_ADBG_BeginSubCase(c, "TA-to-TA via TA private memory");
905 /*
906 * Run the "complete crypto test suite" using TA-to-TA
907 * communication via TA private memory.
908 */
909 xtest_crypto_test(&cs_privmem);
910 Do_ADBG_EndSubCase(c, "TA-to-TA via TA private memory");
911
912 TEEC_CloseSession(&session);
913 }
914 ADBG_CASE_DEFINE(regression, 1011, xtest_tee_test_1011,
915 "Test TA-to-TA features with User Crypt TA");
916
917 /*
918 * Note that this test is failing when
919 * - running twice in a raw
920 * - and the user TA is statically linked
921 * This is because the counter is not reseted when opening the first session
922 * in case the TA is statically linked
923 */
xtest_tee_test_1012(ADBG_Case_t * c)924 static void xtest_tee_test_1012(ADBG_Case_t *c)
925 {
926 TEEC_Session session1 = { };
927 TEEC_Session session2 = { };
928 uint32_t ret_orig = 0;
929 TEEC_UUID uuid = sims_test_ta_uuid;
930
931 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
932 {
933 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
934 static const uint8_t in[] = {
935 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
936 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
937 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
938 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
939 };
940 uint8_t out[32] = { };
941 int i = 0;
942
943 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
944 xtest_teec_open_session(&session1, &uuid, NULL,
945 &ret_orig)))
946 return;
947
948 op.params[0].value.a = 0;
949 op.params[1].tmpref.buffer = (void *)in;
950 op.params[1].tmpref.size = sizeof(in);
951 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
952 TEEC_MEMREF_TEMP_INPUT,
953 TEEC_NONE, TEEC_NONE);
954
955 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
956 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
957 &ret_orig));
958
959 for (i = 1; i < 3; i++) {
960 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
961 xtest_teec_open_session(&session2, &uuid, NULL,
962 &ret_orig)))
963 continue;
964
965 op.params[0].value.a = 0;
966 op.params[1].tmpref.buffer = out;
967 op.params[1].tmpref.size = sizeof(out);
968 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
969 TEEC_MEMREF_TEMP_OUTPUT,
970 TEEC_NONE, TEEC_NONE);
971
972 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
973 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
974 &op, &ret_orig));
975
976 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
977 sizeof(out))) {
978 Do_ADBG_Log("in:");
979 Do_ADBG_HexLog(in, sizeof(in), 16);
980 Do_ADBG_Log("out:");
981 Do_ADBG_HexLog(out, sizeof(out), 16);
982 }
983
984 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
985 TEEC_NONE, TEEC_NONE,
986 TEEC_NONE);
987
988 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
989 TEEC_InvokeCommand(&session1,
990 TA_SIMS_CMD_GET_COUNTER,
991 &op, &ret_orig));
992
993 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
994
995 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
996 TEEC_InvokeCommand(&session2,
997 TA_SIMS_CMD_GET_COUNTER, &op,
998 &ret_orig));
999
1000 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
1001 TEEC_CloseSession(&session2);
1002 }
1003
1004 memset(out, 0, sizeof(out));
1005 op.params[0].value.a = 0;
1006 op.params[1].tmpref.buffer = out;
1007 op.params[1].tmpref.size = sizeof(out);
1008 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
1009 TEEC_MEMREF_TEMP_OUTPUT,
1010 TEEC_NONE, TEEC_NONE);
1011
1012 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1013 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
1014 &ret_orig));
1015
1016 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
1017 Do_ADBG_Log("in:");
1018 Do_ADBG_HexLog(in, sizeof(in), 16);
1019 Do_ADBG_Log("out:");
1020 Do_ADBG_HexLog(out, sizeof(out), 16);
1021 }
1022
1023 TEEC_CloseSession(&session1);
1024 }
1025 Do_ADBG_EndSubCase(c, "Single Instance Multi Session");
1026 }
1027 ADBG_CASE_DEFINE(regression, 1012, xtest_tee_test_1012,
1028 "Test Single Instance Multi Session features with SIMS TA");
1029
1030 struct test_1013_thread_arg {
1031 const TEEC_UUID *uuid;
1032 uint32_t cmd;
1033 uint32_t repeat;
1034 TEEC_SharedMemory *shm;
1035 uint32_t error_orig;
1036 TEEC_Result res;
1037 uint32_t max_concurrency;
1038 const uint8_t *in;
1039 size_t in_len;
1040 uint8_t *out;
1041 size_t out_len;
1042 };
1043
test_1013_thread(void * arg)1044 static void *test_1013_thread(void *arg)
1045 {
1046 struct test_1013_thread_arg *a = arg;
1047 TEEC_Session session = { };
1048 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1049 uint8_t p2 = TEEC_NONE;
1050 uint8_t p3 = TEEC_NONE;
1051
1052 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
1053 &a->error_orig);
1054 if (a->res != TEEC_SUCCESS)
1055 return NULL;
1056
1057 op.params[0].memref.parent = a->shm;
1058 op.params[0].memref.size = a->shm->size;
1059 op.params[0].memref.offset = 0;
1060 op.params[1].value.a = a->repeat;
1061 op.params[1].value.b = 0;
1062 op.params[2].tmpref.buffer = (void *)a->in;
1063 op.params[2].tmpref.size = a->in_len;
1064 op.params[3].tmpref.buffer = a->out;
1065 op.params[3].tmpref.size = a->out_len;
1066
1067 if (a->in_len)
1068 p2 = TEEC_MEMREF_TEMP_INPUT;
1069 if (a->out_len)
1070 p3 = TEEC_MEMREF_TEMP_OUTPUT;
1071
1072 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
1073 TEEC_VALUE_INOUT, p2, p3);
1074
1075 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
1076 a->max_concurrency = op.params[1].value.b;
1077 a->out_len = op.params[3].tmpref.size;
1078 TEEC_CloseSession(&session);
1079 return NULL;
1080 }
1081
1082 #define NUM_THREADS 3
1083
xtest_tee_test_1013_single(ADBG_Case_t * c,double * mean_concurrency,const TEEC_UUID * uuid)1084 static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
1085 const TEEC_UUID *uuid)
1086 {
1087 size_t nt = 0;
1088 size_t n = 0;
1089 size_t repeat = 1000;
1090 TEEC_SharedMemory shm = { };
1091 size_t max_concurrency = 0;
1092 struct test_1013_thread_arg arg[NUM_THREADS] = { };
1093 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
1094 static const uint8_t sha256_out[] = {
1095 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
1096 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
1097 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
1098 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
1099 };
1100 uint8_t out[32] = { };
1101 pthread_t thr[NUM_THREADS] = { };
1102
1103 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
1104 *mean_concurrency = 0;
1105
1106 shm.size = sizeof(struct ta_concurrent_shm);
1107 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1108 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1109 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
1110 return;
1111
1112 memset(shm.buffer, 0, shm.size);
1113 max_concurrency = 0;
1114 nt = NUM_THREADS;
1115
1116 for (n = 0; n < nt; n++) {
1117 arg[n].uuid = uuid;
1118 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
1119 arg[n].repeat = repeat * 10;
1120 arg[n].shm = &shm;
1121 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1122 test_1013_thread, arg + n)))
1123 nt = n; /* break loop and start cleanup */
1124 }
1125
1126 for (n = 0; n < nt; n++) {
1127 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
1128 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
1129 if (arg[n].max_concurrency > max_concurrency)
1130 max_concurrency = arg[n].max_concurrency;
1131 }
1132
1133 /*
1134 * Concurrency can be limited by several factors, for instance in a
1135 * single CPU system it's dependent on the Preemption Model used by
1136 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
1137 * best result there).
1138 */
1139 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
1140 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, NUM_THREADS);
1141 *mean_concurrency += max_concurrency;
1142 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
1143
1144 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
1145 memset(shm.buffer, 0, shm.size);
1146 memset(arg, 0, sizeof(arg));
1147 max_concurrency = 0;
1148 nt = NUM_THREADS;
1149
1150 for (n = 0; n < nt; n++) {
1151 arg[n].uuid = uuid;
1152 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
1153 arg[n].repeat = repeat;
1154 arg[n].shm = &shm;
1155 arg[n].in = sha256_in;
1156 arg[n].in_len = sizeof(sha256_in);
1157 arg[n].out = out;
1158 arg[n].out_len = sizeof(out);
1159 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1160 test_1013_thread, arg + n)))
1161 nt = n; /* break loop and start cleanup */
1162 }
1163
1164 for (n = 0; n < nt; n++) {
1165 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1166 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1167 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1168 arg[n].out, arg[n].out_len);
1169 if (arg[n].max_concurrency > max_concurrency)
1170 max_concurrency = arg[n].max_concurrency;
1171 }
1172 *mean_concurrency += max_concurrency;
1173 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
1174
1175 *mean_concurrency /= 2.0;
1176 TEEC_ReleaseSharedMemory(&shm);
1177 }
1178
xtest_tee_test_1013(ADBG_Case_t * c)1179 static void xtest_tee_test_1013(ADBG_Case_t *c)
1180 {
1181 int i = 0;
1182 double mean_concurrency = 0;
1183 double concurrency = 0;
1184 int nb_loops = 24;
1185
1186 if (level == 0)
1187 nb_loops /= 2;
1188
1189 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
1190 mean_concurrency = 0;
1191 for (i = 0; i < nb_loops; i++) {
1192 xtest_tee_test_1013_single(c, &concurrency,
1193 &concurrent_ta_uuid);
1194 mean_concurrency += concurrency;
1195 }
1196 mean_concurrency /= nb_loops;
1197
1198 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1199 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1200 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
1201
1202 #ifndef CFG_PAGED_USER_TA
1203 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1204 mean_concurrency = 0;
1205 for (i = 0; i < nb_loops; i++) {
1206 xtest_tee_test_1013_single(c, &concurrency,
1207 &concurrent_large_ta_uuid);
1208 mean_concurrency += concurrency;
1209 }
1210 mean_concurrency /= nb_loops;
1211
1212 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1213 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1214 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
1215 #endif
1216 }
1217 ADBG_CASE_DEFINE(regression, 1013, xtest_tee_test_1013,
1218 "Test concurrency with concurrent TA");
1219
1220 #ifdef CFG_SECURE_DATA_PATH
xtest_tee_test_1014(ADBG_Case_t * c)1221 static void xtest_tee_test_1014(ADBG_Case_t *c)
1222 {
1223 UNUSED(c);
1224
1225 int size = 17000;
1226 int loop = 10;
1227 int ion_heap = DEFAULT_ION_HEAP_TYPE;
1228 int rnd_offset = 1;
1229 int test = 0;
1230 int ret = 0;
1231
1232 test = TEST_NS_TO_TA;
1233 Do_ADBG_BeginSubCase(c, "SDP: NonSecure client invokes a SDP TA");
1234 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
1235 ADBG_EXPECT(c, 0, ret);
1236 Do_ADBG_EndSubCase(c, "SDP: NonSecure client invokes a SDP TA");
1237
1238 test = TEST_TA_TO_TA;
1239 Do_ADBG_BeginSubCase(c, "SDP: SDP TA invokes a SDP TA");
1240 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
1241 ADBG_EXPECT(c, 0, ret);
1242 Do_ADBG_EndSubCase(c, "SDP: SDP TA invokes a SDP TA");
1243
1244 test = TEST_TA_TO_PTA;
1245 Do_ADBG_BeginSubCase(c, "SDP: SDP TA invokes a test pTA (invoke_tests.pta)");
1246 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
1247 ADBG_EXPECT(c, 0, ret);
1248 Do_ADBG_EndSubCase(c, "SDP: SDP TA invokes a test pTA (invoke_tests.pta)");
1249
1250 test = TEST_NS_TO_PTA;
1251 Do_ADBG_BeginSubCase(c, "SDP: NSec CA invokes a test pTA (invoke_tests.pta) (should fail)");
1252 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
1253 ADBG_EXPECT(c, 1, ret);
1254 Do_ADBG_EndSubCase(c, "SDP: NSec CA invokes a test pTA (invoke_tests.pta) (should fail)");
1255
1256 Do_ADBG_BeginSubCase(c, "SDP: Invoke TA with out of bounds SDP memref");
1257 ret = sdp_out_of_bounds_memref_test(size, ion_heap, 0);
1258 ADBG_EXPECT(c, 0, ret);
1259 Do_ADBG_EndSubCase(c, NULL);
1260 }
1261 ADBG_CASE_DEFINE(regression, 1014, xtest_tee_test_1014,
1262 "Test secure data path against SDP TAs and pTAs");
1263 #endif /*CFG_SECURE_DATA_PATH*/
1264
xtest_tee_test_1015(ADBG_Case_t * c)1265 static void xtest_tee_test_1015(ADBG_Case_t *c)
1266 {
1267 TEEC_Result res = TEEC_ERROR_GENERIC;
1268 TEEC_Session session = { };
1269 uint32_t ret_orig = 0;
1270
1271 /* Pseudo TA is optional: warn and nicely exit if not found */
1272 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
1273 &ret_orig);
1274 if (res == TEEC_ERROR_ITEM_NOT_FOUND) {
1275 Do_ADBG_Log(" - 1015 - skip test, pseudo TA not found");
1276 return;
1277 }
1278 ADBG_EXPECT_TEEC_SUCCESS(c, res);
1279
1280 ADBG_EXPECT_TEEC_SUCCESS(c,
1281 TEEC_InvokeCommand(&session, PTA_INVOKE_TESTS_CMD_FS_HTREE,
1282 NULL, &ret_orig));
1283 TEEC_CloseSession(&session);
1284 }
1285 ADBG_CASE_DEFINE(regression, 1015, xtest_tee_test_1015,
1286 "FS hash-tree corner cases");
1287
xtest_tee_test_1016(ADBG_Case_t * c)1288 static void xtest_tee_test_1016(ADBG_Case_t *c)
1289 {
1290 TEEC_Session session = { };
1291 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1292 uint32_t ret_orig = 0;
1293
1294 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1295 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
1296 &ret_orig)))
1297 return;
1298
1299 op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE,
1300 TEEC_NONE);
1301
1302 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1303 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_TA2TA_MEMREF, &op,
1304 &ret_orig));
1305
1306 TEEC_CloseSession(&session);
1307 }
1308 ADBG_CASE_DEFINE(regression, 1016, xtest_tee_test_1016,
1309 "Test TA to TA transfers (in/out/inout memrefs on the stack)");
1310
xtest_tee_test_1017(ADBG_Case_t * c)1311 static void xtest_tee_test_1017(ADBG_Case_t *c)
1312 {
1313 TEEC_Session session = { };
1314 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1315 uint32_t ret_orig = 0;
1316 TEEC_SharedMemory shm = { };
1317 size_t page_size = 4096;
1318
1319 shm.size = 8 * page_size;
1320 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1321 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1322 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
1323 return;
1324
1325 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1326 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
1327 &ret_orig)))
1328 goto out;
1329
1330 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT,
1331 TEEC_MEMREF_PARTIAL_INPUT,
1332 TEEC_MEMREF_PARTIAL_OUTPUT,
1333 TEEC_MEMREF_PARTIAL_OUTPUT);
1334
1335 /*
1336 * The first two memrefs are supposed to be combined into in
1337 * region and the last two memrefs should have one region each
1338 * when the parameters are mapped for the TA.
1339 */
1340 op.params[0].memref.parent = &shm;
1341 op.params[0].memref.size = page_size;
1342 op.params[0].memref.offset = 0;
1343
1344 op.params[1].memref.parent = &shm;
1345 op.params[1].memref.size = page_size;
1346 op.params[1].memref.offset = page_size;
1347
1348 op.params[2].memref.parent = &shm;
1349 op.params[2].memref.size = page_size;
1350 op.params[2].memref.offset = 4 * page_size;
1351
1352 op.params[3].memref.parent = &shm;
1353 op.params[3].memref.size = 2 * page_size;
1354 op.params[3].memref.offset = 6 * page_size;
1355
1356 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1357 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PARAMS, &op,
1358 &ret_orig));
1359
1360 TEEC_CloseSession(&session);
1361 out:
1362 TEEC_ReleaseSharedMemory(&shm);
1363 }
1364 ADBG_CASE_DEFINE(regression, 1017, xtest_tee_test_1017,
1365 "Test coalescing memrefs");
1366
invoke_1byte_out_of_bounds(ADBG_Case_t * c,TEEC_Session * session,TEEC_SharedMemory * shm)1367 static void invoke_1byte_out_of_bounds(ADBG_Case_t *c, TEEC_Session *session,
1368 TEEC_SharedMemory *shm)
1369 {
1370 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1371 TEEC_Result ret = TEEC_ERROR_GENERIC;
1372 uint32_t ret_orig = 0;
1373
1374 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT,
1375 TEEC_NONE, TEEC_NONE, TEEC_NONE);
1376
1377 op.params[0].memref.parent = shm;
1378 op.params[0].memref.size = shm->size / 2;
1379 op.params[0].memref.offset = shm->size - (shm->size / 2) + 1;
1380
1381 ret = TEEC_InvokeCommand(session, TA_OS_TEST_CMD_PARAMS,
1382 &op, &ret_orig);
1383
1384 ADBG_EXPECT_COMPARE_UNSIGNED(c, ret_orig, !=, TEEC_ORIGIN_TRUSTED_APP);
1385 if (ret != TEEC_ERROR_BAD_PARAMETERS && ret != TEEC_ERROR_GENERIC) {
1386 ADBG_EXPECT(c, TEEC_ERROR_BAD_PARAMETERS, ret);
1387 ADBG_EXPECT(c, TEEC_ERROR_GENERIC, ret);
1388 }
1389 }
1390
xtest_tee_test_1018(ADBG_Case_t * c)1391 static void xtest_tee_test_1018(ADBG_Case_t *c)
1392 {
1393 TEEC_Session session = { };
1394 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1395 uint32_t ret_orig = 0;
1396 TEEC_SharedMemory shm = { };
1397 TEEC_Result ret = TEEC_ERROR_GENERIC;
1398 size_t page_size = 4096;
1399 /* Intentionally not 4kB aligned and odd */
1400 uint8_t buffer[6001] = { };
1401
1402 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1403 xtest_teec_open_session(&session,
1404 &os_test_ta_uuid,
1405 NULL,
1406 &ret_orig)))
1407 return;
1408
1409 Do_ADBG_BeginSubCase(c, "Out of bounds > 4kB on allocated shm");
1410
1411 shm.size = 8 * page_size;
1412 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1413 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1414 TEEC_AllocateSharedMemory(&xtest_teec_ctx,
1415 &shm)))
1416 goto out;
1417
1418 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT,
1419 TEEC_MEMREF_PARTIAL_INPUT,
1420 TEEC_MEMREF_PARTIAL_OUTPUT,
1421 TEEC_MEMREF_PARTIAL_OUTPUT);
1422
1423 /*
1424 * The first two memrefs are supposed to be combined into in
1425 * region and the last two memrefs should have one region each
1426 * when the parameters are mapped for the TA.
1427 */
1428 op.params[0].memref.parent = &shm;
1429 op.params[0].memref.size = page_size;
1430 op.params[0].memref.offset = 0;
1431
1432 op.params[1].memref.parent = &shm;
1433 op.params[1].memref.size = page_size;
1434 op.params[1].memref.offset = page_size;
1435
1436 op.params[2].memref.parent = &shm;
1437 op.params[2].memref.size = page_size;
1438 op.params[2].memref.offset = 4 * page_size;
1439
1440 op.params[3].memref.parent = &shm;
1441 op.params[3].memref.size = 3 * page_size;
1442 op.params[3].memref.offset = 6 * page_size;
1443
1444 ret = TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PARAMS, &op,
1445 &ret_orig);
1446
1447 ADBG_EXPECT_COMPARE_UNSIGNED(c, ret_orig, !=, TEEC_ORIGIN_TRUSTED_APP);
1448 if (ret != TEEC_ERROR_BAD_PARAMETERS && ret != TEEC_ERROR_GENERIC) {
1449 ADBG_EXPECT(c, TEEC_ERROR_BAD_PARAMETERS, ret);
1450 ADBG_EXPECT(c, TEEC_ERROR_GENERIC, ret);
1451 }
1452
1453 TEEC_ReleaseSharedMemory(&shm);
1454 Do_ADBG_EndSubCase(c, NULL);
1455
1456 Do_ADBG_BeginSubCase(c, "Out of bounds by 1 byte on registered shm");
1457
1458 memset(&shm, 0, sizeof(shm));
1459 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1460 shm.buffer = buffer;
1461 shm.size = sizeof(buffer);
1462
1463 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1464 TEEC_RegisterSharedMemory(&xtest_teec_ctx,
1465 &shm)))
1466 goto out;
1467
1468 invoke_1byte_out_of_bounds(c, &session, &shm);
1469
1470 TEEC_ReleaseSharedMemory(&shm);
1471 Do_ADBG_EndSubCase(c, NULL);
1472
1473 Do_ADBG_BeginSubCase(c, "Out of bounds by 1 byte ref on allocated shm");
1474
1475 memset(&shm, 0, sizeof(shm));
1476 shm.size = sizeof(buffer);
1477 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1478 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1479 TEEC_AllocateSharedMemory(&xtest_teec_ctx,
1480 &shm)))
1481 goto out;
1482
1483 invoke_1byte_out_of_bounds(c, &session, &shm);
1484
1485 TEEC_ReleaseSharedMemory(&shm);
1486 Do_ADBG_EndSubCase(c, NULL);
1487
1488 out:
1489 TEEC_CloseSession(&session);
1490 }
1491 ADBG_CASE_DEFINE(regression, 1018, xtest_tee_test_1018,
1492 "Test memref out of bounds");
1493
xtest_tee_test_1019(ADBG_Case_t * c)1494 static void xtest_tee_test_1019(ADBG_Case_t *c)
1495 {
1496 TEEC_Session session = { };
1497 uint32_t ret_orig = 0;
1498
1499 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1500 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
1501 &ret_orig)))
1502 return;
1503
1504 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1505 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CALL_LIB, NULL,
1506 &ret_orig));
1507
1508 (void)ADBG_EXPECT_TEEC_RESULT(c,
1509 TEEC_ERROR_TARGET_DEAD,
1510 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CALL_LIB_PANIC,
1511 NULL, &ret_orig));
1512
1513 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
1514
1515 TEEC_CloseSession(&session);
1516 }
1517 ADBG_CASE_DEFINE(regression, 1019, xtest_tee_test_1019,
1518 "Test dynamically linked TA");
1519
xtest_tee_test_1020(ADBG_Case_t * c)1520 static void xtest_tee_test_1020(ADBG_Case_t *c)
1521 {
1522 TEEC_Result res = TEEC_ERROR_GENERIC;
1523 TEEC_Session session = { };
1524 uint32_t ret_orig = 0;
1525
1526 /* Pseudo TA is optional: warn and nicely exit if not found */
1527 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
1528 &ret_orig);
1529 if (res == TEEC_ERROR_ITEM_NOT_FOUND) {
1530 Do_ADBG_Log(" - 1020 - skip test, pseudo TA not found");
1531 return;
1532 }
1533 ADBG_EXPECT_TEEC_SUCCESS(c, res);
1534
1535 res = TEEC_InvokeCommand(&session, PTA_INVOKE_TESTS_CMD_LOCKDEP,
1536 NULL, &ret_orig);
1537 if (res != TEEC_SUCCESS) {
1538 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
1539 ret_orig);
1540 if (res == TEEC_ERROR_NOT_SUPPORTED) {
1541 Do_ADBG_Log(" - 1020 - skip test, feature not "
1542 "implemented");
1543 goto out;
1544 }
1545 /* Error */
1546 (void)ADBG_EXPECT_TEEC_SUCCESS(c, res);
1547 }
1548 out:
1549 TEEC_CloseSession(&session);
1550 }
1551 ADBG_CASE_DEFINE(regression, 1020, xtest_tee_test_1020,
1552 "Test lockdep algorithm");
1553
open_sec_session(TEEC_Session * session,const TEEC_UUID * uuid)1554 static TEEC_Result open_sec_session(TEEC_Session *session,
1555 const TEEC_UUID *uuid)
1556 {
1557 TEEC_Result res = TEEC_ERROR_GENERIC;
1558 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1559 uint32_t ret_orig = 0;
1560
1561 op.params[0].tmpref.buffer = (void *)uuid;
1562 op.params[0].tmpref.size = sizeof(*uuid);
1563 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
1564 TEEC_NONE, TEEC_NONE, TEEC_NONE);
1565
1566 res = TEEC_InvokeCommand(session, TA_SIMS_OPEN_TA_SESSION,
1567 &op, &ret_orig);
1568 if (res != TEEC_SUCCESS)
1569 return TEEC_ERROR_GENERIC;
1570
1571 return res;
1572 }
1573
sims_get_counter(TEEC_Session * session,uint32_t * counter)1574 static TEEC_Result sims_get_counter(TEEC_Session *session,
1575 uint32_t *counter)
1576 {
1577 TEEC_Result res = TEEC_ERROR_GENERIC;
1578 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1579 uint32_t ret_orig = 0;
1580
1581 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
1582 TEEC_NONE, TEEC_NONE, TEEC_NONE);
1583
1584 res = TEEC_InvokeCommand(session, TA_SIMS_CMD_GET_COUNTER,
1585 &op, &ret_orig);
1586 if (res == TEEC_SUCCESS)
1587 *counter = op.params[0].value.a;
1588
1589 return res;
1590 }
1591
trigger_panic(TEEC_Session * session,const TEEC_UUID * uuid)1592 static TEEC_Result trigger_panic(TEEC_Session *session,
1593 const TEEC_UUID *uuid)
1594 {
1595 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1596 uint32_t ret_orig = 0;
1597
1598 if (!uuid) {
1599 op.params[0].tmpref.buffer = NULL;
1600 op.params[0].tmpref.size = 0;
1601 } else {
1602 op.params[0].tmpref.buffer = (void *)uuid;
1603 op.params[0].tmpref.size = sizeof(*uuid);
1604 }
1605 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
1606 TEEC_NONE, TEEC_NONE, TEEC_NONE);
1607
1608 return TEEC_InvokeCommand(session, TA_SIMS_CMD_PANIC,
1609 &op, &ret_orig);
1610 }
1611
test_panic_ca_to_ta(ADBG_Case_t * c,const TEEC_UUID * uuid,bool multi_instance)1612 static void test_panic_ca_to_ta(ADBG_Case_t *c, const TEEC_UUID *uuid,
1613 bool multi_instance)
1614 {
1615 TEEC_Result exp_res = TEEC_ERROR_GENERIC;
1616 uint32_t counter = 0;
1617 uint32_t ret_orig = 0;
1618 uint32_t exp_counter = 0;
1619 TEEC_Session cs[3] = { };
1620
1621 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1622 xtest_teec_open_session(&cs[0], uuid, NULL,
1623 &ret_orig)))
1624 return;
1625
1626 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1627 xtest_teec_open_session(&cs[1], uuid, NULL,
1628 &ret_orig)))
1629 goto bail0;
1630
1631 if (!ADBG_EXPECT_TEEC_SUCCESS(c, sims_get_counter(&cs[0], &counter)))
1632 goto bail1;
1633
1634 if (!ADBG_EXPECT(c, 0, counter))
1635 goto bail1;
1636
1637 if (!ADBG_EXPECT_TEEC_SUCCESS(c, sims_get_counter(&cs[1], &counter)))
1638 goto bail1;
1639
1640 exp_counter = multi_instance ? 0 : 1;
1641 if (!ADBG_EXPECT(c, exp_counter, counter))
1642 goto bail1;
1643
1644 if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
1645 trigger_panic(&cs[1], NULL)))
1646 goto bail1;
1647
1648 exp_res = multi_instance ? TEEC_SUCCESS : TEEC_ERROR_TARGET_DEAD;
1649 if (!ADBG_EXPECT_TEEC_RESULT(c, exp_res,
1650 sims_get_counter(&cs[0], &counter)))
1651 goto bail1;
1652
1653 if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
1654 sims_get_counter(&cs[1], &counter)))
1655 goto bail1;
1656
1657 /* Attempt to open a session on panicked context */
1658 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1659 xtest_teec_open_session(&cs[1], uuid, NULL,
1660 &ret_orig)))
1661 goto bail1;
1662
1663 /* Sanity check of still valid TA context */
1664 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1665 xtest_teec_open_session(&cs[2], uuid, NULL,
1666 &ret_orig)))
1667 goto bail1;
1668
1669 /* Sanity check of still valid TA context */
1670 if (multi_instance) {
1671 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1672 sims_get_counter(&cs[0], &counter)))
1673 goto bail2;
1674
1675 if (!ADBG_EXPECT(c, 0, counter))
1676 goto bail2;
1677 }
1678
1679 if (!ADBG_EXPECT_TEEC_SUCCESS(c, sims_get_counter(&cs[2], &counter)))
1680 goto bail2;
1681
1682 exp_counter = multi_instance ? 0 : 1;
1683 if (!ADBG_EXPECT(c, exp_counter, counter))
1684 goto bail2;
1685
1686 bail2:
1687 TEEC_CloseSession(&cs[2]);
1688 bail1:
1689 TEEC_CloseSession(&cs[1]);
1690 bail0:
1691 TEEC_CloseSession(&cs[0]);
1692 }
1693
test_panic_ta_to_ta(ADBG_Case_t * c,const TEEC_UUID * uuid1,const TEEC_UUID * uuid2)1694 static void test_panic_ta_to_ta(ADBG_Case_t *c, const TEEC_UUID *uuid1,
1695 const TEEC_UUID *uuid2)
1696 {
1697 uint32_t ret_orig = 0;
1698 uint32_t counter = 0;
1699 TEEC_Session cs[3] = { };
1700
1701 /* Test pre-conditions */
1702 /* 2.1 - CA opens a session toward TA1 */
1703 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1704 xtest_teec_open_session(&cs[0], uuid1, NULL,
1705 &ret_orig)))
1706 return;
1707
1708 /* 2.2 - CA opens a session toward TA2 */
1709 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1710 xtest_teec_open_session(&cs[1], uuid2, NULL,
1711 &ret_orig)))
1712 goto bail0;
1713
1714 /* 2.3 - TA1 opens a session toward TA2 */
1715 if (!ADBG_EXPECT_TEEC_SUCCESS(c, open_sec_session(&cs[0], uuid2)))
1716 goto bail1;
1717
1718 /* 2.4 - CA invokes TA2 which panics */
1719 if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
1720 trigger_panic(&cs[1], NULL)))
1721 goto bail1;
1722
1723 /* Expected results */
1724 /* 2.5 - Expect CA->TA1 session is still alive */
1725 if (!ADBG_EXPECT_TEEC_SUCCESS(c, sims_get_counter(&cs[0], &counter)))
1726 goto bail1;
1727
1728 /* 2.6 - Expect CA->TA2 session is properly released */
1729 if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
1730 sims_get_counter(&cs[1], &counter)))
1731 goto bail1;
1732
1733 bail1:
1734 TEEC_CloseSession(&cs[1]);
1735 bail0:
1736 TEEC_CloseSession(&cs[0]);
1737
1738 memset(cs, 0, sizeof(cs));
1739
1740 /* Test pre-conditions */
1741 /* 2.1 - CA opens a session toward TA1 */
1742 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1743 xtest_teec_open_session(&cs[0], uuid1, NULL,
1744 &ret_orig)))
1745 return;
1746
1747 /* 2.2 - CA opens a session toward TA2 */
1748 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1749 xtest_teec_open_session(&cs[1], uuid2, NULL,
1750 &ret_orig)))
1751 goto bail2;
1752
1753 /* 2.3 - TA1 opens a session toward TA2 */
1754 if (!ADBG_EXPECT_TEEC_SUCCESS(c, open_sec_session(&cs[0], uuid2)))
1755 goto bail3;
1756
1757 /* 2.4 - CA invokes TA1 which invokes TA2 which panics */
1758 if (!ADBG_EXPECT_TEEC_SUCCESS(c, trigger_panic(&cs[0], uuid2)))
1759 goto bail3;
1760
1761 /* Expected results */
1762 /* 2.5 - Expect CA->TA1 session is still alive */
1763 if (!ADBG_EXPECT_TEEC_SUCCESS(c, sims_get_counter(&cs[0], &counter)))
1764 goto bail3;
1765
1766 /* 2.6 - Expect CA->TA2 session is properly released */
1767 if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
1768 sims_get_counter(&cs[1], &counter)))
1769 goto bail3;
1770
1771 bail3:
1772 TEEC_CloseSession(&cs[1]);
1773 bail2:
1774 TEEC_CloseSession(&cs[0]);
1775 }
1776
xtest_tee_test_1021(ADBG_Case_t * c)1777 static void xtest_tee_test_1021(ADBG_Case_t *c)
1778 {
1779 Do_ADBG_BeginSubCase(c, "Multiple Instances Single Session");
1780 test_panic_ca_to_ta(c, &miss_test_ta_uuid, true);
1781 Do_ADBG_EndSubCase(c, "Multiple Instances Single Session");
1782
1783 Do_ADBG_BeginSubCase(c, "Single Instance Multi Sessions");
1784 test_panic_ca_to_ta(c, &sims_test_ta_uuid, false);
1785 Do_ADBG_EndSubCase(c, "Single Instance Multi Sessions");
1786
1787 Do_ADBG_BeginSubCase(c, "Single Instance Multi Sessions Keep Alive");
1788 test_panic_ca_to_ta(c, &sims_keepalive_test_ta_uuid, false);
1789 Do_ADBG_EndSubCase(c, "Single Instance Multi Sessions Keep Alive");
1790
1791 Do_ADBG_BeginSubCase(c, "Multi Sessions TA to TA");
1792 test_panic_ta_to_ta(c, &sims_test_ta_uuid,
1793 &sims_keepalive_test_ta_uuid);
1794 Do_ADBG_EndSubCase(c, "Multi Sessions TA to TA");
1795 }
1796 ADBG_CASE_DEFINE(regression, 1021, xtest_tee_test_1021,
1797 "Test panic context release");
1798
xtest_tee_test_1022(ADBG_Case_t * c)1799 static void xtest_tee_test_1022(ADBG_Case_t *c)
1800 {
1801 TEEC_Session session = { 0 };
1802 uint32_t ret_orig = 0;
1803
1804 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1805 xtest_teec_open_session(&session, &os_test_ta_uuid,
1806 NULL, &ret_orig)))
1807 return;
1808
1809 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1810 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CALL_LIB_DL, NULL,
1811 &ret_orig));
1812
1813 (void)ADBG_EXPECT_TEEC_RESULT(c,
1814 TEEC_ERROR_TARGET_DEAD,
1815 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CALL_LIB_DL_PANIC,
1816 NULL, &ret_orig));
1817
1818 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
1819
1820 TEEC_CloseSession(&session);
1821 }
1822 ADBG_CASE_DEFINE(regression, 1022, xtest_tee_test_1022,
1823 "Test dlopen()/dlsym()/dlclose() API");
1824
1825 /*
1826 * Testing the ELF initialization (.init_array)
1827 *
1828 * - The TA has a global variable which can also be accessed by the two shared
1829 * libraries os_test_lib (linked with the TA) and os_test_lib_dl (loaded via
1830 * dlopen())
1831 * - The TA and both libraries have initialization functions (declared with the
1832 * "constructor" attribute) which perform the following:
1833 * * The TA multiplies by 10 then adds 1
1834 * * os_test_lib multiplies by 10 then adds 2
1835 * * os_test_lib_dl multiplies by 10 then adds 3
1836 * By testing the variable value we make sure the initializations occurred in
1837 * the correct order.
1838 */
xtest_tee_test_1023(ADBG_Case_t * c)1839 static void xtest_tee_test_1023(ADBG_Case_t *c)
1840 {
1841 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1842 TEEC_Session session = { 0 };
1843 uint32_t ret_orig = 0;
1844
1845 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE,
1846 TEEC_NONE, TEEC_NONE);
1847
1848 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1849 xtest_teec_open_session(&session, &os_test_ta_uuid,
1850 NULL, &ret_orig)))
1851 return;
1852
1853 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1854 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_GET_GLOBAL_VAR, &op,
1855 &ret_orig));
1856
1857 /* Expected: initialization of os_test_lib, then TA */
1858 (void)ADBG_EXPECT_COMPARE_SIGNED(c, op.params[0].value.a, ==, 21);
1859
1860 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1861 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CALL_LIB_DL, NULL,
1862 &ret_orig));
1863
1864 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1865 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_GET_GLOBAL_VAR, &op,
1866 &ret_orig));
1867
1868 /* Expected: initialization of os_test_lib_dl */
1869 (void)ADBG_EXPECT_COMPARE_SIGNED(c, op.params[0].value.a, ==, 213);
1870
1871 TEEC_CloseSession(&session);
1872 }
1873 ADBG_CASE_DEFINE(regression, 1023, xtest_tee_test_1023,
1874 "Test ELF initialization (.init_array)");
1875
1876 #ifdef CFG_CORE_TPM_EVENT_LOG
xtest_tee_test_1024(ADBG_Case_t * c)1877 static void xtest_tee_test_1024(ADBG_Case_t *c)
1878 {
1879 TEEC_Session session = {};
1880 uint32_t ret_orig = 0;
1881
1882 xtest_teec_open_session(&session, &tpm_log_test_ta_uuid,
1883 NULL, &ret_orig);
1884
1885 Do_ADBG_BeginSubCase(c, "TPM test service invocation");
1886 ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(&session,
1887 TA_TPM_TEST_GET_LOG,
1888 NULL, &ret_orig));
1889 Do_ADBG_EndSubCase(c, "TPM test service invocation");
1890
1891 Do_ADBG_BeginSubCase(c, "TPM test passing short buffer");
1892 ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(&session,
1893 TA_TPM_TEST_SHORT_BUF,
1894 NULL, &ret_orig));
1895 Do_ADBG_EndSubCase(c, "TPM test passing short buffer");
1896
1897 TEEC_CloseSession(&session);
1898 }
1899
1900 ADBG_CASE_DEFINE(regression, 1024, xtest_tee_test_1024,
1901 "Test PTA_SYSTEM_GET_TPM_EVENT_LOG Service");
1902 #endif /* CFG_CORE_TPM_EVENT_LOG */
1903
xtest_tee_test_1025(ADBG_Case_t * c)1904 static void xtest_tee_test_1025(ADBG_Case_t *c)
1905 {
1906 TEEC_Session session = {};
1907 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1908 uint32_t ret_orig = 0;
1909 uint8_t *empty_buf = NULL;
1910 TEEC_SharedMemory shm = { };
1911 TEEC_Result res = TEEC_ERROR_GENERIC;
1912
1913 Do_ADBG_BeginSubCase(c, "Invalid NULL buffer memref registration");
1914
1915 memset(&shm, 0, sizeof(shm));
1916 shm.flags = TEEC_MEM_INPUT;
1917 shm.buffer = NULL;
1918 shm.size = 0;
1919
1920 ADBG_EXPECT(c, TEEC_ERROR_BAD_PARAMETERS,
1921 TEEC_RegisterSharedMemory(&xtest_teec_ctx, &shm));
1922
1923 memset(&shm, 0, sizeof(shm));
1924 shm.flags = TEEC_MEM_OUTPUT;
1925 shm.buffer = NULL;
1926 shm.size = 0;
1927
1928 ADBG_EXPECT(c, TEEC_ERROR_BAD_PARAMETERS,
1929 TEEC_RegisterSharedMemory(&xtest_teec_ctx, &shm));
1930
1931 Do_ADBG_EndSubCase(c, "Invalid NULL buffer memref registration");
1932
1933 if (!xtest_teec_ctx.memref_null) {
1934 Do_ADBG_Log("Skip subcases: MEMREF_NULL capability not supported");
1935 return;
1936 }
1937
1938 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1939 xtest_teec_open_session(&session,
1940 &os_test_ta_uuid,
1941 NULL, &ret_orig)))
1942 return;
1943
1944 empty_buf = malloc(1);
1945 if (!empty_buf) {
1946 (void)ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_ERROR_OUT_OF_MEMORY);
1947 goto out_session;
1948 }
1949
1950 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
1951 TEEC_MEMREF_TEMP_INPUT,
1952 TEEC_MEMREF_TEMP_OUTPUT,
1953 TEEC_MEMREF_TEMP_OUTPUT);
1954
1955 Do_ADBG_BeginSubCase(c,
1956 "Input/Output MEMREF Buffer NULL - Size 0 bytes");
1957
1958 op.params[0].tmpref.buffer = empty_buf;
1959 op.params[0].tmpref.size = 0;
1960
1961 op.params[1].tmpref.buffer = NULL;
1962 op.params[1].tmpref.size = 0;
1963
1964 op.params[2].tmpref.buffer = empty_buf;
1965 op.params[2].tmpref.size = 0;
1966
1967 op.params[3].tmpref.buffer = NULL;
1968 op.params[3].tmpref.size = 0;
1969
1970 ADBG_EXPECT(c, TEE_SUCCESS,
1971 TEEC_InvokeCommand(&session,
1972 TA_OS_TEST_CMD_NULL_MEMREF_PARAMS, &op,
1973 &ret_orig));
1974
1975 Do_ADBG_EndSubCase(c, "Input/Output MEMREF Buffer NULL - Size 0 bytes");
1976
1977 Do_ADBG_BeginSubCase(c, "Input MEMREF Buffer NULL - Size non 0 bytes");
1978
1979 op.params[0].tmpref.buffer = empty_buf;
1980 op.params[0].tmpref.size = 1;
1981
1982 op.params[1].tmpref.buffer = NULL;
1983 op.params[1].tmpref.size = 0;
1984
1985 op.params[2].tmpref.buffer = empty_buf;
1986 op.params[2].tmpref.size = 0;
1987
1988 op.params[3].tmpref.buffer = NULL;
1989 op.params[3].tmpref.size = 0;
1990
1991 ADBG_EXPECT(c, TEE_ERROR_BAD_PARAMETERS,
1992 TEEC_InvokeCommand(&session,
1993 TA_OS_TEST_CMD_NULL_MEMREF_PARAMS, &op,
1994 &ret_orig));
1995
1996 TEEC_CloseSession(&session);
1997
1998 Do_ADBG_EndSubCase(c, "Input MEMREF Buffer NULL - Size non 0 bytes");
1999
2000 Do_ADBG_BeginSubCase(c, "Input MEMREF Buffer NULL over PTA invocation");
2001
2002 /* Pseudo TA is optional: warn and nicely exit if not found */
2003 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
2004 &ret_orig);
2005 if (res == TEEC_ERROR_ITEM_NOT_FOUND) {
2006 Do_ADBG_Log(" - 1025 - skip test, pseudo TA not found");
2007 goto out;
2008 }
2009 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
2010 goto out;
2011
2012 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE,
2013 TEEC_NONE, TEEC_NONE);
2014 op.params[0].tmpref.buffer = NULL;
2015 op.params[0].tmpref.size = 0;
2016
2017 ADBG_EXPECT(c, TEE_SUCCESS,
2018 TEEC_InvokeCommand(&session,
2019 PTA_INVOKE_TESTS_CMD_MEMREF_NULL,
2020 &op, &ret_orig));
2021
2022 out_session:
2023 TEEC_CloseSession(&session);
2024 out:
2025 Do_ADBG_EndSubCase(c, NULL);
2026 free(empty_buf);
2027 }
2028 ADBG_CASE_DEFINE(regression, 1025, xtest_tee_test_1025,
2029 "Test memref NULL and/or 0 bytes size");
2030
2031 #define TEE_UUID_NS_NAME_SIZE 128
2032
2033 /*
2034 * TEE Client UUID name space identifier (UUIDv4)
2035 *
2036 * Value here is random UUID that is allocated as name space identifier for
2037 * forming Client UUID's for TEE environment using UUIDv5 scheme.
2038 */
2039 static const char *client_uuid_linux_ns = "58ac9ca0-2086-4683-a1b8-ec4bc08e01b6";
2040
2041 /* TEEC_LOGIN_PUBLIC's Client UUID is NIL UUID */
2042 static TEEC_UUID client_uuid_public = { };
2043
xtest_tee_test_1026(ADBG_Case_t * c)2044 static void xtest_tee_test_1026(ADBG_Case_t *c)
2045 {
2046 TEEC_Result result = TEEC_ERROR_GENERIC;
2047 uint32_t ret_orig = 0;
2048 TEEC_Session session = { };
2049 uint32_t login = UINT32_MAX;
2050 TEEC_UUID client_uuid = { };
2051
2052 result = TEEC_OpenSession(&xtest_teec_ctx, &session, &os_test_ta_uuid,
2053 TEEC_LOGIN_PUBLIC, NULL, NULL, &ret_orig);
2054
2055 if (!ADBG_EXPECT_TEEC_SUCCESS(c, result))
2056 return;
2057
2058 result = ta_os_test_cmd_client_identity(&session, &login,
2059 &client_uuid);
2060
2061 if (!ADBG_EXPECT_TEEC_SUCCESS(c, result))
2062 goto out;
2063
2064 ADBG_EXPECT_COMPARE_UNSIGNED(c, login, ==, TEEC_LOGIN_PUBLIC);
2065
2066 ADBG_EXPECT_EQUAL(c, &client_uuid_public, &client_uuid,
2067 sizeof(TEEC_UUID));
2068
2069 out:
2070 TEEC_CloseSession(&session);
2071 }
2072
2073 ADBG_CASE_DEFINE(regression, 1026, xtest_tee_test_1026,
2074 "Session: public login");
2075
2076 /*
2077 * regression_1027
2078 * Depends on OpenSSL
2079 * Depends on kernel commit "tee: optee: Add support for session login client UUID generation"
2080 * Linaro tree: https://github.com/linaro-swg/linux/commit/ad19acdcdbc5
2081 * Upstream: <put sha-1 here when known>
2082 *
2083 * xtest skips the test when not built with OpenSSL.
2084 */
xtest_tee_test_1027(ADBG_Case_t * c)2085 static void xtest_tee_test_1027(ADBG_Case_t *c)
2086 {
2087 #ifdef OPENSSL_FOUND
2088 TEEC_Result result = TEEC_ERROR_GENERIC;
2089 uint32_t ret_orig = 0;
2090 TEEC_Session session = { };
2091 uint32_t login = UINT32_MAX;
2092 TEEC_UUID client_uuid = { };
2093 TEEC_UUID expected_client_uuid = { };
2094 TEEC_UUID uuid_ns = { };
2095 char uuid_name[TEE_UUID_NS_NAME_SIZE] = { };
2096
2097 result = xtest_uuid_from_str(&uuid_ns, client_uuid_linux_ns);
2098
2099 if (!ADBG_EXPECT_TEEC_SUCCESS(c, result))
2100 return;
2101
2102 sprintf(uuid_name, "uid=%x", geteuid());
2103
2104 result = xtest_uuid_v5(&expected_client_uuid, &uuid_ns, uuid_name,
2105 strlen(uuid_name));
2106 if (!ADBG_EXPECT_TEEC_SUCCESS(c, result))
2107 return;
2108
2109 result = TEEC_OpenSession(&xtest_teec_ctx, &session, &os_test_ta_uuid,
2110 TEEC_LOGIN_USER, NULL, NULL, &ret_orig);
2111
2112 if (!ADBG_EXPECT_TEEC_SUCCESS(c, result))
2113 return;
2114
2115 result = ta_os_test_cmd_client_identity(&session, &login,
2116 &client_uuid);
2117
2118 if (!ADBG_EXPECT_TEEC_SUCCESS(c, result))
2119 goto out;
2120
2121 ADBG_EXPECT_COMPARE_UNSIGNED(c, login, ==, TEEC_LOGIN_USER);
2122
2123 ADBG_EXPECT_EQUAL(c, &expected_client_uuid, &client_uuid,
2124 sizeof(TEEC_UUID));
2125
2126 out:
2127 TEEC_CloseSession(&session);
2128 #else /*!OPENSSL_FOUND*/
2129 UNUSED(c);
2130 UNUSED(client_uuid_linux_ns);
2131 /* xtest_uuid_v5() depends on OpenSSL */
2132 Do_ADBG_Log("OpenSSL not available, skipping test 1027");
2133 #endif
2134 }
2135
2136 ADBG_CASE_DEFINE(regression, 1027, xtest_tee_test_1027,
2137 "Session: user login for current user");
2138
2139 /*
2140 * regression_1028
2141 * Depends on OpenSSL and kernel commit "tee: optee: Add support for session login client UUID generation"
2142 * Linaro tree: https://github.com/linaro-swg/linux/commit/ad19acdcdbc5
2143 * Upstream: <put sha-1 here when known>
2144 *
2145 * xtest skips the test when not built with OpenSSL.
2146 */
xtest_tee_test_1028(ADBG_Case_t * c)2147 static void xtest_tee_test_1028(ADBG_Case_t *c)
2148 {
2149 #ifdef OPENSSL_FOUND
2150 TEEC_Result result = TEEC_ERROR_GENERIC;
2151 uint32_t ret_orig = 0;
2152 TEEC_Session session = { };
2153 uint32_t login = UINT32_MAX;
2154 TEEC_UUID client_uuid = { };
2155 TEEC_UUID expected_client_uuid = { };
2156 TEEC_UUID uuid_ns = { };
2157 char uuid_name[TEE_UUID_NS_NAME_SIZE] = { };
2158 uint32_t group = 0;
2159
2160 group = getegid();
2161
2162 result = xtest_uuid_from_str(&uuid_ns, client_uuid_linux_ns);
2163
2164 if (!ADBG_EXPECT_TEEC_SUCCESS(c, result))
2165 return;
2166
2167 sprintf(uuid_name, "gid=%x", group);
2168
2169 result = xtest_uuid_v5(&expected_client_uuid, &uuid_ns, uuid_name,
2170 strlen(uuid_name));
2171 if (!ADBG_EXPECT_TEEC_SUCCESS(c, result))
2172 return;
2173
2174 result = TEEC_OpenSession(&xtest_teec_ctx, &session, &os_test_ta_uuid,
2175 TEEC_LOGIN_GROUP, &group, NULL, &ret_orig);
2176
2177 if (!ADBG_EXPECT_TEEC_SUCCESS(c, result))
2178 return;
2179
2180 result = ta_os_test_cmd_client_identity(&session, &login,
2181 &client_uuid);
2182
2183 if (!ADBG_EXPECT_TEEC_SUCCESS(c, result))
2184 goto out;
2185
2186 ADBG_EXPECT_COMPARE_UNSIGNED(c, login, ==, TEEC_LOGIN_GROUP);
2187
2188 ADBG_EXPECT_EQUAL(c, &expected_client_uuid, &client_uuid,
2189 sizeof(TEEC_UUID));
2190
2191 out:
2192 TEEC_CloseSession(&session);
2193 #else /*!OPENSSL_FOUND*/
2194 UNUSED(c);
2195 /* xtest_uuid_v5() depends on OpenSSL */
2196 Do_ADBG_Log("OpenSSL not available, skipping test 1028");
2197 #endif
2198 }
2199
2200 ADBG_CASE_DEFINE(regression, 1028, xtest_tee_test_1028,
2201 "Session: group login for current user's effective group");
2202
xtest_tee_test_1029(ADBG_Case_t * c)2203 static void xtest_tee_test_1029(ADBG_Case_t *c)
2204 {
2205 TEEC_Result res = TEEC_SUCCESS;
2206 TEEC_Session session = { 0 };
2207 uint32_t ret_orig = 0;
2208
2209 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
2210 xtest_teec_open_session(&session, &os_test_ta_uuid,
2211 NULL, &ret_orig)))
2212 return;
2213
2214 Do_ADBG_BeginSubCase(c, "TLS variables (main program)");
2215 res = TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_TLS_TEST_MAIN, NULL,
2216 &ret_orig);
2217 if (res == TEEC_ERROR_NOT_SUPPORTED)
2218 Do_ADBG_Log(" - 1029 - skip test, "
2219 "TA returned TEEC_ERROR_NOT_SUPPORTED");
2220 else
2221 ADBG_EXPECT_TEEC_SUCCESS(c, res);
2222 Do_ADBG_EndSubCase(c, "TLS variables (main program)");
2223
2224 Do_ADBG_BeginSubCase(c, "TLS variables (shared library)");
2225 res = TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_TLS_TEST_SHLIB, NULL,
2226 &ret_orig);
2227 if (res == TEEC_ERROR_NOT_SUPPORTED)
2228 Do_ADBG_Log(" - 1029 - skip test, "
2229 "TA returned TEEC_ERROR_NOT_SUPPORTED");
2230 else
2231 ADBG_EXPECT_TEEC_SUCCESS(c, res);
2232 Do_ADBG_EndSubCase(c, "TLS variables (shared library)");
2233
2234 TEEC_CloseSession(&session);
2235 }
2236 ADBG_CASE_DEFINE(regression, 1029, xtest_tee_test_1029,
2237 "Test __thread attribute");
2238
xtest_tee_test_1030(ADBG_Case_t * c)2239 static void xtest_tee_test_1030(ADBG_Case_t *c)
2240 {
2241 TEEC_Session session = { 0 };
2242 uint32_t ret_orig = 0;
2243
2244 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
2245 xtest_teec_open_session(&session, &os_test_ta_uuid,
2246 NULL, &ret_orig)))
2247 return;
2248
2249 Do_ADBG_BeginSubCase(c, "Before dlopen()");
2250 ADBG_EXPECT_TEEC_SUCCESS(c,
2251 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_DL_PHDR, NULL,
2252 &ret_orig));
2253 Do_ADBG_EndSubCase(c, "Before dlopen()");
2254
2255 Do_ADBG_BeginSubCase(c, "After dlopen()");
2256 ADBG_EXPECT_TEEC_SUCCESS(c,
2257 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_DL_PHDR_DL, NULL,
2258 &ret_orig));
2259 Do_ADBG_EndSubCase(c, "After dlopen()");
2260
2261 TEEC_CloseSession(&session);
2262 }
2263 ADBG_CASE_DEFINE(regression, 1030, xtest_tee_test_1030,
2264 "Test dl_iterate_phdr()");
2265
2266 #ifndef __clang__
xtest_tee_test_1031(ADBG_Case_t * c)2267 static void xtest_tee_test_1031(ADBG_Case_t *c)
2268 {
2269 TEEC_Result ret = TEE_SUCCESS;
2270 TEEC_Session session = { 0 };
2271 uint32_t ret_orig = 0;
2272
2273 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
2274 xtest_teec_open_session(&session, &os_test_ta_uuid,
2275 NULL, &ret_orig)))
2276 return;
2277
2278 Do_ADBG_BeginSubCase(c, "Global object constructor (main program)");
2279 ret = TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CXX_CTOR_MAIN, NULL,
2280 &ret_orig);
2281 if (ret == TEEC_ERROR_NOT_SUPPORTED) {
2282 printf("TA not built with C++ support, skipping C++ tests\n");
2283 Do_ADBG_EndSubCase(c, "Global object constructor (main program)");
2284 goto out;
2285
2286 }
2287 ADBG_EXPECT_TEEC_SUCCESS(c, ret);
2288 Do_ADBG_EndSubCase(c, "Global object constructor (main program)");
2289
2290 Do_ADBG_BeginSubCase(c, "Global object constructor (shared library)");
2291 ADBG_EXPECT_TEEC_SUCCESS(c,
2292 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CXX_CTOR_SHLIB,
2293 NULL, &ret_orig));
2294 Do_ADBG_EndSubCase(c, "Global object constructor (shared library)");
2295
2296 Do_ADBG_BeginSubCase(c, "Global object constructor (dlopen()ed lib)");
2297 ADBG_EXPECT_TEEC_SUCCESS(c,
2298 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CXX_CTOR_SHLIB_DL,
2299 NULL, &ret_orig));
2300 Do_ADBG_EndSubCase(c, "Global object constructor (dlopen()ed lib)");
2301
2302 Do_ADBG_BeginSubCase(c, "Exceptions (simple)");
2303 ADBG_EXPECT_TEEC_SUCCESS(c,
2304 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CXX_EXC_MAIN, NULL,
2305 &ret_orig));
2306 Do_ADBG_EndSubCase(c, "Exceptions (simple)");
2307
2308 Do_ADBG_BeginSubCase(c, "Exceptions (mixed C/C++ frames)");
2309 ADBG_EXPECT_TEEC_SUCCESS(c,
2310 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CXX_EXC_MIXED, NULL,
2311 &ret_orig));
2312 Do_ADBG_EndSubCase(c, "Exceptions (mixed C/C++ frames)");
2313 out:
2314 TEEC_CloseSession(&session);
2315 }
2316 ADBG_CASE_DEFINE(regression, 1031, xtest_tee_test_1031,
2317 "Test C++ features");
2318 #endif
2319
xtest_tee_test_1032(ADBG_Case_t * c)2320 static void xtest_tee_test_1032(ADBG_Case_t *c)
2321 {
2322 TEEC_Result res = TEEC_SUCCESS;
2323 TEEC_Context ctx = { };
2324 TEEC_SharedMemory shm1 = {
2325 .buffer = xtest_tee_test_1032,
2326 .size = 32,
2327 .flags = TEEC_MEM_INPUT,
2328 };
2329 static const uint8_t dummy_data[32] = { 1, 2, 3, 4, };
2330 TEEC_SharedMemory shm2 = {
2331 .buffer = (void *)dummy_data,
2332 .size = sizeof(dummy_data),
2333 .flags = TEEC_MEM_INPUT,
2334 };
2335
2336 res = TEEC_InitializeContext(xtest_tee_name, &ctx);
2337 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
2338 return;
2339
2340 res = TEEC_RegisterSharedMemory(&ctx, &shm1);
2341 if (ADBG_EXPECT_TEEC_SUCCESS(c, res))
2342 TEEC_ReleaseSharedMemory(&shm1);
2343
2344 res = TEEC_RegisterSharedMemory(&ctx, &shm2);
2345 if (ADBG_EXPECT_TEEC_SUCCESS(c, res))
2346 TEEC_ReleaseSharedMemory(&shm2);
2347
2348 TEEC_FinalizeContext(&ctx);
2349 }
2350 ADBG_CASE_DEFINE(regression, 1032, xtest_tee_test_1032,
2351 "Register read-only shared memory");
2352
xtest_tee_test_1033(ADBG_Case_t * c)2353 static void xtest_tee_test_1033(ADBG_Case_t *c)
2354 {
2355 TEEC_Session session = { };
2356 uint32_t ret_orig = 0;
2357
2358 /* TA will ping the test plugin during open session operation */
2359 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
2360 xtest_teec_open_session(&session, &supp_plugin_test_ta_uuid,
2361 NULL, &ret_orig)))
2362 return;
2363
2364 Do_ADBG_BeginSubCase(c, "Pass values to/from a plugin");
2365 {
2366 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
2367
2368 op.params[0].value.a = 20;
2369 op.params[0].value.b = 10;
2370 op.params[1].value.a = '+';
2371 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT,
2372 TEEC_VALUE_INPUT, TEEC_NONE,
2373 TEEC_NONE);
2374
2375 ADBG_EXPECT_TEEC_SUCCESS(c,
2376 TEEC_InvokeCommand(&session,
2377 TA_SUPP_PLUGIN_CMD_PASS_VALUES, &op,
2378 &ret_orig));
2379 ADBG_EXPECT(c, 30, op.params[0].value.a);
2380
2381 /* reassign, because the values was changed during previous op */
2382 op.params[0].value.a = 20;
2383 op.params[0].value.b = 10;
2384 op.params[1].value.a = '-';
2385 ADBG_EXPECT_TEEC_SUCCESS(c,
2386 TEEC_InvokeCommand(&session,
2387 TA_SUPP_PLUGIN_CMD_PASS_VALUES, &op,
2388 &ret_orig));
2389 ADBG_EXPECT(c, 10, op.params[0].value.a);
2390 }
2391 Do_ADBG_EndSubCase(c, "Pass values to/from a plugin");
2392
2393 Do_ADBG_BeginSubCase(c, "Pass array to a plugin");
2394 {
2395 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
2396 uint8_t to_plugin[] = { 0, 1, 2, 3, 4, 5 };
2397
2398 op.params[0].tmpref.buffer = to_plugin;
2399 op.params[0].tmpref.size = sizeof(to_plugin);
2400 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
2401 TEEC_VALUE_OUTPUT,
2402 TEEC_NONE, TEEC_NONE);
2403
2404 ADBG_EXPECT_TEEC_SUCCESS(c,
2405 TEEC_InvokeCommand(&session,
2406 TA_SUPP_PLUGIN_CMD_WRITE_ARR,
2407 &op, &ret_orig));
2408
2409 /*
2410 * The test plugin must calculate a sum of the input elements
2411 * and store it to 'op.params[1].value.a'
2412 */
2413 ADBG_EXPECT(c, 15, op.params[1].value.a);
2414 }
2415 Do_ADBG_EndSubCase(c, "Pass array to a plugin");
2416
2417 Do_ADBG_BeginSubCase(c, "Get array from a plugin");
2418 {
2419 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
2420 char from_plugin[64] = { };
2421 char expected_arr[] = "Array from plugin";
2422 size_t expectes_size = sizeof(expected_arr);
2423
2424 op.params[0].tmpref.buffer = from_plugin;
2425 op.params[0].tmpref.size = sizeof(from_plugin);
2426 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT,
2427 TEEC_VALUE_OUTPUT, TEEC_NONE,
2428 TEEC_NONE);
2429 ADBG_EXPECT_TEEC_SUCCESS(c,
2430 TEEC_InvokeCommand(&session,
2431 TA_SUPP_PLUGIN_CMD_GET_ARR, &op,
2432 &ret_orig));
2433 ADBG_EXPECT(c, expectes_size, op.params[1].value.a);
2434 ADBG_EXPECT_EQUAL(c, expected_arr, from_plugin, expectes_size);
2435 }
2436 Do_ADBG_EndSubCase(c, "Get array from a plugin");
2437
2438 Do_ADBG_BeginSubCase(c, "Not allow bad input to a plugin");
2439 {
2440 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
2441
2442 op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE,
2443 TEEC_NONE, TEEC_NONE);
2444 ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_BAD_PARAMETERS,
2445 TEEC_InvokeCommand(&session,
2446 TA_SUPP_PLUGIN_CMD_BAD_UUID, &op,
2447 &ret_orig));
2448 ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_BAD_PARAMETERS,
2449 TEEC_InvokeCommand(&session,
2450 TA_SUPP_PLUGIN_CMD_BAD_IN_DATA, &op,
2451 &ret_orig));
2452 ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_BAD_PARAMETERS,
2453 TEEC_InvokeCommand(&session,
2454 TA_SUPP_PLUGIN_CMD_BAD_IN_LEN, &op,
2455 &ret_orig));
2456 }
2457 Do_ADBG_EndSubCase(c, "Not allow bad input to a plugin");
2458
2459 Do_ADBG_BeginSubCase(c, "Call an unknown plugin");
2460 {
2461 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
2462
2463 op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE,
2464 TEEC_NONE, TEEC_NONE);
2465 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_ITEM_NOT_FOUND,
2466 TEEC_InvokeCommand(&session,
2467 TA_SUPP_PLUGIN_CMD_UNKNOWN_UUID,
2468 &op, &ret_orig));
2469 }
2470 Do_ADBG_EndSubCase(c, "Call an unknown plugin");
2471
2472 TEEC_CloseSession(&session);
2473 }
2474 ADBG_CASE_DEFINE(regression, 1033, xtest_tee_test_1033,
2475 "Test the supplicant plugin framework");
2476