blob: 785d43425b5f1ae121db9c5fc5b3eba823e3537f [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
Etienne Carrierea4653552017-01-11 10:04:24 +010014#include <limits.h>
15#include <pthread.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020016#include <stdio.h>
17#include <string.h>
David Brownb2865ab2016-08-02 11:44:41 -060018#include <sys/stat.h>
19#include <sys/types.h>
Etienne Carrierea4653552017-01-11 10:04:24 +010020#include <unistd.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020021
22#include "xtest_test.h"
23#include "xtest_helpers.h"
Jens Wiklander4441fe22015-10-23 16:53:02 +020024#include <signed_hdr.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020025
Etienne Carriere726d8bc2017-03-21 15:45:59 +010026#include <pta_invoke_tests.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020027#include <ta_crypt.h>
28#include <ta_os_test.h>
29#include <ta_create_fail_test.h>
30#include <ta_rpc_test.h>
31#include <ta_sims_test.h>
Jens Wiklanderac27ec12015-07-15 15:23:14 +020032#include <ta_concurrent.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020033
34static void xtest_tee_test_1001(ADBG_Case_t *Case_p);
35static void xtest_tee_test_1004(ADBG_Case_t *Case_p);
36static void xtest_tee_test_1005(ADBG_Case_t *Case_p);
37static void xtest_tee_test_1006(ADBG_Case_t *Case_p);
38static void xtest_tee_test_1007(ADBG_Case_t *Case_p);
39static void xtest_tee_test_1008(ADBG_Case_t *Case_p);
40static void xtest_tee_test_1009(ADBG_Case_t *Case_p);
41static void xtest_tee_test_1010(ADBG_Case_t *Case_p);
42static void xtest_tee_test_1011(ADBG_Case_t *Case_p);
43static void xtest_tee_test_1012(ADBG_Case_t *Case_p);
Jens Wiklanderac27ec12015-07-15 15:23:14 +020044static void xtest_tee_test_1013(ADBG_Case_t *Case_p);
Pascal Brandc639ac82015-07-02 08:53:34 +020045
Jens Wiklander74abfe32017-01-03 14:17:47 +010046ADBG_CASE_DEFINE(regression, 1001, xtest_tee_test_1001, "Core self tests");
47ADBG_CASE_DEFINE(regression, 1004, xtest_tee_test_1004, "Test User Crypt TA");
48ADBG_CASE_DEFINE(regression, 1005, xtest_tee_test_1005, "Many sessions");
49ADBG_CASE_DEFINE(regression, 1006, xtest_tee_test_1006,
50 "Test Basic OS features");
51ADBG_CASE_DEFINE(regression, 1007, xtest_tee_test_1007, "Test Panic");
52ADBG_CASE_DEFINE(regression, 1008, xtest_tee_test_1008,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010053 "TEE internal client API");
Jens Wiklander74abfe32017-01-03 14:17:47 +010054ADBG_CASE_DEFINE(regression, 1009, xtest_tee_test_1009, "TEE Wait");
55ADBG_CASE_DEFINE(regression, 1010, xtest_tee_test_1010,
56 "Invalid memory access");
57ADBG_CASE_DEFINE(regression, 1011, xtest_tee_test_1011,
Jens Wiklanderf7b9c632017-01-03 17:32:26 +010058 "Test TA-to-TA features with User Crypt TA");
Jens Wiklander74abfe32017-01-03 14:17:47 +010059ADBG_CASE_DEFINE(regression, 1012, xtest_tee_test_1012,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010060 "Test Single Instance Multi Session features with SIMS TA");
Jens Wiklander74abfe32017-01-03 14:17:47 +010061ADBG_CASE_DEFINE(regression, 1013, xtest_tee_test_1013,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010062 "Test concurency with concurrent TA");
Jens Wiklanderac27ec12015-07-15 15:23:14 +020063
Pascal Brandc639ac82015-07-02 08:53:34 +020064struct xtest_crypto_session {
65 ADBG_Case_t *c;
66 TEEC_Session *session;
67 uint32_t cmd_id_sha256;
68 uint32_t cmd_id_aes256ecb_encrypt;
69 uint32_t cmd_id_aes256ecb_decrypt;
70};
71
72static void xtest_crypto_test(struct xtest_crypto_session *cs)
73{
74 uint32_t ret_orig;
75 uint8_t crypt_out[16];
76 uint8_t crypt_in[16] = { 22, 17 };
77
78 crypt_in[15] = 60;
79
80 Do_ADBG_BeginSubCase(cs->c, "AES encrypt");
81 {
82 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
83
84 op.params[0].tmpref.buffer = crypt_in;
85 op.params[0].tmpref.size = sizeof(crypt_in);
86 op.params[1].tmpref.buffer = crypt_out;
87 op.params[1].tmpref.size = sizeof(crypt_out);
88 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
89 TEEC_MEMREF_TEMP_OUTPUT,
90 TEEC_NONE, TEEC_NONE);
91
92 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
93 TEEC_InvokeCommand(cs->session,
94 cs->
95 cmd_id_aes256ecb_encrypt,
96 &op,
97 &ret_orig));
98 }
99 Do_ADBG_EndSubCase(cs->c, "AES encrypt");
100
101 Do_ADBG_BeginSubCase(cs->c, "AES decrypt");
102 {
103 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
104 uint8_t out[16];
105
106 op.params[0].tmpref.buffer = crypt_out;
107 op.params[0].tmpref.size = sizeof(crypt_out);
108 op.params[1].tmpref.buffer = out;
109 op.params[1].tmpref.size = sizeof(out);
110 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
111 TEEC_MEMREF_TEMP_OUTPUT,
112 TEEC_NONE, TEEC_NONE);
113
114 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
115 TEEC_InvokeCommand(cs->session,
116 cs->
117 cmd_id_aes256ecb_decrypt,
118 &op,
119 &ret_orig));
120
121 if (!ADBG_EXPECT(cs->c, 0,
122 memcmp(crypt_in, out, sizeof(crypt_in)))) {
123 Do_ADBG_Log("crypt_in:");
124 Do_ADBG_HexLog(crypt_in, sizeof(crypt_in), 16);
125 Do_ADBG_Log("out:");
126 Do_ADBG_HexLog(out, sizeof(out), 16);
127 }
128 }
129 Do_ADBG_EndSubCase(cs->c, "AES decrypt");
130
131 Do_ADBG_BeginSubCase(cs->c, "SHA-256 test, 3 bytes input");
132 {
133 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
134 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
135 static const uint8_t sha256_out[] = {
136 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
137 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
138 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
139 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
140 };
141 uint8_t out[32] = { 0 };
142
143 op.params[0].tmpref.buffer = (void *)sha256_in;
144 op.params[0].tmpref.size = sizeof(sha256_in);
145 op.params[1].tmpref.buffer = out;
146 op.params[1].tmpref.size = sizeof(out);
147 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
148 TEEC_MEMREF_TEMP_OUTPUT,
149 TEEC_NONE, TEEC_NONE);
150
151 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
152 TEEC_InvokeCommand(cs->session,
153 cs->
154 cmd_id_sha256,
155 &op,
156 &ret_orig));
157
158 if (!ADBG_EXPECT(cs->c, 0, memcmp(sha256_out, out,
159 sizeof(sha256_out)))) {
160 Do_ADBG_Log("sha256_out:");
161 Do_ADBG_HexLog(sha256_out, sizeof(sha256_out), 16);
162 Do_ADBG_Log("out:");
163 Do_ADBG_HexLog(out, sizeof(out), 16);
164 }
165 }
166 Do_ADBG_EndSubCase(cs->c, "SHA-256 test, 3 bytes input");
167
168 Do_ADBG_BeginSubCase(cs->c,
169 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
170 {
171 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
172 static const uint8_t in[] = {
173 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
174 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
175 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
176 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
177 };
178 static const uint8_t exp_out[] = {
179 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
180 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
181 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
182 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
183 };
184 uint8_t out[sizeof(exp_out)];
185
186 op.params[0].tmpref.buffer = (void *)in;
187 op.params[0].tmpref.size = sizeof(in);
188 op.params[1].tmpref.buffer = out;
189 op.params[1].tmpref.size = sizeof(out);
190 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
191 TEEC_MEMREF_TEMP_OUTPUT,
192 TEEC_NONE, TEEC_NONE);
193
194 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
195 TEEC_InvokeCommand(cs->session,
196 cs->
197 cmd_id_aes256ecb_encrypt,
198 &op,
199 &ret_orig));
200
201 if (!ADBG_EXPECT(cs->c, 0,
202 memcmp(exp_out, out, sizeof(exp_out)))) {
203 Do_ADBG_Log("exp_out:");
204 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
205 Do_ADBG_Log("out:");
206 Do_ADBG_HexLog(out, sizeof(out), 16);
207 }
208 }
209 Do_ADBG_EndSubCase(cs->c,
210 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
211
212 Do_ADBG_BeginSubCase(cs->c,
213 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
214 {
215 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
216 static const uint8_t in[] = {
217 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
218 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
219 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
220 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
221 };
222 static const uint8_t exp_out[] = {
223 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
224 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
225 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
226 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
227 };
228 uint8_t out[sizeof(exp_out)];
229
230 op.params[0].tmpref.buffer = (void *)in;
231 op.params[0].tmpref.size = sizeof(in);
232 op.params[1].tmpref.buffer = out;
233 op.params[1].tmpref.size = sizeof(out);
234 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
235 TEEC_MEMREF_TEMP_OUTPUT,
236 TEEC_NONE, TEEC_NONE);
237
238 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
239 TEEC_InvokeCommand(cs->session,
240 cs->
241 cmd_id_aes256ecb_decrypt,
242 &op,
243 &ret_orig));
244
245 if (!ADBG_EXPECT(cs->c, 0,
246 memcmp(exp_out, out, sizeof(exp_out)))) {
247 Do_ADBG_Log("exp_out:");
248 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
249 Do_ADBG_Log("out:");
250 Do_ADBG_HexLog(out, sizeof(out), 16);
251 }
252 }
253 Do_ADBG_EndSubCase(cs->c,
254 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
255}
256
257static void xtest_tee_test_1001(ADBG_Case_t *c)
258{
Jens Wiklandercf16e842016-02-10 09:07:09 +0100259 TEEC_Result res;
260 TEEC_Session session = { 0 };
261 uint32_t ret_orig;
Pascal Brandc639ac82015-07-02 08:53:34 +0200262
Etienne Carriere726d8bc2017-03-21 15:45:59 +0100263 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
Jens Wiklandercf16e842016-02-10 09:07:09 +0100264 &ret_orig);
265 /*
266 * If the static TA (which is optional) isn't available, skip this
267 * test.
268 */
269 if (res != TEEC_SUCCESS)
270 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200271
Jens Wiklandercf16e842016-02-10 09:07:09 +0100272 (void)ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
Etienne Carriere726d8bc2017-03-21 15:45:59 +0100273 &session, PTA_INVOKE_TESTS_CMD_SELF_TESTS, NULL, &ret_orig));
Jens Wiklandercf16e842016-02-10 09:07:09 +0100274 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200275}
276
277static void xtest_tee_test_1004(ADBG_Case_t *c)
278{
279 TEEC_Session session = { 0 };
280 uint32_t ret_orig;
281 struct xtest_crypto_session cs = { c, &session, TA_CRYPT_CMD_SHA256,
282 TA_CRYPT_CMD_AES256ECB_ENC,
283 TA_CRYPT_CMD_AES256ECB_DEC };
284
285 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
286 &session, &crypt_user_ta_uuid,
287 NULL, &ret_orig)))
288 return;
289
290 /* Run the "complete crypto test suite" */
291 xtest_crypto_test(&cs);
292
293 TEEC_CloseSession(&session);
294}
295
296#ifndef TEEC_ERROR_TARGET_DEAD
297/* To be removed when we have TEEC_ERROR_TARGET_DEAD from tee_client_api.h */
298#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024
299#endif
300
301static void xtest_tee_test_invalid_mem_access(ADBG_Case_t *c, uint32_t n)
302{
303 TEEC_Session session = { 0 };
304 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
305 uint32_t ret_orig;
306
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300307 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200308 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300309 &ret_orig)))
310 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200311
312 op.params[0].value.a = n;
313 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
314 TEEC_NONE);
315
316 (void)ADBG_EXPECT_TEEC_RESULT(c,
317 TEEC_ERROR_TARGET_DEAD,
318 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
319 &ret_orig));
320
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300321 (void)ADBG_EXPECT_TEEC_RESULT(c,
322 TEEC_ERROR_TARGET_DEAD,
323 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
Pascal Brandc639ac82015-07-02 08:53:34 +0200324 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300325
Pascal Brandc639ac82015-07-02 08:53:34 +0200326 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
327
328 TEEC_CloseSession(&session);
329}
330
331static void xtest_tee_test_1005(ADBG_Case_t *c)
332{
333 uint32_t ret_orig;
334#define MAX_SESSIONS 3
335 TEEC_Session sessions[MAX_SESSIONS];
336 int i;
337
338 for (i = 0; i < MAX_SESSIONS; i++) {
339 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Jens Wiklandereb6bce72016-09-23 11:37:33 +0200340 xtest_teec_open_session(&sessions[i],
341 &concurrent_ta_uuid,
Pascal Brandc639ac82015-07-02 08:53:34 +0200342 NULL, &ret_orig)))
343 break;
344 }
345
346 for (; --i >= 0; )
347 TEEC_CloseSession(&sessions[i]);
348}
349
350static void xtest_tee_test_1006(ADBG_Case_t *c)
351{
352 TEEC_Session session = { 0 };
353 uint32_t ret_orig;
354 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
355 uint8_t buf[32];
356
357 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
358 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
359 &ret_orig)))
360 return;
361
362 op.params[0].tmpref.buffer = buf;
363 op.params[0].tmpref.size = sizeof(buf);
364 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
365 TEEC_NONE, TEEC_NONE);
366
367 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
368 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
369 &ret_orig));
370
371 TEEC_CloseSession(&session);
372}
373
374static void xtest_tee_test_1007(ADBG_Case_t *c)
375{
376 TEEC_Session session = { 0 };
377 uint32_t ret_orig;
378
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300379 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200380 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300381 &ret_orig)))
382 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200383
384 (void)ADBG_EXPECT_TEEC_RESULT(c,
385 TEEC_ERROR_TARGET_DEAD,
386 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
387 &ret_orig));
388
389 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
390
391 (void)ADBG_EXPECT_TEEC_RESULT(c,
392 TEEC_ERROR_TARGET_DEAD,
393 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
394 &ret_orig));
395
396 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
397
398 TEEC_CloseSession(&session);
399}
400
Jerome Forissierf02a2212015-10-29 14:33:35 +0100401#ifndef TA_DIR
Victor Chong3d8798f2017-03-01 18:31:48 +0000402# ifdef __ANDROID__
403#define TA_DIR "/system/lib/optee_armtz"
404# else
Jerome Forissierf02a2212015-10-29 14:33:35 +0100405#define TA_DIR "/lib/optee_armtz"
Victor Chong3d8798f2017-03-01 18:31:48 +0000406# endif
Jerome Forissierf02a2212015-10-29 14:33:35 +0100407#endif
408
David Brownb2865ab2016-08-02 11:44:41 -0600409#ifndef TA_TEST_DIR
410# ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200411# define TA_TEST_DIR "/data/tee/optee_armtz"
David Brownb2865ab2016-08-02 11:44:41 -0600412# else
413# define TA_TEST_DIR "/tmp/optee_armtz"
414# endif
415#endif
Jens Wiklanderb7940892015-10-23 16:02:40 +0200416
David Brownb2865ab2016-08-02 11:44:41 -0600417static void make_test_ta_dir(void)
418{
419#ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200420 (void)mkdir("/data/tee", 0755);
David Brownb2865ab2016-08-02 11:44:41 -0600421#endif
422 (void)mkdir(TA_TEST_DIR, 0755);
423}
424
425static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
426 bool for_write)
427{
Jens Wiklanderb7940892015-10-23 16:02:40 +0200428 snprintf(buf, blen,
Jens Wiklander6203b872016-12-08 19:18:29 +0100429 "%s/%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x.ta",
David Brownb2865ab2016-08-02 11:44:41 -0600430 for_write ? TA_TEST_DIR : TA_DIR,
431 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
Jens Wiklanderb7940892015-10-23 16:02:40 +0200432 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
433 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
434 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
David Brownb2865ab2016-08-02 11:44:41 -0600435 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200436}
437
David Brownb2865ab2016-08-02 11:44:41 -0600438static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode,
439 bool for_write)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200440{
441 char buf[PATH_MAX];
442
David Brownb2865ab2016-08-02 11:44:41 -0600443 uuid_to_full_name(buf, sizeof(buf), uuid, for_write);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200444 return fopen(buf, mode);
445}
446
David Brownb2865ab2016-08-02 11:44:41 -0600447static bool rm_file(const TEEC_UUID *uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200448{
449 char buf[PATH_MAX];
450
David Brownb2865ab2016-08-02 11:44:41 -0600451 uuid_to_full_name(buf, sizeof(buf), uuid, true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200452 return !unlink(buf);
453}
454
David Brownb2865ab2016-08-02 11:44:41 -0600455static bool copy_file(const TEEC_UUID *src_uuid, const TEEC_UUID *dst_uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200456{
457 char buf[4 * 1024];
David Brownb2865ab2016-08-02 11:44:41 -0600458 FILE *src = open_ta_file(src_uuid, "r", false);
459 FILE *dst = open_ta_file(dst_uuid, "w", true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200460 size_t r;
461 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200462 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200463
Jens Wiklander4441fe22015-10-23 16:53:02 +0200464 if (src && dst) {
465 do {
466 r = fread(buf, 1, sizeof(buf), src);
467 if (!r) {
468 ret = !!feof(src);
469 break;
470 }
471 w = fwrite(buf, 1, r, dst);
472 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200473 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200474
475 if (src)
476 fclose(src);
477 if (dst)
478 fclose(dst);
479 return ret;
480}
481
482static bool corrupt_file(FILE *f, long offs, uint8_t mask)
483{
484 uint8_t b;
485
486 if (fseek(f, offs, SEEK_SET))
487 return false;
488
489 if (fread(&b, 1, 1, f) != 1)
490 return false;
491
492 b ^= mask;
493
494 if (fseek(f, offs, SEEK_SET))
495 return false;
496
497 if (fwrite(&b, 1, 1, f) != 1)
498 return false;
499
500 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200501}
502
503static void load_fake_ta(ADBG_Case_t *c)
504{
505 static const TEEC_UUID fake_uuid = {
506 0x7e0a0900, 0x586b, 0x11e5,
507 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
508 };
509 TEEC_Session session = { 0 };
510 TEEC_Result res;
511 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200512 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200513
David Brownb2865ab2016-08-02 11:44:41 -0600514 r = copy_file(&create_fail_test_ta_uuid, &fake_uuid);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200515
516 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200517 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
518 &ret_orig);
519 if (res == TEEC_SUCCESS)
520 TEEC_CloseSession(&session);
521 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200522 }
523
David Brownb2865ab2016-08-02 11:44:41 -0600524 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid));
Jens Wiklanderb7940892015-10-23 16:02:40 +0200525}
526
Jens Wiklander4441fe22015-10-23 16:53:02 +0200527static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
528{
529 TEEC_Session session = { 0 };
530 TEEC_Result res;
531 uint32_t ret_orig;
532 FILE *f;
533 bool r;
534
David Brownb2865ab2016-08-02 11:44:41 -0600535 r = copy_file(&create_fail_test_ta_uuid, &create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200536 if (!ADBG_EXPECT_TRUE(c, r)) {
David Brownb2865ab2016-08-02 11:44:41 -0600537 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200538 return false;
539 }
540
David Brownb2865ab2016-08-02 11:44:41 -0600541 f = open_ta_file(&create_fail_test_ta_uuid, "r+", true);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200542 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
David Brownb2865ab2016-08-02 11:44:41 -0600543 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200544 return false;
545 }
546 r = corrupt_file(f, offs, mask);
547 fclose(f);
548
549 if (ADBG_EXPECT_TRUE(c, r)) {
550 res = xtest_teec_open_session(&session,
551 &create_fail_test_ta_uuid,
552 NULL, &ret_orig);
553 if (res == TEEC_SUCCESS)
554 TEEC_CloseSession(&session);
555 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
556 }
557
David Brownb2865ab2016-08-02 11:44:41 -0600558 r &= ADBG_EXPECT_TRUE(c, rm_file(&create_fail_test_ta_uuid));
Jens Wiklander4441fe22015-10-23 16:53:02 +0200559 return r;
560}
561
Pascal Brandc639ac82015-07-02 08:53:34 +0200562static void xtest_tee_test_1008(ADBG_Case_t *c)
563{
564 TEEC_Session session = { 0 };
565 TEEC_Session session_crypt = { 0 };
566 uint32_t ret_orig;
567
568 Do_ADBG_BeginSubCase(c, "Invoke command");
569 {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300570 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200571 xtest_teec_open_session(&session, &os_test_ta_uuid,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300572 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200573
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300574 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
575 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
576 NULL, &ret_orig));
577 TEEC_CloseSession(&session);
578 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200579
Pascal Brandc639ac82015-07-02 08:53:34 +0200580 }
581 Do_ADBG_EndSubCase(c, "Invoke command");
582
583 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
584 {
585 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
586
587 op.params[0].value.a = 2000;
588 op.paramTypes = TEEC_PARAM_TYPES(
589 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
590
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300591 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200592 xtest_teec_open_session(&session,
593 &os_test_ta_uuid,
594 NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300595 &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200596
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300597 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
598 TEEC_InvokeCommand(&session,
599 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
600 &op, &ret_orig));
601 TEEC_CloseSession(&session);
602 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200603 }
604 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
605
606 Do_ADBG_BeginSubCase(c, "Create session fail");
607 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200608 size_t n;
609
Pascal Brandc639ac82015-07-02 08:53:34 +0200610 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
611 xtest_teec_open_session(&session_crypt,
612 &create_fail_test_ta_uuid, NULL,
613 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200614 /*
615 * Run this several times to see that there's no memory leakage.
616 */
617 for (n = 0; n < 100; n++) {
618 Do_ADBG_Log("n = %zu", n);
619 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
620 xtest_teec_open_session(&session_crypt,
621 &create_fail_test_ta_uuid,
622 NULL, &ret_orig));
623 }
624 }
625 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200626
David Brownb2865ab2016-08-02 11:44:41 -0600627 make_test_ta_dir();
628
Jens Wiklanderb7940892015-10-23 16:02:40 +0200629 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
630 load_fake_ta(c);
631 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
632
Jens Wiklander4441fe22015-10-23 16:53:02 +0200633 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
634 ADBG_EXPECT_TRUE(c,
635 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
636 ADBG_EXPECT_TRUE(c,
637 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
638 ADBG_EXPECT_TRUE(c,
639 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
640 ADBG_EXPECT_TRUE(c,
641 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
642 ADBG_EXPECT_TRUE(c,
643 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
644 ADBG_EXPECT_TRUE(c,
645 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
646 ADBG_EXPECT_TRUE(c,
647 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
648 ADBG_EXPECT_TRUE(c,
649 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
650 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
651 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
652 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200653}
654
Pascal Brandc639ac82015-07-02 08:53:34 +0200655static void *cancellation_thread(void *arg)
656{
657 /*
658 * Sleep 0.5 seconds before cancellation to make sure that the other
659 * thread is in RPC_WAIT.
660 */
661 (void)usleep(500000);
662 TEEC_RequestCancellation(arg);
663 return NULL;
664}
Pascal Brandc639ac82015-07-02 08:53:34 +0200665
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300666static void xtest_tee_test_1009_subcase(ADBG_Case_t *c, const char *subcase,
667 uint32_t timeout, bool cancel)
Pascal Brandc639ac82015-07-02 08:53:34 +0200668{
669 TEEC_Session session = { 0 };
670 uint32_t ret_orig;
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300671 pthread_t thr;
Pascal Brandc639ac82015-07-02 08:53:34 +0200672
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300673 Do_ADBG_BeginSubCase(c, "%s", subcase);
Pascal Brandc639ac82015-07-02 08:53:34 +0200674 {
675 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
676
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300677 if (ADBG_EXPECT_TEEC_SUCCESS(c,
678 xtest_teec_open_session(&session, &os_test_ta_uuid,
679 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200680
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300681 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c,
682 TEEC_ORIGIN_TRUSTED_APP,
683 ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200684
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300685 op.params[0].value.a = timeout;
686 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
687 TEEC_NONE,
688 TEEC_NONE, TEEC_NONE);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300689 if (cancel) {
690 (void)ADBG_EXPECT(c, 0,
691 pthread_create(&thr, NULL,
692 cancellation_thread, &op));
Pascal Brandc639ac82015-07-02 08:53:34 +0200693
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300694 (void)ADBG_EXPECT_TEEC_RESULT(c,
695 TEEC_ERROR_CANCEL,
696 TEEC_InvokeCommand(&session,
697 TA_OS_TEST_CMD_WAIT,
698 &op,
699 &ret_orig));
700 } else
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300701
702 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
703 TEEC_InvokeCommand(&session,
704 TA_OS_TEST_CMD_WAIT,
705 &op,
706 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300707 if (cancel)
708 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300709
710 TEEC_CloseSession(&session);
711 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200712 }
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300713 Do_ADBG_EndSubCase(c, "%s", subcase);
714}
715
716static void xtest_tee_test_1009(ADBG_Case_t *c)
717{
718 xtest_tee_test_1009_subcase(c, "TEE Wait 0.1s", 100, false);
719 xtest_tee_test_1009_subcase(c, "TEE Wait 0.5s", 500, false);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300720 xtest_tee_test_1009_subcase(c, "TEE Wait 2s cancel", 2000, true);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300721 xtest_tee_test_1009_subcase(c, "TEE Wait 2s", 2000, false);
Pascal Brandc639ac82015-07-02 08:53:34 +0200722}
723
724static void xtest_tee_test_1010(ADBG_Case_t *c)
725{
726 unsigned n;
727
728 for (n = 1; n <= 5; n++) {
729 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
730 xtest_tee_test_invalid_mem_access(c, n);
731 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
732 }
733}
734
735static void xtest_tee_test_1011(ADBG_Case_t *c)
736{
737 TEEC_Session session = { 0 };
738 uint32_t ret_orig;
739 struct xtest_crypto_session cs = {
740 c, &session, TA_RPC_CMD_CRYPT_SHA256,
741 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
742 TA_RPC_CMD_CRYPT_AES256ECB_DEC
743 };
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100744 struct xtest_crypto_session cs_privmem = {
745 c, &session,
746 TA_RPC_CMD_CRYPT_PRIVMEM_SHA256,
747 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_ENC,
748 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_DEC
749 };
Pascal Brandc639ac82015-07-02 08:53:34 +0200750 TEEC_UUID uuid = rpc_test_ta_uuid;
751
752 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
753 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
754 return;
755
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100756 Do_ADBG_BeginSubCase(c, "TA-to-TA via non-secure shared memory");
Pascal Brandc639ac82015-07-02 08:53:34 +0200757 /*
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100758 * Run the "complete crypto test suite" using TA-to-TA
759 * communication
Pascal Brandc639ac82015-07-02 08:53:34 +0200760 */
761 xtest_crypto_test(&cs);
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100762 Do_ADBG_EndSubCase(c, "TA-to-TA via non-secure shared memory");
763
764 Do_ADBG_BeginSubCase(c, "TA-to-TA via TA private memory");
765 /*
766 * Run the "complete crypto test suite" using TA-to-TA
767 * communication via TA private memory.
768 */
769 xtest_crypto_test(&cs_privmem);
770 Do_ADBG_EndSubCase(c, "TA-to-TA via TA private memory");
771
Pascal Brandc639ac82015-07-02 08:53:34 +0200772 TEEC_CloseSession(&session);
773}
774
775/*
776 * Note that this test is failing when
777 * - running twice in a raw
778 * - and the user TA is statically linked
779 * This is because the counter is not reseted when opening the first session
780 * in case the TA is statically linked
781 */
782static void xtest_tee_test_1012(ADBG_Case_t *c)
783{
784 TEEC_Session session1 = { 0 };
785 TEEC_Session session2 = { 0 };
786 uint32_t ret_orig;
787 TEEC_UUID uuid = sims_test_ta_uuid;
788
789 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
790 {
791 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
792 static const uint8_t in[] = {
793 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
794 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
795 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
796 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
797 };
798 uint8_t out[32] = { 0 };
799 int i;
800
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300801 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200802 xtest_teec_open_session(&session1, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300803 &ret_orig)))
804 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200805
806 op.params[0].value.a = 0;
807 op.params[1].tmpref.buffer = (void *)in;
808 op.params[1].tmpref.size = sizeof(in);
809 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
810 TEEC_MEMREF_TEMP_INPUT,
811 TEEC_NONE, TEEC_NONE);
812
813 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
814 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
815 &ret_orig));
816
817 for (i = 1; i < 1000; i++) {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300818 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200819 xtest_teec_open_session(&session2, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300820 &ret_orig)))
821 continue;
Pascal Brandc639ac82015-07-02 08:53:34 +0200822
823 op.params[0].value.a = 0;
824 op.params[1].tmpref.buffer = out;
825 op.params[1].tmpref.size = sizeof(out);
826 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
827 TEEC_MEMREF_TEMP_OUTPUT,
828 TEEC_NONE, TEEC_NONE);
829
830 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
831 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
832 &op, &ret_orig));
833
834 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
835 sizeof(out))) {
836 Do_ADBG_Log("in:");
837 Do_ADBG_HexLog(in, sizeof(in), 16);
838 Do_ADBG_Log("out:");
839 Do_ADBG_HexLog(out, sizeof(out), 16);
840 }
841
842 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
843 TEEC_NONE, TEEC_NONE,
844 TEEC_NONE);
845
846 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
847 TEEC_InvokeCommand(&session1,
848 TA_SIMS_CMD_GET_COUNTER,
849 &op, &ret_orig));
850
851 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
852
853 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
854 TEEC_InvokeCommand(&session2,
855 TA_SIMS_CMD_GET_COUNTER, &op,
856 &ret_orig));
857
858 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
859 TEEC_CloseSession(&session2);
860 }
861
862 memset(out, 0, sizeof(out));
863 op.params[0].value.a = 0;
864 op.params[1].tmpref.buffer = out;
865 op.params[1].tmpref.size = sizeof(out);
866 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
867 TEEC_MEMREF_TEMP_OUTPUT,
868 TEEC_NONE, TEEC_NONE);
869
870 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
871 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
872 &ret_orig));
873
874 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
875 Do_ADBG_Log("in:");
876 Do_ADBG_HexLog(in, sizeof(in), 16);
877 Do_ADBG_Log("out:");
878 Do_ADBG_HexLog(out, sizeof(out), 16);
879 }
880
881 TEEC_CloseSession(&session1);
882 }
883}
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200884
885struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +0200886 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200887 uint32_t cmd;
888 uint32_t repeat;
889 TEEC_SharedMemory *shm;
890 uint32_t error_orig;
891 TEEC_Result res;
892 uint32_t max_concurrency;
893 const uint8_t *in;
894 size_t in_len;
895 uint8_t *out;
896 size_t out_len;
897};
898
899static void *test_1013_thread(void *arg)
900{
901 struct test_1013_thread_arg *a = arg;
902 TEEC_Session session = { 0 };
903 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
904 uint8_t p2 = TEEC_NONE;
905 uint8_t p3 = TEEC_NONE;
906
Jens Wiklander70672972016-04-06 00:01:45 +0200907 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200908 &a->error_orig);
909 if (a->res != TEEC_SUCCESS)
910 return NULL;
911
912 op.params[0].memref.parent = a->shm;
913 op.params[0].memref.size = a->shm->size;
914 op.params[0].memref.offset = 0;
915 op.params[1].value.a = a->repeat;
916 op.params[1].value.b = 0;
917 op.params[2].tmpref.buffer = (void *)a->in;
918 op.params[2].tmpref.size = a->in_len;
919 op.params[3].tmpref.buffer = a->out;
920 op.params[3].tmpref.size = a->out_len;
921
922 if (a->in_len)
923 p2 = TEEC_MEMREF_TEMP_INPUT;
924 if (a->out_len)
925 p3 = TEEC_MEMREF_TEMP_OUTPUT;
926
927 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
928 TEEC_VALUE_INOUT, p2, p3);
929
930 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
931 a->max_concurrency = op.params[1].value.b;
932 a->out_len = op.params[3].tmpref.size;
933 TEEC_CloseSession(&session);
934 return NULL;
935}
936
Pascal Brand4fa35582015-12-17 10:59:12 +0100937#define NUM_THREADS 3
938
Jens Wiklander70672972016-04-06 00:01:45 +0200939static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
940 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200941{
Pascal Brand4fa35582015-12-17 10:59:12 +0100942 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200943 size_t nt;
944 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +0200945 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200946 pthread_t thr[num_threads];
947 TEEC_SharedMemory shm;
948 size_t max_concurrency;
949 struct test_1013_thread_arg arg[num_threads];
950 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
951 static const uint8_t sha256_out[] = {
952 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
953 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
954 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
955 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
956 };
957 uint8_t out[32] = { 0 };
958
Jens Wiklander70672972016-04-06 00:01:45 +0200959 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +0100960 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200961
962 memset(&shm, 0, sizeof(shm));
963 shm.size = sizeof(struct ta_concurrent_shm);
964 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
965 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
966 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
967 return;
968
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200969 memset(shm.buffer, 0, shm.size);
970 memset(arg, 0, sizeof(arg));
971 max_concurrency = 0;
972 nt = num_threads;
973
974 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +0200975 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200976 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +0200977 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200978 arg[n].shm = &shm;
979 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
980 test_1013_thread, arg + n)))
981 nt = n; /* break loop and start cleanup */
982 }
983
984 for (n = 0; n < nt; n++) {
985 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
986 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
987 if (arg[n].max_concurrency > max_concurrency)
988 max_concurrency = arg[n].max_concurrency;
989 }
990
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200991 /*
992 * Concurrency can be limited by several factors, for instance in a
993 * single CPU system it's dependent on the Preemtion Model used by
994 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
995 * best result there).
996 */
997 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
998 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +0100999 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001000 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001001
Jens Wiklander70672972016-04-06 00:01:45 +02001002 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001003 memset(shm.buffer, 0, shm.size);
1004 memset(arg, 0, sizeof(arg));
1005 max_concurrency = 0;
1006 nt = num_threads;
1007
1008 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001009 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001010 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +02001011 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001012 arg[n].shm = &shm;
1013 arg[n].in = sha256_in;
1014 arg[n].in_len = sizeof(sha256_in);
1015 arg[n].out = out;
1016 arg[n].out_len = sizeof(out);
1017 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1018 test_1013_thread, arg + n)))
1019 nt = n; /* break loop and start cleanup */
1020 }
1021
1022 for (n = 0; n < nt; n++) {
1023 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1024 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1025 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1026 arg[n].out, arg[n].out_len);
1027 if (arg[n].max_concurrency > max_concurrency)
1028 max_concurrency = arg[n].max_concurrency;
1029 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001030 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001031 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001032
Pascal Brand4fa35582015-12-17 10:59:12 +01001033 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001034 TEEC_ReleaseSharedMemory(&shm);
1035}
Pascal Brand4fa35582015-12-17 10:59:12 +01001036
1037static void xtest_tee_test_1013(ADBG_Case_t *c)
1038{
1039 int i;
1040 double mean_concurrency;
1041 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001042 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001043
1044 if (level == 0)
1045 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001046
Jens Wiklander70672972016-04-06 00:01:45 +02001047 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001048 mean_concurrency = 0;
1049 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001050 xtest_tee_test_1013_single(c, &concurrency,
1051 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001052 mean_concurrency += concurrency;
1053 }
1054 mean_concurrency /= nb_loops;
1055
1056 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1057 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001058 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001059
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001060#ifndef CFG_PAGED_USER_TA
Jens Wiklander70672972016-04-06 00:01:45 +02001061 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1062 mean_concurrency = 0;
1063 for (i = 0; i < nb_loops; i++) {
1064 xtest_tee_test_1013_single(c, &concurrency,
1065 &concurrent_large_ta_uuid);
1066 mean_concurrency += concurrency;
1067 }
1068 mean_concurrency /= nb_loops;
1069
1070 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1071 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1072 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001073#endif
Jens Wiklander70672972016-04-06 00:01:45 +02001074}