blob: 18d011d3a064ea60b3b42598201a79c5992570a0 [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
Jens Wiklander272d3642017-04-03 13:03:47 +020049static void xtest_tee_test_1015(ADBG_Case_t *Case_p);
Pascal Brandc639ac82015-07-02 08:53:34 +020050
Jens Wiklander74abfe32017-01-03 14:17:47 +010051ADBG_CASE_DEFINE(regression, 1001, xtest_tee_test_1001, "Core self tests");
52ADBG_CASE_DEFINE(regression, 1004, xtest_tee_test_1004, "Test User Crypt TA");
53ADBG_CASE_DEFINE(regression, 1005, xtest_tee_test_1005, "Many sessions");
54ADBG_CASE_DEFINE(regression, 1006, xtest_tee_test_1006,
55 "Test Basic OS features");
56ADBG_CASE_DEFINE(regression, 1007, xtest_tee_test_1007, "Test Panic");
57ADBG_CASE_DEFINE(regression, 1008, xtest_tee_test_1008,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010058 "TEE internal client API");
Jens Wiklander74abfe32017-01-03 14:17:47 +010059ADBG_CASE_DEFINE(regression, 1009, xtest_tee_test_1009, "TEE Wait");
60ADBG_CASE_DEFINE(regression, 1010, xtest_tee_test_1010,
61 "Invalid memory access");
62ADBG_CASE_DEFINE(regression, 1011, xtest_tee_test_1011,
Jens Wiklanderf7b9c632017-01-03 17:32:26 +010063 "Test TA-to-TA features with User Crypt TA");
Jens Wiklander74abfe32017-01-03 14:17:47 +010064ADBG_CASE_DEFINE(regression, 1012, xtest_tee_test_1012,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010065 "Test Single Instance Multi Session features with SIMS TA");
Jens Wiklander74abfe32017-01-03 14:17:47 +010066ADBG_CASE_DEFINE(regression, 1013, xtest_tee_test_1013,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010067 "Test concurency with concurrent TA");
Etienne Carriere50abf9a2017-03-24 11:33:50 +010068#ifdef CFG_SECURE_DATA_PATH
69ADBG_CASE_DEFINE(regression, 1014, xtest_tee_test_1014,
70 "Test secure data path against SDP TAs and pTAs");
71#endif
Jens Wiklander272d3642017-04-03 13:03:47 +020072ADBG_CASE_DEFINE(regression, 1015, xtest_tee_test_1015,
73 "FS hash-tree corner cases");
Jens Wiklanderac27ec12015-07-15 15:23:14 +020074
Pascal Brandc639ac82015-07-02 08:53:34 +020075struct xtest_crypto_session {
76 ADBG_Case_t *c;
77 TEEC_Session *session;
78 uint32_t cmd_id_sha256;
79 uint32_t cmd_id_aes256ecb_encrypt;
80 uint32_t cmd_id_aes256ecb_decrypt;
81};
82
83static void xtest_crypto_test(struct xtest_crypto_session *cs)
84{
85 uint32_t ret_orig;
86 uint8_t crypt_out[16];
87 uint8_t crypt_in[16] = { 22, 17 };
88
89 crypt_in[15] = 60;
90
91 Do_ADBG_BeginSubCase(cs->c, "AES encrypt");
92 {
93 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
94
95 op.params[0].tmpref.buffer = crypt_in;
96 op.params[0].tmpref.size = sizeof(crypt_in);
97 op.params[1].tmpref.buffer = crypt_out;
98 op.params[1].tmpref.size = sizeof(crypt_out);
99 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
100 TEEC_MEMREF_TEMP_OUTPUT,
101 TEEC_NONE, TEEC_NONE);
102
103 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
104 TEEC_InvokeCommand(cs->session,
105 cs->
106 cmd_id_aes256ecb_encrypt,
107 &op,
108 &ret_orig));
109 }
110 Do_ADBG_EndSubCase(cs->c, "AES encrypt");
111
112 Do_ADBG_BeginSubCase(cs->c, "AES decrypt");
113 {
114 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
115 uint8_t out[16];
116
117 op.params[0].tmpref.buffer = crypt_out;
118 op.params[0].tmpref.size = sizeof(crypt_out);
119 op.params[1].tmpref.buffer = out;
120 op.params[1].tmpref.size = sizeof(out);
121 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
122 TEEC_MEMREF_TEMP_OUTPUT,
123 TEEC_NONE, TEEC_NONE);
124
125 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
126 TEEC_InvokeCommand(cs->session,
127 cs->
128 cmd_id_aes256ecb_decrypt,
129 &op,
130 &ret_orig));
131
132 if (!ADBG_EXPECT(cs->c, 0,
133 memcmp(crypt_in, out, sizeof(crypt_in)))) {
134 Do_ADBG_Log("crypt_in:");
135 Do_ADBG_HexLog(crypt_in, sizeof(crypt_in), 16);
136 Do_ADBG_Log("out:");
137 Do_ADBG_HexLog(out, sizeof(out), 16);
138 }
139 }
140 Do_ADBG_EndSubCase(cs->c, "AES decrypt");
141
142 Do_ADBG_BeginSubCase(cs->c, "SHA-256 test, 3 bytes input");
143 {
144 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
145 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
146 static const uint8_t sha256_out[] = {
147 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
148 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
149 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
150 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
151 };
152 uint8_t out[32] = { 0 };
153
154 op.params[0].tmpref.buffer = (void *)sha256_in;
155 op.params[0].tmpref.size = sizeof(sha256_in);
156 op.params[1].tmpref.buffer = out;
157 op.params[1].tmpref.size = sizeof(out);
158 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
159 TEEC_MEMREF_TEMP_OUTPUT,
160 TEEC_NONE, TEEC_NONE);
161
162 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
163 TEEC_InvokeCommand(cs->session,
164 cs->
165 cmd_id_sha256,
166 &op,
167 &ret_orig));
168
169 if (!ADBG_EXPECT(cs->c, 0, memcmp(sha256_out, out,
170 sizeof(sha256_out)))) {
171 Do_ADBG_Log("sha256_out:");
172 Do_ADBG_HexLog(sha256_out, sizeof(sha256_out), 16);
173 Do_ADBG_Log("out:");
174 Do_ADBG_HexLog(out, sizeof(out), 16);
175 }
176 }
177 Do_ADBG_EndSubCase(cs->c, "SHA-256 test, 3 bytes input");
178
179 Do_ADBG_BeginSubCase(cs->c,
180 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
181 {
182 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
183 static const uint8_t in[] = {
184 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
185 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
186 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
187 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
188 };
189 static const uint8_t exp_out[] = {
190 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
191 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
192 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
193 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
194 };
195 uint8_t out[sizeof(exp_out)];
196
197 op.params[0].tmpref.buffer = (void *)in;
198 op.params[0].tmpref.size = sizeof(in);
199 op.params[1].tmpref.buffer = out;
200 op.params[1].tmpref.size = sizeof(out);
201 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
202 TEEC_MEMREF_TEMP_OUTPUT,
203 TEEC_NONE, TEEC_NONE);
204
205 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
206 TEEC_InvokeCommand(cs->session,
207 cs->
208 cmd_id_aes256ecb_encrypt,
209 &op,
210 &ret_orig));
211
212 if (!ADBG_EXPECT(cs->c, 0,
213 memcmp(exp_out, out, sizeof(exp_out)))) {
214 Do_ADBG_Log("exp_out:");
215 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
216 Do_ADBG_Log("out:");
217 Do_ADBG_HexLog(out, sizeof(out), 16);
218 }
219 }
220 Do_ADBG_EndSubCase(cs->c,
221 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
222
223 Do_ADBG_BeginSubCase(cs->c,
224 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
225 {
226 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
227 static const uint8_t in[] = {
228 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
229 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
230 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
231 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
232 };
233 static const uint8_t exp_out[] = {
234 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
235 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
236 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
237 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
238 };
239 uint8_t out[sizeof(exp_out)];
240
241 op.params[0].tmpref.buffer = (void *)in;
242 op.params[0].tmpref.size = sizeof(in);
243 op.params[1].tmpref.buffer = out;
244 op.params[1].tmpref.size = sizeof(out);
245 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
246 TEEC_MEMREF_TEMP_OUTPUT,
247 TEEC_NONE, TEEC_NONE);
248
249 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
250 TEEC_InvokeCommand(cs->session,
251 cs->
252 cmd_id_aes256ecb_decrypt,
253 &op,
254 &ret_orig));
255
256 if (!ADBG_EXPECT(cs->c, 0,
257 memcmp(exp_out, out, sizeof(exp_out)))) {
258 Do_ADBG_Log("exp_out:");
259 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
260 Do_ADBG_Log("out:");
261 Do_ADBG_HexLog(out, sizeof(out), 16);
262 }
263 }
264 Do_ADBG_EndSubCase(cs->c,
265 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
266}
267
268static void xtest_tee_test_1001(ADBG_Case_t *c)
269{
Jens Wiklandercf16e842016-02-10 09:07:09 +0100270 TEEC_Result res;
271 TEEC_Session session = { 0 };
272 uint32_t ret_orig;
Pascal Brandc639ac82015-07-02 08:53:34 +0200273
Etienne Carriere726d8bc2017-03-21 15:45:59 +0100274 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
Jens Wiklandercf16e842016-02-10 09:07:09 +0100275 &ret_orig);
276 /*
277 * If the static TA (which is optional) isn't available, skip this
278 * test.
279 */
280 if (res != TEEC_SUCCESS)
281 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200282
Jens Wiklandercf16e842016-02-10 09:07:09 +0100283 (void)ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
Etienne Carriere726d8bc2017-03-21 15:45:59 +0100284 &session, PTA_INVOKE_TESTS_CMD_SELF_TESTS, NULL, &ret_orig));
Jens Wiklandercf16e842016-02-10 09:07:09 +0100285 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200286}
287
288static void xtest_tee_test_1004(ADBG_Case_t *c)
289{
290 TEEC_Session session = { 0 };
291 uint32_t ret_orig;
292 struct xtest_crypto_session cs = { c, &session, TA_CRYPT_CMD_SHA256,
293 TA_CRYPT_CMD_AES256ECB_ENC,
294 TA_CRYPT_CMD_AES256ECB_DEC };
295
296 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
297 &session, &crypt_user_ta_uuid,
298 NULL, &ret_orig)))
299 return;
300
301 /* Run the "complete crypto test suite" */
302 xtest_crypto_test(&cs);
303
304 TEEC_CloseSession(&session);
305}
306
307#ifndef TEEC_ERROR_TARGET_DEAD
308/* To be removed when we have TEEC_ERROR_TARGET_DEAD from tee_client_api.h */
309#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024
310#endif
311
312static void xtest_tee_test_invalid_mem_access(ADBG_Case_t *c, uint32_t n)
313{
314 TEEC_Session session = { 0 };
315 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
316 uint32_t ret_orig;
317
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300318 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200319 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300320 &ret_orig)))
321 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200322
323 op.params[0].value.a = n;
324 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
325 TEEC_NONE);
326
327 (void)ADBG_EXPECT_TEEC_RESULT(c,
328 TEEC_ERROR_TARGET_DEAD,
329 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
330 &ret_orig));
331
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300332 (void)ADBG_EXPECT_TEEC_RESULT(c,
333 TEEC_ERROR_TARGET_DEAD,
334 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
Pascal Brandc639ac82015-07-02 08:53:34 +0200335 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300336
Pascal Brandc639ac82015-07-02 08:53:34 +0200337 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
338
339 TEEC_CloseSession(&session);
340}
341
342static void xtest_tee_test_1005(ADBG_Case_t *c)
343{
344 uint32_t ret_orig;
345#define MAX_SESSIONS 3
346 TEEC_Session sessions[MAX_SESSIONS];
347 int i;
348
349 for (i = 0; i < MAX_SESSIONS; i++) {
350 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Jens Wiklandereb6bce72016-09-23 11:37:33 +0200351 xtest_teec_open_session(&sessions[i],
352 &concurrent_ta_uuid,
Pascal Brandc639ac82015-07-02 08:53:34 +0200353 NULL, &ret_orig)))
354 break;
355 }
356
357 for (; --i >= 0; )
358 TEEC_CloseSession(&sessions[i]);
359}
360
361static void xtest_tee_test_1006(ADBG_Case_t *c)
362{
363 TEEC_Session session = { 0 };
364 uint32_t ret_orig;
365 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
366 uint8_t buf[32];
367
368 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
369 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
370 &ret_orig)))
371 return;
372
373 op.params[0].tmpref.buffer = buf;
374 op.params[0].tmpref.size = sizeof(buf);
375 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
376 TEEC_NONE, TEEC_NONE);
377
378 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
379 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
380 &ret_orig));
381
382 TEEC_CloseSession(&session);
383}
384
385static void xtest_tee_test_1007(ADBG_Case_t *c)
386{
387 TEEC_Session session = { 0 };
388 uint32_t ret_orig;
389
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300390 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200391 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300392 &ret_orig)))
393 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200394
395 (void)ADBG_EXPECT_TEEC_RESULT(c,
396 TEEC_ERROR_TARGET_DEAD,
397 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
398 &ret_orig));
399
400 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
401
402 (void)ADBG_EXPECT_TEEC_RESULT(c,
403 TEEC_ERROR_TARGET_DEAD,
404 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
405 &ret_orig));
406
407 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
408
409 TEEC_CloseSession(&session);
410}
411
Jerome Forissierf02a2212015-10-29 14:33:35 +0100412#ifndef TA_DIR
Victor Chong3d8798f2017-03-01 18:31:48 +0000413# ifdef __ANDROID__
414#define TA_DIR "/system/lib/optee_armtz"
415# else
Jerome Forissierf02a2212015-10-29 14:33:35 +0100416#define TA_DIR "/lib/optee_armtz"
Victor Chong3d8798f2017-03-01 18:31:48 +0000417# endif
Jerome Forissierf02a2212015-10-29 14:33:35 +0100418#endif
419
David Brownb2865ab2016-08-02 11:44:41 -0600420#ifndef TA_TEST_DIR
421# ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200422# define TA_TEST_DIR "/data/tee/optee_armtz"
David Brownb2865ab2016-08-02 11:44:41 -0600423# else
424# define TA_TEST_DIR "/tmp/optee_armtz"
425# endif
426#endif
Jens Wiklanderb7940892015-10-23 16:02:40 +0200427
David Brownb2865ab2016-08-02 11:44:41 -0600428static void make_test_ta_dir(void)
429{
430#ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200431 (void)mkdir("/data/tee", 0755);
David Brownb2865ab2016-08-02 11:44:41 -0600432#endif
433 (void)mkdir(TA_TEST_DIR, 0755);
434}
435
436static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
437 bool for_write)
438{
Jens Wiklanderb7940892015-10-23 16:02:40 +0200439 snprintf(buf, blen,
Jens Wiklander6203b872016-12-08 19:18:29 +0100440 "%s/%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x.ta",
David Brownb2865ab2016-08-02 11:44:41 -0600441 for_write ? TA_TEST_DIR : TA_DIR,
442 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
Jens Wiklanderb7940892015-10-23 16:02:40 +0200443 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
444 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
445 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
David Brownb2865ab2016-08-02 11:44:41 -0600446 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200447}
448
David Brownb2865ab2016-08-02 11:44:41 -0600449static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode,
450 bool for_write)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200451{
452 char buf[PATH_MAX];
453
David Brownb2865ab2016-08-02 11:44:41 -0600454 uuid_to_full_name(buf, sizeof(buf), uuid, for_write);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200455 return fopen(buf, mode);
456}
457
David Brownb2865ab2016-08-02 11:44:41 -0600458static bool rm_file(const TEEC_UUID *uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200459{
460 char buf[PATH_MAX];
461
David Brownb2865ab2016-08-02 11:44:41 -0600462 uuid_to_full_name(buf, sizeof(buf), uuid, true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200463 return !unlink(buf);
464}
465
David Brownb2865ab2016-08-02 11:44:41 -0600466static bool copy_file(const TEEC_UUID *src_uuid, const TEEC_UUID *dst_uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200467{
468 char buf[4 * 1024];
David Brownb2865ab2016-08-02 11:44:41 -0600469 FILE *src = open_ta_file(src_uuid, "r", false);
470 FILE *dst = open_ta_file(dst_uuid, "w", true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200471 size_t r;
472 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200473 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200474
Jens Wiklander4441fe22015-10-23 16:53:02 +0200475 if (src && dst) {
476 do {
477 r = fread(buf, 1, sizeof(buf), src);
478 if (!r) {
479 ret = !!feof(src);
480 break;
481 }
482 w = fwrite(buf, 1, r, dst);
483 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200484 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200485
486 if (src)
487 fclose(src);
488 if (dst)
489 fclose(dst);
490 return ret;
491}
492
493static bool corrupt_file(FILE *f, long offs, uint8_t mask)
494{
495 uint8_t b;
496
497 if (fseek(f, offs, SEEK_SET))
498 return false;
499
500 if (fread(&b, 1, 1, f) != 1)
501 return false;
502
503 b ^= mask;
504
505 if (fseek(f, offs, SEEK_SET))
506 return false;
507
508 if (fwrite(&b, 1, 1, f) != 1)
509 return false;
510
511 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200512}
513
514static void load_fake_ta(ADBG_Case_t *c)
515{
516 static const TEEC_UUID fake_uuid = {
517 0x7e0a0900, 0x586b, 0x11e5,
518 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
519 };
520 TEEC_Session session = { 0 };
521 TEEC_Result res;
522 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200523 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200524
David Brownb2865ab2016-08-02 11:44:41 -0600525 r = copy_file(&create_fail_test_ta_uuid, &fake_uuid);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200526
527 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200528 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
529 &ret_orig);
530 if (res == TEEC_SUCCESS)
531 TEEC_CloseSession(&session);
532 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200533 }
534
David Brownb2865ab2016-08-02 11:44:41 -0600535 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid));
Jens Wiklanderb7940892015-10-23 16:02:40 +0200536}
537
Jens Wiklander4441fe22015-10-23 16:53:02 +0200538static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
539{
540 TEEC_Session session = { 0 };
541 TEEC_Result res;
542 uint32_t ret_orig;
543 FILE *f;
544 bool r;
545
David Brownb2865ab2016-08-02 11:44:41 -0600546 r = copy_file(&create_fail_test_ta_uuid, &create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200547 if (!ADBG_EXPECT_TRUE(c, r)) {
David Brownb2865ab2016-08-02 11:44:41 -0600548 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200549 return false;
550 }
551
David Brownb2865ab2016-08-02 11:44:41 -0600552 f = open_ta_file(&create_fail_test_ta_uuid, "r+", true);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200553 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
David Brownb2865ab2016-08-02 11:44:41 -0600554 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200555 return false;
556 }
557 r = corrupt_file(f, offs, mask);
558 fclose(f);
559
560 if (ADBG_EXPECT_TRUE(c, r)) {
561 res = xtest_teec_open_session(&session,
562 &create_fail_test_ta_uuid,
563 NULL, &ret_orig);
564 if (res == TEEC_SUCCESS)
565 TEEC_CloseSession(&session);
566 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
567 }
568
David Brownb2865ab2016-08-02 11:44:41 -0600569 r &= ADBG_EXPECT_TRUE(c, rm_file(&create_fail_test_ta_uuid));
Jens Wiklander4441fe22015-10-23 16:53:02 +0200570 return r;
571}
572
Pascal Brandc639ac82015-07-02 08:53:34 +0200573static void xtest_tee_test_1008(ADBG_Case_t *c)
574{
575 TEEC_Session session = { 0 };
576 TEEC_Session session_crypt = { 0 };
577 uint32_t ret_orig;
578
579 Do_ADBG_BeginSubCase(c, "Invoke command");
580 {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300581 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200582 xtest_teec_open_session(&session, &os_test_ta_uuid,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300583 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200584
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300585 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
586 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
587 NULL, &ret_orig));
588 TEEC_CloseSession(&session);
589 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200590
Pascal Brandc639ac82015-07-02 08:53:34 +0200591 }
592 Do_ADBG_EndSubCase(c, "Invoke command");
593
594 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
595 {
596 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
597
598 op.params[0].value.a = 2000;
599 op.paramTypes = TEEC_PARAM_TYPES(
600 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
601
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300602 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200603 xtest_teec_open_session(&session,
604 &os_test_ta_uuid,
605 NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300606 &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200607
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300608 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
609 TEEC_InvokeCommand(&session,
610 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
611 &op, &ret_orig));
612 TEEC_CloseSession(&session);
613 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200614 }
615 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
616
617 Do_ADBG_BeginSubCase(c, "Create session fail");
618 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200619 size_t n;
620
Pascal Brandc639ac82015-07-02 08:53:34 +0200621 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
622 xtest_teec_open_session(&session_crypt,
623 &create_fail_test_ta_uuid, NULL,
624 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200625 /*
626 * Run this several times to see that there's no memory leakage.
627 */
628 for (n = 0; n < 100; n++) {
629 Do_ADBG_Log("n = %zu", n);
630 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
631 xtest_teec_open_session(&session_crypt,
632 &create_fail_test_ta_uuid,
633 NULL, &ret_orig));
634 }
635 }
636 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200637
David Brownb2865ab2016-08-02 11:44:41 -0600638 make_test_ta_dir();
639
Jens Wiklanderb7940892015-10-23 16:02:40 +0200640 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
641 load_fake_ta(c);
642 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
643
Jens Wiklander4441fe22015-10-23 16:53:02 +0200644 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
645 ADBG_EXPECT_TRUE(c,
646 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
647 ADBG_EXPECT_TRUE(c,
648 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
649 ADBG_EXPECT_TRUE(c,
650 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
651 ADBG_EXPECT_TRUE(c,
652 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
653 ADBG_EXPECT_TRUE(c,
654 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
655 ADBG_EXPECT_TRUE(c,
656 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
657 ADBG_EXPECT_TRUE(c,
658 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
659 ADBG_EXPECT_TRUE(c,
660 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
661 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
662 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
663 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200664}
665
Pascal Brandc639ac82015-07-02 08:53:34 +0200666static void *cancellation_thread(void *arg)
667{
668 /*
669 * Sleep 0.5 seconds before cancellation to make sure that the other
670 * thread is in RPC_WAIT.
671 */
672 (void)usleep(500000);
673 TEEC_RequestCancellation(arg);
674 return NULL;
675}
Pascal Brandc639ac82015-07-02 08:53:34 +0200676
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300677static void xtest_tee_test_1009_subcase(ADBG_Case_t *c, const char *subcase,
678 uint32_t timeout, bool cancel)
Pascal Brandc639ac82015-07-02 08:53:34 +0200679{
680 TEEC_Session session = { 0 };
681 uint32_t ret_orig;
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300682 pthread_t thr;
Pascal Brandc639ac82015-07-02 08:53:34 +0200683
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300684 Do_ADBG_BeginSubCase(c, "%s", subcase);
Pascal Brandc639ac82015-07-02 08:53:34 +0200685 {
686 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
687
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300688 if (ADBG_EXPECT_TEEC_SUCCESS(c,
689 xtest_teec_open_session(&session, &os_test_ta_uuid,
690 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200691
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300692 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c,
693 TEEC_ORIGIN_TRUSTED_APP,
694 ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200695
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300696 op.params[0].value.a = timeout;
697 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
698 TEEC_NONE,
699 TEEC_NONE, TEEC_NONE);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300700 if (cancel) {
701 (void)ADBG_EXPECT(c, 0,
702 pthread_create(&thr, NULL,
703 cancellation_thread, &op));
Pascal Brandc639ac82015-07-02 08:53:34 +0200704
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300705 (void)ADBG_EXPECT_TEEC_RESULT(c,
706 TEEC_ERROR_CANCEL,
707 TEEC_InvokeCommand(&session,
708 TA_OS_TEST_CMD_WAIT,
709 &op,
710 &ret_orig));
711 } else
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300712
713 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
714 TEEC_InvokeCommand(&session,
715 TA_OS_TEST_CMD_WAIT,
716 &op,
717 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300718 if (cancel)
719 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300720
721 TEEC_CloseSession(&session);
722 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200723 }
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300724 Do_ADBG_EndSubCase(c, "%s", subcase);
725}
726
727static void xtest_tee_test_1009(ADBG_Case_t *c)
728{
729 xtest_tee_test_1009_subcase(c, "TEE Wait 0.1s", 100, false);
730 xtest_tee_test_1009_subcase(c, "TEE Wait 0.5s", 500, false);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300731 xtest_tee_test_1009_subcase(c, "TEE Wait 2s cancel", 2000, true);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300732 xtest_tee_test_1009_subcase(c, "TEE Wait 2s", 2000, false);
Pascal Brandc639ac82015-07-02 08:53:34 +0200733}
734
735static void xtest_tee_test_1010(ADBG_Case_t *c)
736{
737 unsigned n;
738
739 for (n = 1; n <= 5; n++) {
740 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
741 xtest_tee_test_invalid_mem_access(c, n);
742 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
743 }
744}
745
746static void xtest_tee_test_1011(ADBG_Case_t *c)
747{
748 TEEC_Session session = { 0 };
749 uint32_t ret_orig;
750 struct xtest_crypto_session cs = {
751 c, &session, TA_RPC_CMD_CRYPT_SHA256,
752 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
753 TA_RPC_CMD_CRYPT_AES256ECB_DEC
754 };
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100755 struct xtest_crypto_session cs_privmem = {
756 c, &session,
757 TA_RPC_CMD_CRYPT_PRIVMEM_SHA256,
758 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_ENC,
759 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_DEC
760 };
Pascal Brandc639ac82015-07-02 08:53:34 +0200761 TEEC_UUID uuid = rpc_test_ta_uuid;
762
763 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
764 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
765 return;
766
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100767 Do_ADBG_BeginSubCase(c, "TA-to-TA via non-secure shared memory");
Pascal Brandc639ac82015-07-02 08:53:34 +0200768 /*
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100769 * Run the "complete crypto test suite" using TA-to-TA
770 * communication
Pascal Brandc639ac82015-07-02 08:53:34 +0200771 */
772 xtest_crypto_test(&cs);
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100773 Do_ADBG_EndSubCase(c, "TA-to-TA via non-secure shared memory");
774
775 Do_ADBG_BeginSubCase(c, "TA-to-TA via TA private memory");
776 /*
777 * Run the "complete crypto test suite" using TA-to-TA
778 * communication via TA private memory.
779 */
780 xtest_crypto_test(&cs_privmem);
781 Do_ADBG_EndSubCase(c, "TA-to-TA via TA private memory");
782
Pascal Brandc639ac82015-07-02 08:53:34 +0200783 TEEC_CloseSession(&session);
784}
785
786/*
787 * Note that this test is failing when
788 * - running twice in a raw
789 * - and the user TA is statically linked
790 * This is because the counter is not reseted when opening the first session
791 * in case the TA is statically linked
792 */
793static void xtest_tee_test_1012(ADBG_Case_t *c)
794{
795 TEEC_Session session1 = { 0 };
796 TEEC_Session session2 = { 0 };
797 uint32_t ret_orig;
798 TEEC_UUID uuid = sims_test_ta_uuid;
799
800 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
801 {
802 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
803 static const uint8_t in[] = {
804 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
805 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
806 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
807 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
808 };
809 uint8_t out[32] = { 0 };
810 int i;
811
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300812 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200813 xtest_teec_open_session(&session1, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300814 &ret_orig)))
815 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200816
817 op.params[0].value.a = 0;
818 op.params[1].tmpref.buffer = (void *)in;
819 op.params[1].tmpref.size = sizeof(in);
820 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
821 TEEC_MEMREF_TEMP_INPUT,
822 TEEC_NONE, TEEC_NONE);
823
824 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
825 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
826 &ret_orig));
827
828 for (i = 1; i < 1000; i++) {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300829 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200830 xtest_teec_open_session(&session2, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300831 &ret_orig)))
832 continue;
Pascal Brandc639ac82015-07-02 08:53:34 +0200833
834 op.params[0].value.a = 0;
835 op.params[1].tmpref.buffer = out;
836 op.params[1].tmpref.size = sizeof(out);
837 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
838 TEEC_MEMREF_TEMP_OUTPUT,
839 TEEC_NONE, TEEC_NONE);
840
841 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
842 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
843 &op, &ret_orig));
844
845 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
846 sizeof(out))) {
847 Do_ADBG_Log("in:");
848 Do_ADBG_HexLog(in, sizeof(in), 16);
849 Do_ADBG_Log("out:");
850 Do_ADBG_HexLog(out, sizeof(out), 16);
851 }
852
853 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
854 TEEC_NONE, TEEC_NONE,
855 TEEC_NONE);
856
857 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
858 TEEC_InvokeCommand(&session1,
859 TA_SIMS_CMD_GET_COUNTER,
860 &op, &ret_orig));
861
862 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
863
864 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
865 TEEC_InvokeCommand(&session2,
866 TA_SIMS_CMD_GET_COUNTER, &op,
867 &ret_orig));
868
869 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
870 TEEC_CloseSession(&session2);
871 }
872
873 memset(out, 0, sizeof(out));
874 op.params[0].value.a = 0;
875 op.params[1].tmpref.buffer = out;
876 op.params[1].tmpref.size = sizeof(out);
877 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
878 TEEC_MEMREF_TEMP_OUTPUT,
879 TEEC_NONE, TEEC_NONE);
880
881 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
882 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
883 &ret_orig));
884
885 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
886 Do_ADBG_Log("in:");
887 Do_ADBG_HexLog(in, sizeof(in), 16);
888 Do_ADBG_Log("out:");
889 Do_ADBG_HexLog(out, sizeof(out), 16);
890 }
891
892 TEEC_CloseSession(&session1);
893 }
894}
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200895
896struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +0200897 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200898 uint32_t cmd;
899 uint32_t repeat;
900 TEEC_SharedMemory *shm;
901 uint32_t error_orig;
902 TEEC_Result res;
903 uint32_t max_concurrency;
904 const uint8_t *in;
905 size_t in_len;
906 uint8_t *out;
907 size_t out_len;
908};
909
910static void *test_1013_thread(void *arg)
911{
912 struct test_1013_thread_arg *a = arg;
913 TEEC_Session session = { 0 };
914 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
915 uint8_t p2 = TEEC_NONE;
916 uint8_t p3 = TEEC_NONE;
917
Jens Wiklander70672972016-04-06 00:01:45 +0200918 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200919 &a->error_orig);
920 if (a->res != TEEC_SUCCESS)
921 return NULL;
922
923 op.params[0].memref.parent = a->shm;
924 op.params[0].memref.size = a->shm->size;
925 op.params[0].memref.offset = 0;
926 op.params[1].value.a = a->repeat;
927 op.params[1].value.b = 0;
928 op.params[2].tmpref.buffer = (void *)a->in;
929 op.params[2].tmpref.size = a->in_len;
930 op.params[3].tmpref.buffer = a->out;
931 op.params[3].tmpref.size = a->out_len;
932
933 if (a->in_len)
934 p2 = TEEC_MEMREF_TEMP_INPUT;
935 if (a->out_len)
936 p3 = TEEC_MEMREF_TEMP_OUTPUT;
937
938 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
939 TEEC_VALUE_INOUT, p2, p3);
940
941 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
942 a->max_concurrency = op.params[1].value.b;
943 a->out_len = op.params[3].tmpref.size;
944 TEEC_CloseSession(&session);
945 return NULL;
946}
947
Pascal Brand4fa35582015-12-17 10:59:12 +0100948#define NUM_THREADS 3
949
Jens Wiklander70672972016-04-06 00:01:45 +0200950static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
951 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200952{
Pascal Brand4fa35582015-12-17 10:59:12 +0100953 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200954 size_t nt;
955 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +0200956 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200957 pthread_t thr[num_threads];
958 TEEC_SharedMemory shm;
959 size_t max_concurrency;
960 struct test_1013_thread_arg arg[num_threads];
961 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
962 static const uint8_t sha256_out[] = {
963 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
964 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
965 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
966 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
967 };
968 uint8_t out[32] = { 0 };
969
Jens Wiklander70672972016-04-06 00:01:45 +0200970 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +0100971 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200972
973 memset(&shm, 0, sizeof(shm));
974 shm.size = sizeof(struct ta_concurrent_shm);
975 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
976 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
977 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
978 return;
979
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200980 memset(shm.buffer, 0, shm.size);
981 memset(arg, 0, sizeof(arg));
982 max_concurrency = 0;
983 nt = num_threads;
984
985 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +0200986 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200987 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +0200988 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200989 arg[n].shm = &shm;
990 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
991 test_1013_thread, arg + n)))
992 nt = n; /* break loop and start cleanup */
993 }
994
995 for (n = 0; n < nt; n++) {
996 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
997 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
998 if (arg[n].max_concurrency > max_concurrency)
999 max_concurrency = arg[n].max_concurrency;
1000 }
1001
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001002 /*
1003 * Concurrency can be limited by several factors, for instance in a
1004 * single CPU system it's dependent on the Preemtion Model used by
1005 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
1006 * best result there).
1007 */
1008 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
1009 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +01001010 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001011 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001012
Jens Wiklander70672972016-04-06 00:01:45 +02001013 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001014 memset(shm.buffer, 0, shm.size);
1015 memset(arg, 0, sizeof(arg));
1016 max_concurrency = 0;
1017 nt = num_threads;
1018
1019 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001020 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001021 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +02001022 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001023 arg[n].shm = &shm;
1024 arg[n].in = sha256_in;
1025 arg[n].in_len = sizeof(sha256_in);
1026 arg[n].out = out;
1027 arg[n].out_len = sizeof(out);
1028 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1029 test_1013_thread, arg + n)))
1030 nt = n; /* break loop and start cleanup */
1031 }
1032
1033 for (n = 0; n < nt; n++) {
1034 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1035 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1036 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1037 arg[n].out, arg[n].out_len);
1038 if (arg[n].max_concurrency > max_concurrency)
1039 max_concurrency = arg[n].max_concurrency;
1040 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001041 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001042 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001043
Pascal Brand4fa35582015-12-17 10:59:12 +01001044 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001045 TEEC_ReleaseSharedMemory(&shm);
1046}
Pascal Brand4fa35582015-12-17 10:59:12 +01001047
1048static void xtest_tee_test_1013(ADBG_Case_t *c)
1049{
1050 int i;
1051 double mean_concurrency;
1052 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001053 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001054
1055 if (level == 0)
1056 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001057
Jens Wiklander70672972016-04-06 00:01:45 +02001058 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001059 mean_concurrency = 0;
1060 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001061 xtest_tee_test_1013_single(c, &concurrency,
1062 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001063 mean_concurrency += concurrency;
1064 }
1065 mean_concurrency /= nb_loops;
1066
1067 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1068 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001069 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001070
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001071#ifndef CFG_PAGED_USER_TA
Jens Wiklander70672972016-04-06 00:01:45 +02001072 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1073 mean_concurrency = 0;
1074 for (i = 0; i < nb_loops; i++) {
1075 xtest_tee_test_1013_single(c, &concurrency,
1076 &concurrent_large_ta_uuid);
1077 mean_concurrency += concurrency;
1078 }
1079 mean_concurrency /= nb_loops;
1080
1081 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1082 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1083 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001084#endif
Jens Wiklander70672972016-04-06 00:01:45 +02001085}
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001086
1087#ifdef CFG_SECURE_DATA_PATH
1088static void xtest_tee_test_1014(ADBG_Case_t *c)
1089{
1090 UNUSED(c);
1091
1092 int size = 17000;
1093 int loop = 10;
1094 int ion_heap = DEFAULT_ION_HEAP_TYPE;
1095 int rnd_offset = 1;
1096 int test;
1097 int ret;
1098
1099 test = TEST_NS_TO_TA;
1100 Do_ADBG_BeginSubCase(c, "SDP: NonSecure client invokes a SDP TA");
1101 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset);
1102 ADBG_EXPECT(c, 0, ret);
1103 Do_ADBG_EndSubCase(c, "SDP: NonSecure client invokes a SDP TA");
1104
1105 test = TEST_TA_TO_TA;
1106 Do_ADBG_BeginSubCase(c, "SDP: SDP TA invokes a SDP TA");
1107 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset);
1108 ADBG_EXPECT(c, 0, ret);
1109 Do_ADBG_EndSubCase(c, "SDP: SDP TA invokes a SDP TA");
1110
1111 test = TEST_TA_TO_PTA;
1112 Do_ADBG_BeginSubCase(c, "SDP: SDP TA invokes a SDP pTA");
1113 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset);
1114 ADBG_EXPECT(c, 0, ret);
1115 Do_ADBG_EndSubCase(c, "SDP: SDP TA invokes a SDP pTA");
1116
1117 test = TEST_NS_TO_PTA;
1118 Do_ADBG_BeginSubCase(c, "SDP: NonSecure client invokes SDP pTA (should fail)");
1119 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset);
1120 ADBG_EXPECT(c, 1, ret);
1121 Do_ADBG_EndSubCase(c, "SDP: NonSecure client invokes SDP pTA (should fail)");
1122}
1123#endif
Jens Wiklander272d3642017-04-03 13:03:47 +02001124
1125static void xtest_tee_test_1015(ADBG_Case_t *c)
1126{
1127 TEEC_Result res;
1128 TEEC_Session session = { 0 };
1129 uint32_t ret_orig;
1130
1131 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
1132 &ret_orig);
1133 /*
1134 * If the static TA (which is optional) isn't available, skip this
1135 * test.
1136 */
1137 if (res != TEEC_SUCCESS)
1138 return;
1139
1140 ADBG_EXPECT_TEEC_SUCCESS(c,
1141 TEEC_InvokeCommand(&session, PTA_INVOKE_TESTS_CMD_FS_HTREE,
1142 NULL, &ret_orig));
1143 TEEC_CloseSession(&session);
1144}