blob: bd3ddb1f1d89dd15325e23ef9c5e32d94cba8659 [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>
David Brownb2865ab2016-08-02 11:44:41 -060021#include <sys/stat.h>
22#include <sys/types.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020023#endif
24
25#include "xtest_test.h"
26#include "xtest_helpers.h"
Jens Wiklander4441fe22015-10-23 16:53:02 +020027#include <signed_hdr.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020028
29#include <ta_crypt.h>
30#include <ta_os_test.h>
31#include <ta_create_fail_test.h>
32#include <ta_rpc_test.h>
33#include <ta_sims_test.h>
Jens Wiklanderac27ec12015-07-15 15:23:14 +020034#include <ta_concurrent.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020035
36static void xtest_tee_test_1001(ADBG_Case_t *Case_p);
37static void xtest_tee_test_1004(ADBG_Case_t *Case_p);
38static void xtest_tee_test_1005(ADBG_Case_t *Case_p);
39static void xtest_tee_test_1006(ADBG_Case_t *Case_p);
40static void xtest_tee_test_1007(ADBG_Case_t *Case_p);
41static void xtest_tee_test_1008(ADBG_Case_t *Case_p);
42static void xtest_tee_test_1009(ADBG_Case_t *Case_p);
43static void xtest_tee_test_1010(ADBG_Case_t *Case_p);
44static void xtest_tee_test_1011(ADBG_Case_t *Case_p);
45static void xtest_tee_test_1012(ADBG_Case_t *Case_p);
Jens Wiklanderac27ec12015-07-15 15:23:14 +020046static void xtest_tee_test_1013(ADBG_Case_t *Case_p);
Pascal Brandc639ac82015-07-02 08:53:34 +020047
48ADBG_CASE_DEFINE(XTEST_TEE_1001, xtest_tee_test_1001,
49 /* Title */
Jens Wiklandercf16e842016-02-10 09:07:09 +010050 "Core self tests",
Pascal Brandc639ac82015-07-02 08:53:34 +020051 /* Short description */
52 "Short description ...",
53 /* Requirement IDs */
54 "TEE-??",
55 /* How to implement */
56 "Description of how to implement ..."
57 );
58
59ADBG_CASE_DEFINE(XTEST_TEE_1004, xtest_tee_test_1004,
60 /* Title */
61 "Test User Crypt TA",
62 /* Short description */
63 "Short description ...",
64 /* Requirement IDs */
65 "TEE-??",
66 /* How to implement */
67 "Description of how to implement ..."
68 );
69
70ADBG_CASE_DEFINE(XTEST_TEE_1005, xtest_tee_test_1005,
71 /* Title */
72 "Many sessions",
73 /* Short description */
74 "Short description ...",
75 /* Requirement IDs */
76 "TEE-??",
77 /* How to implement */
78 "Description of how to implement ..."
79 );
80
81ADBG_CASE_DEFINE(XTEST_TEE_1006, xtest_tee_test_1006,
82 /* Title */
83 "Test Basic OS features",
84 /* Short description */
85 "Short description ...",
86 /* Requirement IDs */
87 "TEE-??",
88 /* How to implement */
89 "Description of how to implement ..."
90 );
91
92ADBG_CASE_DEFINE(XTEST_TEE_1007, xtest_tee_test_1007,
93 /* Title */
94 "Test Panic",
95 /* Short description */
96 "Short description ...",
97 /* Requirement IDs */
98 "TEE-??",
99 /* How to implement */
100 "Description of how to implement ..."
101 );
102
103ADBG_CASE_DEFINE(XTEST_TEE_1008, xtest_tee_test_1008,
104 /* Title */
105 "TEE internal client API",
106 /* Short description */
107 "Short description ...",
108 /* Requirement IDs */
109 "TEE-??",
110 /* How to implement */
111 "Description of how to implement ..."
112 );
113
114ADBG_CASE_DEFINE(XTEST_TEE_1009, xtest_tee_test_1009,
115 /* Title */
116 "TEE Wait",
117 /* Short description */
118 "Short description ...",
119 /* Requirement IDs */
120 "TEE-??",
121 /* How to implement */
122 "Description of how to implement ..."
123 );
124
125ADBG_CASE_DEFINE(XTEST_TEE_1010, xtest_tee_test_1010,
126 /* Title */
127 "Invalid memory access",
128 /* Short description */
129 "Short description ...",
130 /* Requirement IDs */
131 "TEE-??",
132 /* How to implement */
133 "Description of how to implement ..."
134 );
135
136ADBG_CASE_DEFINE(XTEST_TEE_1011, xtest_tee_test_1011,
137 /* Title */
138 "Test RPC features with User Crypt TA",
139 /* Short description */
140 "Short description ...",
141 /* Requirement IDs */
142 "TEE-??",
143 /* How to implement */
144 "Description of how to implement ..."
145 );
146
147ADBG_CASE_DEFINE(XTEST_TEE_1012, xtest_tee_test_1012,
148 /* Title */
149 "Test Single Instance Multi Session features with SIMS TA",
150 /* Short description */
151 "Short description ...",
152 /* Requirement IDs */
153 "TEE-??",
154 /* How to implement */
155 "Description of how to implement ..."
156 );
157
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200158ADBG_CASE_DEFINE(XTEST_TEE_1013, xtest_tee_test_1013,
159 /* Title */
160 "Test concurency with concurrent TA",
161 /* Short description */
162 "Short description ...",
163 /* Requirement IDs */
164 "TEE-??",
165 /* How to implement */
166 "Description of how to implement ..."
167 );
168
Pascal Brandc639ac82015-07-02 08:53:34 +0200169struct xtest_crypto_session {
170 ADBG_Case_t *c;
171 TEEC_Session *session;
172 uint32_t cmd_id_sha256;
173 uint32_t cmd_id_aes256ecb_encrypt;
174 uint32_t cmd_id_aes256ecb_decrypt;
175};
176
177static void xtest_crypto_test(struct xtest_crypto_session *cs)
178{
179 uint32_t ret_orig;
180 uint8_t crypt_out[16];
181 uint8_t crypt_in[16] = { 22, 17 };
182
183 crypt_in[15] = 60;
184
185 Do_ADBG_BeginSubCase(cs->c, "AES encrypt");
186 {
187 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
188
189 op.params[0].tmpref.buffer = crypt_in;
190 op.params[0].tmpref.size = sizeof(crypt_in);
191 op.params[1].tmpref.buffer = crypt_out;
192 op.params[1].tmpref.size = sizeof(crypt_out);
193 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
194 TEEC_MEMREF_TEMP_OUTPUT,
195 TEEC_NONE, TEEC_NONE);
196
197 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
198 TEEC_InvokeCommand(cs->session,
199 cs->
200 cmd_id_aes256ecb_encrypt,
201 &op,
202 &ret_orig));
203 }
204 Do_ADBG_EndSubCase(cs->c, "AES encrypt");
205
206 Do_ADBG_BeginSubCase(cs->c, "AES decrypt");
207 {
208 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
209 uint8_t out[16];
210
211 op.params[0].tmpref.buffer = crypt_out;
212 op.params[0].tmpref.size = sizeof(crypt_out);
213 op.params[1].tmpref.buffer = out;
214 op.params[1].tmpref.size = sizeof(out);
215 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
216 TEEC_MEMREF_TEMP_OUTPUT,
217 TEEC_NONE, TEEC_NONE);
218
219 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
220 TEEC_InvokeCommand(cs->session,
221 cs->
222 cmd_id_aes256ecb_decrypt,
223 &op,
224 &ret_orig));
225
226 if (!ADBG_EXPECT(cs->c, 0,
227 memcmp(crypt_in, out, sizeof(crypt_in)))) {
228 Do_ADBG_Log("crypt_in:");
229 Do_ADBG_HexLog(crypt_in, sizeof(crypt_in), 16);
230 Do_ADBG_Log("out:");
231 Do_ADBG_HexLog(out, sizeof(out), 16);
232 }
233 }
234 Do_ADBG_EndSubCase(cs->c, "AES decrypt");
235
236 Do_ADBG_BeginSubCase(cs->c, "SHA-256 test, 3 bytes input");
237 {
238 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
239 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
240 static const uint8_t sha256_out[] = {
241 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
242 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
243 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
244 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
245 };
246 uint8_t out[32] = { 0 };
247
248 op.params[0].tmpref.buffer = (void *)sha256_in;
249 op.params[0].tmpref.size = sizeof(sha256_in);
250 op.params[1].tmpref.buffer = out;
251 op.params[1].tmpref.size = sizeof(out);
252 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
253 TEEC_MEMREF_TEMP_OUTPUT,
254 TEEC_NONE, TEEC_NONE);
255
256 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
257 TEEC_InvokeCommand(cs->session,
258 cs->
259 cmd_id_sha256,
260 &op,
261 &ret_orig));
262
263 if (!ADBG_EXPECT(cs->c, 0, memcmp(sha256_out, out,
264 sizeof(sha256_out)))) {
265 Do_ADBG_Log("sha256_out:");
266 Do_ADBG_HexLog(sha256_out, sizeof(sha256_out), 16);
267 Do_ADBG_Log("out:");
268 Do_ADBG_HexLog(out, sizeof(out), 16);
269 }
270 }
271 Do_ADBG_EndSubCase(cs->c, "SHA-256 test, 3 bytes input");
272
273 Do_ADBG_BeginSubCase(cs->c,
274 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
275 {
276 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
277 static const uint8_t in[] = {
278 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
279 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
280 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
281 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
282 };
283 static const uint8_t exp_out[] = {
284 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
285 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
286 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
287 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
288 };
289 uint8_t out[sizeof(exp_out)];
290
291 op.params[0].tmpref.buffer = (void *)in;
292 op.params[0].tmpref.size = sizeof(in);
293 op.params[1].tmpref.buffer = out;
294 op.params[1].tmpref.size = sizeof(out);
295 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
296 TEEC_MEMREF_TEMP_OUTPUT,
297 TEEC_NONE, TEEC_NONE);
298
299 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
300 TEEC_InvokeCommand(cs->session,
301 cs->
302 cmd_id_aes256ecb_encrypt,
303 &op,
304 &ret_orig));
305
306 if (!ADBG_EXPECT(cs->c, 0,
307 memcmp(exp_out, out, sizeof(exp_out)))) {
308 Do_ADBG_Log("exp_out:");
309 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
310 Do_ADBG_Log("out:");
311 Do_ADBG_HexLog(out, sizeof(out), 16);
312 }
313 }
314 Do_ADBG_EndSubCase(cs->c,
315 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
316
317 Do_ADBG_BeginSubCase(cs->c,
318 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
319 {
320 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
321 static const uint8_t in[] = {
322 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
323 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
324 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
325 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
326 };
327 static const uint8_t exp_out[] = {
328 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
329 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
330 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
331 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
332 };
333 uint8_t out[sizeof(exp_out)];
334
335 op.params[0].tmpref.buffer = (void *)in;
336 op.params[0].tmpref.size = sizeof(in);
337 op.params[1].tmpref.buffer = out;
338 op.params[1].tmpref.size = sizeof(out);
339 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
340 TEEC_MEMREF_TEMP_OUTPUT,
341 TEEC_NONE, TEEC_NONE);
342
343 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
344 TEEC_InvokeCommand(cs->session,
345 cs->
346 cmd_id_aes256ecb_decrypt,
347 &op,
348 &ret_orig));
349
350 if (!ADBG_EXPECT(cs->c, 0,
351 memcmp(exp_out, out, sizeof(exp_out)))) {
352 Do_ADBG_Log("exp_out:");
353 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
354 Do_ADBG_Log("out:");
355 Do_ADBG_HexLog(out, sizeof(out), 16);
356 }
357 }
358 Do_ADBG_EndSubCase(cs->c,
359 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
360}
361
362static void xtest_tee_test_1001(ADBG_Case_t *c)
363{
Jens Wiklandercf16e842016-02-10 09:07:09 +0100364 TEEC_Result res;
365 TEEC_Session session = { 0 };
366 uint32_t ret_orig;
Pascal Brandc639ac82015-07-02 08:53:34 +0200367
Jens Wiklandercf16e842016-02-10 09:07:09 +0100368#define CMD_SELF_TESTS 2
Pascal Brandc639ac82015-07-02 08:53:34 +0200369
Jens Wiklandercf16e842016-02-10 09:07:09 +0100370 res = xtest_teec_open_session(&session, &sta_test_ta_uuid, NULL,
371 &ret_orig);
372 /*
373 * If the static TA (which is optional) isn't available, skip this
374 * test.
375 */
376 if (res != TEEC_SUCCESS)
377 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200378
Jens Wiklandercf16e842016-02-10 09:07:09 +0100379 (void)ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
380 &session, CMD_SELF_TESTS, NULL, &ret_orig));
381 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200382}
383
384static void xtest_tee_test_1004(ADBG_Case_t *c)
385{
386 TEEC_Session session = { 0 };
387 uint32_t ret_orig;
388 struct xtest_crypto_session cs = { c, &session, TA_CRYPT_CMD_SHA256,
389 TA_CRYPT_CMD_AES256ECB_ENC,
390 TA_CRYPT_CMD_AES256ECB_DEC };
391
392 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
393 &session, &crypt_user_ta_uuid,
394 NULL, &ret_orig)))
395 return;
396
397 /* Run the "complete crypto test suite" */
398 xtest_crypto_test(&cs);
399
400 TEEC_CloseSession(&session);
401}
402
403#ifndef TEEC_ERROR_TARGET_DEAD
404/* To be removed when we have TEEC_ERROR_TARGET_DEAD from tee_client_api.h */
405#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024
406#endif
407
408static void xtest_tee_test_invalid_mem_access(ADBG_Case_t *c, uint32_t n)
409{
410 TEEC_Session session = { 0 };
411 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
412 uint32_t ret_orig;
413
414 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
415 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
416 &ret_orig));
417
418 op.params[0].value.a = n;
419 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
420 TEEC_NONE);
421
422 (void)ADBG_EXPECT_TEEC_RESULT(c,
423 TEEC_ERROR_TARGET_DEAD,
424 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
425 &ret_orig));
426
427 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
428 TEEC_InvokeCommand(&session,
429 TA_OS_TEST_CMD_BAD_MEM_ACCESS,
430 &op,
431 &ret_orig));
432 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
433
434 TEEC_CloseSession(&session);
435}
436
437static void xtest_tee_test_1005(ADBG_Case_t *c)
438{
439 uint32_t ret_orig;
440#define MAX_SESSIONS 3
441 TEEC_Session sessions[MAX_SESSIONS];
442 int i;
443
444 for (i = 0; i < MAX_SESSIONS; i++) {
445 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Jens Wiklandereb6bce72016-09-23 11:37:33 +0200446 xtest_teec_open_session(&sessions[i],
447 &concurrent_ta_uuid,
Pascal Brandc639ac82015-07-02 08:53:34 +0200448 NULL, &ret_orig)))
449 break;
450 }
451
452 for (; --i >= 0; )
453 TEEC_CloseSession(&sessions[i]);
454}
455
456static void xtest_tee_test_1006(ADBG_Case_t *c)
457{
458 TEEC_Session session = { 0 };
459 uint32_t ret_orig;
460 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
461 uint8_t buf[32];
462
463 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
464 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
465 &ret_orig)))
466 return;
467
468 op.params[0].tmpref.buffer = buf;
469 op.params[0].tmpref.size = sizeof(buf);
470 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
471 TEEC_NONE, TEEC_NONE);
472
473 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
474 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
475 &ret_orig));
476
477 TEEC_CloseSession(&session);
478}
479
480static void xtest_tee_test_1007(ADBG_Case_t *c)
481{
482 TEEC_Session session = { 0 };
483 uint32_t ret_orig;
484
485 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
486 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
487 &ret_orig));
488
489 (void)ADBG_EXPECT_TEEC_RESULT(c,
490 TEEC_ERROR_TARGET_DEAD,
491 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
492 &ret_orig));
493
494 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
495
496 (void)ADBG_EXPECT_TEEC_RESULT(c,
497 TEEC_ERROR_TARGET_DEAD,
498 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
499 &ret_orig));
500
501 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
502
503 TEEC_CloseSession(&session);
504}
505
Jerome Forissierf02a2212015-10-29 14:33:35 +0100506#ifndef TA_DIR
507#define TA_DIR "/lib/optee_armtz"
508#endif
509
David Brownb2865ab2016-08-02 11:44:41 -0600510#ifndef TA_TEST_DIR
511# ifdef __ANDROID__
512# define TA_TEST_DIR "/data/tmp/optee_armtz"
513# else
514# define TA_TEST_DIR "/tmp/optee_armtz"
515# endif
516#endif
Jens Wiklanderb7940892015-10-23 16:02:40 +0200517
David Brownb2865ab2016-08-02 11:44:41 -0600518static void make_test_ta_dir(void)
519{
520#ifdef __ANDROID__
521 (void)mkdir("/data/tmp", 0755);
522#endif
523 (void)mkdir(TA_TEST_DIR, 0755);
524}
525
526static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
527 bool for_write)
528{
Jens Wiklanderb7940892015-10-23 16:02:40 +0200529 snprintf(buf, blen,
David Brownb2865ab2016-08-02 11:44:41 -0600530 "%s/%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x.ta",
531 for_write ? TA_TEST_DIR : TA_DIR,
532 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
Jens Wiklanderb7940892015-10-23 16:02:40 +0200533 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
534 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
535 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
David Brownb2865ab2016-08-02 11:44:41 -0600536 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200537}
538
David Brownb2865ab2016-08-02 11:44:41 -0600539static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode,
540 bool for_write)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200541{
542 char buf[PATH_MAX];
543
David Brownb2865ab2016-08-02 11:44:41 -0600544 uuid_to_full_name(buf, sizeof(buf), uuid, for_write);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200545 return fopen(buf, mode);
546}
547
David Brownb2865ab2016-08-02 11:44:41 -0600548static bool rm_file(const TEEC_UUID *uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200549{
550 char buf[PATH_MAX];
551
David Brownb2865ab2016-08-02 11:44:41 -0600552 uuid_to_full_name(buf, sizeof(buf), uuid, true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200553 return !unlink(buf);
554}
555
David Brownb2865ab2016-08-02 11:44:41 -0600556static bool copy_file(const TEEC_UUID *src_uuid, const TEEC_UUID *dst_uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200557{
558 char buf[4 * 1024];
David Brownb2865ab2016-08-02 11:44:41 -0600559 FILE *src = open_ta_file(src_uuid, "r", false);
560 FILE *dst = open_ta_file(dst_uuid, "w", true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200561 size_t r;
562 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200563 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200564
Jens Wiklander4441fe22015-10-23 16:53:02 +0200565 if (src && dst) {
566 do {
567 r = fread(buf, 1, sizeof(buf), src);
568 if (!r) {
569 ret = !!feof(src);
570 break;
571 }
572 w = fwrite(buf, 1, r, dst);
573 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200574 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200575
576 if (src)
577 fclose(src);
578 if (dst)
579 fclose(dst);
580 return ret;
581}
582
583static bool corrupt_file(FILE *f, long offs, uint8_t mask)
584{
585 uint8_t b;
586
587 if (fseek(f, offs, SEEK_SET))
588 return false;
589
590 if (fread(&b, 1, 1, f) != 1)
591 return false;
592
593 b ^= mask;
594
595 if (fseek(f, offs, SEEK_SET))
596 return false;
597
598 if (fwrite(&b, 1, 1, f) != 1)
599 return false;
600
601 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200602}
603
604static void load_fake_ta(ADBG_Case_t *c)
605{
606 static const TEEC_UUID fake_uuid = {
607 0x7e0a0900, 0x586b, 0x11e5,
608 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
609 };
610 TEEC_Session session = { 0 };
611 TEEC_Result res;
612 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200613 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200614
David Brownb2865ab2016-08-02 11:44:41 -0600615 r = copy_file(&create_fail_test_ta_uuid, &fake_uuid);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200616
617 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200618 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
619 &ret_orig);
620 if (res == TEEC_SUCCESS)
621 TEEC_CloseSession(&session);
622 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200623 }
624
David Brownb2865ab2016-08-02 11:44:41 -0600625 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid));
Jens Wiklanderb7940892015-10-23 16:02:40 +0200626}
627
Jens Wiklander4441fe22015-10-23 16:53:02 +0200628static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
629{
630 TEEC_Session session = { 0 };
631 TEEC_Result res;
632 uint32_t ret_orig;
633 FILE *f;
634 bool r;
635
David Brownb2865ab2016-08-02 11:44:41 -0600636 r = copy_file(&create_fail_test_ta_uuid, &create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200637 if (!ADBG_EXPECT_TRUE(c, r)) {
David Brownb2865ab2016-08-02 11:44:41 -0600638 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200639 return false;
640 }
641
David Brownb2865ab2016-08-02 11:44:41 -0600642 f = open_ta_file(&create_fail_test_ta_uuid, "r+", true);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200643 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
David Brownb2865ab2016-08-02 11:44:41 -0600644 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200645 return false;
646 }
647 r = corrupt_file(f, offs, mask);
648 fclose(f);
649
650 if (ADBG_EXPECT_TRUE(c, r)) {
651 res = xtest_teec_open_session(&session,
652 &create_fail_test_ta_uuid,
653 NULL, &ret_orig);
654 if (res == TEEC_SUCCESS)
655 TEEC_CloseSession(&session);
656 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
657 }
658
David Brownb2865ab2016-08-02 11:44:41 -0600659 r &= ADBG_EXPECT_TRUE(c, rm_file(&create_fail_test_ta_uuid));
Jens Wiklander4441fe22015-10-23 16:53:02 +0200660 return r;
661}
662
Pascal Brandc639ac82015-07-02 08:53:34 +0200663static void xtest_tee_test_1008(ADBG_Case_t *c)
664{
665 TEEC_Session session = { 0 };
666 TEEC_Session session_crypt = { 0 };
667 uint32_t ret_orig;
668
669 Do_ADBG_BeginSubCase(c, "Invoke command");
670 {
671 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200672 xtest_teec_open_session(&session, &os_test_ta_uuid,
673 NULL, &ret_orig));
674
675 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
676 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
677 NULL, &ret_orig));
678
679 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200680 }
681 Do_ADBG_EndSubCase(c, "Invoke command");
682
683 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
684 {
685 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
686
687 op.params[0].value.a = 2000;
688 op.paramTypes = TEEC_PARAM_TYPES(
689 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
690
691 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
692 xtest_teec_open_session(&session,
693 &os_test_ta_uuid,
694 NULL,
695 &ret_orig));
696
697 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
698 TEEC_InvokeCommand(&session,
699 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
700 &op, &ret_orig));
701
702 TEEC_CloseSession(&session);
703 }
704 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
705
706 Do_ADBG_BeginSubCase(c, "Create session fail");
707 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200708 size_t n;
709
Pascal Brandc639ac82015-07-02 08:53:34 +0200710 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
711 xtest_teec_open_session(&session_crypt,
712 &create_fail_test_ta_uuid, NULL,
713 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200714 /*
715 * Run this several times to see that there's no memory leakage.
716 */
717 for (n = 0; n < 100; n++) {
718 Do_ADBG_Log("n = %zu", n);
719 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
720 xtest_teec_open_session(&session_crypt,
721 &create_fail_test_ta_uuid,
722 NULL, &ret_orig));
723 }
724 }
725 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200726
David Brownb2865ab2016-08-02 11:44:41 -0600727 make_test_ta_dir();
728
Jens Wiklanderb7940892015-10-23 16:02:40 +0200729 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
730 load_fake_ta(c);
731 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
732
Jens Wiklander4441fe22015-10-23 16:53:02 +0200733 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
734 ADBG_EXPECT_TRUE(c,
735 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
736 ADBG_EXPECT_TRUE(c,
737 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
738 ADBG_EXPECT_TRUE(c,
739 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
740 ADBG_EXPECT_TRUE(c,
741 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
742 ADBG_EXPECT_TRUE(c,
743 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
744 ADBG_EXPECT_TRUE(c,
745 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
746 ADBG_EXPECT_TRUE(c,
747 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
748 ADBG_EXPECT_TRUE(c,
749 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
750 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
751 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
752 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200753}
754
755#ifdef USER_SPACE
756static void *cancellation_thread(void *arg)
757{
758 /*
759 * Sleep 0.5 seconds before cancellation to make sure that the other
760 * thread is in RPC_WAIT.
761 */
762 (void)usleep(500000);
763 TEEC_RequestCancellation(arg);
764 return NULL;
765}
766#endif
767
768static void xtest_tee_test_1009(ADBG_Case_t *c)
769{
770 TEEC_Session session = { 0 };
771 uint32_t ret_orig;
772
773 Do_ADBG_BeginSubCase(c, "TEE Wait 0.1s");
774 {
775 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
776
777 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
778 xtest_teec_open_session(&session, &os_test_ta_uuid,
779 NULL, &ret_orig));
780
781 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
782 ret_orig);
783
784 op.params[0].value.a = 100;
785 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
786 TEEC_NONE, TEEC_NONE);
787
788 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
789 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
790 &ret_orig));
791 TEEC_CloseSession(&session);
792 }
793 Do_ADBG_EndSubCase(c, "TEE Wait 0.1s");
794
795 Do_ADBG_BeginSubCase(c, "TEE Wait 0.5s");
796 {
797 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
798
799 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
800 xtest_teec_open_session(&session, &os_test_ta_uuid,
801 NULL, &ret_orig));
802
803 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
804 ret_orig);
805
806 op.params[0].value.a = 500;
807 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
808 TEEC_NONE, TEEC_NONE);
809
810 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
811 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
812 &ret_orig));
813
814 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
815 ret_orig);
816 TEEC_CloseSession(&session);
817 }
818 Do_ADBG_EndSubCase(c, "TEE Wait 0.5s");
819
820#ifdef USER_SPACE
821 Do_ADBG_BeginSubCase(c, "TEE Wait 2s cancel");
822 {
823 pthread_t thr;
824 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
825
826 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
827 xtest_teec_open_session(&session, &os_test_ta_uuid,
828 NULL, &ret_orig));
829
830 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
831 ret_orig);
832
833 op.params[0].value.a = 2000;
834 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
835 TEEC_NONE, TEEC_NONE);
836
837 (void)ADBG_EXPECT(c, 0,
838 pthread_create(&thr, NULL, cancellation_thread, &op));
839
840 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_CANCEL,
841 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
842 &ret_orig));
843
844 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
845 ret_orig);
846 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
847 TEEC_CloseSession(&session);
848 }
849 Do_ADBG_EndSubCase(c, "TEE Wait 2s cancel");
850#endif
851
852 Do_ADBG_BeginSubCase(c, "TEE Wait 2s");
853 {
854 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
855
856 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
857 xtest_teec_open_session(&session, &os_test_ta_uuid,
858 NULL, &ret_orig));
859
860 op.params[0].value.a = 2000;
861 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
862 TEEC_NONE, TEEC_NONE);
863
864 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
865 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
866 &ret_orig));
867
868 TEEC_CloseSession(&session);
869 }
870 Do_ADBG_EndSubCase(c, "TEE Wait 2s");
871}
872
873static void xtest_tee_test_1010(ADBG_Case_t *c)
874{
875 unsigned n;
876
877 for (n = 1; n <= 5; n++) {
878 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
879 xtest_tee_test_invalid_mem_access(c, n);
880 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
881 }
882}
883
884static void xtest_tee_test_1011(ADBG_Case_t *c)
885{
886 TEEC_Session session = { 0 };
887 uint32_t ret_orig;
888 struct xtest_crypto_session cs = {
889 c, &session, TA_RPC_CMD_CRYPT_SHA256,
890 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
891 TA_RPC_CMD_CRYPT_AES256ECB_DEC
892 };
893 TEEC_UUID uuid = rpc_test_ta_uuid;
894
895 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
896 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
897 return;
898
899 /*
900 * Run the "complete crypto test suite" using RPC
901 */
902 xtest_crypto_test(&cs);
903 TEEC_CloseSession(&session);
904}
905
906/*
907 * Note that this test is failing when
908 * - running twice in a raw
909 * - and the user TA is statically linked
910 * This is because the counter is not reseted when opening the first session
911 * in case the TA is statically linked
912 */
913static void xtest_tee_test_1012(ADBG_Case_t *c)
914{
915 TEEC_Session session1 = { 0 };
916 TEEC_Session session2 = { 0 };
917 uint32_t ret_orig;
918 TEEC_UUID uuid = sims_test_ta_uuid;
919
920 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
921 {
922 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
923 static const uint8_t in[] = {
924 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
925 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
926 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
927 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
928 };
929 uint8_t out[32] = { 0 };
930 int i;
931
932 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
933 xtest_teec_open_session(&session1, &uuid, NULL,
934 &ret_orig));
935
936 op.params[0].value.a = 0;
937 op.params[1].tmpref.buffer = (void *)in;
938 op.params[1].tmpref.size = sizeof(in);
939 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
940 TEEC_MEMREF_TEMP_INPUT,
941 TEEC_NONE, TEEC_NONE);
942
943 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
944 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
945 &ret_orig));
946
947 for (i = 1; i < 1000; i++) {
948 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
949 xtest_teec_open_session(&session2, &uuid, NULL,
950 &ret_orig));
951
952 op.params[0].value.a = 0;
953 op.params[1].tmpref.buffer = out;
954 op.params[1].tmpref.size = sizeof(out);
955 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
956 TEEC_MEMREF_TEMP_OUTPUT,
957 TEEC_NONE, TEEC_NONE);
958
959 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
960 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
961 &op, &ret_orig));
962
963 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
964 sizeof(out))) {
965 Do_ADBG_Log("in:");
966 Do_ADBG_HexLog(in, sizeof(in), 16);
967 Do_ADBG_Log("out:");
968 Do_ADBG_HexLog(out, sizeof(out), 16);
969 }
970
971 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
972 TEEC_NONE, TEEC_NONE,
973 TEEC_NONE);
974
975 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
976 TEEC_InvokeCommand(&session1,
977 TA_SIMS_CMD_GET_COUNTER,
978 &op, &ret_orig));
979
980 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
981
982 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
983 TEEC_InvokeCommand(&session2,
984 TA_SIMS_CMD_GET_COUNTER, &op,
985 &ret_orig));
986
987 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
988 TEEC_CloseSession(&session2);
989 }
990
991 memset(out, 0, sizeof(out));
992 op.params[0].value.a = 0;
993 op.params[1].tmpref.buffer = out;
994 op.params[1].tmpref.size = sizeof(out);
995 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
996 TEEC_MEMREF_TEMP_OUTPUT,
997 TEEC_NONE, TEEC_NONE);
998
999 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1000 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
1001 &ret_orig));
1002
1003 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
1004 Do_ADBG_Log("in:");
1005 Do_ADBG_HexLog(in, sizeof(in), 16);
1006 Do_ADBG_Log("out:");
1007 Do_ADBG_HexLog(out, sizeof(out), 16);
1008 }
1009
1010 TEEC_CloseSession(&session1);
1011 }
1012}
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001013
1014struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +02001015 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001016 uint32_t cmd;
1017 uint32_t repeat;
1018 TEEC_SharedMemory *shm;
1019 uint32_t error_orig;
1020 TEEC_Result res;
1021 uint32_t max_concurrency;
1022 const uint8_t *in;
1023 size_t in_len;
1024 uint8_t *out;
1025 size_t out_len;
1026};
1027
1028static void *test_1013_thread(void *arg)
1029{
1030 struct test_1013_thread_arg *a = arg;
1031 TEEC_Session session = { 0 };
1032 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1033 uint8_t p2 = TEEC_NONE;
1034 uint8_t p3 = TEEC_NONE;
1035
Jens Wiklander70672972016-04-06 00:01:45 +02001036 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001037 &a->error_orig);
1038 if (a->res != TEEC_SUCCESS)
1039 return NULL;
1040
1041 op.params[0].memref.parent = a->shm;
1042 op.params[0].memref.size = a->shm->size;
1043 op.params[0].memref.offset = 0;
1044 op.params[1].value.a = a->repeat;
1045 op.params[1].value.b = 0;
1046 op.params[2].tmpref.buffer = (void *)a->in;
1047 op.params[2].tmpref.size = a->in_len;
1048 op.params[3].tmpref.buffer = a->out;
1049 op.params[3].tmpref.size = a->out_len;
1050
1051 if (a->in_len)
1052 p2 = TEEC_MEMREF_TEMP_INPUT;
1053 if (a->out_len)
1054 p3 = TEEC_MEMREF_TEMP_OUTPUT;
1055
1056 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
1057 TEEC_VALUE_INOUT, p2, p3);
1058
1059 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
1060 a->max_concurrency = op.params[1].value.b;
1061 a->out_len = op.params[3].tmpref.size;
1062 TEEC_CloseSession(&session);
1063 return NULL;
1064}
1065
Pascal Brand4fa35582015-12-17 10:59:12 +01001066#define NUM_THREADS 3
1067
Jens Wiklander70672972016-04-06 00:01:45 +02001068static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
1069 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001070{
Pascal Brand4fa35582015-12-17 10:59:12 +01001071 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001072 size_t nt;
1073 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +02001074 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001075 pthread_t thr[num_threads];
1076 TEEC_SharedMemory shm;
1077 size_t max_concurrency;
1078 struct test_1013_thread_arg arg[num_threads];
1079 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
1080 static const uint8_t sha256_out[] = {
1081 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
1082 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
1083 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
1084 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
1085 };
1086 uint8_t out[32] = { 0 };
1087
Jens Wiklander70672972016-04-06 00:01:45 +02001088 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +01001089 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001090
1091 memset(&shm, 0, sizeof(shm));
1092 shm.size = sizeof(struct ta_concurrent_shm);
1093 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1094 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1095 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
1096 return;
1097
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001098 memset(shm.buffer, 0, shm.size);
1099 memset(arg, 0, sizeof(arg));
1100 max_concurrency = 0;
1101 nt = num_threads;
1102
1103 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001104 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001105 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +02001106 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001107 arg[n].shm = &shm;
1108 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1109 test_1013_thread, arg + n)))
1110 nt = n; /* break loop and start cleanup */
1111 }
1112
1113 for (n = 0; n < nt; n++) {
1114 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
1115 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
1116 if (arg[n].max_concurrency > max_concurrency)
1117 max_concurrency = arg[n].max_concurrency;
1118 }
1119
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001120 /*
1121 * Concurrency can be limited by several factors, for instance in a
1122 * single CPU system it's dependent on the Preemtion Model used by
1123 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
1124 * best result there).
1125 */
1126 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
1127 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +01001128 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001129 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001130
Jens Wiklander70672972016-04-06 00:01:45 +02001131 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001132 memset(shm.buffer, 0, shm.size);
1133 memset(arg, 0, sizeof(arg));
1134 max_concurrency = 0;
1135 nt = num_threads;
1136
1137 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001138 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001139 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +02001140 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001141 arg[n].shm = &shm;
1142 arg[n].in = sha256_in;
1143 arg[n].in_len = sizeof(sha256_in);
1144 arg[n].out = out;
1145 arg[n].out_len = sizeof(out);
1146 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1147 test_1013_thread, arg + n)))
1148 nt = n; /* break loop and start cleanup */
1149 }
1150
1151 for (n = 0; n < nt; n++) {
1152 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1153 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1154 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1155 arg[n].out, arg[n].out_len);
1156 if (arg[n].max_concurrency > max_concurrency)
1157 max_concurrency = arg[n].max_concurrency;
1158 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001159 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001160 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001161
Pascal Brand4fa35582015-12-17 10:59:12 +01001162 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001163 TEEC_ReleaseSharedMemory(&shm);
1164}
Pascal Brand4fa35582015-12-17 10:59:12 +01001165
1166static void xtest_tee_test_1013(ADBG_Case_t *c)
1167{
1168 int i;
1169 double mean_concurrency;
1170 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001171 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001172
1173 if (level == 0)
1174 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001175
Jens Wiklander70672972016-04-06 00:01:45 +02001176 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001177 mean_concurrency = 0;
1178 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001179 xtest_tee_test_1013_single(c, &concurrency,
1180 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001181 mean_concurrency += concurrency;
1182 }
1183 mean_concurrency /= nb_loops;
1184
1185 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1186 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001187 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001188
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001189#ifndef CFG_PAGED_USER_TA
Jens Wiklander70672972016-04-06 00:01:45 +02001190 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1191 mean_concurrency = 0;
1192 for (i = 0; i < nb_loops; i++) {
1193 xtest_tee_test_1013_single(c, &concurrency,
1194 &concurrent_large_ta_uuid);
1195 mean_concurrency += concurrency;
1196 }
1197 mean_concurrency /= nb_loops;
1198
1199 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1200 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1201 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001202#endif
Jens Wiklander70672972016-04-06 00:01:45 +02001203}