blob: 0fee2e2eb37746fe888c6737942b930723af265e [file] [log] [blame]
Pascal Brandc639ac82015-07-02 08:53:34 +02001/*
2 * Copyright (c) 2014, STMicroelectronics International N.V.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <stdio.h>
15#include <string.h>
Jens Wiklanderb7940892015-10-23 16:02:40 +020016#include <limits.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020017
18#ifdef USER_SPACE
19#include <pthread.h>
20#include <unistd.h>
21#endif
22
23#include "xtest_test.h"
24#include "xtest_helpers.h"
Jens Wiklander4441fe22015-10-23 16:53:02 +020025#include <signed_hdr.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020026
27#include <ta_crypt.h>
28#include <ta_os_test.h>
29#include <ta_create_fail_test.h>
30#include <ta_rpc_test.h>
31#include <ta_sims_test.h>
Jens Wiklanderac27ec12015-07-15 15:23:14 +020032#include <ta_concurrent.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020033
34static void xtest_tee_test_1001(ADBG_Case_t *Case_p);
35static void xtest_tee_test_1004(ADBG_Case_t *Case_p);
36static void xtest_tee_test_1005(ADBG_Case_t *Case_p);
37static void xtest_tee_test_1006(ADBG_Case_t *Case_p);
38static void xtest_tee_test_1007(ADBG_Case_t *Case_p);
39static void xtest_tee_test_1008(ADBG_Case_t *Case_p);
40static void xtest_tee_test_1009(ADBG_Case_t *Case_p);
41static void xtest_tee_test_1010(ADBG_Case_t *Case_p);
42static void xtest_tee_test_1011(ADBG_Case_t *Case_p);
43static void xtest_tee_test_1012(ADBG_Case_t *Case_p);
Jens Wiklanderac27ec12015-07-15 15:23:14 +020044static void xtest_tee_test_1013(ADBG_Case_t *Case_p);
Pascal Brandc639ac82015-07-02 08:53:34 +020045
46ADBG_CASE_DEFINE(XTEST_TEE_1001, xtest_tee_test_1001,
47 /* Title */
48 "Registering TAs",
49 /* Short description */
50 "Short description ...",
51 /* Requirement IDs */
52 "TEE-??",
53 /* How to implement */
54 "Description of how to implement ..."
55 );
56
57ADBG_CASE_DEFINE(XTEST_TEE_1004, xtest_tee_test_1004,
58 /* Title */
59 "Test User Crypt TA",
60 /* Short description */
61 "Short description ...",
62 /* Requirement IDs */
63 "TEE-??",
64 /* How to implement */
65 "Description of how to implement ..."
66 );
67
68ADBG_CASE_DEFINE(XTEST_TEE_1005, xtest_tee_test_1005,
69 /* Title */
70 "Many sessions",
71 /* Short description */
72 "Short description ...",
73 /* Requirement IDs */
74 "TEE-??",
75 /* How to implement */
76 "Description of how to implement ..."
77 );
78
79ADBG_CASE_DEFINE(XTEST_TEE_1006, xtest_tee_test_1006,
80 /* Title */
81 "Test Basic OS features",
82 /* Short description */
83 "Short description ...",
84 /* Requirement IDs */
85 "TEE-??",
86 /* How to implement */
87 "Description of how to implement ..."
88 );
89
90ADBG_CASE_DEFINE(XTEST_TEE_1007, xtest_tee_test_1007,
91 /* Title */
92 "Test Panic",
93 /* Short description */
94 "Short description ...",
95 /* Requirement IDs */
96 "TEE-??",
97 /* How to implement */
98 "Description of how to implement ..."
99 );
100
101ADBG_CASE_DEFINE(XTEST_TEE_1008, xtest_tee_test_1008,
102 /* Title */
103 "TEE internal client API",
104 /* Short description */
105 "Short description ...",
106 /* Requirement IDs */
107 "TEE-??",
108 /* How to implement */
109 "Description of how to implement ..."
110 );
111
112ADBG_CASE_DEFINE(XTEST_TEE_1009, xtest_tee_test_1009,
113 /* Title */
114 "TEE Wait",
115 /* Short description */
116 "Short description ...",
117 /* Requirement IDs */
118 "TEE-??",
119 /* How to implement */
120 "Description of how to implement ..."
121 );
122
123ADBG_CASE_DEFINE(XTEST_TEE_1010, xtest_tee_test_1010,
124 /* Title */
125 "Invalid memory access",
126 /* Short description */
127 "Short description ...",
128 /* Requirement IDs */
129 "TEE-??",
130 /* How to implement */
131 "Description of how to implement ..."
132 );
133
134ADBG_CASE_DEFINE(XTEST_TEE_1011, xtest_tee_test_1011,
135 /* Title */
136 "Test RPC features with User Crypt TA",
137 /* Short description */
138 "Short description ...",
139 /* Requirement IDs */
140 "TEE-??",
141 /* How to implement */
142 "Description of how to implement ..."
143 );
144
145ADBG_CASE_DEFINE(XTEST_TEE_1012, xtest_tee_test_1012,
146 /* Title */
147 "Test Single Instance Multi Session features with SIMS TA",
148 /* Short description */
149 "Short description ...",
150 /* Requirement IDs */
151 "TEE-??",
152 /* How to implement */
153 "Description of how to implement ..."
154 );
155
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200156ADBG_CASE_DEFINE(XTEST_TEE_1013, xtest_tee_test_1013,
157 /* Title */
158 "Test concurency with concurrent TA",
159 /* Short description */
160 "Short description ...",
161 /* Requirement IDs */
162 "TEE-??",
163 /* How to implement */
164 "Description of how to implement ..."
165 );
166
Pascal Brandc639ac82015-07-02 08:53:34 +0200167struct xtest_crypto_session {
168 ADBG_Case_t *c;
169 TEEC_Session *session;
170 uint32_t cmd_id_sha256;
171 uint32_t cmd_id_aes256ecb_encrypt;
172 uint32_t cmd_id_aes256ecb_decrypt;
173};
174
175static void xtest_crypto_test(struct xtest_crypto_session *cs)
176{
177 uint32_t ret_orig;
178 uint8_t crypt_out[16];
179 uint8_t crypt_in[16] = { 22, 17 };
180
181 crypt_in[15] = 60;
182
183 Do_ADBG_BeginSubCase(cs->c, "AES encrypt");
184 {
185 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
186
187 op.params[0].tmpref.buffer = crypt_in;
188 op.params[0].tmpref.size = sizeof(crypt_in);
189 op.params[1].tmpref.buffer = crypt_out;
190 op.params[1].tmpref.size = sizeof(crypt_out);
191 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
192 TEEC_MEMREF_TEMP_OUTPUT,
193 TEEC_NONE, TEEC_NONE);
194
195 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
196 TEEC_InvokeCommand(cs->session,
197 cs->
198 cmd_id_aes256ecb_encrypt,
199 &op,
200 &ret_orig));
201 }
202 Do_ADBG_EndSubCase(cs->c, "AES encrypt");
203
204 Do_ADBG_BeginSubCase(cs->c, "AES decrypt");
205 {
206 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
207 uint8_t out[16];
208
209 op.params[0].tmpref.buffer = crypt_out;
210 op.params[0].tmpref.size = sizeof(crypt_out);
211 op.params[1].tmpref.buffer = out;
212 op.params[1].tmpref.size = sizeof(out);
213 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
214 TEEC_MEMREF_TEMP_OUTPUT,
215 TEEC_NONE, TEEC_NONE);
216
217 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
218 TEEC_InvokeCommand(cs->session,
219 cs->
220 cmd_id_aes256ecb_decrypt,
221 &op,
222 &ret_orig));
223
224 if (!ADBG_EXPECT(cs->c, 0,
225 memcmp(crypt_in, out, sizeof(crypt_in)))) {
226 Do_ADBG_Log("crypt_in:");
227 Do_ADBG_HexLog(crypt_in, sizeof(crypt_in), 16);
228 Do_ADBG_Log("out:");
229 Do_ADBG_HexLog(out, sizeof(out), 16);
230 }
231 }
232 Do_ADBG_EndSubCase(cs->c, "AES decrypt");
233
234 Do_ADBG_BeginSubCase(cs->c, "SHA-256 test, 3 bytes input");
235 {
236 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
237 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
238 static const uint8_t sha256_out[] = {
239 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
240 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
241 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
242 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
243 };
244 uint8_t out[32] = { 0 };
245
246 op.params[0].tmpref.buffer = (void *)sha256_in;
247 op.params[0].tmpref.size = sizeof(sha256_in);
248 op.params[1].tmpref.buffer = out;
249 op.params[1].tmpref.size = sizeof(out);
250 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
251 TEEC_MEMREF_TEMP_OUTPUT,
252 TEEC_NONE, TEEC_NONE);
253
254 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
255 TEEC_InvokeCommand(cs->session,
256 cs->
257 cmd_id_sha256,
258 &op,
259 &ret_orig));
260
261 if (!ADBG_EXPECT(cs->c, 0, memcmp(sha256_out, out,
262 sizeof(sha256_out)))) {
263 Do_ADBG_Log("sha256_out:");
264 Do_ADBG_HexLog(sha256_out, sizeof(sha256_out), 16);
265 Do_ADBG_Log("out:");
266 Do_ADBG_HexLog(out, sizeof(out), 16);
267 }
268 }
269 Do_ADBG_EndSubCase(cs->c, "SHA-256 test, 3 bytes input");
270
271 Do_ADBG_BeginSubCase(cs->c,
272 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
273 {
274 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
275 static const uint8_t in[] = {
276 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
277 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
278 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
279 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
280 };
281 static const uint8_t exp_out[] = {
282 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
283 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
284 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
285 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
286 };
287 uint8_t out[sizeof(exp_out)];
288
289 op.params[0].tmpref.buffer = (void *)in;
290 op.params[0].tmpref.size = sizeof(in);
291 op.params[1].tmpref.buffer = out;
292 op.params[1].tmpref.size = sizeof(out);
293 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
294 TEEC_MEMREF_TEMP_OUTPUT,
295 TEEC_NONE, TEEC_NONE);
296
297 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
298 TEEC_InvokeCommand(cs->session,
299 cs->
300 cmd_id_aes256ecb_encrypt,
301 &op,
302 &ret_orig));
303
304 if (!ADBG_EXPECT(cs->c, 0,
305 memcmp(exp_out, out, sizeof(exp_out)))) {
306 Do_ADBG_Log("exp_out:");
307 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
308 Do_ADBG_Log("out:");
309 Do_ADBG_HexLog(out, sizeof(out), 16);
310 }
311 }
312 Do_ADBG_EndSubCase(cs->c,
313 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
314
315 Do_ADBG_BeginSubCase(cs->c,
316 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
317 {
318 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
319 static const uint8_t in[] = {
320 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
321 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
322 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
323 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
324 };
325 static const uint8_t exp_out[] = {
326 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
327 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
328 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
329 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
330 };
331 uint8_t out[sizeof(exp_out)];
332
333 op.params[0].tmpref.buffer = (void *)in;
334 op.params[0].tmpref.size = sizeof(in);
335 op.params[1].tmpref.buffer = out;
336 op.params[1].tmpref.size = sizeof(out);
337 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
338 TEEC_MEMREF_TEMP_OUTPUT,
339 TEEC_NONE, TEEC_NONE);
340
341 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
342 TEEC_InvokeCommand(cs->session,
343 cs->
344 cmd_id_aes256ecb_decrypt,
345 &op,
346 &ret_orig));
347
348 if (!ADBG_EXPECT(cs->c, 0,
349 memcmp(exp_out, out, sizeof(exp_out)))) {
350 Do_ADBG_Log("exp_out:");
351 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
352 Do_ADBG_Log("out:");
353 Do_ADBG_HexLog(out, sizeof(out), 16);
354 }
355 }
356 Do_ADBG_EndSubCase(cs->c,
357 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
358}
359
360static void xtest_tee_test_1001(ADBG_Case_t *c)
361{
362#ifdef USER_SPACE
363 (void)c;
364#else
365#define REG_TA(name) \
366 (void)ADBG_EXPECT_TEEC_SUCCESS(c, \
367 TEEC_RegisterTA(name, name ## _size))
368
369 REG_TA(crypt_user_ta);
370 REG_TA(os_test_ta);
371 REG_TA(create_fail_test_ta);
372 REG_TA(rpc_test_ta);
373 REG_TA(sims_test_ta);
374
375 TEEC_UnregisterTA(crypt_user_ta);
376 TEEC_UnregisterTA(os_test_ta);
377 TEEC_UnregisterTA(create_fail_test_ta);
378 TEEC_UnregisterTA(rpc_test_ta);
379 TEEC_UnregisterTA(sims_test_ta);
380
381 REG_TA(crypt_user_ta);
382 REG_TA(os_test_ta);
383 REG_TA(create_fail_test_ta);
384 REG_TA(rpc_test_ta);
385 REG_TA(sims_test_ta);
386 REG_TA(storage_ta);
387
388 REG_TA(gp_tta_testing_client_api_ta);
389 REG_TA(gp_tta_answer_success_to_open_session_invoke_ta);
390 REG_TA(gp_tta_answer_error_to_invoke_ta);
391 REG_TA(gp_tta_answer_error_to_open_session_ta);
392 REG_TA(gp_tta_check_open_session_with_4_parameters_ta);
393 REG_TA(gp_tta_time_ta);
394 REG_TA(gp_tta_ds_ta);
395 REG_TA(gp_tta_tcf_ta);
396 REG_TA(gp_tta_crypto_ta);
397 REG_TA(gp_tta_arithm_ta);
398 REG_TA(gp_tta_ica_ta);
399 REG_TA(gp_tta_ica2_ta);
400 REG_TA(gp_tta_tcf_singleinstance_ta);
401 REG_TA(gp_tta_tcf_multipleinstance_ta);
402#endif /*!USER_SPACE*/
403}
404
405static void xtest_tee_test_1004(ADBG_Case_t *c)
406{
407 TEEC_Session session = { 0 };
408 uint32_t ret_orig;
409 struct xtest_crypto_session cs = { c, &session, TA_CRYPT_CMD_SHA256,
410 TA_CRYPT_CMD_AES256ECB_ENC,
411 TA_CRYPT_CMD_AES256ECB_DEC };
412
413 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
414 &session, &crypt_user_ta_uuid,
415 NULL, &ret_orig)))
416 return;
417
418 /* Run the "complete crypto test suite" */
419 xtest_crypto_test(&cs);
420
421 TEEC_CloseSession(&session);
422}
423
424#ifndef TEEC_ERROR_TARGET_DEAD
425/* To be removed when we have TEEC_ERROR_TARGET_DEAD from tee_client_api.h */
426#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024
427#endif
428
429static void xtest_tee_test_invalid_mem_access(ADBG_Case_t *c, uint32_t n)
430{
431 TEEC_Session session = { 0 };
432 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
433 uint32_t ret_orig;
434
435 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
436 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
437 &ret_orig));
438
439 op.params[0].value.a = n;
440 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
441 TEEC_NONE);
442
443 (void)ADBG_EXPECT_TEEC_RESULT(c,
444 TEEC_ERROR_TARGET_DEAD,
445 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
446 &ret_orig));
447
448 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
449 TEEC_InvokeCommand(&session,
450 TA_OS_TEST_CMD_BAD_MEM_ACCESS,
451 &op,
452 &ret_orig));
453 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
454
455 TEEC_CloseSession(&session);
456}
457
458static void xtest_tee_test_1005(ADBG_Case_t *c)
459{
460 uint32_t ret_orig;
461#define MAX_SESSIONS 3
462 TEEC_Session sessions[MAX_SESSIONS];
463 int i;
464
465 for (i = 0; i < MAX_SESSIONS; i++) {
466 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
467 xtest_teec_open_session(&sessions[i], &os_test_ta_uuid,
468 NULL, &ret_orig)))
469 break;
470 }
471
472 for (; --i >= 0; )
473 TEEC_CloseSession(&sessions[i]);
474}
475
476static void xtest_tee_test_1006(ADBG_Case_t *c)
477{
478 TEEC_Session session = { 0 };
479 uint32_t ret_orig;
480 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
481 uint8_t buf[32];
482
483 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
484 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
485 &ret_orig)))
486 return;
487
488 op.params[0].tmpref.buffer = buf;
489 op.params[0].tmpref.size = sizeof(buf);
490 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
491 TEEC_NONE, TEEC_NONE);
492
493 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
494 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
495 &ret_orig));
496
497 TEEC_CloseSession(&session);
498}
499
500static void xtest_tee_test_1007(ADBG_Case_t *c)
501{
502 TEEC_Session session = { 0 };
503 uint32_t ret_orig;
504
505 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
506 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
507 &ret_orig));
508
509 (void)ADBG_EXPECT_TEEC_RESULT(c,
510 TEEC_ERROR_TARGET_DEAD,
511 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
512 &ret_orig));
513
514 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
515
516 (void)ADBG_EXPECT_TEEC_RESULT(c,
517 TEEC_ERROR_TARGET_DEAD,
518 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
519 &ret_orig));
520
521 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
522
523 TEEC_CloseSession(&session);
524}
525
Jerome Forissierf02a2212015-10-29 14:33:35 +0100526#ifndef TA_DIR
527#define TA_DIR "/lib/optee_armtz"
528#endif
529
Jens Wiklanderb7940892015-10-23 16:02:40 +0200530static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
531 const char *extra_suffix)
532{
Jerome Forissierf02a2212015-10-29 14:33:35 +0100533 static const char ta_dir[] = TA_DIR;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200534
535 snprintf(buf, blen,
536 "%s/%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x.ta%s",
537 ta_dir, uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
538 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
539 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
540 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
541 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7],
542 extra_suffix ? extra_suffix : "");
543}
544
545static FILE *open_ta_file(const TEEC_UUID *uuid, const char *extra_suffix,
546 const char *mode)
547{
548 char buf[PATH_MAX];
549
550 uuid_to_full_name(buf, sizeof(buf), uuid, extra_suffix);
551 return fopen(buf, mode);
552}
553
554static bool rm_file(const TEEC_UUID *uuid, const char *extra_suffix)
555{
556 char buf[PATH_MAX];
557
558 uuid_to_full_name(buf, sizeof(buf), uuid, extra_suffix);
559 return !unlink(buf);
560}
561
Jens Wiklander4441fe22015-10-23 16:53:02 +0200562static bool rename_file(const TEEC_UUID *old_uuid, const char *old_extra_suffix,
563 const TEEC_UUID *new_uuid, const char *new_extra_suffix)
564{
565 char old_buf[PATH_MAX];
566 char new_buf[PATH_MAX];
567
568 uuid_to_full_name(old_buf, sizeof(old_buf), old_uuid, old_extra_suffix);
569 uuid_to_full_name(new_buf, sizeof(new_buf), new_uuid, new_extra_suffix);
570 return !rename(old_buf, new_buf);
571}
572
573static bool copy_file(const TEEC_UUID *src_uuid, const char *src_extra_suffix,
574 const TEEC_UUID *dst_uuid, const char *dst_extra_suffix)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200575{
576 char buf[4 * 1024];
Jens Wiklander4441fe22015-10-23 16:53:02 +0200577 FILE *src = open_ta_file(src_uuid, src_extra_suffix, "r");
578 FILE *dst = open_ta_file(dst_uuid, dst_extra_suffix, "w");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200579 size_t r;
580 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200581 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200582
Jens Wiklander4441fe22015-10-23 16:53:02 +0200583 if (src && dst) {
584 do {
585 r = fread(buf, 1, sizeof(buf), src);
586 if (!r) {
587 ret = !!feof(src);
588 break;
589 }
590 w = fwrite(buf, 1, r, dst);
591 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200592 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200593
594 if (src)
595 fclose(src);
596 if (dst)
597 fclose(dst);
598 return ret;
599}
600
601static bool corrupt_file(FILE *f, long offs, uint8_t mask)
602{
603 uint8_t b;
604
605 if (fseek(f, offs, SEEK_SET))
606 return false;
607
608 if (fread(&b, 1, 1, f) != 1)
609 return false;
610
611 b ^= mask;
612
613 if (fseek(f, offs, SEEK_SET))
614 return false;
615
616 if (fwrite(&b, 1, 1, f) != 1)
617 return false;
618
619 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200620}
621
622static void load_fake_ta(ADBG_Case_t *c)
623{
624 static const TEEC_UUID fake_uuid = {
625 0x7e0a0900, 0x586b, 0x11e5,
626 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
627 };
628 TEEC_Session session = { 0 };
629 TEEC_Result res;
630 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200631 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200632
Jens Wiklander4441fe22015-10-23 16:53:02 +0200633 r = copy_file(&create_fail_test_ta_uuid, NULL, &fake_uuid, NULL);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200634
635 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200636 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
637 &ret_orig);
638 if (res == TEEC_SUCCESS)
639 TEEC_CloseSession(&session);
640 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200641 }
642
643 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid, NULL));
644}
645
Jens Wiklander4441fe22015-10-23 16:53:02 +0200646static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
647{
648 TEEC_Session session = { 0 };
649 TEEC_Result res;
650 uint32_t ret_orig;
651 FILE *f;
652 bool r;
653
654 r = copy_file(&create_fail_test_ta_uuid, NULL,
655 &create_fail_test_ta_uuid, "save");
656 if (!ADBG_EXPECT_TRUE(c, r)) {
657 rm_file(&create_fail_test_ta_uuid, "save");
658 return false;
659 }
660
661 f = open_ta_file(&create_fail_test_ta_uuid, NULL, "r+");
662 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
663 rm_file(&create_fail_test_ta_uuid, "save");
664 return false;
665 }
666 r = corrupt_file(f, offs, mask);
667 fclose(f);
668
669 if (ADBG_EXPECT_TRUE(c, r)) {
670 res = xtest_teec_open_session(&session,
671 &create_fail_test_ta_uuid,
672 NULL, &ret_orig);
673 if (res == TEEC_SUCCESS)
674 TEEC_CloseSession(&session);
675 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
676 }
677
678 r &= ADBG_EXPECT_TRUE(c, rename_file(&create_fail_test_ta_uuid, "save",
679 &create_fail_test_ta_uuid, NULL));
680 return r;
681}
682
Pascal Brandc639ac82015-07-02 08:53:34 +0200683static void xtest_tee_test_1008(ADBG_Case_t *c)
684{
685 TEEC_Session session = { 0 };
686 TEEC_Session session_crypt = { 0 };
687 uint32_t ret_orig;
688
689 Do_ADBG_BeginSubCase(c, "Invoke command");
690 {
691 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
692 xtest_teec_open_session(&session_crypt,
693 &crypt_user_ta_uuid, NULL,
694 &ret_orig));
695
696 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
697 xtest_teec_open_session(&session, &os_test_ta_uuid,
698 NULL, &ret_orig));
699
700 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
701 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
702 NULL, &ret_orig));
703
704 TEEC_CloseSession(&session);
705 TEEC_CloseSession(&session_crypt);
706 }
707 Do_ADBG_EndSubCase(c, "Invoke command");
708
709 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
710 {
711 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
712
713 op.params[0].value.a = 2000;
714 op.paramTypes = TEEC_PARAM_TYPES(
715 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
716
717 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
718 xtest_teec_open_session(&session,
719 &os_test_ta_uuid,
720 NULL,
721 &ret_orig));
722
723 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
724 TEEC_InvokeCommand(&session,
725 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
726 &op, &ret_orig));
727
728 TEEC_CloseSession(&session);
729 }
730 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
731
732 Do_ADBG_BeginSubCase(c, "Create session fail");
733 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200734 size_t n;
735
Pascal Brandc639ac82015-07-02 08:53:34 +0200736 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
737 xtest_teec_open_session(&session_crypt,
738 &create_fail_test_ta_uuid, NULL,
739 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200740 /*
741 * Run this several times to see that there's no memory leakage.
742 */
743 for (n = 0; n < 100; n++) {
744 Do_ADBG_Log("n = %zu", n);
745 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
746 xtest_teec_open_session(&session_crypt,
747 &create_fail_test_ta_uuid,
748 NULL, &ret_orig));
749 }
750 }
751 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200752
753 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
754 load_fake_ta(c);
755 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
756
Jens Wiklander4441fe22015-10-23 16:53:02 +0200757 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
758 ADBG_EXPECT_TRUE(c,
759 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
760 ADBG_EXPECT_TRUE(c,
761 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
762 ADBG_EXPECT_TRUE(c,
763 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
764 ADBG_EXPECT_TRUE(c,
765 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
766 ADBG_EXPECT_TRUE(c,
767 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
768 ADBG_EXPECT_TRUE(c,
769 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
770 ADBG_EXPECT_TRUE(c,
771 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
772 ADBG_EXPECT_TRUE(c,
773 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
774 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
775 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
776 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200777}
778
779#ifdef USER_SPACE
780static void *cancellation_thread(void *arg)
781{
782 /*
783 * Sleep 0.5 seconds before cancellation to make sure that the other
784 * thread is in RPC_WAIT.
785 */
786 (void)usleep(500000);
787 TEEC_RequestCancellation(arg);
788 return NULL;
789}
790#endif
791
792static void xtest_tee_test_1009(ADBG_Case_t *c)
793{
794 TEEC_Session session = { 0 };
795 uint32_t ret_orig;
796
797 Do_ADBG_BeginSubCase(c, "TEE Wait 0.1s");
798 {
799 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
800
801 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
802 xtest_teec_open_session(&session, &os_test_ta_uuid,
803 NULL, &ret_orig));
804
805 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
806 ret_orig);
807
808 op.params[0].value.a = 100;
809 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
810 TEEC_NONE, TEEC_NONE);
811
812 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
813 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
814 &ret_orig));
815 TEEC_CloseSession(&session);
816 }
817 Do_ADBG_EndSubCase(c, "TEE Wait 0.1s");
818
819 Do_ADBG_BeginSubCase(c, "TEE Wait 0.5s");
820 {
821 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
822
823 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
824 xtest_teec_open_session(&session, &os_test_ta_uuid,
825 NULL, &ret_orig));
826
827 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
828 ret_orig);
829
830 op.params[0].value.a = 500;
831 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
832 TEEC_NONE, TEEC_NONE);
833
834 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
835 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
836 &ret_orig));
837
838 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
839 ret_orig);
840 TEEC_CloseSession(&session);
841 }
842 Do_ADBG_EndSubCase(c, "TEE Wait 0.5s");
843
844#ifdef USER_SPACE
845 Do_ADBG_BeginSubCase(c, "TEE Wait 2s cancel");
846 {
847 pthread_t thr;
848 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
849
850 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
851 xtest_teec_open_session(&session, &os_test_ta_uuid,
852 NULL, &ret_orig));
853
854 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
855 ret_orig);
856
857 op.params[0].value.a = 2000;
858 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
859 TEEC_NONE, TEEC_NONE);
860
861 (void)ADBG_EXPECT(c, 0,
862 pthread_create(&thr, NULL, cancellation_thread, &op));
863
864 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_CANCEL,
865 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
866 &ret_orig));
867
868 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
869 ret_orig);
870 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
871 TEEC_CloseSession(&session);
872 }
873 Do_ADBG_EndSubCase(c, "TEE Wait 2s cancel");
874#endif
875
876 Do_ADBG_BeginSubCase(c, "TEE Wait 2s");
877 {
878 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
879
880 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
881 xtest_teec_open_session(&session, &os_test_ta_uuid,
882 NULL, &ret_orig));
883
884 op.params[0].value.a = 2000;
885 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
886 TEEC_NONE, TEEC_NONE);
887
888 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
889 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
890 &ret_orig));
891
892 TEEC_CloseSession(&session);
893 }
894 Do_ADBG_EndSubCase(c, "TEE Wait 2s");
895}
896
897static void xtest_tee_test_1010(ADBG_Case_t *c)
898{
899 unsigned n;
900
901 for (n = 1; n <= 5; n++) {
902 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
903 xtest_tee_test_invalid_mem_access(c, n);
904 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
905 }
906}
907
908static void xtest_tee_test_1011(ADBG_Case_t *c)
909{
910 TEEC_Session session = { 0 };
911 uint32_t ret_orig;
912 struct xtest_crypto_session cs = {
913 c, &session, TA_RPC_CMD_CRYPT_SHA256,
914 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
915 TA_RPC_CMD_CRYPT_AES256ECB_DEC
916 };
917 TEEC_UUID uuid = rpc_test_ta_uuid;
918
919 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
920 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
921 return;
922
923 /*
924 * Run the "complete crypto test suite" using RPC
925 */
926 xtest_crypto_test(&cs);
927 TEEC_CloseSession(&session);
928}
929
930/*
931 * Note that this test is failing when
932 * - running twice in a raw
933 * - and the user TA is statically linked
934 * This is because the counter is not reseted when opening the first session
935 * in case the TA is statically linked
936 */
937static void xtest_tee_test_1012(ADBG_Case_t *c)
938{
939 TEEC_Session session1 = { 0 };
940 TEEC_Session session2 = { 0 };
941 uint32_t ret_orig;
942 TEEC_UUID uuid = sims_test_ta_uuid;
943
944 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
945 {
946 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
947 static const uint8_t in[] = {
948 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
949 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
950 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
951 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
952 };
953 uint8_t out[32] = { 0 };
954 int i;
955
956 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
957 xtest_teec_open_session(&session1, &uuid, NULL,
958 &ret_orig));
959
960 op.params[0].value.a = 0;
961 op.params[1].tmpref.buffer = (void *)in;
962 op.params[1].tmpref.size = sizeof(in);
963 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
964 TEEC_MEMREF_TEMP_INPUT,
965 TEEC_NONE, TEEC_NONE);
966
967 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
968 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
969 &ret_orig));
970
971 for (i = 1; i < 1000; i++) {
972 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
973 xtest_teec_open_session(&session2, &uuid, NULL,
974 &ret_orig));
975
976 op.params[0].value.a = 0;
977 op.params[1].tmpref.buffer = out;
978 op.params[1].tmpref.size = sizeof(out);
979 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
980 TEEC_MEMREF_TEMP_OUTPUT,
981 TEEC_NONE, TEEC_NONE);
982
983 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
984 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
985 &op, &ret_orig));
986
987 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
988 sizeof(out))) {
989 Do_ADBG_Log("in:");
990 Do_ADBG_HexLog(in, sizeof(in), 16);
991 Do_ADBG_Log("out:");
992 Do_ADBG_HexLog(out, sizeof(out), 16);
993 }
994
995 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
996 TEEC_NONE, TEEC_NONE,
997 TEEC_NONE);
998
999 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1000 TEEC_InvokeCommand(&session1,
1001 TA_SIMS_CMD_GET_COUNTER,
1002 &op, &ret_orig));
1003
1004 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
1005
1006 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1007 TEEC_InvokeCommand(&session2,
1008 TA_SIMS_CMD_GET_COUNTER, &op,
1009 &ret_orig));
1010
1011 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
1012 TEEC_CloseSession(&session2);
1013 }
1014
1015 memset(out, 0, sizeof(out));
1016 op.params[0].value.a = 0;
1017 op.params[1].tmpref.buffer = out;
1018 op.params[1].tmpref.size = sizeof(out);
1019 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
1020 TEEC_MEMREF_TEMP_OUTPUT,
1021 TEEC_NONE, TEEC_NONE);
1022
1023 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1024 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
1025 &ret_orig));
1026
1027 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
1028 Do_ADBG_Log("in:");
1029 Do_ADBG_HexLog(in, sizeof(in), 16);
1030 Do_ADBG_Log("out:");
1031 Do_ADBG_HexLog(out, sizeof(out), 16);
1032 }
1033
1034 TEEC_CloseSession(&session1);
1035 }
1036}
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001037
1038struct test_1013_thread_arg {
1039 uint32_t cmd;
1040 uint32_t repeat;
1041 TEEC_SharedMemory *shm;
1042 uint32_t error_orig;
1043 TEEC_Result res;
1044 uint32_t max_concurrency;
1045 const uint8_t *in;
1046 size_t in_len;
1047 uint8_t *out;
1048 size_t out_len;
1049};
1050
1051static void *test_1013_thread(void *arg)
1052{
1053 struct test_1013_thread_arg *a = arg;
1054 TEEC_Session session = { 0 };
1055 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1056 uint8_t p2 = TEEC_NONE;
1057 uint8_t p3 = TEEC_NONE;
1058
1059 a->res = xtest_teec_open_session(&session, &concurrent_ta_uuid, NULL,
1060 &a->error_orig);
1061 if (a->res != TEEC_SUCCESS)
1062 return NULL;
1063
1064 op.params[0].memref.parent = a->shm;
1065 op.params[0].memref.size = a->shm->size;
1066 op.params[0].memref.offset = 0;
1067 op.params[1].value.a = a->repeat;
1068 op.params[1].value.b = 0;
1069 op.params[2].tmpref.buffer = (void *)a->in;
1070 op.params[2].tmpref.size = a->in_len;
1071 op.params[3].tmpref.buffer = a->out;
1072 op.params[3].tmpref.size = a->out_len;
1073
1074 if (a->in_len)
1075 p2 = TEEC_MEMREF_TEMP_INPUT;
1076 if (a->out_len)
1077 p3 = TEEC_MEMREF_TEMP_OUTPUT;
1078
1079 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
1080 TEEC_VALUE_INOUT, p2, p3);
1081
1082 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
1083 a->max_concurrency = op.params[1].value.b;
1084 a->out_len = op.params[3].tmpref.size;
1085 TEEC_CloseSession(&session);
1086 return NULL;
1087}
1088
1089static void xtest_tee_test_1013(ADBG_Case_t *c)
1090{
1091 size_t num_threads = 3;
1092 size_t nt;
1093 size_t n;
1094 pthread_t thr[num_threads];
1095 TEEC_SharedMemory shm;
1096 size_t max_concurrency;
1097 struct test_1013_thread_arg arg[num_threads];
1098 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
1099 static const uint8_t sha256_out[] = {
1100 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
1101 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
1102 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
1103 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
1104 };
1105 uint8_t out[32] = { 0 };
1106
1107
1108 memset(&shm, 0, sizeof(shm));
1109 shm.size = sizeof(struct ta_concurrent_shm);
1110 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1111 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1112 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
1113 return;
1114
1115 Do_ADBG_BeginSubCase(c, "Busy loop with %zu parallel threads",
1116 num_threads);
1117
1118 memset(shm.buffer, 0, shm.size);
1119 memset(arg, 0, sizeof(arg));
1120 max_concurrency = 0;
1121 nt = num_threads;
1122
1123 for (n = 0; n < nt; n++) {
1124 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
1125 arg[n].repeat = 10000;
1126 arg[n].shm = &shm;
1127 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1128 test_1013_thread, arg + n)))
1129 nt = n; /* break loop and start cleanup */
1130 }
1131
1132 for (n = 0; n < nt; n++) {
1133 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
1134 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
1135 if (arg[n].max_concurrency > max_concurrency)
1136 max_concurrency = arg[n].max_concurrency;
1137 }
1138
1139 Do_ADBG_Log("Max concurrency %zu", max_concurrency);
1140
1141 /*
1142 * Concurrency can be limited by several factors, for instance in a
1143 * single CPU system it's dependent on the Preemtion Model used by
1144 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
1145 * best result there).
1146 */
1147 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
1148 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
1149
1150 Do_ADBG_EndSubCase(c, "Busy loop with %zu parallel threads",
1151 num_threads);
1152
1153
1154 Do_ADBG_BeginSubCase(c, "Hashing with %zu parallel threads",
1155 num_threads);
1156
1157 memset(shm.buffer, 0, shm.size);
1158 memset(arg, 0, sizeof(arg));
1159 max_concurrency = 0;
1160 nt = num_threads;
1161
1162 for (n = 0; n < nt; n++) {
1163 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
1164 arg[n].repeat = 1000;
1165 arg[n].shm = &shm;
1166 arg[n].in = sha256_in;
1167 arg[n].in_len = sizeof(sha256_in);
1168 arg[n].out = out;
1169 arg[n].out_len = sizeof(out);
1170 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1171 test_1013_thread, arg + n)))
1172 nt = n; /* break loop and start cleanup */
1173 }
1174
1175 for (n = 0; n < nt; n++) {
1176 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1177 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1178 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1179 arg[n].out, arg[n].out_len);
1180 if (arg[n].max_concurrency > max_concurrency)
1181 max_concurrency = arg[n].max_concurrency;
1182 }
1183
1184 Do_ADBG_Log("Max concurrency %zu", max_concurrency);
1185
1186 Do_ADBG_EndSubCase(c, "Hashing with %zu parallel threads",
1187 num_threads);
1188
1189 TEEC_ReleaseSharedMemory(&shm);
1190}