blob: 7967c9dacf728466e7062f31218f9e23fdc7c0d0 [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 {
Jens Wiklander70672972016-04-06 00:01:45 +02001010 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001011 uint32_t cmd;
1012 uint32_t repeat;
1013 TEEC_SharedMemory *shm;
1014 uint32_t error_orig;
1015 TEEC_Result res;
1016 uint32_t max_concurrency;
1017 const uint8_t *in;
1018 size_t in_len;
1019 uint8_t *out;
1020 size_t out_len;
1021};
1022
1023static void *test_1013_thread(void *arg)
1024{
1025 struct test_1013_thread_arg *a = arg;
1026 TEEC_Session session = { 0 };
1027 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1028 uint8_t p2 = TEEC_NONE;
1029 uint8_t p3 = TEEC_NONE;
1030
Jens Wiklander70672972016-04-06 00:01:45 +02001031 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001032 &a->error_orig);
1033 if (a->res != TEEC_SUCCESS)
1034 return NULL;
1035
1036 op.params[0].memref.parent = a->shm;
1037 op.params[0].memref.size = a->shm->size;
1038 op.params[0].memref.offset = 0;
1039 op.params[1].value.a = a->repeat;
1040 op.params[1].value.b = 0;
1041 op.params[2].tmpref.buffer = (void *)a->in;
1042 op.params[2].tmpref.size = a->in_len;
1043 op.params[3].tmpref.buffer = a->out;
1044 op.params[3].tmpref.size = a->out_len;
1045
1046 if (a->in_len)
1047 p2 = TEEC_MEMREF_TEMP_INPUT;
1048 if (a->out_len)
1049 p3 = TEEC_MEMREF_TEMP_OUTPUT;
1050
1051 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
1052 TEEC_VALUE_INOUT, p2, p3);
1053
1054 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
1055 a->max_concurrency = op.params[1].value.b;
1056 a->out_len = op.params[3].tmpref.size;
1057 TEEC_CloseSession(&session);
1058 return NULL;
1059}
1060
Pascal Brand4fa35582015-12-17 10:59:12 +01001061#define NUM_THREADS 3
1062
Jens Wiklander70672972016-04-06 00:01:45 +02001063static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
1064 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001065{
Pascal Brand4fa35582015-12-17 10:59:12 +01001066 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001067 size_t nt;
1068 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +02001069 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001070 pthread_t thr[num_threads];
1071 TEEC_SharedMemory shm;
1072 size_t max_concurrency;
1073 struct test_1013_thread_arg arg[num_threads];
1074 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
1075 static const uint8_t sha256_out[] = {
1076 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
1077 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
1078 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
1079 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
1080 };
1081 uint8_t out[32] = { 0 };
1082
Jens Wiklander70672972016-04-06 00:01:45 +02001083 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +01001084 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001085
1086 memset(&shm, 0, sizeof(shm));
1087 shm.size = sizeof(struct ta_concurrent_shm);
1088 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1089 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1090 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
1091 return;
1092
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001093 memset(shm.buffer, 0, shm.size);
1094 memset(arg, 0, sizeof(arg));
1095 max_concurrency = 0;
1096 nt = num_threads;
1097
1098 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001099 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001100 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +02001101 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001102 arg[n].shm = &shm;
1103 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1104 test_1013_thread, arg + n)))
1105 nt = n; /* break loop and start cleanup */
1106 }
1107
1108 for (n = 0; n < nt; n++) {
1109 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
1110 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
1111 if (arg[n].max_concurrency > max_concurrency)
1112 max_concurrency = arg[n].max_concurrency;
1113 }
1114
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001115 /*
1116 * Concurrency can be limited by several factors, for instance in a
1117 * single CPU system it's dependent on the Preemtion Model used by
1118 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
1119 * best result there).
1120 */
1121 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
1122 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +01001123 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001124 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001125
Jens Wiklander70672972016-04-06 00:01:45 +02001126 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001127 memset(shm.buffer, 0, shm.size);
1128 memset(arg, 0, sizeof(arg));
1129 max_concurrency = 0;
1130 nt = num_threads;
1131
1132 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001133 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001134 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +02001135 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001136 arg[n].shm = &shm;
1137 arg[n].in = sha256_in;
1138 arg[n].in_len = sizeof(sha256_in);
1139 arg[n].out = out;
1140 arg[n].out_len = sizeof(out);
1141 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1142 test_1013_thread, arg + n)))
1143 nt = n; /* break loop and start cleanup */
1144 }
1145
1146 for (n = 0; n < nt; n++) {
1147 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1148 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1149 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1150 arg[n].out, arg[n].out_len);
1151 if (arg[n].max_concurrency > max_concurrency)
1152 max_concurrency = arg[n].max_concurrency;
1153 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001154 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001155 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001156
Pascal Brand4fa35582015-12-17 10:59:12 +01001157 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001158 TEEC_ReleaseSharedMemory(&shm);
1159}
Pascal Brand4fa35582015-12-17 10:59:12 +01001160
1161static void xtest_tee_test_1013(ADBG_Case_t *c)
1162{
1163 int i;
1164 double mean_concurrency;
1165 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001166 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001167
1168 if (level == 0)
1169 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001170
Jens Wiklander70672972016-04-06 00:01:45 +02001171 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001172 mean_concurrency = 0;
1173 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001174 xtest_tee_test_1013_single(c, &concurrency,
1175 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001176 mean_concurrency += concurrency;
1177 }
1178 mean_concurrency /= nb_loops;
1179
1180 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1181 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001182 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001183
Jens Wiklander70672972016-04-06 00:01:45 +02001184 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1185 mean_concurrency = 0;
1186 for (i = 0; i < nb_loops; i++) {
1187 xtest_tee_test_1013_single(c, &concurrency,
1188 &concurrent_large_ta_uuid);
1189 mean_concurrency += concurrency;
1190 }
1191 mean_concurrency /= nb_loops;
1192
1193 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1194 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1195 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
1196}