blob: 9840a045e281d6e31279c7ccc396eb3dad073b7a [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,
446 xtest_teec_open_session(&sessions[i], &os_test_ta_uuid,
447 NULL, &ret_orig)))
448 break;
449 }
450
451 for (; --i >= 0; )
452 TEEC_CloseSession(&sessions[i]);
453}
454
455static void xtest_tee_test_1006(ADBG_Case_t *c)
456{
457 TEEC_Session session = { 0 };
458 uint32_t ret_orig;
459 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
460 uint8_t buf[32];
461
462 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
463 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
464 &ret_orig)))
465 return;
466
467 op.params[0].tmpref.buffer = buf;
468 op.params[0].tmpref.size = sizeof(buf);
469 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
470 TEEC_NONE, TEEC_NONE);
471
472 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
473 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
474 &ret_orig));
475
476 TEEC_CloseSession(&session);
477}
478
479static void xtest_tee_test_1007(ADBG_Case_t *c)
480{
481 TEEC_Session session = { 0 };
482 uint32_t ret_orig;
483
484 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
485 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
486 &ret_orig));
487
488 (void)ADBG_EXPECT_TEEC_RESULT(c,
489 TEEC_ERROR_TARGET_DEAD,
490 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
491 &ret_orig));
492
493 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
494
495 (void)ADBG_EXPECT_TEEC_RESULT(c,
496 TEEC_ERROR_TARGET_DEAD,
497 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
498 &ret_orig));
499
500 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
501
502 TEEC_CloseSession(&session);
503}
504
Jerome Forissierf02a2212015-10-29 14:33:35 +0100505#ifndef TA_DIR
506#define TA_DIR "/lib/optee_armtz"
507#endif
508
David Brownb2865ab2016-08-02 11:44:41 -0600509#ifndef TA_TEST_DIR
510# ifdef __ANDROID__
511# define TA_TEST_DIR "/data/tmp/optee_armtz"
512# else
513# define TA_TEST_DIR "/tmp/optee_armtz"
514# endif
515#endif
Jens Wiklanderb7940892015-10-23 16:02:40 +0200516
David Brownb2865ab2016-08-02 11:44:41 -0600517static void make_test_ta_dir(void)
518{
519#ifdef __ANDROID__
520 (void)mkdir("/data/tmp", 0755);
521#endif
522 (void)mkdir(TA_TEST_DIR, 0755);
523}
524
525static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
526 bool for_write)
527{
Jens Wiklanderb7940892015-10-23 16:02:40 +0200528 snprintf(buf, blen,
David Brownb2865ab2016-08-02 11:44:41 -0600529 "%s/%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x.ta",
530 for_write ? TA_TEST_DIR : TA_DIR,
531 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
Jens Wiklanderb7940892015-10-23 16:02:40 +0200532 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
533 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
534 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
David Brownb2865ab2016-08-02 11:44:41 -0600535 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200536}
537
David Brownb2865ab2016-08-02 11:44:41 -0600538static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode,
539 bool for_write)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200540{
541 char buf[PATH_MAX];
542
David Brownb2865ab2016-08-02 11:44:41 -0600543 uuid_to_full_name(buf, sizeof(buf), uuid, for_write);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200544 return fopen(buf, mode);
545}
546
David Brownb2865ab2016-08-02 11:44:41 -0600547static bool rm_file(const TEEC_UUID *uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200548{
549 char buf[PATH_MAX];
550
David Brownb2865ab2016-08-02 11:44:41 -0600551 uuid_to_full_name(buf, sizeof(buf), uuid, true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200552 return !unlink(buf);
553}
554
David Brownb2865ab2016-08-02 11:44:41 -0600555static bool copy_file(const TEEC_UUID *src_uuid, const TEEC_UUID *dst_uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200556{
557 char buf[4 * 1024];
David Brownb2865ab2016-08-02 11:44:41 -0600558 FILE *src = open_ta_file(src_uuid, "r", false);
559 FILE *dst = open_ta_file(dst_uuid, "w", true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200560 size_t r;
561 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200562 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200563
Jens Wiklander4441fe22015-10-23 16:53:02 +0200564 if (src && dst) {
565 do {
566 r = fread(buf, 1, sizeof(buf), src);
567 if (!r) {
568 ret = !!feof(src);
569 break;
570 }
571 w = fwrite(buf, 1, r, dst);
572 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200573 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200574
575 if (src)
576 fclose(src);
577 if (dst)
578 fclose(dst);
579 return ret;
580}
581
582static bool corrupt_file(FILE *f, long offs, uint8_t mask)
583{
584 uint8_t b;
585
586 if (fseek(f, offs, SEEK_SET))
587 return false;
588
589 if (fread(&b, 1, 1, f) != 1)
590 return false;
591
592 b ^= mask;
593
594 if (fseek(f, offs, SEEK_SET))
595 return false;
596
597 if (fwrite(&b, 1, 1, f) != 1)
598 return false;
599
600 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200601}
602
603static void load_fake_ta(ADBG_Case_t *c)
604{
605 static const TEEC_UUID fake_uuid = {
606 0x7e0a0900, 0x586b, 0x11e5,
607 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
608 };
609 TEEC_Session session = { 0 };
610 TEEC_Result res;
611 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200612 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200613
David Brownb2865ab2016-08-02 11:44:41 -0600614 r = copy_file(&create_fail_test_ta_uuid, &fake_uuid);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200615
616 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200617 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
618 &ret_orig);
619 if (res == TEEC_SUCCESS)
620 TEEC_CloseSession(&session);
621 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200622 }
623
David Brownb2865ab2016-08-02 11:44:41 -0600624 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid));
Jens Wiklanderb7940892015-10-23 16:02:40 +0200625}
626
Jens Wiklander4441fe22015-10-23 16:53:02 +0200627static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
628{
629 TEEC_Session session = { 0 };
630 TEEC_Result res;
631 uint32_t ret_orig;
632 FILE *f;
633 bool r;
634
David Brownb2865ab2016-08-02 11:44:41 -0600635 r = copy_file(&create_fail_test_ta_uuid, &create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200636 if (!ADBG_EXPECT_TRUE(c, r)) {
David Brownb2865ab2016-08-02 11:44:41 -0600637 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200638 return false;
639 }
640
David Brownb2865ab2016-08-02 11:44:41 -0600641 f = open_ta_file(&create_fail_test_ta_uuid, "r+", true);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200642 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
David Brownb2865ab2016-08-02 11:44:41 -0600643 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200644 return false;
645 }
646 r = corrupt_file(f, offs, mask);
647 fclose(f);
648
649 if (ADBG_EXPECT_TRUE(c, r)) {
650 res = xtest_teec_open_session(&session,
651 &create_fail_test_ta_uuid,
652 NULL, &ret_orig);
653 if (res == TEEC_SUCCESS)
654 TEEC_CloseSession(&session);
655 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
656 }
657
David Brownb2865ab2016-08-02 11:44:41 -0600658 r &= ADBG_EXPECT_TRUE(c, rm_file(&create_fail_test_ta_uuid));
Jens Wiklander4441fe22015-10-23 16:53:02 +0200659 return r;
660}
661
Pascal Brandc639ac82015-07-02 08:53:34 +0200662static void xtest_tee_test_1008(ADBG_Case_t *c)
663{
664 TEEC_Session session = { 0 };
665 TEEC_Session session_crypt = { 0 };
666 uint32_t ret_orig;
667
668 Do_ADBG_BeginSubCase(c, "Invoke command");
669 {
670 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200671 xtest_teec_open_session(&session, &os_test_ta_uuid,
672 NULL, &ret_orig));
673
674 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
675 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
676 NULL, &ret_orig));
677
678 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200679 }
680 Do_ADBG_EndSubCase(c, "Invoke command");
681
682 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
683 {
684 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
685
686 op.params[0].value.a = 2000;
687 op.paramTypes = TEEC_PARAM_TYPES(
688 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
689
690 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
691 xtest_teec_open_session(&session,
692 &os_test_ta_uuid,
693 NULL,
694 &ret_orig));
695
696 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
697 TEEC_InvokeCommand(&session,
698 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
699 &op, &ret_orig));
700
701 TEEC_CloseSession(&session);
702 }
703 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
704
705 Do_ADBG_BeginSubCase(c, "Create session fail");
706 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200707 size_t n;
708
Pascal Brandc639ac82015-07-02 08:53:34 +0200709 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
710 xtest_teec_open_session(&session_crypt,
711 &create_fail_test_ta_uuid, NULL,
712 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200713 /*
714 * Run this several times to see that there's no memory leakage.
715 */
716 for (n = 0; n < 100; n++) {
717 Do_ADBG_Log("n = %zu", n);
718 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
719 xtest_teec_open_session(&session_crypt,
720 &create_fail_test_ta_uuid,
721 NULL, &ret_orig));
722 }
723 }
724 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200725
David Brownb2865ab2016-08-02 11:44:41 -0600726 make_test_ta_dir();
727
Jens Wiklanderb7940892015-10-23 16:02:40 +0200728 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
729 load_fake_ta(c);
730 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
731
Jens Wiklander4441fe22015-10-23 16:53:02 +0200732 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
733 ADBG_EXPECT_TRUE(c,
734 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
735 ADBG_EXPECT_TRUE(c,
736 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
737 ADBG_EXPECT_TRUE(c,
738 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
739 ADBG_EXPECT_TRUE(c,
740 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
741 ADBG_EXPECT_TRUE(c,
742 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
743 ADBG_EXPECT_TRUE(c,
744 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
745 ADBG_EXPECT_TRUE(c,
746 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
747 ADBG_EXPECT_TRUE(c,
748 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
749 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
750 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
751 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200752}
753
754#ifdef USER_SPACE
755static void *cancellation_thread(void *arg)
756{
757 /*
758 * Sleep 0.5 seconds before cancellation to make sure that the other
759 * thread is in RPC_WAIT.
760 */
761 (void)usleep(500000);
762 TEEC_RequestCancellation(arg);
763 return NULL;
764}
765#endif
766
767static void xtest_tee_test_1009(ADBG_Case_t *c)
768{
769 TEEC_Session session = { 0 };
770 uint32_t ret_orig;
771
772 Do_ADBG_BeginSubCase(c, "TEE Wait 0.1s");
773 {
774 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
775
776 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
777 xtest_teec_open_session(&session, &os_test_ta_uuid,
778 NULL, &ret_orig));
779
780 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
781 ret_orig);
782
783 op.params[0].value.a = 100;
784 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
785 TEEC_NONE, TEEC_NONE);
786
787 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
788 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
789 &ret_orig));
790 TEEC_CloseSession(&session);
791 }
792 Do_ADBG_EndSubCase(c, "TEE Wait 0.1s");
793
794 Do_ADBG_BeginSubCase(c, "TEE Wait 0.5s");
795 {
796 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
797
798 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
799 xtest_teec_open_session(&session, &os_test_ta_uuid,
800 NULL, &ret_orig));
801
802 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
803 ret_orig);
804
805 op.params[0].value.a = 500;
806 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
807 TEEC_NONE, TEEC_NONE);
808
809 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
810 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
811 &ret_orig));
812
813 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
814 ret_orig);
815 TEEC_CloseSession(&session);
816 }
817 Do_ADBG_EndSubCase(c, "TEE Wait 0.5s");
818
819#ifdef USER_SPACE
820 Do_ADBG_BeginSubCase(c, "TEE Wait 2s cancel");
821 {
822 pthread_t thr;
823 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
824
825 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
826 xtest_teec_open_session(&session, &os_test_ta_uuid,
827 NULL, &ret_orig));
828
829 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
830 ret_orig);
831
832 op.params[0].value.a = 2000;
833 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
834 TEEC_NONE, TEEC_NONE);
835
836 (void)ADBG_EXPECT(c, 0,
837 pthread_create(&thr, NULL, cancellation_thread, &op));
838
839 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_CANCEL,
840 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
841 &ret_orig));
842
843 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
844 ret_orig);
845 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
846 TEEC_CloseSession(&session);
847 }
848 Do_ADBG_EndSubCase(c, "TEE Wait 2s cancel");
849#endif
850
851 Do_ADBG_BeginSubCase(c, "TEE Wait 2s");
852 {
853 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
854
855 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
856 xtest_teec_open_session(&session, &os_test_ta_uuid,
857 NULL, &ret_orig));
858
859 op.params[0].value.a = 2000;
860 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
861 TEEC_NONE, TEEC_NONE);
862
863 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
864 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_WAIT, &op,
865 &ret_orig));
866
867 TEEC_CloseSession(&session);
868 }
869 Do_ADBG_EndSubCase(c, "TEE Wait 2s");
870}
871
872static void xtest_tee_test_1010(ADBG_Case_t *c)
873{
874 unsigned n;
875
876 for (n = 1; n <= 5; n++) {
877 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
878 xtest_tee_test_invalid_mem_access(c, n);
879 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
880 }
881}
882
883static void xtest_tee_test_1011(ADBG_Case_t *c)
884{
885 TEEC_Session session = { 0 };
886 uint32_t ret_orig;
887 struct xtest_crypto_session cs = {
888 c, &session, TA_RPC_CMD_CRYPT_SHA256,
889 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
890 TA_RPC_CMD_CRYPT_AES256ECB_DEC
891 };
892 TEEC_UUID uuid = rpc_test_ta_uuid;
893
894 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
895 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
896 return;
897
898 /*
899 * Run the "complete crypto test suite" using RPC
900 */
901 xtest_crypto_test(&cs);
902 TEEC_CloseSession(&session);
903}
904
905/*
906 * Note that this test is failing when
907 * - running twice in a raw
908 * - and the user TA is statically linked
909 * This is because the counter is not reseted when opening the first session
910 * in case the TA is statically linked
911 */
912static void xtest_tee_test_1012(ADBG_Case_t *c)
913{
914 TEEC_Session session1 = { 0 };
915 TEEC_Session session2 = { 0 };
916 uint32_t ret_orig;
917 TEEC_UUID uuid = sims_test_ta_uuid;
918
919 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
920 {
921 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
922 static const uint8_t in[] = {
923 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
924 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
925 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
926 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
927 };
928 uint8_t out[32] = { 0 };
929 int i;
930
931 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
932 xtest_teec_open_session(&session1, &uuid, NULL,
933 &ret_orig));
934
935 op.params[0].value.a = 0;
936 op.params[1].tmpref.buffer = (void *)in;
937 op.params[1].tmpref.size = sizeof(in);
938 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
939 TEEC_MEMREF_TEMP_INPUT,
940 TEEC_NONE, TEEC_NONE);
941
942 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
943 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
944 &ret_orig));
945
946 for (i = 1; i < 1000; i++) {
947 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
948 xtest_teec_open_session(&session2, &uuid, NULL,
949 &ret_orig));
950
951 op.params[0].value.a = 0;
952 op.params[1].tmpref.buffer = out;
953 op.params[1].tmpref.size = sizeof(out);
954 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
955 TEEC_MEMREF_TEMP_OUTPUT,
956 TEEC_NONE, TEEC_NONE);
957
958 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
959 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
960 &op, &ret_orig));
961
962 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
963 sizeof(out))) {
964 Do_ADBG_Log("in:");
965 Do_ADBG_HexLog(in, sizeof(in), 16);
966 Do_ADBG_Log("out:");
967 Do_ADBG_HexLog(out, sizeof(out), 16);
968 }
969
970 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
971 TEEC_NONE, TEEC_NONE,
972 TEEC_NONE);
973
974 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
975 TEEC_InvokeCommand(&session1,
976 TA_SIMS_CMD_GET_COUNTER,
977 &op, &ret_orig));
978
979 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
980
981 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
982 TEEC_InvokeCommand(&session2,
983 TA_SIMS_CMD_GET_COUNTER, &op,
984 &ret_orig));
985
986 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
987 TEEC_CloseSession(&session2);
988 }
989
990 memset(out, 0, sizeof(out));
991 op.params[0].value.a = 0;
992 op.params[1].tmpref.buffer = out;
993 op.params[1].tmpref.size = sizeof(out);
994 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
995 TEEC_MEMREF_TEMP_OUTPUT,
996 TEEC_NONE, TEEC_NONE);
997
998 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
999 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
1000 &ret_orig));
1001
1002 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
1003 Do_ADBG_Log("in:");
1004 Do_ADBG_HexLog(in, sizeof(in), 16);
1005 Do_ADBG_Log("out:");
1006 Do_ADBG_HexLog(out, sizeof(out), 16);
1007 }
1008
1009 TEEC_CloseSession(&session1);
1010 }
1011}
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001012
1013struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +02001014 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001015 uint32_t cmd;
1016 uint32_t repeat;
1017 TEEC_SharedMemory *shm;
1018 uint32_t error_orig;
1019 TEEC_Result res;
1020 uint32_t max_concurrency;
1021 const uint8_t *in;
1022 size_t in_len;
1023 uint8_t *out;
1024 size_t out_len;
1025};
1026
1027static void *test_1013_thread(void *arg)
1028{
1029 struct test_1013_thread_arg *a = arg;
1030 TEEC_Session session = { 0 };
1031 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1032 uint8_t p2 = TEEC_NONE;
1033 uint8_t p3 = TEEC_NONE;
1034
Jens Wiklander70672972016-04-06 00:01:45 +02001035 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001036 &a->error_orig);
1037 if (a->res != TEEC_SUCCESS)
1038 return NULL;
1039
1040 op.params[0].memref.parent = a->shm;
1041 op.params[0].memref.size = a->shm->size;
1042 op.params[0].memref.offset = 0;
1043 op.params[1].value.a = a->repeat;
1044 op.params[1].value.b = 0;
1045 op.params[2].tmpref.buffer = (void *)a->in;
1046 op.params[2].tmpref.size = a->in_len;
1047 op.params[3].tmpref.buffer = a->out;
1048 op.params[3].tmpref.size = a->out_len;
1049
1050 if (a->in_len)
1051 p2 = TEEC_MEMREF_TEMP_INPUT;
1052 if (a->out_len)
1053 p3 = TEEC_MEMREF_TEMP_OUTPUT;
1054
1055 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
1056 TEEC_VALUE_INOUT, p2, p3);
1057
1058 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
1059 a->max_concurrency = op.params[1].value.b;
1060 a->out_len = op.params[3].tmpref.size;
1061 TEEC_CloseSession(&session);
1062 return NULL;
1063}
1064
Pascal Brand4fa35582015-12-17 10:59:12 +01001065#define NUM_THREADS 3
1066
Jens Wiklander70672972016-04-06 00:01:45 +02001067static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
1068 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001069{
Pascal Brand4fa35582015-12-17 10:59:12 +01001070 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001071 size_t nt;
1072 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +02001073 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001074 pthread_t thr[num_threads];
1075 TEEC_SharedMemory shm;
1076 size_t max_concurrency;
1077 struct test_1013_thread_arg arg[num_threads];
1078 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
1079 static const uint8_t sha256_out[] = {
1080 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
1081 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
1082 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
1083 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
1084 };
1085 uint8_t out[32] = { 0 };
1086
Jens Wiklander70672972016-04-06 00:01:45 +02001087 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +01001088 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001089
1090 memset(&shm, 0, sizeof(shm));
1091 shm.size = sizeof(struct ta_concurrent_shm);
1092 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1093 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1094 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
1095 return;
1096
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001097 memset(shm.buffer, 0, shm.size);
1098 memset(arg, 0, sizeof(arg));
1099 max_concurrency = 0;
1100 nt = num_threads;
1101
1102 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001103 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001104 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +02001105 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001106 arg[n].shm = &shm;
1107 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1108 test_1013_thread, arg + n)))
1109 nt = n; /* break loop and start cleanup */
1110 }
1111
1112 for (n = 0; n < nt; n++) {
1113 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
1114 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
1115 if (arg[n].max_concurrency > max_concurrency)
1116 max_concurrency = arg[n].max_concurrency;
1117 }
1118
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001119 /*
1120 * Concurrency can be limited by several factors, for instance in a
1121 * single CPU system it's dependent on the Preemtion Model used by
1122 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
1123 * best result there).
1124 */
1125 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
1126 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +01001127 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001128 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001129
Jens Wiklander70672972016-04-06 00:01:45 +02001130 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001131 memset(shm.buffer, 0, shm.size);
1132 memset(arg, 0, sizeof(arg));
1133 max_concurrency = 0;
1134 nt = num_threads;
1135
1136 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001137 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001138 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +02001139 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001140 arg[n].shm = &shm;
1141 arg[n].in = sha256_in;
1142 arg[n].in_len = sizeof(sha256_in);
1143 arg[n].out = out;
1144 arg[n].out_len = sizeof(out);
1145 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1146 test_1013_thread, arg + n)))
1147 nt = n; /* break loop and start cleanup */
1148 }
1149
1150 for (n = 0; n < nt; n++) {
1151 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1152 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1153 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1154 arg[n].out, arg[n].out_len);
1155 if (arg[n].max_concurrency > max_concurrency)
1156 max_concurrency = arg[n].max_concurrency;
1157 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001158 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001159 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001160
Pascal Brand4fa35582015-12-17 10:59:12 +01001161 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001162 TEEC_ReleaseSharedMemory(&shm);
1163}
Pascal Brand4fa35582015-12-17 10:59:12 +01001164
1165static void xtest_tee_test_1013(ADBG_Case_t *c)
1166{
1167 int i;
1168 double mean_concurrency;
1169 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001170 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001171
1172 if (level == 0)
1173 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001174
Jens Wiklander70672972016-04-06 00:01:45 +02001175 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001176 mean_concurrency = 0;
1177 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001178 xtest_tee_test_1013_single(c, &concurrency,
1179 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001180 mean_concurrency += concurrency;
1181 }
1182 mean_concurrency /= nb_loops;
1183
1184 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1185 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001186 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001187
Jens Wiklander70672972016-04-06 00:01:45 +02001188 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1189 mean_concurrency = 0;
1190 for (i = 0; i < nb_loops; i++) {
1191 xtest_tee_test_1013_single(c, &concurrency,
1192 &concurrent_large_ta_uuid);
1193 mean_concurrency += concurrency;
1194 }
1195 mean_concurrency /= nb_loops;
1196
1197 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1198 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1199 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
1200}