blob: 4b2f850615e2ef7cf964eaf029a1c0b1577d0537 [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);
Jerome Forissiere916b102017-06-07 17:55:52 +020050static void xtest_tee_test_1016(ADBG_Case_t *Case_p);
Pascal Brandc639ac82015-07-02 08:53:34 +020051
Jens Wiklander74abfe32017-01-03 14:17:47 +010052ADBG_CASE_DEFINE(regression, 1001, xtest_tee_test_1001, "Core self tests");
53ADBG_CASE_DEFINE(regression, 1004, xtest_tee_test_1004, "Test User Crypt TA");
54ADBG_CASE_DEFINE(regression, 1005, xtest_tee_test_1005, "Many sessions");
55ADBG_CASE_DEFINE(regression, 1006, xtest_tee_test_1006,
56 "Test Basic OS features");
57ADBG_CASE_DEFINE(regression, 1007, xtest_tee_test_1007, "Test Panic");
58ADBG_CASE_DEFINE(regression, 1008, xtest_tee_test_1008,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010059 "TEE internal client API");
Jens Wiklander74abfe32017-01-03 14:17:47 +010060ADBG_CASE_DEFINE(regression, 1009, xtest_tee_test_1009, "TEE Wait");
61ADBG_CASE_DEFINE(regression, 1010, xtest_tee_test_1010,
62 "Invalid memory access");
63ADBG_CASE_DEFINE(regression, 1011, xtest_tee_test_1011,
Jens Wiklanderf7b9c632017-01-03 17:32:26 +010064 "Test TA-to-TA features with User Crypt TA");
Jens Wiklander74abfe32017-01-03 14:17:47 +010065ADBG_CASE_DEFINE(regression, 1012, xtest_tee_test_1012,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010066 "Test Single Instance Multi Session features with SIMS TA");
Jens Wiklander74abfe32017-01-03 14:17:47 +010067ADBG_CASE_DEFINE(regression, 1013, xtest_tee_test_1013,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010068 "Test concurency with concurrent TA");
Etienne Carriere50abf9a2017-03-24 11:33:50 +010069#ifdef CFG_SECURE_DATA_PATH
70ADBG_CASE_DEFINE(regression, 1014, xtest_tee_test_1014,
71 "Test secure data path against SDP TAs and pTAs");
72#endif
Jens Wiklander272d3642017-04-03 13:03:47 +020073ADBG_CASE_DEFINE(regression, 1015, xtest_tee_test_1015,
74 "FS hash-tree corner cases");
Jerome Forissiere916b102017-06-07 17:55:52 +020075ADBG_CASE_DEFINE(regression, 1016, xtest_tee_test_1016,
76 "Test TA to TA transfers (in/out/inout memrefs on the stack)");
Jens Wiklanderac27ec12015-07-15 15:23:14 +020077
Pascal Brandc639ac82015-07-02 08:53:34 +020078struct xtest_crypto_session {
79 ADBG_Case_t *c;
80 TEEC_Session *session;
81 uint32_t cmd_id_sha256;
82 uint32_t cmd_id_aes256ecb_encrypt;
83 uint32_t cmd_id_aes256ecb_decrypt;
84};
85
86static void xtest_crypto_test(struct xtest_crypto_session *cs)
87{
88 uint32_t ret_orig;
89 uint8_t crypt_out[16];
90 uint8_t crypt_in[16] = { 22, 17 };
91
92 crypt_in[15] = 60;
93
94 Do_ADBG_BeginSubCase(cs->c, "AES encrypt");
95 {
96 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
97
98 op.params[0].tmpref.buffer = crypt_in;
99 op.params[0].tmpref.size = sizeof(crypt_in);
100 op.params[1].tmpref.buffer = crypt_out;
101 op.params[1].tmpref.size = sizeof(crypt_out);
102 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
103 TEEC_MEMREF_TEMP_OUTPUT,
104 TEEC_NONE, TEEC_NONE);
105
106 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
107 TEEC_InvokeCommand(cs->session,
108 cs->
109 cmd_id_aes256ecb_encrypt,
110 &op,
111 &ret_orig));
112 }
113 Do_ADBG_EndSubCase(cs->c, "AES encrypt");
114
115 Do_ADBG_BeginSubCase(cs->c, "AES decrypt");
116 {
117 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
118 uint8_t out[16];
119
120 op.params[0].tmpref.buffer = crypt_out;
121 op.params[0].tmpref.size = sizeof(crypt_out);
122 op.params[1].tmpref.buffer = out;
123 op.params[1].tmpref.size = sizeof(out);
124 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
125 TEEC_MEMREF_TEMP_OUTPUT,
126 TEEC_NONE, TEEC_NONE);
127
128 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
129 TEEC_InvokeCommand(cs->session,
130 cs->
131 cmd_id_aes256ecb_decrypt,
132 &op,
133 &ret_orig));
134
135 if (!ADBG_EXPECT(cs->c, 0,
136 memcmp(crypt_in, out, sizeof(crypt_in)))) {
137 Do_ADBG_Log("crypt_in:");
138 Do_ADBG_HexLog(crypt_in, sizeof(crypt_in), 16);
139 Do_ADBG_Log("out:");
140 Do_ADBG_HexLog(out, sizeof(out), 16);
141 }
142 }
143 Do_ADBG_EndSubCase(cs->c, "AES decrypt");
144
145 Do_ADBG_BeginSubCase(cs->c, "SHA-256 test, 3 bytes input");
146 {
147 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
148 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
149 static const uint8_t sha256_out[] = {
150 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
151 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
152 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
153 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
154 };
155 uint8_t out[32] = { 0 };
156
157 op.params[0].tmpref.buffer = (void *)sha256_in;
158 op.params[0].tmpref.size = sizeof(sha256_in);
159 op.params[1].tmpref.buffer = out;
160 op.params[1].tmpref.size = sizeof(out);
161 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
162 TEEC_MEMREF_TEMP_OUTPUT,
163 TEEC_NONE, TEEC_NONE);
164
165 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
166 TEEC_InvokeCommand(cs->session,
167 cs->
168 cmd_id_sha256,
169 &op,
170 &ret_orig));
171
172 if (!ADBG_EXPECT(cs->c, 0, memcmp(sha256_out, out,
173 sizeof(sha256_out)))) {
174 Do_ADBG_Log("sha256_out:");
175 Do_ADBG_HexLog(sha256_out, sizeof(sha256_out), 16);
176 Do_ADBG_Log("out:");
177 Do_ADBG_HexLog(out, sizeof(out), 16);
178 }
179 }
180 Do_ADBG_EndSubCase(cs->c, "SHA-256 test, 3 bytes input");
181
182 Do_ADBG_BeginSubCase(cs->c,
183 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
184 {
185 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
186 static const uint8_t in[] = {
187 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
188 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
189 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
190 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
191 };
192 static const uint8_t exp_out[] = {
193 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
194 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
195 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
196 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
197 };
198 uint8_t out[sizeof(exp_out)];
199
200 op.params[0].tmpref.buffer = (void *)in;
201 op.params[0].tmpref.size = sizeof(in);
202 op.params[1].tmpref.buffer = out;
203 op.params[1].tmpref.size = sizeof(out);
204 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
205 TEEC_MEMREF_TEMP_OUTPUT,
206 TEEC_NONE, TEEC_NONE);
207
208 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
209 TEEC_InvokeCommand(cs->session,
210 cs->
211 cmd_id_aes256ecb_encrypt,
212 &op,
213 &ret_orig));
214
215 if (!ADBG_EXPECT(cs->c, 0,
216 memcmp(exp_out, out, sizeof(exp_out)))) {
217 Do_ADBG_Log("exp_out:");
218 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
219 Do_ADBG_Log("out:");
220 Do_ADBG_HexLog(out, sizeof(out), 16);
221 }
222 }
223 Do_ADBG_EndSubCase(cs->c,
224 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
225
226 Do_ADBG_BeginSubCase(cs->c,
227 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
228 {
229 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
230 static const uint8_t in[] = {
231 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
232 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
233 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
234 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
235 };
236 static const uint8_t exp_out[] = {
237 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
238 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
239 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
240 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
241 };
242 uint8_t out[sizeof(exp_out)];
243
244 op.params[0].tmpref.buffer = (void *)in;
245 op.params[0].tmpref.size = sizeof(in);
246 op.params[1].tmpref.buffer = out;
247 op.params[1].tmpref.size = sizeof(out);
248 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
249 TEEC_MEMREF_TEMP_OUTPUT,
250 TEEC_NONE, TEEC_NONE);
251
252 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
253 TEEC_InvokeCommand(cs->session,
254 cs->
255 cmd_id_aes256ecb_decrypt,
256 &op,
257 &ret_orig));
258
259 if (!ADBG_EXPECT(cs->c, 0,
260 memcmp(exp_out, out, sizeof(exp_out)))) {
261 Do_ADBG_Log("exp_out:");
262 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
263 Do_ADBG_Log("out:");
264 Do_ADBG_HexLog(out, sizeof(out), 16);
265 }
266 }
267 Do_ADBG_EndSubCase(cs->c,
268 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
269}
270
271static void xtest_tee_test_1001(ADBG_Case_t *c)
272{
Jens Wiklandercf16e842016-02-10 09:07:09 +0100273 TEEC_Result res;
274 TEEC_Session session = { 0 };
275 uint32_t ret_orig;
Pascal Brandc639ac82015-07-02 08:53:34 +0200276
Etienne Carriere726d8bc2017-03-21 15:45:59 +0100277 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
Jens Wiklandercf16e842016-02-10 09:07:09 +0100278 &ret_orig);
279 /*
280 * If the static TA (which is optional) isn't available, skip this
281 * test.
282 */
283 if (res != TEEC_SUCCESS)
284 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200285
Jens Wiklandercf16e842016-02-10 09:07:09 +0100286 (void)ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
Etienne Carriere726d8bc2017-03-21 15:45:59 +0100287 &session, PTA_INVOKE_TESTS_CMD_SELF_TESTS, NULL, &ret_orig));
Jens Wiklandercf16e842016-02-10 09:07:09 +0100288 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200289}
290
291static void xtest_tee_test_1004(ADBG_Case_t *c)
292{
293 TEEC_Session session = { 0 };
294 uint32_t ret_orig;
295 struct xtest_crypto_session cs = { c, &session, TA_CRYPT_CMD_SHA256,
296 TA_CRYPT_CMD_AES256ECB_ENC,
297 TA_CRYPT_CMD_AES256ECB_DEC };
298
299 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
300 &session, &crypt_user_ta_uuid,
301 NULL, &ret_orig)))
302 return;
303
304 /* Run the "complete crypto test suite" */
305 xtest_crypto_test(&cs);
306
307 TEEC_CloseSession(&session);
308}
309
310#ifndef TEEC_ERROR_TARGET_DEAD
311/* To be removed when we have TEEC_ERROR_TARGET_DEAD from tee_client_api.h */
312#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024
313#endif
314
315static void xtest_tee_test_invalid_mem_access(ADBG_Case_t *c, uint32_t n)
316{
317 TEEC_Session session = { 0 };
318 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
319 uint32_t ret_orig;
320
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300321 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200322 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300323 &ret_orig)))
324 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200325
326 op.params[0].value.a = n;
327 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
328 TEEC_NONE);
329
330 (void)ADBG_EXPECT_TEEC_RESULT(c,
331 TEEC_ERROR_TARGET_DEAD,
332 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
333 &ret_orig));
334
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300335 (void)ADBG_EXPECT_TEEC_RESULT(c,
336 TEEC_ERROR_TARGET_DEAD,
337 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
Pascal Brandc639ac82015-07-02 08:53:34 +0200338 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300339
Pascal Brandc639ac82015-07-02 08:53:34 +0200340 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
341
342 TEEC_CloseSession(&session);
343}
344
345static void xtest_tee_test_1005(ADBG_Case_t *c)
346{
347 uint32_t ret_orig;
348#define MAX_SESSIONS 3
349 TEEC_Session sessions[MAX_SESSIONS];
350 int i;
351
352 for (i = 0; i < MAX_SESSIONS; i++) {
353 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Jens Wiklandereb6bce72016-09-23 11:37:33 +0200354 xtest_teec_open_session(&sessions[i],
355 &concurrent_ta_uuid,
Pascal Brandc639ac82015-07-02 08:53:34 +0200356 NULL, &ret_orig)))
357 break;
358 }
359
360 for (; --i >= 0; )
361 TEEC_CloseSession(&sessions[i]);
362}
363
364static void xtest_tee_test_1006(ADBG_Case_t *c)
365{
366 TEEC_Session session = { 0 };
367 uint32_t ret_orig;
368 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
369 uint8_t buf[32];
370
371 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
372 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
373 &ret_orig)))
374 return;
375
376 op.params[0].tmpref.buffer = buf;
377 op.params[0].tmpref.size = sizeof(buf);
378 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
379 TEEC_NONE, TEEC_NONE);
380
381 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
382 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
383 &ret_orig));
384
385 TEEC_CloseSession(&session);
386}
387
388static void xtest_tee_test_1007(ADBG_Case_t *c)
389{
390 TEEC_Session session = { 0 };
391 uint32_t ret_orig;
392
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300393 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200394 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300395 &ret_orig)))
396 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200397
398 (void)ADBG_EXPECT_TEEC_RESULT(c,
399 TEEC_ERROR_TARGET_DEAD,
400 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
401 &ret_orig));
402
403 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
404
405 (void)ADBG_EXPECT_TEEC_RESULT(c,
406 TEEC_ERROR_TARGET_DEAD,
407 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
408 &ret_orig));
409
410 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
411
412 TEEC_CloseSession(&session);
413}
414
Jerome Forissierf02a2212015-10-29 14:33:35 +0100415#ifndef TA_DIR
Victor Chong3d8798f2017-03-01 18:31:48 +0000416# ifdef __ANDROID__
417#define TA_DIR "/system/lib/optee_armtz"
418# else
Jerome Forissierf02a2212015-10-29 14:33:35 +0100419#define TA_DIR "/lib/optee_armtz"
Victor Chong3d8798f2017-03-01 18:31:48 +0000420# endif
Jerome Forissierf02a2212015-10-29 14:33:35 +0100421#endif
422
David Brownb2865ab2016-08-02 11:44:41 -0600423#ifndef TA_TEST_DIR
424# ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200425# define TA_TEST_DIR "/data/tee/optee_armtz"
David Brownb2865ab2016-08-02 11:44:41 -0600426# else
427# define TA_TEST_DIR "/tmp/optee_armtz"
428# endif
429#endif
Jens Wiklanderb7940892015-10-23 16:02:40 +0200430
David Brownb2865ab2016-08-02 11:44:41 -0600431static void make_test_ta_dir(void)
432{
433#ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200434 (void)mkdir("/data/tee", 0755);
David Brownb2865ab2016-08-02 11:44:41 -0600435#endif
436 (void)mkdir(TA_TEST_DIR, 0755);
437}
438
439static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
440 bool for_write)
441{
Jens Wiklanderb7940892015-10-23 16:02:40 +0200442 snprintf(buf, blen,
Jens Wiklander6203b872016-12-08 19:18:29 +0100443 "%s/%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x.ta",
David Brownb2865ab2016-08-02 11:44:41 -0600444 for_write ? TA_TEST_DIR : TA_DIR,
445 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
Jens Wiklanderb7940892015-10-23 16:02:40 +0200446 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
447 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
448 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
David Brownb2865ab2016-08-02 11:44:41 -0600449 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200450}
451
David Brownb2865ab2016-08-02 11:44:41 -0600452static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode,
453 bool for_write)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200454{
455 char buf[PATH_MAX];
456
David Brownb2865ab2016-08-02 11:44:41 -0600457 uuid_to_full_name(buf, sizeof(buf), uuid, for_write);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200458 return fopen(buf, mode);
459}
460
David Brownb2865ab2016-08-02 11:44:41 -0600461static bool rm_file(const TEEC_UUID *uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200462{
463 char buf[PATH_MAX];
464
David Brownb2865ab2016-08-02 11:44:41 -0600465 uuid_to_full_name(buf, sizeof(buf), uuid, true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200466 return !unlink(buf);
467}
468
David Brownb2865ab2016-08-02 11:44:41 -0600469static bool copy_file(const TEEC_UUID *src_uuid, const TEEC_UUID *dst_uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200470{
471 char buf[4 * 1024];
David Brownb2865ab2016-08-02 11:44:41 -0600472 FILE *src = open_ta_file(src_uuid, "r", false);
473 FILE *dst = open_ta_file(dst_uuid, "w", true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200474 size_t r;
475 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200476 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200477
Jens Wiklander4441fe22015-10-23 16:53:02 +0200478 if (src && dst) {
479 do {
480 r = fread(buf, 1, sizeof(buf), src);
481 if (!r) {
482 ret = !!feof(src);
483 break;
484 }
485 w = fwrite(buf, 1, r, dst);
486 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200487 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200488
489 if (src)
490 fclose(src);
491 if (dst)
492 fclose(dst);
493 return ret;
494}
495
496static bool corrupt_file(FILE *f, long offs, uint8_t mask)
497{
498 uint8_t b;
499
500 if (fseek(f, offs, SEEK_SET))
501 return false;
502
503 if (fread(&b, 1, 1, f) != 1)
504 return false;
505
506 b ^= mask;
507
508 if (fseek(f, offs, SEEK_SET))
509 return false;
510
511 if (fwrite(&b, 1, 1, f) != 1)
512 return false;
513
514 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200515}
516
517static void load_fake_ta(ADBG_Case_t *c)
518{
519 static const TEEC_UUID fake_uuid = {
520 0x7e0a0900, 0x586b, 0x11e5,
521 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
522 };
523 TEEC_Session session = { 0 };
524 TEEC_Result res;
525 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200526 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200527
David Brownb2865ab2016-08-02 11:44:41 -0600528 r = copy_file(&create_fail_test_ta_uuid, &fake_uuid);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200529
530 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200531 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
532 &ret_orig);
533 if (res == TEEC_SUCCESS)
534 TEEC_CloseSession(&session);
535 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200536 }
537
David Brownb2865ab2016-08-02 11:44:41 -0600538 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid));
Jens Wiklanderb7940892015-10-23 16:02:40 +0200539}
540
Jens Wiklander4441fe22015-10-23 16:53:02 +0200541static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
542{
543 TEEC_Session session = { 0 };
544 TEEC_Result res;
545 uint32_t ret_orig;
546 FILE *f;
547 bool r;
548
David Brownb2865ab2016-08-02 11:44:41 -0600549 r = copy_file(&create_fail_test_ta_uuid, &create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200550 if (!ADBG_EXPECT_TRUE(c, r)) {
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
David Brownb2865ab2016-08-02 11:44:41 -0600555 f = open_ta_file(&create_fail_test_ta_uuid, "r+", true);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200556 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
David Brownb2865ab2016-08-02 11:44:41 -0600557 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200558 return false;
559 }
560 r = corrupt_file(f, offs, mask);
561 fclose(f);
562
563 if (ADBG_EXPECT_TRUE(c, r)) {
564 res = xtest_teec_open_session(&session,
565 &create_fail_test_ta_uuid,
566 NULL, &ret_orig);
567 if (res == TEEC_SUCCESS)
568 TEEC_CloseSession(&session);
569 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
570 }
571
David Brownb2865ab2016-08-02 11:44:41 -0600572 r &= ADBG_EXPECT_TRUE(c, rm_file(&create_fail_test_ta_uuid));
Jens Wiklander4441fe22015-10-23 16:53:02 +0200573 return r;
574}
575
Pascal Brandc639ac82015-07-02 08:53:34 +0200576static void xtest_tee_test_1008(ADBG_Case_t *c)
577{
578 TEEC_Session session = { 0 };
579 TEEC_Session session_crypt = { 0 };
580 uint32_t ret_orig;
581
582 Do_ADBG_BeginSubCase(c, "Invoke command");
583 {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300584 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200585 xtest_teec_open_session(&session, &os_test_ta_uuid,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300586 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200587
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300588 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
589 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
590 NULL, &ret_orig));
591 TEEC_CloseSession(&session);
592 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200593
Pascal Brandc639ac82015-07-02 08:53:34 +0200594 }
595 Do_ADBG_EndSubCase(c, "Invoke command");
596
597 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
598 {
599 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
600
601 op.params[0].value.a = 2000;
602 op.paramTypes = TEEC_PARAM_TYPES(
603 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
604
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300605 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200606 xtest_teec_open_session(&session,
607 &os_test_ta_uuid,
608 NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300609 &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200610
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300611 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
612 TEEC_InvokeCommand(&session,
613 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
614 &op, &ret_orig));
615 TEEC_CloseSession(&session);
616 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200617 }
618 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
619
620 Do_ADBG_BeginSubCase(c, "Create session fail");
621 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200622 size_t n;
623
Pascal Brandc639ac82015-07-02 08:53:34 +0200624 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
625 xtest_teec_open_session(&session_crypt,
626 &create_fail_test_ta_uuid, NULL,
627 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200628 /*
629 * Run this several times to see that there's no memory leakage.
630 */
631 for (n = 0; n < 100; n++) {
632 Do_ADBG_Log("n = %zu", n);
633 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
634 xtest_teec_open_session(&session_crypt,
635 &create_fail_test_ta_uuid,
636 NULL, &ret_orig));
637 }
638 }
639 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200640
David Brownb2865ab2016-08-02 11:44:41 -0600641 make_test_ta_dir();
642
Jens Wiklanderb7940892015-10-23 16:02:40 +0200643 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
644 load_fake_ta(c);
645 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
646
Jens Wiklander4441fe22015-10-23 16:53:02 +0200647 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
648 ADBG_EXPECT_TRUE(c,
649 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
650 ADBG_EXPECT_TRUE(c,
651 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
652 ADBG_EXPECT_TRUE(c,
653 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
654 ADBG_EXPECT_TRUE(c,
655 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
656 ADBG_EXPECT_TRUE(c,
657 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
658 ADBG_EXPECT_TRUE(c,
659 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
660 ADBG_EXPECT_TRUE(c,
661 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
662 ADBG_EXPECT_TRUE(c,
663 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
664 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
665 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
666 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200667}
668
Pascal Brandc639ac82015-07-02 08:53:34 +0200669static void *cancellation_thread(void *arg)
670{
671 /*
672 * Sleep 0.5 seconds before cancellation to make sure that the other
673 * thread is in RPC_WAIT.
674 */
675 (void)usleep(500000);
676 TEEC_RequestCancellation(arg);
677 return NULL;
678}
Pascal Brandc639ac82015-07-02 08:53:34 +0200679
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300680static void xtest_tee_test_1009_subcase(ADBG_Case_t *c, const char *subcase,
681 uint32_t timeout, bool cancel)
Pascal Brandc639ac82015-07-02 08:53:34 +0200682{
683 TEEC_Session session = { 0 };
684 uint32_t ret_orig;
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300685 pthread_t thr;
Pascal Brandc639ac82015-07-02 08:53:34 +0200686
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300687 Do_ADBG_BeginSubCase(c, "%s", subcase);
Pascal Brandc639ac82015-07-02 08:53:34 +0200688 {
689 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
690
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300691 if (ADBG_EXPECT_TEEC_SUCCESS(c,
692 xtest_teec_open_session(&session, &os_test_ta_uuid,
693 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200694
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300695 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c,
696 TEEC_ORIGIN_TRUSTED_APP,
697 ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200698
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300699 op.params[0].value.a = timeout;
700 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
701 TEEC_NONE,
702 TEEC_NONE, TEEC_NONE);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300703 if (cancel) {
704 (void)ADBG_EXPECT(c, 0,
705 pthread_create(&thr, NULL,
706 cancellation_thread, &op));
Pascal Brandc639ac82015-07-02 08:53:34 +0200707
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300708 (void)ADBG_EXPECT_TEEC_RESULT(c,
709 TEEC_ERROR_CANCEL,
710 TEEC_InvokeCommand(&session,
711 TA_OS_TEST_CMD_WAIT,
712 &op,
713 &ret_orig));
714 } else
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300715
716 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
717 TEEC_InvokeCommand(&session,
718 TA_OS_TEST_CMD_WAIT,
719 &op,
720 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300721 if (cancel)
722 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300723
724 TEEC_CloseSession(&session);
725 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200726 }
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300727 Do_ADBG_EndSubCase(c, "%s", subcase);
728}
729
730static void xtest_tee_test_1009(ADBG_Case_t *c)
731{
732 xtest_tee_test_1009_subcase(c, "TEE Wait 0.1s", 100, false);
733 xtest_tee_test_1009_subcase(c, "TEE Wait 0.5s", 500, false);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300734 xtest_tee_test_1009_subcase(c, "TEE Wait 2s cancel", 2000, true);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300735 xtest_tee_test_1009_subcase(c, "TEE Wait 2s", 2000, false);
Pascal Brandc639ac82015-07-02 08:53:34 +0200736}
737
738static void xtest_tee_test_1010(ADBG_Case_t *c)
739{
740 unsigned n;
741
742 for (n = 1; n <= 5; n++) {
743 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
744 xtest_tee_test_invalid_mem_access(c, n);
745 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
746 }
747}
748
749static void xtest_tee_test_1011(ADBG_Case_t *c)
750{
751 TEEC_Session session = { 0 };
752 uint32_t ret_orig;
753 struct xtest_crypto_session cs = {
754 c, &session, TA_RPC_CMD_CRYPT_SHA256,
755 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
756 TA_RPC_CMD_CRYPT_AES256ECB_DEC
757 };
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100758 struct xtest_crypto_session cs_privmem = {
759 c, &session,
760 TA_RPC_CMD_CRYPT_PRIVMEM_SHA256,
761 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_ENC,
762 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_DEC
763 };
Pascal Brandc639ac82015-07-02 08:53:34 +0200764 TEEC_UUID uuid = rpc_test_ta_uuid;
765
766 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
767 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
768 return;
769
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100770 Do_ADBG_BeginSubCase(c, "TA-to-TA via non-secure shared memory");
Pascal Brandc639ac82015-07-02 08:53:34 +0200771 /*
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100772 * Run the "complete crypto test suite" using TA-to-TA
773 * communication
Pascal Brandc639ac82015-07-02 08:53:34 +0200774 */
775 xtest_crypto_test(&cs);
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100776 Do_ADBG_EndSubCase(c, "TA-to-TA via non-secure shared memory");
777
778 Do_ADBG_BeginSubCase(c, "TA-to-TA via TA private memory");
779 /*
780 * Run the "complete crypto test suite" using TA-to-TA
781 * communication via TA private memory.
782 */
783 xtest_crypto_test(&cs_privmem);
784 Do_ADBG_EndSubCase(c, "TA-to-TA via TA private memory");
785
Pascal Brandc639ac82015-07-02 08:53:34 +0200786 TEEC_CloseSession(&session);
787}
788
789/*
790 * Note that this test is failing when
791 * - running twice in a raw
792 * - and the user TA is statically linked
793 * This is because the counter is not reseted when opening the first session
794 * in case the TA is statically linked
795 */
796static void xtest_tee_test_1012(ADBG_Case_t *c)
797{
798 TEEC_Session session1 = { 0 };
799 TEEC_Session session2 = { 0 };
800 uint32_t ret_orig;
801 TEEC_UUID uuid = sims_test_ta_uuid;
802
803 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
804 {
805 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
806 static const uint8_t in[] = {
807 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
808 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
809 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
810 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
811 };
812 uint8_t out[32] = { 0 };
813 int i;
814
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300815 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200816 xtest_teec_open_session(&session1, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300817 &ret_orig)))
818 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200819
820 op.params[0].value.a = 0;
821 op.params[1].tmpref.buffer = (void *)in;
822 op.params[1].tmpref.size = sizeof(in);
823 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
824 TEEC_MEMREF_TEMP_INPUT,
825 TEEC_NONE, TEEC_NONE);
826
827 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
828 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
829 &ret_orig));
830
831 for (i = 1; i < 1000; i++) {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300832 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200833 xtest_teec_open_session(&session2, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300834 &ret_orig)))
835 continue;
Pascal Brandc639ac82015-07-02 08:53:34 +0200836
837 op.params[0].value.a = 0;
838 op.params[1].tmpref.buffer = out;
839 op.params[1].tmpref.size = sizeof(out);
840 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
841 TEEC_MEMREF_TEMP_OUTPUT,
842 TEEC_NONE, TEEC_NONE);
843
844 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
845 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
846 &op, &ret_orig));
847
848 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
849 sizeof(out))) {
850 Do_ADBG_Log("in:");
851 Do_ADBG_HexLog(in, sizeof(in), 16);
852 Do_ADBG_Log("out:");
853 Do_ADBG_HexLog(out, sizeof(out), 16);
854 }
855
856 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
857 TEEC_NONE, TEEC_NONE,
858 TEEC_NONE);
859
860 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
861 TEEC_InvokeCommand(&session1,
862 TA_SIMS_CMD_GET_COUNTER,
863 &op, &ret_orig));
864
865 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
866
867 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
868 TEEC_InvokeCommand(&session2,
869 TA_SIMS_CMD_GET_COUNTER, &op,
870 &ret_orig));
871
872 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
873 TEEC_CloseSession(&session2);
874 }
875
876 memset(out, 0, sizeof(out));
877 op.params[0].value.a = 0;
878 op.params[1].tmpref.buffer = out;
879 op.params[1].tmpref.size = sizeof(out);
880 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
881 TEEC_MEMREF_TEMP_OUTPUT,
882 TEEC_NONE, TEEC_NONE);
883
884 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
885 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
886 &ret_orig));
887
888 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
889 Do_ADBG_Log("in:");
890 Do_ADBG_HexLog(in, sizeof(in), 16);
891 Do_ADBG_Log("out:");
892 Do_ADBG_HexLog(out, sizeof(out), 16);
893 }
894
895 TEEC_CloseSession(&session1);
896 }
897}
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200898
899struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +0200900 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200901 uint32_t cmd;
902 uint32_t repeat;
903 TEEC_SharedMemory *shm;
904 uint32_t error_orig;
905 TEEC_Result res;
906 uint32_t max_concurrency;
907 const uint8_t *in;
908 size_t in_len;
909 uint8_t *out;
910 size_t out_len;
911};
912
913static void *test_1013_thread(void *arg)
914{
915 struct test_1013_thread_arg *a = arg;
916 TEEC_Session session = { 0 };
917 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
918 uint8_t p2 = TEEC_NONE;
919 uint8_t p3 = TEEC_NONE;
920
Jens Wiklander70672972016-04-06 00:01:45 +0200921 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200922 &a->error_orig);
923 if (a->res != TEEC_SUCCESS)
924 return NULL;
925
926 op.params[0].memref.parent = a->shm;
927 op.params[0].memref.size = a->shm->size;
928 op.params[0].memref.offset = 0;
929 op.params[1].value.a = a->repeat;
930 op.params[1].value.b = 0;
931 op.params[2].tmpref.buffer = (void *)a->in;
932 op.params[2].tmpref.size = a->in_len;
933 op.params[3].tmpref.buffer = a->out;
934 op.params[3].tmpref.size = a->out_len;
935
936 if (a->in_len)
937 p2 = TEEC_MEMREF_TEMP_INPUT;
938 if (a->out_len)
939 p3 = TEEC_MEMREF_TEMP_OUTPUT;
940
941 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
942 TEEC_VALUE_INOUT, p2, p3);
943
944 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
945 a->max_concurrency = op.params[1].value.b;
946 a->out_len = op.params[3].tmpref.size;
947 TEEC_CloseSession(&session);
948 return NULL;
949}
950
Pascal Brand4fa35582015-12-17 10:59:12 +0100951#define NUM_THREADS 3
952
Jens Wiklander70672972016-04-06 00:01:45 +0200953static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
954 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200955{
Pascal Brand4fa35582015-12-17 10:59:12 +0100956 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200957 size_t nt;
958 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +0200959 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200960 pthread_t thr[num_threads];
961 TEEC_SharedMemory shm;
962 size_t max_concurrency;
963 struct test_1013_thread_arg arg[num_threads];
964 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
965 static const uint8_t sha256_out[] = {
966 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
967 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
968 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
969 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
970 };
971 uint8_t out[32] = { 0 };
972
Jens Wiklander70672972016-04-06 00:01:45 +0200973 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +0100974 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200975
976 memset(&shm, 0, sizeof(shm));
977 shm.size = sizeof(struct ta_concurrent_shm);
978 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
979 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
980 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
981 return;
982
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200983 memset(shm.buffer, 0, shm.size);
984 memset(arg, 0, sizeof(arg));
985 max_concurrency = 0;
986 nt = num_threads;
987
988 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +0200989 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200990 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +0200991 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200992 arg[n].shm = &shm;
993 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
994 test_1013_thread, arg + n)))
995 nt = n; /* break loop and start cleanup */
996 }
997
998 for (n = 0; n < nt; n++) {
999 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
1000 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
1001 if (arg[n].max_concurrency > max_concurrency)
1002 max_concurrency = arg[n].max_concurrency;
1003 }
1004
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001005 /*
1006 * Concurrency can be limited by several factors, for instance in a
1007 * single CPU system it's dependent on the Preemtion Model used by
1008 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
1009 * best result there).
1010 */
1011 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
1012 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +01001013 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001014 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001015
Jens Wiklander70672972016-04-06 00:01:45 +02001016 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001017 memset(shm.buffer, 0, shm.size);
1018 memset(arg, 0, sizeof(arg));
1019 max_concurrency = 0;
1020 nt = num_threads;
1021
1022 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001023 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001024 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +02001025 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001026 arg[n].shm = &shm;
1027 arg[n].in = sha256_in;
1028 arg[n].in_len = sizeof(sha256_in);
1029 arg[n].out = out;
1030 arg[n].out_len = sizeof(out);
1031 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1032 test_1013_thread, arg + n)))
1033 nt = n; /* break loop and start cleanup */
1034 }
1035
1036 for (n = 0; n < nt; n++) {
1037 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1038 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1039 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1040 arg[n].out, arg[n].out_len);
1041 if (arg[n].max_concurrency > max_concurrency)
1042 max_concurrency = arg[n].max_concurrency;
1043 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001044 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001045 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001046
Pascal Brand4fa35582015-12-17 10:59:12 +01001047 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001048 TEEC_ReleaseSharedMemory(&shm);
1049}
Pascal Brand4fa35582015-12-17 10:59:12 +01001050
1051static void xtest_tee_test_1013(ADBG_Case_t *c)
1052{
1053 int i;
1054 double mean_concurrency;
1055 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001056 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001057
1058 if (level == 0)
1059 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001060
Jens Wiklander70672972016-04-06 00:01:45 +02001061 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001062 mean_concurrency = 0;
1063 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001064 xtest_tee_test_1013_single(c, &concurrency,
1065 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001066 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);
Jens Wiklander70672972016-04-06 00:01:45 +02001072 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001073
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001074#ifndef CFG_PAGED_USER_TA
Jens Wiklander70672972016-04-06 00:01:45 +02001075 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1076 mean_concurrency = 0;
1077 for (i = 0; i < nb_loops; i++) {
1078 xtest_tee_test_1013_single(c, &concurrency,
1079 &concurrent_large_ta_uuid);
1080 mean_concurrency += concurrency;
1081 }
1082 mean_concurrency /= nb_loops;
1083
1084 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1085 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1086 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001087#endif
Jens Wiklander70672972016-04-06 00:01:45 +02001088}
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001089
1090#ifdef CFG_SECURE_DATA_PATH
1091static void xtest_tee_test_1014(ADBG_Case_t *c)
1092{
1093 UNUSED(c);
1094
1095 int size = 17000;
1096 int loop = 10;
1097 int ion_heap = DEFAULT_ION_HEAP_TYPE;
1098 int rnd_offset = 1;
1099 int test;
1100 int ret;
1101
1102 test = TEST_NS_TO_TA;
1103 Do_ADBG_BeginSubCase(c, "SDP: NonSecure client invokes a SDP TA");
Etienne Carriereb9a95822017-04-26 15:03:53 +02001104 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001105 ADBG_EXPECT(c, 0, ret);
1106 Do_ADBG_EndSubCase(c, "SDP: NonSecure client invokes a SDP TA");
1107
1108 test = TEST_TA_TO_TA;
1109 Do_ADBG_BeginSubCase(c, "SDP: SDP TA invokes a SDP TA");
Etienne Carriereb9a95822017-04-26 15:03:53 +02001110 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001111 ADBG_EXPECT(c, 0, ret);
1112 Do_ADBG_EndSubCase(c, "SDP: SDP TA invokes a SDP TA");
1113
1114 test = TEST_TA_TO_PTA;
1115 Do_ADBG_BeginSubCase(c, "SDP: SDP TA invokes a SDP pTA");
Etienne Carriereb9a95822017-04-26 15:03:53 +02001116 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001117 ADBG_EXPECT(c, 0, ret);
1118 Do_ADBG_EndSubCase(c, "SDP: SDP TA invokes a SDP pTA");
1119
1120 test = TEST_NS_TO_PTA;
1121 Do_ADBG_BeginSubCase(c, "SDP: NonSecure client invokes SDP pTA (should fail)");
Etienne Carriereb9a95822017-04-26 15:03:53 +02001122 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001123 ADBG_EXPECT(c, 1, ret);
1124 Do_ADBG_EndSubCase(c, "SDP: NonSecure client invokes SDP pTA (should fail)");
1125}
1126#endif
Jens Wiklander272d3642017-04-03 13:03:47 +02001127
1128static void xtest_tee_test_1015(ADBG_Case_t *c)
1129{
1130 TEEC_Result res;
1131 TEEC_Session session = { 0 };
1132 uint32_t ret_orig;
1133
1134 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
1135 &ret_orig);
1136 /*
1137 * If the static TA (which is optional) isn't available, skip this
1138 * test.
1139 */
1140 if (res != TEEC_SUCCESS)
1141 return;
1142
1143 ADBG_EXPECT_TEEC_SUCCESS(c,
1144 TEEC_InvokeCommand(&session, PTA_INVOKE_TESTS_CMD_FS_HTREE,
1145 NULL, &ret_orig));
1146 TEEC_CloseSession(&session);
1147}
Jerome Forissiere916b102017-06-07 17:55:52 +02001148
1149static void xtest_tee_test_1016(ADBG_Case_t *c)
1150{
1151 TEEC_Session session = { 0 };
1152 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1153 uint32_t ret_orig;
1154
1155 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1156 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
1157 &ret_orig)))
1158 return;
1159
1160 op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE,
1161 TEEC_NONE);
1162
1163 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1164 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_TA2TA_MEMREF, &op,
1165 &ret_orig));
1166
1167 TEEC_CloseSession(&session);
1168}