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