blob: f46fa00d95e300011a74cafb24bebc567e3c62f0 [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
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300414 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200415 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300416 &ret_orig)))
417 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200418
419 op.params[0].value.a = n;
420 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
421 TEEC_NONE);
422
423 (void)ADBG_EXPECT_TEEC_RESULT(c,
424 TEEC_ERROR_TARGET_DEAD,
425 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
426 &ret_orig));
427
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300428 (void)ADBG_EXPECT_TEEC_RESULT(c,
429 TEEC_ERROR_TARGET_DEAD,
430 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
Pascal Brandc639ac82015-07-02 08:53:34 +0200431 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300432
Pascal Brandc639ac82015-07-02 08:53:34 +0200433 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
434
435 TEEC_CloseSession(&session);
436}
437
438static void xtest_tee_test_1005(ADBG_Case_t *c)
439{
440 uint32_t ret_orig;
441#define MAX_SESSIONS 3
442 TEEC_Session sessions[MAX_SESSIONS];
443 int i;
444
445 for (i = 0; i < MAX_SESSIONS; i++) {
446 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Jens Wiklandereb6bce72016-09-23 11:37:33 +0200447 xtest_teec_open_session(&sessions[i],
448 &concurrent_ta_uuid,
Pascal Brandc639ac82015-07-02 08:53:34 +0200449 NULL, &ret_orig)))
450 break;
451 }
452
453 for (; --i >= 0; )
454 TEEC_CloseSession(&sessions[i]);
455}
456
457static void xtest_tee_test_1006(ADBG_Case_t *c)
458{
459 TEEC_Session session = { 0 };
460 uint32_t ret_orig;
461 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
462 uint8_t buf[32];
463
464 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
465 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
466 &ret_orig)))
467 return;
468
469 op.params[0].tmpref.buffer = buf;
470 op.params[0].tmpref.size = sizeof(buf);
471 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
472 TEEC_NONE, TEEC_NONE);
473
474 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
475 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
476 &ret_orig));
477
478 TEEC_CloseSession(&session);
479}
480
481static void xtest_tee_test_1007(ADBG_Case_t *c)
482{
483 TEEC_Session session = { 0 };
484 uint32_t ret_orig;
485
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300486 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200487 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300488 &ret_orig)))
489 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200490
491 (void)ADBG_EXPECT_TEEC_RESULT(c,
492 TEEC_ERROR_TARGET_DEAD,
493 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
494 &ret_orig));
495
496 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
497
498 (void)ADBG_EXPECT_TEEC_RESULT(c,
499 TEEC_ERROR_TARGET_DEAD,
500 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
501 &ret_orig));
502
503 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
504
505 TEEC_CloseSession(&session);
506}
507
Jerome Forissierf02a2212015-10-29 14:33:35 +0100508#ifndef TA_DIR
509#define TA_DIR "/lib/optee_armtz"
510#endif
511
David Brownb2865ab2016-08-02 11:44:41 -0600512#ifndef TA_TEST_DIR
513# ifdef __ANDROID__
514# define TA_TEST_DIR "/data/tmp/optee_armtz"
515# else
516# define TA_TEST_DIR "/tmp/optee_armtz"
517# endif
518#endif
Jens Wiklanderb7940892015-10-23 16:02:40 +0200519
David Brownb2865ab2016-08-02 11:44:41 -0600520static void make_test_ta_dir(void)
521{
522#ifdef __ANDROID__
523 (void)mkdir("/data/tmp", 0755);
524#endif
525 (void)mkdir(TA_TEST_DIR, 0755);
526}
527
528static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
529 bool for_write)
530{
Jens Wiklanderb7940892015-10-23 16:02:40 +0200531 snprintf(buf, blen,
David Brownb2865ab2016-08-02 11:44:41 -0600532 "%s/%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x.ta",
533 for_write ? TA_TEST_DIR : TA_DIR,
534 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
Jens Wiklanderb7940892015-10-23 16:02:40 +0200535 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
536 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
537 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
David Brownb2865ab2016-08-02 11:44:41 -0600538 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200539}
540
David Brownb2865ab2016-08-02 11:44:41 -0600541static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode,
542 bool for_write)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200543{
544 char buf[PATH_MAX];
545
David Brownb2865ab2016-08-02 11:44:41 -0600546 uuid_to_full_name(buf, sizeof(buf), uuid, for_write);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200547 return fopen(buf, mode);
548}
549
David Brownb2865ab2016-08-02 11:44:41 -0600550static bool rm_file(const TEEC_UUID *uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200551{
552 char buf[PATH_MAX];
553
David Brownb2865ab2016-08-02 11:44:41 -0600554 uuid_to_full_name(buf, sizeof(buf), uuid, true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200555 return !unlink(buf);
556}
557
David Brownb2865ab2016-08-02 11:44:41 -0600558static bool copy_file(const TEEC_UUID *src_uuid, const TEEC_UUID *dst_uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200559{
560 char buf[4 * 1024];
David Brownb2865ab2016-08-02 11:44:41 -0600561 FILE *src = open_ta_file(src_uuid, "r", false);
562 FILE *dst = open_ta_file(dst_uuid, "w", true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200563 size_t r;
564 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200565 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200566
Jens Wiklander4441fe22015-10-23 16:53:02 +0200567 if (src && dst) {
568 do {
569 r = fread(buf, 1, sizeof(buf), src);
570 if (!r) {
571 ret = !!feof(src);
572 break;
573 }
574 w = fwrite(buf, 1, r, dst);
575 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200576 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200577
578 if (src)
579 fclose(src);
580 if (dst)
581 fclose(dst);
582 return ret;
583}
584
585static bool corrupt_file(FILE *f, long offs, uint8_t mask)
586{
587 uint8_t b;
588
589 if (fseek(f, offs, SEEK_SET))
590 return false;
591
592 if (fread(&b, 1, 1, f) != 1)
593 return false;
594
595 b ^= mask;
596
597 if (fseek(f, offs, SEEK_SET))
598 return false;
599
600 if (fwrite(&b, 1, 1, f) != 1)
601 return false;
602
603 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200604}
605
606static void load_fake_ta(ADBG_Case_t *c)
607{
608 static const TEEC_UUID fake_uuid = {
609 0x7e0a0900, 0x586b, 0x11e5,
610 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
611 };
612 TEEC_Session session = { 0 };
613 TEEC_Result res;
614 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200615 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200616
David Brownb2865ab2016-08-02 11:44:41 -0600617 r = copy_file(&create_fail_test_ta_uuid, &fake_uuid);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200618
619 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200620 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
621 &ret_orig);
622 if (res == TEEC_SUCCESS)
623 TEEC_CloseSession(&session);
624 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200625 }
626
David Brownb2865ab2016-08-02 11:44:41 -0600627 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid));
Jens Wiklanderb7940892015-10-23 16:02:40 +0200628}
629
Jens Wiklander4441fe22015-10-23 16:53:02 +0200630static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
631{
632 TEEC_Session session = { 0 };
633 TEEC_Result res;
634 uint32_t ret_orig;
635 FILE *f;
636 bool r;
637
David Brownb2865ab2016-08-02 11:44:41 -0600638 r = copy_file(&create_fail_test_ta_uuid, &create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200639 if (!ADBG_EXPECT_TRUE(c, r)) {
David Brownb2865ab2016-08-02 11:44:41 -0600640 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200641 return false;
642 }
643
David Brownb2865ab2016-08-02 11:44:41 -0600644 f = open_ta_file(&create_fail_test_ta_uuid, "r+", true);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200645 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
David Brownb2865ab2016-08-02 11:44:41 -0600646 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200647 return false;
648 }
649 r = corrupt_file(f, offs, mask);
650 fclose(f);
651
652 if (ADBG_EXPECT_TRUE(c, r)) {
653 res = xtest_teec_open_session(&session,
654 &create_fail_test_ta_uuid,
655 NULL, &ret_orig);
656 if (res == TEEC_SUCCESS)
657 TEEC_CloseSession(&session);
658 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
659 }
660
David Brownb2865ab2016-08-02 11:44:41 -0600661 r &= ADBG_EXPECT_TRUE(c, rm_file(&create_fail_test_ta_uuid));
Jens Wiklander4441fe22015-10-23 16:53:02 +0200662 return r;
663}
664
Pascal Brandc639ac82015-07-02 08:53:34 +0200665static void xtest_tee_test_1008(ADBG_Case_t *c)
666{
667 TEEC_Session session = { 0 };
668 TEEC_Session session_crypt = { 0 };
669 uint32_t ret_orig;
670
671 Do_ADBG_BeginSubCase(c, "Invoke command");
672 {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300673 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200674 xtest_teec_open_session(&session, &os_test_ta_uuid,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300675 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200676
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300677 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
678 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
679 NULL, &ret_orig));
680 TEEC_CloseSession(&session);
681 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200682
Pascal Brandc639ac82015-07-02 08:53:34 +0200683 }
684 Do_ADBG_EndSubCase(c, "Invoke command");
685
686 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
687 {
688 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
689
690 op.params[0].value.a = 2000;
691 op.paramTypes = TEEC_PARAM_TYPES(
692 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
693
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300694 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200695 xtest_teec_open_session(&session,
696 &os_test_ta_uuid,
697 NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300698 &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200699
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300700 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
701 TEEC_InvokeCommand(&session,
702 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
703 &op, &ret_orig));
704 TEEC_CloseSession(&session);
705 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200706 }
707 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
708
709 Do_ADBG_BeginSubCase(c, "Create session fail");
710 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200711 size_t n;
712
Pascal Brandc639ac82015-07-02 08:53:34 +0200713 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
714 xtest_teec_open_session(&session_crypt,
715 &create_fail_test_ta_uuid, NULL,
716 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200717 /*
718 * Run this several times to see that there's no memory leakage.
719 */
720 for (n = 0; n < 100; n++) {
721 Do_ADBG_Log("n = %zu", n);
722 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
723 xtest_teec_open_session(&session_crypt,
724 &create_fail_test_ta_uuid,
725 NULL, &ret_orig));
726 }
727 }
728 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200729
David Brownb2865ab2016-08-02 11:44:41 -0600730 make_test_ta_dir();
731
Jens Wiklanderb7940892015-10-23 16:02:40 +0200732 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
733 load_fake_ta(c);
734 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
735
Jens Wiklander4441fe22015-10-23 16:53:02 +0200736 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
737 ADBG_EXPECT_TRUE(c,
738 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
739 ADBG_EXPECT_TRUE(c,
740 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
741 ADBG_EXPECT_TRUE(c,
742 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
743 ADBG_EXPECT_TRUE(c,
744 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
745 ADBG_EXPECT_TRUE(c,
746 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
747 ADBG_EXPECT_TRUE(c,
748 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
749 ADBG_EXPECT_TRUE(c,
750 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
751 ADBG_EXPECT_TRUE(c,
752 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
753 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
754 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
755 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200756}
757
758#ifdef USER_SPACE
759static void *cancellation_thread(void *arg)
760{
761 /*
762 * Sleep 0.5 seconds before cancellation to make sure that the other
763 * thread is in RPC_WAIT.
764 */
765 (void)usleep(500000);
766 TEEC_RequestCancellation(arg);
767 return NULL;
768}
769#endif
770
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300771static void xtest_tee_test_1009_subcase(ADBG_Case_t *c, const char *subcase,
772 uint32_t timeout, bool cancel)
Pascal Brandc639ac82015-07-02 08:53:34 +0200773{
774 TEEC_Session session = { 0 };
775 uint32_t ret_orig;
Pascal Brandc639ac82015-07-02 08:53:34 +0200776#ifdef USER_SPACE
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300777 pthread_t thr;
Pascal Brandc639ac82015-07-02 08:53:34 +0200778#endif
779
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300780 Do_ADBG_BeginSubCase(c, "%s", subcase);
Pascal Brandc639ac82015-07-02 08:53:34 +0200781 {
782 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
783
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300784 if (ADBG_EXPECT_TEEC_SUCCESS(c,
785 xtest_teec_open_session(&session, &os_test_ta_uuid,
786 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200787
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300788 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c,
789 TEEC_ORIGIN_TRUSTED_APP,
790 ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200791
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300792 op.params[0].value.a = timeout;
793 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
794 TEEC_NONE,
795 TEEC_NONE, TEEC_NONE);
796#ifdef USER_SPACE
797 if (cancel) {
798 (void)ADBG_EXPECT(c, 0,
799 pthread_create(&thr, NULL,
800 cancellation_thread, &op));
Pascal Brandc639ac82015-07-02 08:53:34 +0200801
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300802 (void)ADBG_EXPECT_TEEC_RESULT(c,
803 TEEC_ERROR_CANCEL,
804 TEEC_InvokeCommand(&session,
805 TA_OS_TEST_CMD_WAIT,
806 &op,
807 &ret_orig));
808 } else
809#endif
810
811 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
812 TEEC_InvokeCommand(&session,
813 TA_OS_TEST_CMD_WAIT,
814 &op,
815 &ret_orig));
816#ifdef USER_SPACE
817 if (cancel)
818 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
819#endif
820
821 TEEC_CloseSession(&session);
822 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200823 }
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300824 Do_ADBG_EndSubCase(c, "%s", subcase);
825}
826
827static void xtest_tee_test_1009(ADBG_Case_t *c)
828{
829 xtest_tee_test_1009_subcase(c, "TEE Wait 0.1s", 100, false);
830 xtest_tee_test_1009_subcase(c, "TEE Wait 0.5s", 500, false);
831#ifdef USER_SPACE
832 xtest_tee_test_1009_subcase(c, "TEE Wait 2s cancel", 2000, true);
833#endif
834 xtest_tee_test_1009_subcase(c, "TEE Wait 2s", 2000, false);
Pascal Brandc639ac82015-07-02 08:53:34 +0200835}
836
837static void xtest_tee_test_1010(ADBG_Case_t *c)
838{
839 unsigned n;
840
841 for (n = 1; n <= 5; n++) {
842 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
843 xtest_tee_test_invalid_mem_access(c, n);
844 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
845 }
846}
847
848static void xtest_tee_test_1011(ADBG_Case_t *c)
849{
850 TEEC_Session session = { 0 };
851 uint32_t ret_orig;
852 struct xtest_crypto_session cs = {
853 c, &session, TA_RPC_CMD_CRYPT_SHA256,
854 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
855 TA_RPC_CMD_CRYPT_AES256ECB_DEC
856 };
857 TEEC_UUID uuid = rpc_test_ta_uuid;
858
859 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
860 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
861 return;
862
863 /*
864 * Run the "complete crypto test suite" using RPC
865 */
866 xtest_crypto_test(&cs);
867 TEEC_CloseSession(&session);
868}
869
870/*
871 * Note that this test is failing when
872 * - running twice in a raw
873 * - and the user TA is statically linked
874 * This is because the counter is not reseted when opening the first session
875 * in case the TA is statically linked
876 */
877static void xtest_tee_test_1012(ADBG_Case_t *c)
878{
879 TEEC_Session session1 = { 0 };
880 TEEC_Session session2 = { 0 };
881 uint32_t ret_orig;
882 TEEC_UUID uuid = sims_test_ta_uuid;
883
884 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
885 {
886 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
887 static const uint8_t in[] = {
888 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
889 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
890 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
891 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
892 };
893 uint8_t out[32] = { 0 };
894 int i;
895
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300896 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200897 xtest_teec_open_session(&session1, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300898 &ret_orig)))
899 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200900
901 op.params[0].value.a = 0;
902 op.params[1].tmpref.buffer = (void *)in;
903 op.params[1].tmpref.size = sizeof(in);
904 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
905 TEEC_MEMREF_TEMP_INPUT,
906 TEEC_NONE, TEEC_NONE);
907
908 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
909 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
910 &ret_orig));
911
912 for (i = 1; i < 1000; i++) {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300913 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200914 xtest_teec_open_session(&session2, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300915 &ret_orig)))
916 continue;
Pascal Brandc639ac82015-07-02 08:53:34 +0200917
918 op.params[0].value.a = 0;
919 op.params[1].tmpref.buffer = out;
920 op.params[1].tmpref.size = sizeof(out);
921 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
922 TEEC_MEMREF_TEMP_OUTPUT,
923 TEEC_NONE, TEEC_NONE);
924
925 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
926 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
927 &op, &ret_orig));
928
929 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
930 sizeof(out))) {
931 Do_ADBG_Log("in:");
932 Do_ADBG_HexLog(in, sizeof(in), 16);
933 Do_ADBG_Log("out:");
934 Do_ADBG_HexLog(out, sizeof(out), 16);
935 }
936
937 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
938 TEEC_NONE, TEEC_NONE,
939 TEEC_NONE);
940
941 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
942 TEEC_InvokeCommand(&session1,
943 TA_SIMS_CMD_GET_COUNTER,
944 &op, &ret_orig));
945
946 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
947
948 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
949 TEEC_InvokeCommand(&session2,
950 TA_SIMS_CMD_GET_COUNTER, &op,
951 &ret_orig));
952
953 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
954 TEEC_CloseSession(&session2);
955 }
956
957 memset(out, 0, sizeof(out));
958 op.params[0].value.a = 0;
959 op.params[1].tmpref.buffer = out;
960 op.params[1].tmpref.size = sizeof(out);
961 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
962 TEEC_MEMREF_TEMP_OUTPUT,
963 TEEC_NONE, TEEC_NONE);
964
965 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
966 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
967 &ret_orig));
968
969 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
970 Do_ADBG_Log("in:");
971 Do_ADBG_HexLog(in, sizeof(in), 16);
972 Do_ADBG_Log("out:");
973 Do_ADBG_HexLog(out, sizeof(out), 16);
974 }
975
976 TEEC_CloseSession(&session1);
977 }
978}
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200979
980struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +0200981 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200982 uint32_t cmd;
983 uint32_t repeat;
984 TEEC_SharedMemory *shm;
985 uint32_t error_orig;
986 TEEC_Result res;
987 uint32_t max_concurrency;
988 const uint8_t *in;
989 size_t in_len;
990 uint8_t *out;
991 size_t out_len;
992};
993
994static void *test_1013_thread(void *arg)
995{
996 struct test_1013_thread_arg *a = arg;
997 TEEC_Session session = { 0 };
998 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
999 uint8_t p2 = TEEC_NONE;
1000 uint8_t p3 = TEEC_NONE;
1001
Jens Wiklander70672972016-04-06 00:01:45 +02001002 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001003 &a->error_orig);
1004 if (a->res != TEEC_SUCCESS)
1005 return NULL;
1006
1007 op.params[0].memref.parent = a->shm;
1008 op.params[0].memref.size = a->shm->size;
1009 op.params[0].memref.offset = 0;
1010 op.params[1].value.a = a->repeat;
1011 op.params[1].value.b = 0;
1012 op.params[2].tmpref.buffer = (void *)a->in;
1013 op.params[2].tmpref.size = a->in_len;
1014 op.params[3].tmpref.buffer = a->out;
1015 op.params[3].tmpref.size = a->out_len;
1016
1017 if (a->in_len)
1018 p2 = TEEC_MEMREF_TEMP_INPUT;
1019 if (a->out_len)
1020 p3 = TEEC_MEMREF_TEMP_OUTPUT;
1021
1022 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
1023 TEEC_VALUE_INOUT, p2, p3);
1024
1025 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
1026 a->max_concurrency = op.params[1].value.b;
1027 a->out_len = op.params[3].tmpref.size;
1028 TEEC_CloseSession(&session);
1029 return NULL;
1030}
1031
Pascal Brand4fa35582015-12-17 10:59:12 +01001032#define NUM_THREADS 3
1033
Jens Wiklander70672972016-04-06 00:01:45 +02001034static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
1035 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001036{
Pascal Brand4fa35582015-12-17 10:59:12 +01001037 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001038 size_t nt;
1039 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +02001040 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001041 pthread_t thr[num_threads];
1042 TEEC_SharedMemory shm;
1043 size_t max_concurrency;
1044 struct test_1013_thread_arg arg[num_threads];
1045 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
1046 static const uint8_t sha256_out[] = {
1047 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
1048 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
1049 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
1050 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
1051 };
1052 uint8_t out[32] = { 0 };
1053
Jens Wiklander70672972016-04-06 00:01:45 +02001054 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +01001055 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001056
1057 memset(&shm, 0, sizeof(shm));
1058 shm.size = sizeof(struct ta_concurrent_shm);
1059 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1060 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1061 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
1062 return;
1063
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001064 memset(shm.buffer, 0, shm.size);
1065 memset(arg, 0, sizeof(arg));
1066 max_concurrency = 0;
1067 nt = num_threads;
1068
1069 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001070 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001071 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +02001072 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001073 arg[n].shm = &shm;
1074 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1075 test_1013_thread, arg + n)))
1076 nt = n; /* break loop and start cleanup */
1077 }
1078
1079 for (n = 0; n < nt; n++) {
1080 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
1081 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
1082 if (arg[n].max_concurrency > max_concurrency)
1083 max_concurrency = arg[n].max_concurrency;
1084 }
1085
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001086 /*
1087 * Concurrency can be limited by several factors, for instance in a
1088 * single CPU system it's dependent on the Preemtion Model used by
1089 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
1090 * best result there).
1091 */
1092 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
1093 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +01001094 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001095 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001096
Jens Wiklander70672972016-04-06 00:01:45 +02001097 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
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_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +02001106 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001107 arg[n].shm = &shm;
1108 arg[n].in = sha256_in;
1109 arg[n].in_len = sizeof(sha256_in);
1110 arg[n].out = out;
1111 arg[n].out_len = sizeof(out);
1112 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1113 test_1013_thread, arg + n)))
1114 nt = n; /* break loop and start cleanup */
1115 }
1116
1117 for (n = 0; n < nt; n++) {
1118 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1119 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1120 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1121 arg[n].out, arg[n].out_len);
1122 if (arg[n].max_concurrency > max_concurrency)
1123 max_concurrency = arg[n].max_concurrency;
1124 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001125 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001126 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001127
Pascal Brand4fa35582015-12-17 10:59:12 +01001128 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001129 TEEC_ReleaseSharedMemory(&shm);
1130}
Pascal Brand4fa35582015-12-17 10:59:12 +01001131
1132static void xtest_tee_test_1013(ADBG_Case_t *c)
1133{
1134 int i;
1135 double mean_concurrency;
1136 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001137 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001138
1139 if (level == 0)
1140 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001141
Jens Wiklander70672972016-04-06 00:01:45 +02001142 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001143 mean_concurrency = 0;
1144 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001145 xtest_tee_test_1013_single(c, &concurrency,
1146 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001147 mean_concurrency += concurrency;
1148 }
1149 mean_concurrency /= nb_loops;
1150
1151 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1152 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001153 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001154
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001155#ifndef CFG_PAGED_USER_TA
Jens Wiklander70672972016-04-06 00:01:45 +02001156 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1157 mean_concurrency = 0;
1158 for (i = 0; i < nb_loops; i++) {
1159 xtest_tee_test_1013_single(c, &concurrency,
1160 &concurrent_large_ta_uuid);
1161 mean_concurrency += concurrency;
1162 }
1163 mean_concurrency /= nb_loops;
1164
1165 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1166 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1167 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001168#endif
Jens Wiklander70672972016-04-06 00:01:45 +02001169}