blob: 0b22e7a890a8e30cdedea1cf737422286f9cfd39 [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
Jens Wiklanderb7940892015-10-23 16:02:40 +0200526static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
527 const char *extra_suffix)
528{
Jens Wiklander4441fe22015-10-23 16:53:02 +0200529 static const char ta_dir[] = "/lib/optee_armtz";
Jens Wiklanderb7940892015-10-23 16:02:40 +0200530
531 snprintf(buf, blen,
532 "%s/%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x.ta%s",
533 ta_dir, uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
534 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
535 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
536 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
537 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7],
538 extra_suffix ? extra_suffix : "");
539}
540
541static FILE *open_ta_file(const TEEC_UUID *uuid, const char *extra_suffix,
542 const char *mode)
543{
544 char buf[PATH_MAX];
545
546 uuid_to_full_name(buf, sizeof(buf), uuid, extra_suffix);
547 return fopen(buf, mode);
548}
549
550static bool rm_file(const TEEC_UUID *uuid, const char *extra_suffix)
551{
552 char buf[PATH_MAX];
553
554 uuid_to_full_name(buf, sizeof(buf), uuid, extra_suffix);
555 return !unlink(buf);
556}
557
Jens Wiklander4441fe22015-10-23 16:53:02 +0200558static bool rename_file(const TEEC_UUID *old_uuid, const char *old_extra_suffix,
559 const TEEC_UUID *new_uuid, const char *new_extra_suffix)
560{
561 char old_buf[PATH_MAX];
562 char new_buf[PATH_MAX];
563
564 uuid_to_full_name(old_buf, sizeof(old_buf), old_uuid, old_extra_suffix);
565 uuid_to_full_name(new_buf, sizeof(new_buf), new_uuid, new_extra_suffix);
566 return !rename(old_buf, new_buf);
567}
568
569static bool copy_file(const TEEC_UUID *src_uuid, const char *src_extra_suffix,
570 const TEEC_UUID *dst_uuid, const char *dst_extra_suffix)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200571{
572 char buf[4 * 1024];
Jens Wiklander4441fe22015-10-23 16:53:02 +0200573 FILE *src = open_ta_file(src_uuid, src_extra_suffix, "r");
574 FILE *dst = open_ta_file(dst_uuid, dst_extra_suffix, "w");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200575 size_t r;
576 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200577 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200578
Jens Wiklander4441fe22015-10-23 16:53:02 +0200579 if (src && dst) {
580 do {
581 r = fread(buf, 1, sizeof(buf), src);
582 if (!r) {
583 ret = !!feof(src);
584 break;
585 }
586 w = fwrite(buf, 1, r, dst);
587 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200588 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200589
590 if (src)
591 fclose(src);
592 if (dst)
593 fclose(dst);
594 return ret;
595}
596
597static bool corrupt_file(FILE *f, long offs, uint8_t mask)
598{
599 uint8_t b;
600
601 if (fseek(f, offs, SEEK_SET))
602 return false;
603
604 if (fread(&b, 1, 1, f) != 1)
605 return false;
606
607 b ^= mask;
608
609 if (fseek(f, offs, SEEK_SET))
610 return false;
611
612 if (fwrite(&b, 1, 1, f) != 1)
613 return false;
614
615 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200616}
617
618static void load_fake_ta(ADBG_Case_t *c)
619{
620 static const TEEC_UUID fake_uuid = {
621 0x7e0a0900, 0x586b, 0x11e5,
622 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
623 };
624 TEEC_Session session = { 0 };
625 TEEC_Result res;
626 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200627 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200628
Jens Wiklander4441fe22015-10-23 16:53:02 +0200629 r = copy_file(&create_fail_test_ta_uuid, NULL, &fake_uuid, NULL);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200630
631 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200632 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
633 &ret_orig);
634 if (res == TEEC_SUCCESS)
635 TEEC_CloseSession(&session);
636 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200637 }
638
639 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid, NULL));
640}
641
Jens Wiklander4441fe22015-10-23 16:53:02 +0200642static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
643{
644 TEEC_Session session = { 0 };
645 TEEC_Result res;
646 uint32_t ret_orig;
647 FILE *f;
648 bool r;
649
650 r = copy_file(&create_fail_test_ta_uuid, NULL,
651 &create_fail_test_ta_uuid, "save");
652 if (!ADBG_EXPECT_TRUE(c, r)) {
653 rm_file(&create_fail_test_ta_uuid, "save");
654 return false;
655 }
656
657 f = open_ta_file(&create_fail_test_ta_uuid, NULL, "r+");
658 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
659 rm_file(&create_fail_test_ta_uuid, "save");
660 return false;
661 }
662 r = corrupt_file(f, offs, mask);
663 fclose(f);
664
665 if (ADBG_EXPECT_TRUE(c, r)) {
666 res = xtest_teec_open_session(&session,
667 &create_fail_test_ta_uuid,
668 NULL, &ret_orig);
669 if (res == TEEC_SUCCESS)
670 TEEC_CloseSession(&session);
671 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
672 }
673
674 r &= ADBG_EXPECT_TRUE(c, rename_file(&create_fail_test_ta_uuid, "save",
675 &create_fail_test_ta_uuid, NULL));
676 return r;
677}
678
Pascal Brandc639ac82015-07-02 08:53:34 +0200679static void xtest_tee_test_1008(ADBG_Case_t *c)
680{
681 TEEC_Session session = { 0 };
682 TEEC_Session session_crypt = { 0 };
683 uint32_t ret_orig;
684
685 Do_ADBG_BeginSubCase(c, "Invoke command");
686 {
687 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
688 xtest_teec_open_session(&session_crypt,
689 &crypt_user_ta_uuid, NULL,
690 &ret_orig));
691
692 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
693 xtest_teec_open_session(&session, &os_test_ta_uuid,
694 NULL, &ret_orig));
695
696 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
697 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
698 NULL, &ret_orig));
699
700 TEEC_CloseSession(&session);
701 TEEC_CloseSession(&session_crypt);
702 }
703 Do_ADBG_EndSubCase(c, "Invoke command");
704
705 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
706 {
707 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
708
709 op.params[0].value.a = 2000;
710 op.paramTypes = TEEC_PARAM_TYPES(
711 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
712
713 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
714 xtest_teec_open_session(&session,
715 &os_test_ta_uuid,
716 NULL,
717 &ret_orig));
718
719 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
720 TEEC_InvokeCommand(&session,
721 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
722 &op, &ret_orig));
723
724 TEEC_CloseSession(&session);
725 }
726 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
727
728 Do_ADBG_BeginSubCase(c, "Create session fail");
729 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200730 size_t n;
731
Pascal Brandc639ac82015-07-02 08:53:34 +0200732 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
733 xtest_teec_open_session(&session_crypt,
734 &create_fail_test_ta_uuid, NULL,
735 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200736 /*
737 * Run this several times to see that there's no memory leakage.
738 */
739 for (n = 0; n < 100; n++) {
740 Do_ADBG_Log("n = %zu", n);
741 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
742 xtest_teec_open_session(&session_crypt,
743 &create_fail_test_ta_uuid,
744 NULL, &ret_orig));
745 }
746 }
747 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200748
749 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
750 load_fake_ta(c);
751 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
752
Jens Wiklander4441fe22015-10-23 16:53:02 +0200753 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
754 ADBG_EXPECT_TRUE(c,
755 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
756 ADBG_EXPECT_TRUE(c,
757 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
758 ADBG_EXPECT_TRUE(c,
759 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
760 ADBG_EXPECT_TRUE(c,
761 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
762 ADBG_EXPECT_TRUE(c,
763 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
764 ADBG_EXPECT_TRUE(c,
765 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
766 ADBG_EXPECT_TRUE(c,
767 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
768 ADBG_EXPECT_TRUE(c,
769 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
770 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
771 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
772 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200773}
774
775#ifdef USER_SPACE
776static 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#endif
787
788static void xtest_tee_test_1009(ADBG_Case_t *c)
789{
790 TEEC_Session session = { 0 };
791 uint32_t ret_orig;
792
793 Do_ADBG_BeginSubCase(c, "TEE Wait 0.1s");
794 {
795 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
796
797 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
798 xtest_teec_open_session(&session, &os_test_ta_uuid,
799 NULL, &ret_orig));
800
801 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
802 ret_orig);
803
804 op.params[0].value.a = 100;
805 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
806 TEEC_NONE, TEEC_NONE);
807
808 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
809 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
810 &ret_orig));
811 TEEC_CloseSession(&session);
812 }
813 Do_ADBG_EndSubCase(c, "TEE Wait 0.1s");
814
815 Do_ADBG_BeginSubCase(c, "TEE Wait 0.5s");
816 {
817 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
818
819 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
820 xtest_teec_open_session(&session, &os_test_ta_uuid,
821 NULL, &ret_orig));
822
823 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
824 ret_orig);
825
826 op.params[0].value.a = 500;
827 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
828 TEEC_NONE, TEEC_NONE);
829
830 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
831 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
832 &ret_orig));
833
834 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
835 ret_orig);
836 TEEC_CloseSession(&session);
837 }
838 Do_ADBG_EndSubCase(c, "TEE Wait 0.5s");
839
840#ifdef USER_SPACE
841 Do_ADBG_BeginSubCase(c, "TEE Wait 2s cancel");
842 {
843 pthread_t thr;
844 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
845
846 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
847 xtest_teec_open_session(&session, &os_test_ta_uuid,
848 NULL, &ret_orig));
849
850 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
851 ret_orig);
852
853 op.params[0].value.a = 2000;
854 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
855 TEEC_NONE, TEEC_NONE);
856
857 (void)ADBG_EXPECT(c, 0,
858 pthread_create(&thr, NULL, cancellation_thread, &op));
859
860 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_CANCEL,
861 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
862 &ret_orig));
863
864 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
865 ret_orig);
866 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
867 TEEC_CloseSession(&session);
868 }
869 Do_ADBG_EndSubCase(c, "TEE Wait 2s cancel");
870#endif
871
872 Do_ADBG_BeginSubCase(c, "TEE Wait 2s");
873 {
874 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
875
876 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
877 xtest_teec_open_session(&session, &os_test_ta_uuid,
878 NULL, &ret_orig));
879
880 op.params[0].value.a = 2000;
881 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
882 TEEC_NONE, TEEC_NONE);
883
884 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
885 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
886 &ret_orig));
887
888 TEEC_CloseSession(&session);
889 }
890 Do_ADBG_EndSubCase(c, "TEE Wait 2s");
891}
892
893static void xtest_tee_test_1010(ADBG_Case_t *c)
894{
895 unsigned n;
896
897 for (n = 1; n <= 5; n++) {
898 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
899 xtest_tee_test_invalid_mem_access(c, n);
900 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
901 }
902}
903
904static void xtest_tee_test_1011(ADBG_Case_t *c)
905{
906 TEEC_Session session = { 0 };
907 uint32_t ret_orig;
908 struct xtest_crypto_session cs = {
909 c, &session, TA_RPC_CMD_CRYPT_SHA256,
910 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
911 TA_RPC_CMD_CRYPT_AES256ECB_DEC
912 };
913 TEEC_UUID uuid = rpc_test_ta_uuid;
914
915 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
916 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
917 return;
918
919 /*
920 * Run the "complete crypto test suite" using RPC
921 */
922 xtest_crypto_test(&cs);
923 TEEC_CloseSession(&session);
924}
925
926/*
927 * Note that this test is failing when
928 * - running twice in a raw
929 * - and the user TA is statically linked
930 * This is because the counter is not reseted when opening the first session
931 * in case the TA is statically linked
932 */
933static void xtest_tee_test_1012(ADBG_Case_t *c)
934{
935 TEEC_Session session1 = { 0 };
936 TEEC_Session session2 = { 0 };
937 uint32_t ret_orig;
938 TEEC_UUID uuid = sims_test_ta_uuid;
939
940 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
941 {
942 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
943 static const uint8_t in[] = {
944 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
945 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
946 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
947 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
948 };
949 uint8_t out[32] = { 0 };
950 int i;
951
952 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
953 xtest_teec_open_session(&session1, &uuid, NULL,
954 &ret_orig));
955
956 op.params[0].value.a = 0;
957 op.params[1].tmpref.buffer = (void *)in;
958 op.params[1].tmpref.size = sizeof(in);
959 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
960 TEEC_MEMREF_TEMP_INPUT,
961 TEEC_NONE, TEEC_NONE);
962
963 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
964 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
965 &ret_orig));
966
967 for (i = 1; i < 1000; i++) {
968 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
969 xtest_teec_open_session(&session2, &uuid, NULL,
970 &ret_orig));
971
972 op.params[0].value.a = 0;
973 op.params[1].tmpref.buffer = out;
974 op.params[1].tmpref.size = sizeof(out);
975 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
976 TEEC_MEMREF_TEMP_OUTPUT,
977 TEEC_NONE, TEEC_NONE);
978
979 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
980 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
981 &op, &ret_orig));
982
983 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
984 sizeof(out))) {
985 Do_ADBG_Log("in:");
986 Do_ADBG_HexLog(in, sizeof(in), 16);
987 Do_ADBG_Log("out:");
988 Do_ADBG_HexLog(out, sizeof(out), 16);
989 }
990
991 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
992 TEEC_NONE, TEEC_NONE,
993 TEEC_NONE);
994
995 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
996 TEEC_InvokeCommand(&session1,
997 TA_SIMS_CMD_GET_COUNTER,
998 &op, &ret_orig));
999
1000 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
1001
1002 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1003 TEEC_InvokeCommand(&session2,
1004 TA_SIMS_CMD_GET_COUNTER, &op,
1005 &ret_orig));
1006
1007 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
1008 TEEC_CloseSession(&session2);
1009 }
1010
1011 memset(out, 0, sizeof(out));
1012 op.params[0].value.a = 0;
1013 op.params[1].tmpref.buffer = out;
1014 op.params[1].tmpref.size = sizeof(out);
1015 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
1016 TEEC_MEMREF_TEMP_OUTPUT,
1017 TEEC_NONE, TEEC_NONE);
1018
1019 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1020 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
1021 &ret_orig));
1022
1023 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
1024 Do_ADBG_Log("in:");
1025 Do_ADBG_HexLog(in, sizeof(in), 16);
1026 Do_ADBG_Log("out:");
1027 Do_ADBG_HexLog(out, sizeof(out), 16);
1028 }
1029
1030 TEEC_CloseSession(&session1);
1031 }
1032}
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001033
1034struct test_1013_thread_arg {
1035 uint32_t cmd;
1036 uint32_t repeat;
1037 TEEC_SharedMemory *shm;
1038 uint32_t error_orig;
1039 TEEC_Result res;
1040 uint32_t max_concurrency;
1041 const uint8_t *in;
1042 size_t in_len;
1043 uint8_t *out;
1044 size_t out_len;
1045};
1046
1047static void *test_1013_thread(void *arg)
1048{
1049 struct test_1013_thread_arg *a = arg;
1050 TEEC_Session session = { 0 };
1051 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1052 uint8_t p2 = TEEC_NONE;
1053 uint8_t p3 = TEEC_NONE;
1054
1055 a->res = xtest_teec_open_session(&session, &concurrent_ta_uuid, NULL,
1056 &a->error_orig);
1057 if (a->res != TEEC_SUCCESS)
1058 return NULL;
1059
1060 op.params[0].memref.parent = a->shm;
1061 op.params[0].memref.size = a->shm->size;
1062 op.params[0].memref.offset = 0;
1063 op.params[1].value.a = a->repeat;
1064 op.params[1].value.b = 0;
1065 op.params[2].tmpref.buffer = (void *)a->in;
1066 op.params[2].tmpref.size = a->in_len;
1067 op.params[3].tmpref.buffer = a->out;
1068 op.params[3].tmpref.size = a->out_len;
1069
1070 if (a->in_len)
1071 p2 = TEEC_MEMREF_TEMP_INPUT;
1072 if (a->out_len)
1073 p3 = TEEC_MEMREF_TEMP_OUTPUT;
1074
1075 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
1076 TEEC_VALUE_INOUT, p2, p3);
1077
1078 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
1079 a->max_concurrency = op.params[1].value.b;
1080 a->out_len = op.params[3].tmpref.size;
1081 TEEC_CloseSession(&session);
1082 return NULL;
1083}
1084
1085static void xtest_tee_test_1013(ADBG_Case_t *c)
1086{
1087 size_t num_threads = 3;
1088 size_t nt;
1089 size_t n;
1090 pthread_t thr[num_threads];
1091 TEEC_SharedMemory shm;
1092 size_t max_concurrency;
1093 struct test_1013_thread_arg arg[num_threads];
1094 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
1095 static const uint8_t sha256_out[] = {
1096 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
1097 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
1098 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
1099 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
1100 };
1101 uint8_t out[32] = { 0 };
1102
1103
1104 memset(&shm, 0, sizeof(shm));
1105 shm.size = sizeof(struct ta_concurrent_shm);
1106 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1107 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1108 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
1109 return;
1110
1111 Do_ADBG_BeginSubCase(c, "Busy loop with %zu parallel threads",
1112 num_threads);
1113
1114 memset(shm.buffer, 0, shm.size);
1115 memset(arg, 0, sizeof(arg));
1116 max_concurrency = 0;
1117 nt = num_threads;
1118
1119 for (n = 0; n < nt; n++) {
1120 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
1121 arg[n].repeat = 10000;
1122 arg[n].shm = &shm;
1123 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1124 test_1013_thread, arg + n)))
1125 nt = n; /* break loop and start cleanup */
1126 }
1127
1128 for (n = 0; n < nt; n++) {
1129 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
1130 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
1131 if (arg[n].max_concurrency > max_concurrency)
1132 max_concurrency = arg[n].max_concurrency;
1133 }
1134
1135 Do_ADBG_Log("Max concurrency %zu", max_concurrency);
1136
1137 /*
1138 * Concurrency can be limited by several factors, for instance in a
1139 * single CPU system it's dependent on the Preemtion Model used by
1140 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
1141 * best result there).
1142 */
1143 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
1144 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
1145
1146 Do_ADBG_EndSubCase(c, "Busy loop with %zu parallel threads",
1147 num_threads);
1148
1149
1150 Do_ADBG_BeginSubCase(c, "Hashing with %zu parallel threads",
1151 num_threads);
1152
1153 memset(shm.buffer, 0, shm.size);
1154 memset(arg, 0, sizeof(arg));
1155 max_concurrency = 0;
1156 nt = num_threads;
1157
1158 for (n = 0; n < nt; n++) {
1159 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
1160 arg[n].repeat = 1000;
1161 arg[n].shm = &shm;
1162 arg[n].in = sha256_in;
1163 arg[n].in_len = sizeof(sha256_in);
1164 arg[n].out = out;
1165 arg[n].out_len = sizeof(out);
1166 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1167 test_1013_thread, arg + n)))
1168 nt = n; /* break loop and start cleanup */
1169 }
1170
1171 for (n = 0; n < nt; n++) {
1172 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1173 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1174 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1175 arg[n].out, arg[n].out_len);
1176 if (arg[n].max_concurrency > max_concurrency)
1177 max_concurrency = arg[n].max_concurrency;
1178 }
1179
1180 Do_ADBG_Log("Max concurrency %zu", max_concurrency);
1181
1182 Do_ADBG_EndSubCase(c, "Hashing with %zu parallel threads",
1183 num_threads);
1184
1185 TEEC_ReleaseSharedMemory(&shm);
1186}