blob: 87aee820b3bf61d6d5a28e4ea64169dd1ac86b76 [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 */
Jens Wiklandercf16e842016-02-10 09:07:09 +010048 "Core self tests",
Pascal Brandc639ac82015-07-02 08:53:34 +020049 /* 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{
Jens Wiklandercf16e842016-02-10 09:07:09 +0100362 TEEC_Result res;
363 TEEC_Session session = { 0 };
364 uint32_t ret_orig;
Pascal Brandc639ac82015-07-02 08:53:34 +0200365
Jens Wiklandercf16e842016-02-10 09:07:09 +0100366#define CMD_SELF_TESTS 2
Pascal Brandc639ac82015-07-02 08:53:34 +0200367
Jens Wiklandercf16e842016-02-10 09:07:09 +0100368 res = xtest_teec_open_session(&session, &sta_test_ta_uuid, NULL,
369 &ret_orig);
370 /*
371 * If the static TA (which is optional) isn't available, skip this
372 * test.
373 */
374 if (res != TEEC_SUCCESS)
375 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200376
Jens Wiklandercf16e842016-02-10 09:07:09 +0100377 (void)ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
378 &session, CMD_SELF_TESTS, NULL, &ret_orig));
379 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200380}
381
382static void xtest_tee_test_1004(ADBG_Case_t *c)
383{
384 TEEC_Session session = { 0 };
385 uint32_t ret_orig;
386 struct xtest_crypto_session cs = { c, &session, TA_CRYPT_CMD_SHA256,
387 TA_CRYPT_CMD_AES256ECB_ENC,
388 TA_CRYPT_CMD_AES256ECB_DEC };
389
390 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
391 &session, &crypt_user_ta_uuid,
392 NULL, &ret_orig)))
393 return;
394
395 /* Run the "complete crypto test suite" */
396 xtest_crypto_test(&cs);
397
398 TEEC_CloseSession(&session);
399}
400
401#ifndef TEEC_ERROR_TARGET_DEAD
402/* To be removed when we have TEEC_ERROR_TARGET_DEAD from tee_client_api.h */
403#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024
404#endif
405
406static void xtest_tee_test_invalid_mem_access(ADBG_Case_t *c, uint32_t n)
407{
408 TEEC_Session session = { 0 };
409 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
410 uint32_t ret_orig;
411
412 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
413 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
414 &ret_orig));
415
416 op.params[0].value.a = n;
417 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
418 TEEC_NONE);
419
420 (void)ADBG_EXPECT_TEEC_RESULT(c,
421 TEEC_ERROR_TARGET_DEAD,
422 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
423 &ret_orig));
424
425 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
426 TEEC_InvokeCommand(&session,
427 TA_OS_TEST_CMD_BAD_MEM_ACCESS,
428 &op,
429 &ret_orig));
430 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
431
432 TEEC_CloseSession(&session);
433}
434
435static void xtest_tee_test_1005(ADBG_Case_t *c)
436{
437 uint32_t ret_orig;
438#define MAX_SESSIONS 3
439 TEEC_Session sessions[MAX_SESSIONS];
440 int i;
441
442 for (i = 0; i < MAX_SESSIONS; i++) {
443 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
444 xtest_teec_open_session(&sessions[i], &os_test_ta_uuid,
445 NULL, &ret_orig)))
446 break;
447 }
448
449 for (; --i >= 0; )
450 TEEC_CloseSession(&sessions[i]);
451}
452
453static void xtest_tee_test_1006(ADBG_Case_t *c)
454{
455 TEEC_Session session = { 0 };
456 uint32_t ret_orig;
457 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
458 uint8_t buf[32];
459
460 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
461 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
462 &ret_orig)))
463 return;
464
465 op.params[0].tmpref.buffer = buf;
466 op.params[0].tmpref.size = sizeof(buf);
467 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
468 TEEC_NONE, TEEC_NONE);
469
470 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
471 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
472 &ret_orig));
473
474 TEEC_CloseSession(&session);
475}
476
477static void xtest_tee_test_1007(ADBG_Case_t *c)
478{
479 TEEC_Session session = { 0 };
480 uint32_t ret_orig;
481
482 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
483 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
484 &ret_orig));
485
486 (void)ADBG_EXPECT_TEEC_RESULT(c,
487 TEEC_ERROR_TARGET_DEAD,
488 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
489 &ret_orig));
490
491 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
492
493 (void)ADBG_EXPECT_TEEC_RESULT(c,
494 TEEC_ERROR_TARGET_DEAD,
495 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
496 &ret_orig));
497
498 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
499
500 TEEC_CloseSession(&session);
501}
502
Jerome Forissierf02a2212015-10-29 14:33:35 +0100503#ifndef TA_DIR
504#define TA_DIR "/lib/optee_armtz"
505#endif
506
Jens Wiklanderb7940892015-10-23 16:02:40 +0200507static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
508 const char *extra_suffix)
509{
Jerome Forissierf02a2212015-10-29 14:33:35 +0100510 static const char ta_dir[] = TA_DIR;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200511
512 snprintf(buf, blen,
513 "%s/%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x.ta%s",
514 ta_dir, uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
515 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
516 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
517 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
518 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7],
519 extra_suffix ? extra_suffix : "");
520}
521
522static FILE *open_ta_file(const TEEC_UUID *uuid, const char *extra_suffix,
523 const char *mode)
524{
525 char buf[PATH_MAX];
526
527 uuid_to_full_name(buf, sizeof(buf), uuid, extra_suffix);
528 return fopen(buf, mode);
529}
530
531static bool rm_file(const TEEC_UUID *uuid, const char *extra_suffix)
532{
533 char buf[PATH_MAX];
534
535 uuid_to_full_name(buf, sizeof(buf), uuid, extra_suffix);
536 return !unlink(buf);
537}
538
Jens Wiklander4441fe22015-10-23 16:53:02 +0200539static bool rename_file(const TEEC_UUID *old_uuid, const char *old_extra_suffix,
540 const TEEC_UUID *new_uuid, const char *new_extra_suffix)
541{
542 char old_buf[PATH_MAX];
543 char new_buf[PATH_MAX];
544
545 uuid_to_full_name(old_buf, sizeof(old_buf), old_uuid, old_extra_suffix);
546 uuid_to_full_name(new_buf, sizeof(new_buf), new_uuid, new_extra_suffix);
547 return !rename(old_buf, new_buf);
548}
549
550static bool copy_file(const TEEC_UUID *src_uuid, const char *src_extra_suffix,
551 const TEEC_UUID *dst_uuid, const char *dst_extra_suffix)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200552{
553 char buf[4 * 1024];
Jens Wiklander4441fe22015-10-23 16:53:02 +0200554 FILE *src = open_ta_file(src_uuid, src_extra_suffix, "r");
555 FILE *dst = open_ta_file(dst_uuid, dst_extra_suffix, "w");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200556 size_t r;
557 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200558 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200559
Jens Wiklander4441fe22015-10-23 16:53:02 +0200560 if (src && dst) {
561 do {
562 r = fread(buf, 1, sizeof(buf), src);
563 if (!r) {
564 ret = !!feof(src);
565 break;
566 }
567 w = fwrite(buf, 1, r, dst);
568 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200569 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200570
571 if (src)
572 fclose(src);
573 if (dst)
574 fclose(dst);
575 return ret;
576}
577
578static bool corrupt_file(FILE *f, long offs, uint8_t mask)
579{
580 uint8_t b;
581
582 if (fseek(f, offs, SEEK_SET))
583 return false;
584
585 if (fread(&b, 1, 1, f) != 1)
586 return false;
587
588 b ^= mask;
589
590 if (fseek(f, offs, SEEK_SET))
591 return false;
592
593 if (fwrite(&b, 1, 1, f) != 1)
594 return false;
595
596 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200597}
598
599static void load_fake_ta(ADBG_Case_t *c)
600{
601 static const TEEC_UUID fake_uuid = {
602 0x7e0a0900, 0x586b, 0x11e5,
603 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
604 };
605 TEEC_Session session = { 0 };
606 TEEC_Result res;
607 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200608 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200609
Jens Wiklander4441fe22015-10-23 16:53:02 +0200610 r = copy_file(&create_fail_test_ta_uuid, NULL, &fake_uuid, NULL);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200611
612 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200613 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
614 &ret_orig);
615 if (res == TEEC_SUCCESS)
616 TEEC_CloseSession(&session);
617 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200618 }
619
620 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid, NULL));
621}
622
Jens Wiklander4441fe22015-10-23 16:53:02 +0200623static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
624{
625 TEEC_Session session = { 0 };
626 TEEC_Result res;
627 uint32_t ret_orig;
628 FILE *f;
629 bool r;
630
631 r = copy_file(&create_fail_test_ta_uuid, NULL,
632 &create_fail_test_ta_uuid, "save");
633 if (!ADBG_EXPECT_TRUE(c, r)) {
634 rm_file(&create_fail_test_ta_uuid, "save");
635 return false;
636 }
637
638 f = open_ta_file(&create_fail_test_ta_uuid, NULL, "r+");
639 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
640 rm_file(&create_fail_test_ta_uuid, "save");
641 return false;
642 }
643 r = corrupt_file(f, offs, mask);
644 fclose(f);
645
646 if (ADBG_EXPECT_TRUE(c, r)) {
647 res = xtest_teec_open_session(&session,
648 &create_fail_test_ta_uuid,
649 NULL, &ret_orig);
650 if (res == TEEC_SUCCESS)
651 TEEC_CloseSession(&session);
652 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
653 }
654
655 r &= ADBG_EXPECT_TRUE(c, rename_file(&create_fail_test_ta_uuid, "save",
656 &create_fail_test_ta_uuid, NULL));
657 return r;
658}
659
Pascal Brandc639ac82015-07-02 08:53:34 +0200660static void xtest_tee_test_1008(ADBG_Case_t *c)
661{
662 TEEC_Session session = { 0 };
663 TEEC_Session session_crypt = { 0 };
664 uint32_t ret_orig;
665
666 Do_ADBG_BeginSubCase(c, "Invoke command");
667 {
668 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200669 xtest_teec_open_session(&session, &os_test_ta_uuid,
670 NULL, &ret_orig));
671
672 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
673 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
674 NULL, &ret_orig));
675
676 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200677 }
678 Do_ADBG_EndSubCase(c, "Invoke command");
679
680 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
681 {
682 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
683
684 op.params[0].value.a = 2000;
685 op.paramTypes = TEEC_PARAM_TYPES(
686 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
687
688 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
689 xtest_teec_open_session(&session,
690 &os_test_ta_uuid,
691 NULL,
692 &ret_orig));
693
694 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
695 TEEC_InvokeCommand(&session,
696 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
697 &op, &ret_orig));
698
699 TEEC_CloseSession(&session);
700 }
701 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
702
703 Do_ADBG_BeginSubCase(c, "Create session fail");
704 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200705 size_t n;
706
Pascal Brandc639ac82015-07-02 08:53:34 +0200707 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
708 xtest_teec_open_session(&session_crypt,
709 &create_fail_test_ta_uuid, NULL,
710 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200711 /*
712 * Run this several times to see that there's no memory leakage.
713 */
714 for (n = 0; n < 100; n++) {
715 Do_ADBG_Log("n = %zu", n);
716 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
717 xtest_teec_open_session(&session_crypt,
718 &create_fail_test_ta_uuid,
719 NULL, &ret_orig));
720 }
721 }
722 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200723
724 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
725 load_fake_ta(c);
726 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
727
Jens Wiklander4441fe22015-10-23 16:53:02 +0200728 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
729 ADBG_EXPECT_TRUE(c,
730 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
731 ADBG_EXPECT_TRUE(c,
732 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
733 ADBG_EXPECT_TRUE(c,
734 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
735 ADBG_EXPECT_TRUE(c,
736 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
737 ADBG_EXPECT_TRUE(c,
738 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
739 ADBG_EXPECT_TRUE(c,
740 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
741 ADBG_EXPECT_TRUE(c,
742 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
743 ADBG_EXPECT_TRUE(c,
744 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
745 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
746 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
747 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200748}
749
750#ifdef USER_SPACE
751static void *cancellation_thread(void *arg)
752{
753 /*
754 * Sleep 0.5 seconds before cancellation to make sure that the other
755 * thread is in RPC_WAIT.
756 */
757 (void)usleep(500000);
758 TEEC_RequestCancellation(arg);
759 return NULL;
760}
761#endif
762
763static void xtest_tee_test_1009(ADBG_Case_t *c)
764{
765 TEEC_Session session = { 0 };
766 uint32_t ret_orig;
767
768 Do_ADBG_BeginSubCase(c, "TEE Wait 0.1s");
769 {
770 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
771
772 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
773 xtest_teec_open_session(&session, &os_test_ta_uuid,
774 NULL, &ret_orig));
775
776 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
777 ret_orig);
778
779 op.params[0].value.a = 100;
780 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
781 TEEC_NONE, TEEC_NONE);
782
783 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
784 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
785 &ret_orig));
786 TEEC_CloseSession(&session);
787 }
788 Do_ADBG_EndSubCase(c, "TEE Wait 0.1s");
789
790 Do_ADBG_BeginSubCase(c, "TEE Wait 0.5s");
791 {
792 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
793
794 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
795 xtest_teec_open_session(&session, &os_test_ta_uuid,
796 NULL, &ret_orig));
797
798 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
799 ret_orig);
800
801 op.params[0].value.a = 500;
802 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
803 TEEC_NONE, TEEC_NONE);
804
805 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
806 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
807 &ret_orig));
808
809 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
810 ret_orig);
811 TEEC_CloseSession(&session);
812 }
813 Do_ADBG_EndSubCase(c, "TEE Wait 0.5s");
814
815#ifdef USER_SPACE
816 Do_ADBG_BeginSubCase(c, "TEE Wait 2s cancel");
817 {
818 pthread_t thr;
819 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
820
821 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
822 xtest_teec_open_session(&session, &os_test_ta_uuid,
823 NULL, &ret_orig));
824
825 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
826 ret_orig);
827
828 op.params[0].value.a = 2000;
829 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
830 TEEC_NONE, TEEC_NONE);
831
832 (void)ADBG_EXPECT(c, 0,
833 pthread_create(&thr, NULL, cancellation_thread, &op));
834
835 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_CANCEL,
836 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
837 &ret_orig));
838
839 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
840 ret_orig);
841 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
842 TEEC_CloseSession(&session);
843 }
844 Do_ADBG_EndSubCase(c, "TEE Wait 2s cancel");
845#endif
846
847 Do_ADBG_BeginSubCase(c, "TEE Wait 2s");
848 {
849 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
850
851 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
852 xtest_teec_open_session(&session, &os_test_ta_uuid,
853 NULL, &ret_orig));
854
855 op.params[0].value.a = 2000;
856 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
857 TEEC_NONE, TEEC_NONE);
858
859 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
860 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
861 &ret_orig));
862
863 TEEC_CloseSession(&session);
864 }
865 Do_ADBG_EndSubCase(c, "TEE Wait 2s");
866}
867
868static void xtest_tee_test_1010(ADBG_Case_t *c)
869{
870 unsigned n;
871
872 for (n = 1; n <= 5; n++) {
873 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
874 xtest_tee_test_invalid_mem_access(c, n);
875 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
876 }
877}
878
879static void xtest_tee_test_1011(ADBG_Case_t *c)
880{
881 TEEC_Session session = { 0 };
882 uint32_t ret_orig;
883 struct xtest_crypto_session cs = {
884 c, &session, TA_RPC_CMD_CRYPT_SHA256,
885 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
886 TA_RPC_CMD_CRYPT_AES256ECB_DEC
887 };
888 TEEC_UUID uuid = rpc_test_ta_uuid;
889
890 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
891 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
892 return;
893
894 /*
895 * Run the "complete crypto test suite" using RPC
896 */
897 xtest_crypto_test(&cs);
898 TEEC_CloseSession(&session);
899}
900
901/*
902 * Note that this test is failing when
903 * - running twice in a raw
904 * - and the user TA is statically linked
905 * This is because the counter is not reseted when opening the first session
906 * in case the TA is statically linked
907 */
908static void xtest_tee_test_1012(ADBG_Case_t *c)
909{
910 TEEC_Session session1 = { 0 };
911 TEEC_Session session2 = { 0 };
912 uint32_t ret_orig;
913 TEEC_UUID uuid = sims_test_ta_uuid;
914
915 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
916 {
917 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
918 static const uint8_t in[] = {
919 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
920 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
921 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
922 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
923 };
924 uint8_t out[32] = { 0 };
925 int i;
926
927 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
928 xtest_teec_open_session(&session1, &uuid, NULL,
929 &ret_orig));
930
931 op.params[0].value.a = 0;
932 op.params[1].tmpref.buffer = (void *)in;
933 op.params[1].tmpref.size = sizeof(in);
934 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
935 TEEC_MEMREF_TEMP_INPUT,
936 TEEC_NONE, TEEC_NONE);
937
938 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
939 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
940 &ret_orig));
941
942 for (i = 1; i < 1000; i++) {
943 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
944 xtest_teec_open_session(&session2, &uuid, NULL,
945 &ret_orig));
946
947 op.params[0].value.a = 0;
948 op.params[1].tmpref.buffer = out;
949 op.params[1].tmpref.size = sizeof(out);
950 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
951 TEEC_MEMREF_TEMP_OUTPUT,
952 TEEC_NONE, TEEC_NONE);
953
954 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
955 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
956 &op, &ret_orig));
957
958 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
959 sizeof(out))) {
960 Do_ADBG_Log("in:");
961 Do_ADBG_HexLog(in, sizeof(in), 16);
962 Do_ADBG_Log("out:");
963 Do_ADBG_HexLog(out, sizeof(out), 16);
964 }
965
966 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
967 TEEC_NONE, TEEC_NONE,
968 TEEC_NONE);
969
970 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
971 TEEC_InvokeCommand(&session1,
972 TA_SIMS_CMD_GET_COUNTER,
973 &op, &ret_orig));
974
975 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
976
977 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
978 TEEC_InvokeCommand(&session2,
979 TA_SIMS_CMD_GET_COUNTER, &op,
980 &ret_orig));
981
982 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
983 TEEC_CloseSession(&session2);
984 }
985
986 memset(out, 0, sizeof(out));
987 op.params[0].value.a = 0;
988 op.params[1].tmpref.buffer = out;
989 op.params[1].tmpref.size = sizeof(out);
990 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
991 TEEC_MEMREF_TEMP_OUTPUT,
992 TEEC_NONE, TEEC_NONE);
993
994 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
995 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
996 &ret_orig));
997
998 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
999 Do_ADBG_Log("in:");
1000 Do_ADBG_HexLog(in, sizeof(in), 16);
1001 Do_ADBG_Log("out:");
1002 Do_ADBG_HexLog(out, sizeof(out), 16);
1003 }
1004
1005 TEEC_CloseSession(&session1);
1006 }
1007}
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001008
1009struct test_1013_thread_arg {
1010 uint32_t cmd;
1011 uint32_t repeat;
1012 TEEC_SharedMemory *shm;
1013 uint32_t error_orig;
1014 TEEC_Result res;
1015 uint32_t max_concurrency;
1016 const uint8_t *in;
1017 size_t in_len;
1018 uint8_t *out;
1019 size_t out_len;
1020};
1021
1022static void *test_1013_thread(void *arg)
1023{
1024 struct test_1013_thread_arg *a = arg;
1025 TEEC_Session session = { 0 };
1026 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1027 uint8_t p2 = TEEC_NONE;
1028 uint8_t p3 = TEEC_NONE;
1029
1030 a->res = xtest_teec_open_session(&session, &concurrent_ta_uuid, NULL,
1031 &a->error_orig);
1032 if (a->res != TEEC_SUCCESS)
1033 return NULL;
1034
1035 op.params[0].memref.parent = a->shm;
1036 op.params[0].memref.size = a->shm->size;
1037 op.params[0].memref.offset = 0;
1038 op.params[1].value.a = a->repeat;
1039 op.params[1].value.b = 0;
1040 op.params[2].tmpref.buffer = (void *)a->in;
1041 op.params[2].tmpref.size = a->in_len;
1042 op.params[3].tmpref.buffer = a->out;
1043 op.params[3].tmpref.size = a->out_len;
1044
1045 if (a->in_len)
1046 p2 = TEEC_MEMREF_TEMP_INPUT;
1047 if (a->out_len)
1048 p3 = TEEC_MEMREF_TEMP_OUTPUT;
1049
1050 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
1051 TEEC_VALUE_INOUT, p2, p3);
1052
1053 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
1054 a->max_concurrency = op.params[1].value.b;
1055 a->out_len = op.params[3].tmpref.size;
1056 TEEC_CloseSession(&session);
1057 return NULL;
1058}
1059
Pascal Brand4fa35582015-12-17 10:59:12 +01001060#define NUM_THREADS 3
1061
1062static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency)
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001063{
Pascal Brand4fa35582015-12-17 10:59:12 +01001064 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001065 size_t nt;
1066 size_t n;
1067 pthread_t thr[num_threads];
1068 TEEC_SharedMemory shm;
1069 size_t max_concurrency;
1070 struct test_1013_thread_arg arg[num_threads];
1071 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
1072 static const uint8_t sha256_out[] = {
1073 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
1074 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
1075 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
1076 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
1077 };
1078 uint8_t out[32] = { 0 };
1079
Pascal Brand4fa35582015-12-17 10:59:12 +01001080 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001081
1082 memset(&shm, 0, sizeof(shm));
1083 shm.size = sizeof(struct ta_concurrent_shm);
1084 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1085 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1086 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
1087 return;
1088
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001089 memset(shm.buffer, 0, shm.size);
1090 memset(arg, 0, sizeof(arg));
1091 max_concurrency = 0;
1092 nt = num_threads;
1093
1094 for (n = 0; n < nt; n++) {
1095 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
1096 arg[n].repeat = 10000;
1097 arg[n].shm = &shm;
1098 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1099 test_1013_thread, arg + n)))
1100 nt = n; /* break loop and start cleanup */
1101 }
1102
1103 for (n = 0; n < nt; n++) {
1104 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
1105 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
1106 if (arg[n].max_concurrency > max_concurrency)
1107 max_concurrency = arg[n].max_concurrency;
1108 }
1109
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001110 /*
1111 * Concurrency can be limited by several factors, for instance in a
1112 * single CPU system it's dependent on the Preemtion Model used by
1113 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
1114 * best result there).
1115 */
1116 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
1117 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +01001118 *mean_concurrency += max_concurrency;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001119
1120 memset(shm.buffer, 0, shm.size);
1121 memset(arg, 0, sizeof(arg));
1122 max_concurrency = 0;
1123 nt = num_threads;
1124
1125 for (n = 0; n < nt; n++) {
1126 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
1127 arg[n].repeat = 1000;
1128 arg[n].shm = &shm;
1129 arg[n].in = sha256_in;
1130 arg[n].in_len = sizeof(sha256_in);
1131 arg[n].out = out;
1132 arg[n].out_len = sizeof(out);
1133 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1134 test_1013_thread, arg + n)))
1135 nt = n; /* break loop and start cleanup */
1136 }
1137
1138 for (n = 0; n < nt; n++) {
1139 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1140 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1141 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1142 arg[n].out, arg[n].out_len);
1143 if (arg[n].max_concurrency > max_concurrency)
1144 max_concurrency = arg[n].max_concurrency;
1145 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001146 *mean_concurrency += max_concurrency;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001147
Pascal Brand4fa35582015-12-17 10:59:12 +01001148 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001149 TEEC_ReleaseSharedMemory(&shm);
1150}
Pascal Brand4fa35582015-12-17 10:59:12 +01001151
1152static void xtest_tee_test_1013(ADBG_Case_t *c)
1153{
1154 int i;
1155 double mean_concurrency;
1156 double concurrency;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001157 int nb_loops = 50;
1158
1159 if (level == 0)
1160 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001161
1162 mean_concurrency = 0;
1163 for (i = 0; i < nb_loops; i++) {
1164 xtest_tee_test_1013_single(c, &concurrency);
1165 mean_concurrency += concurrency;
1166 }
1167 mean_concurrency /= nb_loops;
1168
1169 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1170 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1171}
1172