blob: b20fd4ee063c7aab42f2058b8ee315b40c6b0cfa [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>
Etienne Carriere50abf9a2017-03-24 11:33:50 +010033#include <sdp_basic.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020034
35static void xtest_tee_test_1001(ADBG_Case_t *Case_p);
36static void xtest_tee_test_1004(ADBG_Case_t *Case_p);
37static void xtest_tee_test_1005(ADBG_Case_t *Case_p);
38static void xtest_tee_test_1006(ADBG_Case_t *Case_p);
39static void xtest_tee_test_1007(ADBG_Case_t *Case_p);
40static void xtest_tee_test_1008(ADBG_Case_t *Case_p);
41static void xtest_tee_test_1009(ADBG_Case_t *Case_p);
42static void xtest_tee_test_1010(ADBG_Case_t *Case_p);
43static void xtest_tee_test_1011(ADBG_Case_t *Case_p);
44static void xtest_tee_test_1012(ADBG_Case_t *Case_p);
Jens Wiklanderac27ec12015-07-15 15:23:14 +020045static void xtest_tee_test_1013(ADBG_Case_t *Case_p);
Etienne Carriere50abf9a2017-03-24 11:33:50 +010046#ifdef CFG_SECURE_DATA_PATH
47static void xtest_tee_test_1014(ADBG_Case_t *Case_p);
48#endif
Pascal Brandc639ac82015-07-02 08:53:34 +020049
Jens Wiklander74abfe32017-01-03 14:17:47 +010050ADBG_CASE_DEFINE(regression, 1001, xtest_tee_test_1001, "Core self tests");
51ADBG_CASE_DEFINE(regression, 1004, xtest_tee_test_1004, "Test User Crypt TA");
52ADBG_CASE_DEFINE(regression, 1005, xtest_tee_test_1005, "Many sessions");
53ADBG_CASE_DEFINE(regression, 1006, xtest_tee_test_1006,
54 "Test Basic OS features");
55ADBG_CASE_DEFINE(regression, 1007, xtest_tee_test_1007, "Test Panic");
56ADBG_CASE_DEFINE(regression, 1008, xtest_tee_test_1008,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010057 "TEE internal client API");
Jens Wiklander74abfe32017-01-03 14:17:47 +010058ADBG_CASE_DEFINE(regression, 1009, xtest_tee_test_1009, "TEE Wait");
59ADBG_CASE_DEFINE(regression, 1010, xtest_tee_test_1010,
60 "Invalid memory access");
61ADBG_CASE_DEFINE(regression, 1011, xtest_tee_test_1011,
Jens Wiklanderf7b9c632017-01-03 17:32:26 +010062 "Test TA-to-TA features with User Crypt TA");
Jens Wiklander74abfe32017-01-03 14:17:47 +010063ADBG_CASE_DEFINE(regression, 1012, xtest_tee_test_1012,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010064 "Test Single Instance Multi Session features with SIMS TA");
Jens Wiklander74abfe32017-01-03 14:17:47 +010065ADBG_CASE_DEFINE(regression, 1013, xtest_tee_test_1013,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010066 "Test concurency with concurrent TA");
Etienne Carriere50abf9a2017-03-24 11:33:50 +010067#ifdef CFG_SECURE_DATA_PATH
68ADBG_CASE_DEFINE(regression, 1014, xtest_tee_test_1014,
69 "Test secure data path against SDP TAs and pTAs");
70#endif
Jens Wiklanderac27ec12015-07-15 15:23:14 +020071
Pascal Brandc639ac82015-07-02 08:53:34 +020072struct xtest_crypto_session {
73 ADBG_Case_t *c;
74 TEEC_Session *session;
75 uint32_t cmd_id_sha256;
76 uint32_t cmd_id_aes256ecb_encrypt;
77 uint32_t cmd_id_aes256ecb_decrypt;
78};
79
80static void xtest_crypto_test(struct xtest_crypto_session *cs)
81{
82 uint32_t ret_orig;
83 uint8_t crypt_out[16];
84 uint8_t crypt_in[16] = { 22, 17 };
85
86 crypt_in[15] = 60;
87
88 Do_ADBG_BeginSubCase(cs->c, "AES encrypt");
89 {
90 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
91
92 op.params[0].tmpref.buffer = crypt_in;
93 op.params[0].tmpref.size = sizeof(crypt_in);
94 op.params[1].tmpref.buffer = crypt_out;
95 op.params[1].tmpref.size = sizeof(crypt_out);
96 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
97 TEEC_MEMREF_TEMP_OUTPUT,
98 TEEC_NONE, TEEC_NONE);
99
100 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
101 TEEC_InvokeCommand(cs->session,
102 cs->
103 cmd_id_aes256ecb_encrypt,
104 &op,
105 &ret_orig));
106 }
107 Do_ADBG_EndSubCase(cs->c, "AES encrypt");
108
109 Do_ADBG_BeginSubCase(cs->c, "AES decrypt");
110 {
111 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
112 uint8_t out[16];
113
114 op.params[0].tmpref.buffer = crypt_out;
115 op.params[0].tmpref.size = sizeof(crypt_out);
116 op.params[1].tmpref.buffer = out;
117 op.params[1].tmpref.size = sizeof(out);
118 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
119 TEEC_MEMREF_TEMP_OUTPUT,
120 TEEC_NONE, TEEC_NONE);
121
122 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
123 TEEC_InvokeCommand(cs->session,
124 cs->
125 cmd_id_aes256ecb_decrypt,
126 &op,
127 &ret_orig));
128
129 if (!ADBG_EXPECT(cs->c, 0,
130 memcmp(crypt_in, out, sizeof(crypt_in)))) {
131 Do_ADBG_Log("crypt_in:");
132 Do_ADBG_HexLog(crypt_in, sizeof(crypt_in), 16);
133 Do_ADBG_Log("out:");
134 Do_ADBG_HexLog(out, sizeof(out), 16);
135 }
136 }
137 Do_ADBG_EndSubCase(cs->c, "AES decrypt");
138
139 Do_ADBG_BeginSubCase(cs->c, "SHA-256 test, 3 bytes input");
140 {
141 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
142 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
143 static const uint8_t sha256_out[] = {
144 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
145 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
146 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
147 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
148 };
149 uint8_t out[32] = { 0 };
150
151 op.params[0].tmpref.buffer = (void *)sha256_in;
152 op.params[0].tmpref.size = sizeof(sha256_in);
153 op.params[1].tmpref.buffer = out;
154 op.params[1].tmpref.size = sizeof(out);
155 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
156 TEEC_MEMREF_TEMP_OUTPUT,
157 TEEC_NONE, TEEC_NONE);
158
159 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
160 TEEC_InvokeCommand(cs->session,
161 cs->
162 cmd_id_sha256,
163 &op,
164 &ret_orig));
165
166 if (!ADBG_EXPECT(cs->c, 0, memcmp(sha256_out, out,
167 sizeof(sha256_out)))) {
168 Do_ADBG_Log("sha256_out:");
169 Do_ADBG_HexLog(sha256_out, sizeof(sha256_out), 16);
170 Do_ADBG_Log("out:");
171 Do_ADBG_HexLog(out, sizeof(out), 16);
172 }
173 }
174 Do_ADBG_EndSubCase(cs->c, "SHA-256 test, 3 bytes input");
175
176 Do_ADBG_BeginSubCase(cs->c,
177 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
178 {
179 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
180 static const uint8_t in[] = {
181 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
182 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
183 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
184 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
185 };
186 static const uint8_t exp_out[] = {
187 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
188 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
189 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
190 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
191 };
192 uint8_t out[sizeof(exp_out)];
193
194 op.params[0].tmpref.buffer = (void *)in;
195 op.params[0].tmpref.size = sizeof(in);
196 op.params[1].tmpref.buffer = out;
197 op.params[1].tmpref.size = sizeof(out);
198 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
199 TEEC_MEMREF_TEMP_OUTPUT,
200 TEEC_NONE, TEEC_NONE);
201
202 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
203 TEEC_InvokeCommand(cs->session,
204 cs->
205 cmd_id_aes256ecb_encrypt,
206 &op,
207 &ret_orig));
208
209 if (!ADBG_EXPECT(cs->c, 0,
210 memcmp(exp_out, out, sizeof(exp_out)))) {
211 Do_ADBG_Log("exp_out:");
212 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
213 Do_ADBG_Log("out:");
214 Do_ADBG_HexLog(out, sizeof(out), 16);
215 }
216 }
217 Do_ADBG_EndSubCase(cs->c,
218 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
219
220 Do_ADBG_BeginSubCase(cs->c,
221 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
222 {
223 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
224 static const uint8_t in[] = {
225 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
226 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
227 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
228 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
229 };
230 static const uint8_t exp_out[] = {
231 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
232 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
233 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
234 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
235 };
236 uint8_t out[sizeof(exp_out)];
237
238 op.params[0].tmpref.buffer = (void *)in;
239 op.params[0].tmpref.size = sizeof(in);
240 op.params[1].tmpref.buffer = out;
241 op.params[1].tmpref.size = sizeof(out);
242 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
243 TEEC_MEMREF_TEMP_OUTPUT,
244 TEEC_NONE, TEEC_NONE);
245
246 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
247 TEEC_InvokeCommand(cs->session,
248 cs->
249 cmd_id_aes256ecb_decrypt,
250 &op,
251 &ret_orig));
252
253 if (!ADBG_EXPECT(cs->c, 0,
254 memcmp(exp_out, out, sizeof(exp_out)))) {
255 Do_ADBG_Log("exp_out:");
256 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
257 Do_ADBG_Log("out:");
258 Do_ADBG_HexLog(out, sizeof(out), 16);
259 }
260 }
261 Do_ADBG_EndSubCase(cs->c,
262 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
263}
264
265static void xtest_tee_test_1001(ADBG_Case_t *c)
266{
Jens Wiklandercf16e842016-02-10 09:07:09 +0100267 TEEC_Result res;
268 TEEC_Session session = { 0 };
269 uint32_t ret_orig;
Pascal Brandc639ac82015-07-02 08:53:34 +0200270
Etienne Carriere726d8bc2017-03-21 15:45:59 +0100271 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
Jens Wiklandercf16e842016-02-10 09:07:09 +0100272 &ret_orig);
273 /*
274 * If the static TA (which is optional) isn't available, skip this
275 * test.
276 */
277 if (res != TEEC_SUCCESS)
278 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200279
Jens Wiklandercf16e842016-02-10 09:07:09 +0100280 (void)ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
Etienne Carriere726d8bc2017-03-21 15:45:59 +0100281 &session, PTA_INVOKE_TESTS_CMD_SELF_TESTS, NULL, &ret_orig));
Jens Wiklandercf16e842016-02-10 09:07:09 +0100282 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200283}
284
285static void xtest_tee_test_1004(ADBG_Case_t *c)
286{
287 TEEC_Session session = { 0 };
288 uint32_t ret_orig;
289 struct xtest_crypto_session cs = { c, &session, TA_CRYPT_CMD_SHA256,
290 TA_CRYPT_CMD_AES256ECB_ENC,
291 TA_CRYPT_CMD_AES256ECB_DEC };
292
293 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
294 &session, &crypt_user_ta_uuid,
295 NULL, &ret_orig)))
296 return;
297
298 /* Run the "complete crypto test suite" */
299 xtest_crypto_test(&cs);
300
301 TEEC_CloseSession(&session);
302}
303
304#ifndef TEEC_ERROR_TARGET_DEAD
305/* To be removed when we have TEEC_ERROR_TARGET_DEAD from tee_client_api.h */
306#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024
307#endif
308
309static void xtest_tee_test_invalid_mem_access(ADBG_Case_t *c, uint32_t n)
310{
311 TEEC_Session session = { 0 };
312 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
313 uint32_t ret_orig;
314
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300315 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200316 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300317 &ret_orig)))
318 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200319
320 op.params[0].value.a = n;
321 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
322 TEEC_NONE);
323
324 (void)ADBG_EXPECT_TEEC_RESULT(c,
325 TEEC_ERROR_TARGET_DEAD,
326 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
327 &ret_orig));
328
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300329 (void)ADBG_EXPECT_TEEC_RESULT(c,
330 TEEC_ERROR_TARGET_DEAD,
331 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
Pascal Brandc639ac82015-07-02 08:53:34 +0200332 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300333
Pascal Brandc639ac82015-07-02 08:53:34 +0200334 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
335
336 TEEC_CloseSession(&session);
337}
338
339static void xtest_tee_test_1005(ADBG_Case_t *c)
340{
341 uint32_t ret_orig;
342#define MAX_SESSIONS 3
343 TEEC_Session sessions[MAX_SESSIONS];
344 int i;
345
346 for (i = 0; i < MAX_SESSIONS; i++) {
347 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Jens Wiklandereb6bce72016-09-23 11:37:33 +0200348 xtest_teec_open_session(&sessions[i],
349 &concurrent_ta_uuid,
Pascal Brandc639ac82015-07-02 08:53:34 +0200350 NULL, &ret_orig)))
351 break;
352 }
353
354 for (; --i >= 0; )
355 TEEC_CloseSession(&sessions[i]);
356}
357
358static void xtest_tee_test_1006(ADBG_Case_t *c)
359{
360 TEEC_Session session = { 0 };
361 uint32_t ret_orig;
362 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
363 uint8_t buf[32];
364
365 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
366 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
367 &ret_orig)))
368 return;
369
370 op.params[0].tmpref.buffer = buf;
371 op.params[0].tmpref.size = sizeof(buf);
372 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
373 TEEC_NONE, TEEC_NONE);
374
375 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
376 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
377 &ret_orig));
378
379 TEEC_CloseSession(&session);
380}
381
382static void xtest_tee_test_1007(ADBG_Case_t *c)
383{
384 TEEC_Session session = { 0 };
385 uint32_t ret_orig;
386
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300387 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200388 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300389 &ret_orig)))
390 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200391
392 (void)ADBG_EXPECT_TEEC_RESULT(c,
393 TEEC_ERROR_TARGET_DEAD,
394 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
395 &ret_orig));
396
397 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
398
399 (void)ADBG_EXPECT_TEEC_RESULT(c,
400 TEEC_ERROR_TARGET_DEAD,
401 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
402 &ret_orig));
403
404 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
405
406 TEEC_CloseSession(&session);
407}
408
Jerome Forissierf02a2212015-10-29 14:33:35 +0100409#ifndef TA_DIR
Victor Chong3d8798f2017-03-01 18:31:48 +0000410# ifdef __ANDROID__
411#define TA_DIR "/system/lib/optee_armtz"
412# else
Jerome Forissierf02a2212015-10-29 14:33:35 +0100413#define TA_DIR "/lib/optee_armtz"
Victor Chong3d8798f2017-03-01 18:31:48 +0000414# endif
Jerome Forissierf02a2212015-10-29 14:33:35 +0100415#endif
416
David Brownb2865ab2016-08-02 11:44:41 -0600417#ifndef TA_TEST_DIR
418# ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200419# define TA_TEST_DIR "/data/tee/optee_armtz"
David Brownb2865ab2016-08-02 11:44:41 -0600420# else
421# define TA_TEST_DIR "/tmp/optee_armtz"
422# endif
423#endif
Jens Wiklanderb7940892015-10-23 16:02:40 +0200424
David Brownb2865ab2016-08-02 11:44:41 -0600425static void make_test_ta_dir(void)
426{
427#ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200428 (void)mkdir("/data/tee", 0755);
David Brownb2865ab2016-08-02 11:44:41 -0600429#endif
430 (void)mkdir(TA_TEST_DIR, 0755);
431}
432
433static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
434 bool for_write)
435{
Jens Wiklanderb7940892015-10-23 16:02:40 +0200436 snprintf(buf, blen,
Jens Wiklander6203b872016-12-08 19:18:29 +0100437 "%s/%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x.ta",
David Brownb2865ab2016-08-02 11:44:41 -0600438 for_write ? TA_TEST_DIR : TA_DIR,
439 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
Jens Wiklanderb7940892015-10-23 16:02:40 +0200440 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
441 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
442 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
David Brownb2865ab2016-08-02 11:44:41 -0600443 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200444}
445
David Brownb2865ab2016-08-02 11:44:41 -0600446static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode,
447 bool for_write)
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, for_write);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200452 return fopen(buf, mode);
453}
454
David Brownb2865ab2016-08-02 11:44:41 -0600455static bool rm_file(const TEEC_UUID *uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200456{
457 char buf[PATH_MAX];
458
David Brownb2865ab2016-08-02 11:44:41 -0600459 uuid_to_full_name(buf, sizeof(buf), uuid, true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200460 return !unlink(buf);
461}
462
David Brownb2865ab2016-08-02 11:44:41 -0600463static bool copy_file(const TEEC_UUID *src_uuid, const TEEC_UUID *dst_uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200464{
465 char buf[4 * 1024];
David Brownb2865ab2016-08-02 11:44:41 -0600466 FILE *src = open_ta_file(src_uuid, "r", false);
467 FILE *dst = open_ta_file(dst_uuid, "w", true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200468 size_t r;
469 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200470 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200471
Jens Wiklander4441fe22015-10-23 16:53:02 +0200472 if (src && dst) {
473 do {
474 r = fread(buf, 1, sizeof(buf), src);
475 if (!r) {
476 ret = !!feof(src);
477 break;
478 }
479 w = fwrite(buf, 1, r, dst);
480 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200481 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200482
483 if (src)
484 fclose(src);
485 if (dst)
486 fclose(dst);
487 return ret;
488}
489
490static bool corrupt_file(FILE *f, long offs, uint8_t mask)
491{
492 uint8_t b;
493
494 if (fseek(f, offs, SEEK_SET))
495 return false;
496
497 if (fread(&b, 1, 1, f) != 1)
498 return false;
499
500 b ^= mask;
501
502 if (fseek(f, offs, SEEK_SET))
503 return false;
504
505 if (fwrite(&b, 1, 1, f) != 1)
506 return false;
507
508 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200509}
510
511static void load_fake_ta(ADBG_Case_t *c)
512{
513 static const TEEC_UUID fake_uuid = {
514 0x7e0a0900, 0x586b, 0x11e5,
515 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
516 };
517 TEEC_Session session = { 0 };
518 TEEC_Result res;
519 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200520 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200521
David Brownb2865ab2016-08-02 11:44:41 -0600522 r = copy_file(&create_fail_test_ta_uuid, &fake_uuid);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200523
524 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200525 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
526 &ret_orig);
527 if (res == TEEC_SUCCESS)
528 TEEC_CloseSession(&session);
529 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200530 }
531
David Brownb2865ab2016-08-02 11:44:41 -0600532 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid));
Jens Wiklanderb7940892015-10-23 16:02:40 +0200533}
534
Jens Wiklander4441fe22015-10-23 16:53:02 +0200535static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
536{
537 TEEC_Session session = { 0 };
538 TEEC_Result res;
539 uint32_t ret_orig;
540 FILE *f;
541 bool r;
542
David Brownb2865ab2016-08-02 11:44:41 -0600543 r = copy_file(&create_fail_test_ta_uuid, &create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200544 if (!ADBG_EXPECT_TRUE(c, r)) {
David Brownb2865ab2016-08-02 11:44:41 -0600545 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200546 return false;
547 }
548
David Brownb2865ab2016-08-02 11:44:41 -0600549 f = open_ta_file(&create_fail_test_ta_uuid, "r+", true);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200550 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
David Brownb2865ab2016-08-02 11:44:41 -0600551 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200552 return false;
553 }
554 r = corrupt_file(f, offs, mask);
555 fclose(f);
556
557 if (ADBG_EXPECT_TRUE(c, r)) {
558 res = xtest_teec_open_session(&session,
559 &create_fail_test_ta_uuid,
560 NULL, &ret_orig);
561 if (res == TEEC_SUCCESS)
562 TEEC_CloseSession(&session);
563 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
564 }
565
David Brownb2865ab2016-08-02 11:44:41 -0600566 r &= ADBG_EXPECT_TRUE(c, rm_file(&create_fail_test_ta_uuid));
Jens Wiklander4441fe22015-10-23 16:53:02 +0200567 return r;
568}
569
Pascal Brandc639ac82015-07-02 08:53:34 +0200570static void xtest_tee_test_1008(ADBG_Case_t *c)
571{
572 TEEC_Session session = { 0 };
573 TEEC_Session session_crypt = { 0 };
574 uint32_t ret_orig;
575
576 Do_ADBG_BeginSubCase(c, "Invoke command");
577 {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300578 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200579 xtest_teec_open_session(&session, &os_test_ta_uuid,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300580 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200581
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300582 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
583 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
584 NULL, &ret_orig));
585 TEEC_CloseSession(&session);
586 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200587
Pascal Brandc639ac82015-07-02 08:53:34 +0200588 }
589 Do_ADBG_EndSubCase(c, "Invoke command");
590
591 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
592 {
593 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
594
595 op.params[0].value.a = 2000;
596 op.paramTypes = TEEC_PARAM_TYPES(
597 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
598
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300599 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200600 xtest_teec_open_session(&session,
601 &os_test_ta_uuid,
602 NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300603 &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200604
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300605 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
606 TEEC_InvokeCommand(&session,
607 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
608 &op, &ret_orig));
609 TEEC_CloseSession(&session);
610 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200611 }
612 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
613
614 Do_ADBG_BeginSubCase(c, "Create session fail");
615 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200616 size_t n;
617
Pascal Brandc639ac82015-07-02 08:53:34 +0200618 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
619 xtest_teec_open_session(&session_crypt,
620 &create_fail_test_ta_uuid, NULL,
621 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200622 /*
623 * Run this several times to see that there's no memory leakage.
624 */
625 for (n = 0; n < 100; n++) {
626 Do_ADBG_Log("n = %zu", n);
627 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
628 xtest_teec_open_session(&session_crypt,
629 &create_fail_test_ta_uuid,
630 NULL, &ret_orig));
631 }
632 }
633 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200634
David Brownb2865ab2016-08-02 11:44:41 -0600635 make_test_ta_dir();
636
Jens Wiklanderb7940892015-10-23 16:02:40 +0200637 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
638 load_fake_ta(c);
639 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
640
Jens Wiklander4441fe22015-10-23 16:53:02 +0200641 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
642 ADBG_EXPECT_TRUE(c,
643 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
644 ADBG_EXPECT_TRUE(c,
645 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
646 ADBG_EXPECT_TRUE(c,
647 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
648 ADBG_EXPECT_TRUE(c,
649 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
650 ADBG_EXPECT_TRUE(c,
651 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
652 ADBG_EXPECT_TRUE(c,
653 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
654 ADBG_EXPECT_TRUE(c,
655 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
656 ADBG_EXPECT_TRUE(c,
657 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
658 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
659 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
660 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200661}
662
Pascal Brandc639ac82015-07-02 08:53:34 +0200663static void *cancellation_thread(void *arg)
664{
665 /*
666 * Sleep 0.5 seconds before cancellation to make sure that the other
667 * thread is in RPC_WAIT.
668 */
669 (void)usleep(500000);
670 TEEC_RequestCancellation(arg);
671 return NULL;
672}
Pascal Brandc639ac82015-07-02 08:53:34 +0200673
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300674static void xtest_tee_test_1009_subcase(ADBG_Case_t *c, const char *subcase,
675 uint32_t timeout, bool cancel)
Pascal Brandc639ac82015-07-02 08:53:34 +0200676{
677 TEEC_Session session = { 0 };
678 uint32_t ret_orig;
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300679 pthread_t thr;
Pascal Brandc639ac82015-07-02 08:53:34 +0200680
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300681 Do_ADBG_BeginSubCase(c, "%s", subcase);
Pascal Brandc639ac82015-07-02 08:53:34 +0200682 {
683 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
684
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300685 if (ADBG_EXPECT_TEEC_SUCCESS(c,
686 xtest_teec_open_session(&session, &os_test_ta_uuid,
687 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200688
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300689 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c,
690 TEEC_ORIGIN_TRUSTED_APP,
691 ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200692
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300693 op.params[0].value.a = timeout;
694 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
695 TEEC_NONE,
696 TEEC_NONE, TEEC_NONE);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300697 if (cancel) {
698 (void)ADBG_EXPECT(c, 0,
699 pthread_create(&thr, NULL,
700 cancellation_thread, &op));
Pascal Brandc639ac82015-07-02 08:53:34 +0200701
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300702 (void)ADBG_EXPECT_TEEC_RESULT(c,
703 TEEC_ERROR_CANCEL,
704 TEEC_InvokeCommand(&session,
705 TA_OS_TEST_CMD_WAIT,
706 &op,
707 &ret_orig));
708 } else
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300709
710 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
711 TEEC_InvokeCommand(&session,
712 TA_OS_TEST_CMD_WAIT,
713 &op,
714 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300715 if (cancel)
716 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300717
718 TEEC_CloseSession(&session);
719 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200720 }
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300721 Do_ADBG_EndSubCase(c, "%s", subcase);
722}
723
724static void xtest_tee_test_1009(ADBG_Case_t *c)
725{
726 xtest_tee_test_1009_subcase(c, "TEE Wait 0.1s", 100, false);
727 xtest_tee_test_1009_subcase(c, "TEE Wait 0.5s", 500, false);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300728 xtest_tee_test_1009_subcase(c, "TEE Wait 2s cancel", 2000, true);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300729 xtest_tee_test_1009_subcase(c, "TEE Wait 2s", 2000, false);
Pascal Brandc639ac82015-07-02 08:53:34 +0200730}
731
732static void xtest_tee_test_1010(ADBG_Case_t *c)
733{
734 unsigned n;
735
736 for (n = 1; n <= 5; n++) {
737 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
738 xtest_tee_test_invalid_mem_access(c, n);
739 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
740 }
741}
742
743static void xtest_tee_test_1011(ADBG_Case_t *c)
744{
745 TEEC_Session session = { 0 };
746 uint32_t ret_orig;
747 struct xtest_crypto_session cs = {
748 c, &session, TA_RPC_CMD_CRYPT_SHA256,
749 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
750 TA_RPC_CMD_CRYPT_AES256ECB_DEC
751 };
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100752 struct xtest_crypto_session cs_privmem = {
753 c, &session,
754 TA_RPC_CMD_CRYPT_PRIVMEM_SHA256,
755 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_ENC,
756 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_DEC
757 };
Pascal Brandc639ac82015-07-02 08:53:34 +0200758 TEEC_UUID uuid = rpc_test_ta_uuid;
759
760 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
761 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
762 return;
763
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100764 Do_ADBG_BeginSubCase(c, "TA-to-TA via non-secure shared memory");
Pascal Brandc639ac82015-07-02 08:53:34 +0200765 /*
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100766 * Run the "complete crypto test suite" using TA-to-TA
767 * communication
Pascal Brandc639ac82015-07-02 08:53:34 +0200768 */
769 xtest_crypto_test(&cs);
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100770 Do_ADBG_EndSubCase(c, "TA-to-TA via non-secure shared memory");
771
772 Do_ADBG_BeginSubCase(c, "TA-to-TA via TA private memory");
773 /*
774 * Run the "complete crypto test suite" using TA-to-TA
775 * communication via TA private memory.
776 */
777 xtest_crypto_test(&cs_privmem);
778 Do_ADBG_EndSubCase(c, "TA-to-TA via TA private memory");
779
Pascal Brandc639ac82015-07-02 08:53:34 +0200780 TEEC_CloseSession(&session);
781}
782
783/*
784 * Note that this test is failing when
785 * - running twice in a raw
786 * - and the user TA is statically linked
787 * This is because the counter is not reseted when opening the first session
788 * in case the TA is statically linked
789 */
790static void xtest_tee_test_1012(ADBG_Case_t *c)
791{
792 TEEC_Session session1 = { 0 };
793 TEEC_Session session2 = { 0 };
794 uint32_t ret_orig;
795 TEEC_UUID uuid = sims_test_ta_uuid;
796
797 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
798 {
799 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
800 static const uint8_t in[] = {
801 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
802 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
803 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
804 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
805 };
806 uint8_t out[32] = { 0 };
807 int i;
808
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300809 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200810 xtest_teec_open_session(&session1, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300811 &ret_orig)))
812 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200813
814 op.params[0].value.a = 0;
815 op.params[1].tmpref.buffer = (void *)in;
816 op.params[1].tmpref.size = sizeof(in);
817 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
818 TEEC_MEMREF_TEMP_INPUT,
819 TEEC_NONE, TEEC_NONE);
820
821 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
822 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
823 &ret_orig));
824
825 for (i = 1; i < 1000; i++) {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300826 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200827 xtest_teec_open_session(&session2, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300828 &ret_orig)))
829 continue;
Pascal Brandc639ac82015-07-02 08:53:34 +0200830
831 op.params[0].value.a = 0;
832 op.params[1].tmpref.buffer = out;
833 op.params[1].tmpref.size = sizeof(out);
834 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
835 TEEC_MEMREF_TEMP_OUTPUT,
836 TEEC_NONE, TEEC_NONE);
837
838 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
839 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
840 &op, &ret_orig));
841
842 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
843 sizeof(out))) {
844 Do_ADBG_Log("in:");
845 Do_ADBG_HexLog(in, sizeof(in), 16);
846 Do_ADBG_Log("out:");
847 Do_ADBG_HexLog(out, sizeof(out), 16);
848 }
849
850 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
851 TEEC_NONE, TEEC_NONE,
852 TEEC_NONE);
853
854 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
855 TEEC_InvokeCommand(&session1,
856 TA_SIMS_CMD_GET_COUNTER,
857 &op, &ret_orig));
858
859 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
860
861 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
862 TEEC_InvokeCommand(&session2,
863 TA_SIMS_CMD_GET_COUNTER, &op,
864 &ret_orig));
865
866 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
867 TEEC_CloseSession(&session2);
868 }
869
870 memset(out, 0, sizeof(out));
871 op.params[0].value.a = 0;
872 op.params[1].tmpref.buffer = out;
873 op.params[1].tmpref.size = sizeof(out);
874 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
875 TEEC_MEMREF_TEMP_OUTPUT,
876 TEEC_NONE, TEEC_NONE);
877
878 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
879 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
880 &ret_orig));
881
882 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
883 Do_ADBG_Log("in:");
884 Do_ADBG_HexLog(in, sizeof(in), 16);
885 Do_ADBG_Log("out:");
886 Do_ADBG_HexLog(out, sizeof(out), 16);
887 }
888
889 TEEC_CloseSession(&session1);
890 }
891}
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200892
893struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +0200894 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200895 uint32_t cmd;
896 uint32_t repeat;
897 TEEC_SharedMemory *shm;
898 uint32_t error_orig;
899 TEEC_Result res;
900 uint32_t max_concurrency;
901 const uint8_t *in;
902 size_t in_len;
903 uint8_t *out;
904 size_t out_len;
905};
906
907static void *test_1013_thread(void *arg)
908{
909 struct test_1013_thread_arg *a = arg;
910 TEEC_Session session = { 0 };
911 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
912 uint8_t p2 = TEEC_NONE;
913 uint8_t p3 = TEEC_NONE;
914
Jens Wiklander70672972016-04-06 00:01:45 +0200915 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200916 &a->error_orig);
917 if (a->res != TEEC_SUCCESS)
918 return NULL;
919
920 op.params[0].memref.parent = a->shm;
921 op.params[0].memref.size = a->shm->size;
922 op.params[0].memref.offset = 0;
923 op.params[1].value.a = a->repeat;
924 op.params[1].value.b = 0;
925 op.params[2].tmpref.buffer = (void *)a->in;
926 op.params[2].tmpref.size = a->in_len;
927 op.params[3].tmpref.buffer = a->out;
928 op.params[3].tmpref.size = a->out_len;
929
930 if (a->in_len)
931 p2 = TEEC_MEMREF_TEMP_INPUT;
932 if (a->out_len)
933 p3 = TEEC_MEMREF_TEMP_OUTPUT;
934
935 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
936 TEEC_VALUE_INOUT, p2, p3);
937
938 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
939 a->max_concurrency = op.params[1].value.b;
940 a->out_len = op.params[3].tmpref.size;
941 TEEC_CloseSession(&session);
942 return NULL;
943}
944
Pascal Brand4fa35582015-12-17 10:59:12 +0100945#define NUM_THREADS 3
946
Jens Wiklander70672972016-04-06 00:01:45 +0200947static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
948 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200949{
Pascal Brand4fa35582015-12-17 10:59:12 +0100950 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200951 size_t nt;
952 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +0200953 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200954 pthread_t thr[num_threads];
955 TEEC_SharedMemory shm;
956 size_t max_concurrency;
957 struct test_1013_thread_arg arg[num_threads];
958 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
959 static const uint8_t sha256_out[] = {
960 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
961 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
962 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
963 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
964 };
965 uint8_t out[32] = { 0 };
966
Jens Wiklander70672972016-04-06 00:01:45 +0200967 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +0100968 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200969
970 memset(&shm, 0, sizeof(shm));
971 shm.size = sizeof(struct ta_concurrent_shm);
972 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
973 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
974 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
975 return;
976
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200977 memset(shm.buffer, 0, shm.size);
978 memset(arg, 0, sizeof(arg));
979 max_concurrency = 0;
980 nt = num_threads;
981
982 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +0200983 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200984 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +0200985 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200986 arg[n].shm = &shm;
987 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
988 test_1013_thread, arg + n)))
989 nt = n; /* break loop and start cleanup */
990 }
991
992 for (n = 0; n < nt; n++) {
993 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
994 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
995 if (arg[n].max_concurrency > max_concurrency)
996 max_concurrency = arg[n].max_concurrency;
997 }
998
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200999 /*
1000 * Concurrency can be limited by several factors, for instance in a
1001 * single CPU system it's dependent on the Preemtion Model used by
1002 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
1003 * best result there).
1004 */
1005 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
1006 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +01001007 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001008 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001009
Jens Wiklander70672972016-04-06 00:01:45 +02001010 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001011 memset(shm.buffer, 0, shm.size);
1012 memset(arg, 0, sizeof(arg));
1013 max_concurrency = 0;
1014 nt = num_threads;
1015
1016 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001017 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001018 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +02001019 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001020 arg[n].shm = &shm;
1021 arg[n].in = sha256_in;
1022 arg[n].in_len = sizeof(sha256_in);
1023 arg[n].out = out;
1024 arg[n].out_len = sizeof(out);
1025 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1026 test_1013_thread, arg + n)))
1027 nt = n; /* break loop and start cleanup */
1028 }
1029
1030 for (n = 0; n < nt; n++) {
1031 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1032 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1033 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1034 arg[n].out, arg[n].out_len);
1035 if (arg[n].max_concurrency > max_concurrency)
1036 max_concurrency = arg[n].max_concurrency;
1037 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001038 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001039 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001040
Pascal Brand4fa35582015-12-17 10:59:12 +01001041 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001042 TEEC_ReleaseSharedMemory(&shm);
1043}
Pascal Brand4fa35582015-12-17 10:59:12 +01001044
1045static void xtest_tee_test_1013(ADBG_Case_t *c)
1046{
1047 int i;
1048 double mean_concurrency;
1049 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001050 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001051
1052 if (level == 0)
1053 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001054
Jens Wiklander70672972016-04-06 00:01:45 +02001055 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001056 mean_concurrency = 0;
1057 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001058 xtest_tee_test_1013_single(c, &concurrency,
1059 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001060 mean_concurrency += concurrency;
1061 }
1062 mean_concurrency /= nb_loops;
1063
1064 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1065 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001066 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001067
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001068#ifndef CFG_PAGED_USER_TA
Jens Wiklander70672972016-04-06 00:01:45 +02001069 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1070 mean_concurrency = 0;
1071 for (i = 0; i < nb_loops; i++) {
1072 xtest_tee_test_1013_single(c, &concurrency,
1073 &concurrent_large_ta_uuid);
1074 mean_concurrency += concurrency;
1075 }
1076 mean_concurrency /= nb_loops;
1077
1078 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1079 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1080 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001081#endif
Jens Wiklander70672972016-04-06 00:01:45 +02001082}
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001083
1084#ifdef CFG_SECURE_DATA_PATH
1085static void xtest_tee_test_1014(ADBG_Case_t *c)
1086{
1087 UNUSED(c);
1088
1089 int size = 17000;
1090 int loop = 10;
1091 int ion_heap = DEFAULT_ION_HEAP_TYPE;
1092 int rnd_offset = 1;
1093 int test;
1094 int ret;
1095
1096 test = TEST_NS_TO_TA;
1097 Do_ADBG_BeginSubCase(c, "SDP: NonSecure client invokes a SDP TA");
1098 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset);
1099 ADBG_EXPECT(c, 0, ret);
1100 Do_ADBG_EndSubCase(c, "SDP: NonSecure client invokes a SDP TA");
1101
1102 test = TEST_TA_TO_TA;
1103 Do_ADBG_BeginSubCase(c, "SDP: SDP TA invokes a SDP TA");
1104 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset);
1105 ADBG_EXPECT(c, 0, ret);
1106 Do_ADBG_EndSubCase(c, "SDP: SDP TA invokes a SDP TA");
1107
1108 test = TEST_TA_TO_PTA;
1109 Do_ADBG_BeginSubCase(c, "SDP: SDP TA invokes a SDP pTA");
1110 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset);
1111 ADBG_EXPECT(c, 0, ret);
1112 Do_ADBG_EndSubCase(c, "SDP: SDP TA invokes a SDP pTA");
1113
1114 test = TEST_NS_TO_PTA;
1115 Do_ADBG_BeginSubCase(c, "SDP: NonSecure client invokes SDP pTA (should fail)");
1116 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset);
1117 ADBG_EXPECT(c, 1, ret);
1118 Do_ADBG_EndSubCase(c, "SDP: NonSecure client invokes SDP pTA (should fail)");
1119}
1120#endif