blob: 7066855b325a864e66e4267974b0318b5f7860cc [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);
Jens Wiklander1d70a112017-10-16 15:16:39 +020036static void xtest_tee_test_1002(ADBG_Case_t *Case_p);
Pascal Brandc639ac82015-07-02 08:53:34 +020037static void xtest_tee_test_1004(ADBG_Case_t *Case_p);
38static void xtest_tee_test_1005(ADBG_Case_t *Case_p);
39static void xtest_tee_test_1006(ADBG_Case_t *Case_p);
40static void xtest_tee_test_1007(ADBG_Case_t *Case_p);
41static void xtest_tee_test_1008(ADBG_Case_t *Case_p);
42static void xtest_tee_test_1009(ADBG_Case_t *Case_p);
43static void xtest_tee_test_1010(ADBG_Case_t *Case_p);
44static void xtest_tee_test_1011(ADBG_Case_t *Case_p);
45static void xtest_tee_test_1012(ADBG_Case_t *Case_p);
Jens Wiklanderac27ec12015-07-15 15:23:14 +020046static void xtest_tee_test_1013(ADBG_Case_t *Case_p);
Etienne Carriere50abf9a2017-03-24 11:33:50 +010047#ifdef CFG_SECURE_DATA_PATH
48static void xtest_tee_test_1014(ADBG_Case_t *Case_p);
49#endif
Jens Wiklander272d3642017-04-03 13:03:47 +020050static void xtest_tee_test_1015(ADBG_Case_t *Case_p);
Jerome Forissiere916b102017-06-07 17:55:52 +020051static void xtest_tee_test_1016(ADBG_Case_t *Case_p);
Pascal Brandc639ac82015-07-02 08:53:34 +020052
Jens Wiklander74abfe32017-01-03 14:17:47 +010053ADBG_CASE_DEFINE(regression, 1001, xtest_tee_test_1001, "Core self tests");
Jens Wiklander1d70a112017-10-16 15:16:39 +020054ADBG_CASE_DEFINE(regression, 1002, xtest_tee_test_1002, "PTA parameters");
Jens Wiklander74abfe32017-01-03 14:17:47 +010055ADBG_CASE_DEFINE(regression, 1004, xtest_tee_test_1004, "Test User Crypt TA");
56ADBG_CASE_DEFINE(regression, 1005, xtest_tee_test_1005, "Many sessions");
57ADBG_CASE_DEFINE(regression, 1006, xtest_tee_test_1006,
58 "Test Basic OS features");
59ADBG_CASE_DEFINE(regression, 1007, xtest_tee_test_1007, "Test Panic");
60ADBG_CASE_DEFINE(regression, 1008, xtest_tee_test_1008,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010061 "TEE internal client API");
Jens Wiklander74abfe32017-01-03 14:17:47 +010062ADBG_CASE_DEFINE(regression, 1009, xtest_tee_test_1009, "TEE Wait");
63ADBG_CASE_DEFINE(regression, 1010, xtest_tee_test_1010,
64 "Invalid memory access");
65ADBG_CASE_DEFINE(regression, 1011, xtest_tee_test_1011,
Jens Wiklanderf7b9c632017-01-03 17:32:26 +010066 "Test TA-to-TA features with User Crypt TA");
Jens Wiklander74abfe32017-01-03 14:17:47 +010067ADBG_CASE_DEFINE(regression, 1012, xtest_tee_test_1012,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010068 "Test Single Instance Multi Session features with SIMS TA");
Jens Wiklander74abfe32017-01-03 14:17:47 +010069ADBG_CASE_DEFINE(regression, 1013, xtest_tee_test_1013,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010070 "Test concurency with concurrent TA");
Etienne Carriere50abf9a2017-03-24 11:33:50 +010071#ifdef CFG_SECURE_DATA_PATH
72ADBG_CASE_DEFINE(regression, 1014, xtest_tee_test_1014,
73 "Test secure data path against SDP TAs and pTAs");
74#endif
Jens Wiklander272d3642017-04-03 13:03:47 +020075ADBG_CASE_DEFINE(regression, 1015, xtest_tee_test_1015,
76 "FS hash-tree corner cases");
Jerome Forissiere916b102017-06-07 17:55:52 +020077ADBG_CASE_DEFINE(regression, 1016, xtest_tee_test_1016,
78 "Test TA to TA transfers (in/out/inout memrefs on the stack)");
Jens Wiklanderac27ec12015-07-15 15:23:14 +020079
Pascal Brandc639ac82015-07-02 08:53:34 +020080struct xtest_crypto_session {
81 ADBG_Case_t *c;
82 TEEC_Session *session;
83 uint32_t cmd_id_sha256;
84 uint32_t cmd_id_aes256ecb_encrypt;
85 uint32_t cmd_id_aes256ecb_decrypt;
86};
87
88static void xtest_crypto_test(struct xtest_crypto_session *cs)
89{
90 uint32_t ret_orig;
91 uint8_t crypt_out[16];
92 uint8_t crypt_in[16] = { 22, 17 };
93
94 crypt_in[15] = 60;
95
96 Do_ADBG_BeginSubCase(cs->c, "AES encrypt");
97 {
98 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
99
100 op.params[0].tmpref.buffer = crypt_in;
101 op.params[0].tmpref.size = sizeof(crypt_in);
102 op.params[1].tmpref.buffer = crypt_out;
103 op.params[1].tmpref.size = sizeof(crypt_out);
104 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
105 TEEC_MEMREF_TEMP_OUTPUT,
106 TEEC_NONE, TEEC_NONE);
107
108 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
109 TEEC_InvokeCommand(cs->session,
110 cs->
111 cmd_id_aes256ecb_encrypt,
112 &op,
113 &ret_orig));
114 }
115 Do_ADBG_EndSubCase(cs->c, "AES encrypt");
116
117 Do_ADBG_BeginSubCase(cs->c, "AES decrypt");
118 {
119 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
120 uint8_t out[16];
121
122 op.params[0].tmpref.buffer = crypt_out;
123 op.params[0].tmpref.size = sizeof(crypt_out);
124 op.params[1].tmpref.buffer = out;
125 op.params[1].tmpref.size = sizeof(out);
126 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
127 TEEC_MEMREF_TEMP_OUTPUT,
128 TEEC_NONE, TEEC_NONE);
129
130 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
131 TEEC_InvokeCommand(cs->session,
132 cs->
133 cmd_id_aes256ecb_decrypt,
134 &op,
135 &ret_orig));
136
137 if (!ADBG_EXPECT(cs->c, 0,
138 memcmp(crypt_in, out, sizeof(crypt_in)))) {
139 Do_ADBG_Log("crypt_in:");
140 Do_ADBG_HexLog(crypt_in, sizeof(crypt_in), 16);
141 Do_ADBG_Log("out:");
142 Do_ADBG_HexLog(out, sizeof(out), 16);
143 }
144 }
145 Do_ADBG_EndSubCase(cs->c, "AES decrypt");
146
147 Do_ADBG_BeginSubCase(cs->c, "SHA-256 test, 3 bytes input");
148 {
149 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
150 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
151 static const uint8_t sha256_out[] = {
152 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
153 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
154 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
155 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
156 };
157 uint8_t out[32] = { 0 };
158
159 op.params[0].tmpref.buffer = (void *)sha256_in;
160 op.params[0].tmpref.size = sizeof(sha256_in);
161 op.params[1].tmpref.buffer = out;
162 op.params[1].tmpref.size = sizeof(out);
163 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
164 TEEC_MEMREF_TEMP_OUTPUT,
165 TEEC_NONE, TEEC_NONE);
166
167 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
168 TEEC_InvokeCommand(cs->session,
169 cs->
170 cmd_id_sha256,
171 &op,
172 &ret_orig));
173
174 if (!ADBG_EXPECT(cs->c, 0, memcmp(sha256_out, out,
175 sizeof(sha256_out)))) {
176 Do_ADBG_Log("sha256_out:");
177 Do_ADBG_HexLog(sha256_out, sizeof(sha256_out), 16);
178 Do_ADBG_Log("out:");
179 Do_ADBG_HexLog(out, sizeof(out), 16);
180 }
181 }
182 Do_ADBG_EndSubCase(cs->c, "SHA-256 test, 3 bytes input");
183
184 Do_ADBG_BeginSubCase(cs->c,
185 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
186 {
187 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
188 static const uint8_t in[] = {
189 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
190 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
191 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
192 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
193 };
194 static const uint8_t exp_out[] = {
195 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
196 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
197 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
198 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
199 };
200 uint8_t out[sizeof(exp_out)];
201
202 op.params[0].tmpref.buffer = (void *)in;
203 op.params[0].tmpref.size = sizeof(in);
204 op.params[1].tmpref.buffer = out;
205 op.params[1].tmpref.size = sizeof(out);
206 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
207 TEEC_MEMREF_TEMP_OUTPUT,
208 TEEC_NONE, TEEC_NONE);
209
210 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
211 TEEC_InvokeCommand(cs->session,
212 cs->
213 cmd_id_aes256ecb_encrypt,
214 &op,
215 &ret_orig));
216
217 if (!ADBG_EXPECT(cs->c, 0,
218 memcmp(exp_out, out, sizeof(exp_out)))) {
219 Do_ADBG_Log("exp_out:");
220 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
221 Do_ADBG_Log("out:");
222 Do_ADBG_HexLog(out, sizeof(out), 16);
223 }
224 }
225 Do_ADBG_EndSubCase(cs->c,
226 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
227
228 Do_ADBG_BeginSubCase(cs->c,
229 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
230 {
231 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
232 static const uint8_t in[] = {
233 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
234 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
235 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
236 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
237 };
238 static const uint8_t exp_out[] = {
239 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
240 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
241 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
242 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
243 };
244 uint8_t out[sizeof(exp_out)];
245
246 op.params[0].tmpref.buffer = (void *)in;
247 op.params[0].tmpref.size = sizeof(in);
248 op.params[1].tmpref.buffer = out;
249 op.params[1].tmpref.size = sizeof(out);
250 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
251 TEEC_MEMREF_TEMP_OUTPUT,
252 TEEC_NONE, TEEC_NONE);
253
254 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
255 TEEC_InvokeCommand(cs->session,
256 cs->
257 cmd_id_aes256ecb_decrypt,
258 &op,
259 &ret_orig));
260
261 if (!ADBG_EXPECT(cs->c, 0,
262 memcmp(exp_out, out, sizeof(exp_out)))) {
263 Do_ADBG_Log("exp_out:");
264 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
265 Do_ADBG_Log("out:");
266 Do_ADBG_HexLog(out, sizeof(out), 16);
267 }
268 }
269 Do_ADBG_EndSubCase(cs->c,
270 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
271}
272
273static void xtest_tee_test_1001(ADBG_Case_t *c)
274{
Jens Wiklandercf16e842016-02-10 09:07:09 +0100275 TEEC_Result res;
276 TEEC_Session session = { 0 };
277 uint32_t ret_orig;
Pascal Brandc639ac82015-07-02 08:53:34 +0200278
Etienne Carriere726d8bc2017-03-21 15:45:59 +0100279 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
Jens Wiklandercf16e842016-02-10 09:07:09 +0100280 &ret_orig);
281 /*
282 * If the static TA (which is optional) isn't available, skip this
283 * test.
284 */
285 if (res != TEEC_SUCCESS)
286 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200287
Jens Wiklandercf16e842016-02-10 09:07:09 +0100288 (void)ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
Etienne Carriere726d8bc2017-03-21 15:45:59 +0100289 &session, PTA_INVOKE_TESTS_CMD_SELF_TESTS, NULL, &ret_orig));
Jens Wiklandercf16e842016-02-10 09:07:09 +0100290 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200291}
292
Jens Wiklander1d70a112017-10-16 15:16:39 +0200293static void xtest_tee_test_1002(ADBG_Case_t *c)
294{
295 TEEC_Result res;
296 TEEC_Session session = { 0 };
297 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
298 uint32_t ret_orig;
299 uint8_t buf[16 * 1024];
300 uint8_t exp_sum = 0;
301 size_t n;
302
303 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
304 &ret_orig);
305 /*
306 * If the pseudo TA (which is optional) isn't available, skip this
307 * test.
308 */
309 if (res != TEEC_SUCCESS)
310 return;
311
312 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE,
313 TEEC_NONE, TEEC_NONE);
314 op.params[0].tmpref.size = sizeof(buf);
315 op.params[0].tmpref.buffer = buf;
316
317 for (n = 0; n < sizeof(buf); n++)
318 buf[n] = n + 1;
319 for (n = 0; n < sizeof(buf); n++)
320 exp_sum += buf[n];
321
322 if (!ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
323 &session, PTA_INVOKE_TESTS_CMD_PARAMS, &op, &ret_orig)))
324 goto out;
325
326 ADBG_EXPECT_COMPARE_SIGNED(c, exp_sum, ==, buf[0]);
327out:
328 TEEC_CloseSession(&session);
329}
330
331
332
Pascal Brandc639ac82015-07-02 08:53:34 +0200333static void xtest_tee_test_1004(ADBG_Case_t *c)
334{
335 TEEC_Session session = { 0 };
336 uint32_t ret_orig;
337 struct xtest_crypto_session cs = { c, &session, TA_CRYPT_CMD_SHA256,
338 TA_CRYPT_CMD_AES256ECB_ENC,
339 TA_CRYPT_CMD_AES256ECB_DEC };
340
341 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
342 &session, &crypt_user_ta_uuid,
343 NULL, &ret_orig)))
344 return;
345
346 /* Run the "complete crypto test suite" */
347 xtest_crypto_test(&cs);
348
349 TEEC_CloseSession(&session);
350}
351
352#ifndef TEEC_ERROR_TARGET_DEAD
353/* To be removed when we have TEEC_ERROR_TARGET_DEAD from tee_client_api.h */
354#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024
355#endif
356
357static void xtest_tee_test_invalid_mem_access(ADBG_Case_t *c, uint32_t n)
358{
359 TEEC_Session session = { 0 };
360 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
361 uint32_t ret_orig;
362
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300363 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200364 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300365 &ret_orig)))
366 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200367
368 op.params[0].value.a = n;
369 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
370 TEEC_NONE);
371
372 (void)ADBG_EXPECT_TEEC_RESULT(c,
373 TEEC_ERROR_TARGET_DEAD,
374 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
375 &ret_orig));
376
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300377 (void)ADBG_EXPECT_TEEC_RESULT(c,
378 TEEC_ERROR_TARGET_DEAD,
379 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
Pascal Brandc639ac82015-07-02 08:53:34 +0200380 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300381
Pascal Brandc639ac82015-07-02 08:53:34 +0200382 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
383
384 TEEC_CloseSession(&session);
385}
386
387static void xtest_tee_test_1005(ADBG_Case_t *c)
388{
389 uint32_t ret_orig;
390#define MAX_SESSIONS 3
391 TEEC_Session sessions[MAX_SESSIONS];
392 int i;
393
394 for (i = 0; i < MAX_SESSIONS; i++) {
395 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Jens Wiklandereb6bce72016-09-23 11:37:33 +0200396 xtest_teec_open_session(&sessions[i],
397 &concurrent_ta_uuid,
Pascal Brandc639ac82015-07-02 08:53:34 +0200398 NULL, &ret_orig)))
399 break;
400 }
401
402 for (; --i >= 0; )
403 TEEC_CloseSession(&sessions[i]);
404}
405
406static void xtest_tee_test_1006(ADBG_Case_t *c)
407{
408 TEEC_Session session = { 0 };
409 uint32_t ret_orig;
410 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
411 uint8_t buf[32];
412
413 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
414 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
415 &ret_orig)))
416 return;
417
418 op.params[0].tmpref.buffer = buf;
419 op.params[0].tmpref.size = sizeof(buf);
420 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
421 TEEC_NONE, TEEC_NONE);
422
423 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
424 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
425 &ret_orig));
426
427 TEEC_CloseSession(&session);
428}
429
430static void xtest_tee_test_1007(ADBG_Case_t *c)
431{
432 TEEC_Session session = { 0 };
433 uint32_t ret_orig;
434
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300435 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200436 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300437 &ret_orig)))
438 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200439
440 (void)ADBG_EXPECT_TEEC_RESULT(c,
441 TEEC_ERROR_TARGET_DEAD,
442 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
443 &ret_orig));
444
445 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
446
447 (void)ADBG_EXPECT_TEEC_RESULT(c,
448 TEEC_ERROR_TARGET_DEAD,
449 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
450 &ret_orig));
451
452 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
453
454 TEEC_CloseSession(&session);
455}
456
Jerome Forissierf02a2212015-10-29 14:33:35 +0100457#ifndef TA_DIR
Victor Chong3d8798f2017-03-01 18:31:48 +0000458# ifdef __ANDROID__
459#define TA_DIR "/system/lib/optee_armtz"
460# else
Jerome Forissierf02a2212015-10-29 14:33:35 +0100461#define TA_DIR "/lib/optee_armtz"
Victor Chong3d8798f2017-03-01 18:31:48 +0000462# endif
Jerome Forissierf02a2212015-10-29 14:33:35 +0100463#endif
464
David Brownb2865ab2016-08-02 11:44:41 -0600465#ifndef TA_TEST_DIR
466# ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200467# define TA_TEST_DIR "/data/tee/optee_armtz"
David Brownb2865ab2016-08-02 11:44:41 -0600468# else
469# define TA_TEST_DIR "/tmp/optee_armtz"
470# endif
471#endif
Jens Wiklanderb7940892015-10-23 16:02:40 +0200472
David Brownb2865ab2016-08-02 11:44:41 -0600473static void make_test_ta_dir(void)
474{
475#ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200476 (void)mkdir("/data/tee", 0755);
David Brownb2865ab2016-08-02 11:44:41 -0600477#endif
478 (void)mkdir(TA_TEST_DIR, 0755);
479}
480
481static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
482 bool for_write)
483{
Jens Wiklanderb7940892015-10-23 16:02:40 +0200484 snprintf(buf, blen,
Jens Wiklander6203b872016-12-08 19:18:29 +0100485 "%s/%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x.ta",
David Brownb2865ab2016-08-02 11:44:41 -0600486 for_write ? TA_TEST_DIR : TA_DIR,
487 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
Jens Wiklanderb7940892015-10-23 16:02:40 +0200488 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
489 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
490 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
David Brownb2865ab2016-08-02 11:44:41 -0600491 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200492}
493
David Brownb2865ab2016-08-02 11:44:41 -0600494static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode,
495 bool for_write)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200496{
497 char buf[PATH_MAX];
498
David Brownb2865ab2016-08-02 11:44:41 -0600499 uuid_to_full_name(buf, sizeof(buf), uuid, for_write);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200500 return fopen(buf, mode);
501}
502
David Brownb2865ab2016-08-02 11:44:41 -0600503static bool rm_file(const TEEC_UUID *uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200504{
505 char buf[PATH_MAX];
506
David Brownb2865ab2016-08-02 11:44:41 -0600507 uuid_to_full_name(buf, sizeof(buf), uuid, true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200508 return !unlink(buf);
509}
510
David Brownb2865ab2016-08-02 11:44:41 -0600511static bool copy_file(const TEEC_UUID *src_uuid, const TEEC_UUID *dst_uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200512{
513 char buf[4 * 1024];
David Brownb2865ab2016-08-02 11:44:41 -0600514 FILE *src = open_ta_file(src_uuid, "r", false);
515 FILE *dst = open_ta_file(dst_uuid, "w", true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200516 size_t r;
517 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200518 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200519
Jens Wiklander4441fe22015-10-23 16:53:02 +0200520 if (src && dst) {
521 do {
522 r = fread(buf, 1, sizeof(buf), src);
523 if (!r) {
524 ret = !!feof(src);
525 break;
526 }
527 w = fwrite(buf, 1, r, dst);
528 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200529 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200530
531 if (src)
532 fclose(src);
533 if (dst)
534 fclose(dst);
535 return ret;
536}
537
538static bool corrupt_file(FILE *f, long offs, uint8_t mask)
539{
540 uint8_t b;
541
542 if (fseek(f, offs, SEEK_SET))
543 return false;
544
545 if (fread(&b, 1, 1, f) != 1)
546 return false;
547
548 b ^= mask;
549
550 if (fseek(f, offs, SEEK_SET))
551 return false;
552
553 if (fwrite(&b, 1, 1, f) != 1)
554 return false;
555
556 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200557}
558
559static void load_fake_ta(ADBG_Case_t *c)
560{
561 static const TEEC_UUID fake_uuid = {
562 0x7e0a0900, 0x586b, 0x11e5,
563 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
564 };
565 TEEC_Session session = { 0 };
566 TEEC_Result res;
567 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200568 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200569
David Brownb2865ab2016-08-02 11:44:41 -0600570 r = copy_file(&create_fail_test_ta_uuid, &fake_uuid);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200571
572 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200573 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
574 &ret_orig);
575 if (res == TEEC_SUCCESS)
576 TEEC_CloseSession(&session);
577 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200578 }
579
David Brownb2865ab2016-08-02 11:44:41 -0600580 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid));
Jens Wiklanderb7940892015-10-23 16:02:40 +0200581}
582
Jens Wiklander4441fe22015-10-23 16:53:02 +0200583static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
584{
585 TEEC_Session session = { 0 };
586 TEEC_Result res;
587 uint32_t ret_orig;
588 FILE *f;
589 bool r;
590
David Brownb2865ab2016-08-02 11:44:41 -0600591 r = copy_file(&create_fail_test_ta_uuid, &create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200592 if (!ADBG_EXPECT_TRUE(c, r)) {
David Brownb2865ab2016-08-02 11:44:41 -0600593 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200594 return false;
595 }
596
David Brownb2865ab2016-08-02 11:44:41 -0600597 f = open_ta_file(&create_fail_test_ta_uuid, "r+", true);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200598 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
David Brownb2865ab2016-08-02 11:44:41 -0600599 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200600 return false;
601 }
602 r = corrupt_file(f, offs, mask);
603 fclose(f);
604
605 if (ADBG_EXPECT_TRUE(c, r)) {
606 res = xtest_teec_open_session(&session,
607 &create_fail_test_ta_uuid,
608 NULL, &ret_orig);
609 if (res == TEEC_SUCCESS)
610 TEEC_CloseSession(&session);
611 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
612 }
613
David Brownb2865ab2016-08-02 11:44:41 -0600614 r &= ADBG_EXPECT_TRUE(c, rm_file(&create_fail_test_ta_uuid));
Jens Wiklander4441fe22015-10-23 16:53:02 +0200615 return r;
616}
617
Pascal Brandc639ac82015-07-02 08:53:34 +0200618static void xtest_tee_test_1008(ADBG_Case_t *c)
619{
620 TEEC_Session session = { 0 };
621 TEEC_Session session_crypt = { 0 };
622 uint32_t ret_orig;
623
624 Do_ADBG_BeginSubCase(c, "Invoke command");
625 {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300626 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200627 xtest_teec_open_session(&session, &os_test_ta_uuid,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300628 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200629
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300630 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
631 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
632 NULL, &ret_orig));
633 TEEC_CloseSession(&session);
634 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200635
Pascal Brandc639ac82015-07-02 08:53:34 +0200636 }
637 Do_ADBG_EndSubCase(c, "Invoke command");
638
639 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
640 {
641 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
642
643 op.params[0].value.a = 2000;
644 op.paramTypes = TEEC_PARAM_TYPES(
645 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
646
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300647 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200648 xtest_teec_open_session(&session,
649 &os_test_ta_uuid,
650 NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300651 &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200652
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300653 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
654 TEEC_InvokeCommand(&session,
655 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
656 &op, &ret_orig));
657 TEEC_CloseSession(&session);
658 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200659 }
660 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
661
662 Do_ADBG_BeginSubCase(c, "Create session fail");
663 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200664 size_t n;
665
Pascal Brandc639ac82015-07-02 08:53:34 +0200666 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
667 xtest_teec_open_session(&session_crypt,
668 &create_fail_test_ta_uuid, NULL,
669 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200670 /*
671 * Run this several times to see that there's no memory leakage.
672 */
673 for (n = 0; n < 100; n++) {
674 Do_ADBG_Log("n = %zu", n);
675 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
676 xtest_teec_open_session(&session_crypt,
677 &create_fail_test_ta_uuid,
678 NULL, &ret_orig));
679 }
680 }
681 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200682
David Brownb2865ab2016-08-02 11:44:41 -0600683 make_test_ta_dir();
684
Jens Wiklanderb7940892015-10-23 16:02:40 +0200685 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
686 load_fake_ta(c);
687 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
688
Jens Wiklander4441fe22015-10-23 16:53:02 +0200689 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
690 ADBG_EXPECT_TRUE(c,
691 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
692 ADBG_EXPECT_TRUE(c,
693 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
694 ADBG_EXPECT_TRUE(c,
695 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
696 ADBG_EXPECT_TRUE(c,
697 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
698 ADBG_EXPECT_TRUE(c,
699 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
700 ADBG_EXPECT_TRUE(c,
701 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
702 ADBG_EXPECT_TRUE(c,
703 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
704 ADBG_EXPECT_TRUE(c,
705 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
706 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
707 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
708 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200709}
710
Pascal Brandc639ac82015-07-02 08:53:34 +0200711static void *cancellation_thread(void *arg)
712{
713 /*
714 * Sleep 0.5 seconds before cancellation to make sure that the other
715 * thread is in RPC_WAIT.
716 */
717 (void)usleep(500000);
718 TEEC_RequestCancellation(arg);
719 return NULL;
720}
Pascal Brandc639ac82015-07-02 08:53:34 +0200721
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300722static void xtest_tee_test_1009_subcase(ADBG_Case_t *c, const char *subcase,
723 uint32_t timeout, bool cancel)
Pascal Brandc639ac82015-07-02 08:53:34 +0200724{
725 TEEC_Session session = { 0 };
726 uint32_t ret_orig;
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300727 pthread_t thr;
Pascal Brandc639ac82015-07-02 08:53:34 +0200728
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300729 Do_ADBG_BeginSubCase(c, "%s", subcase);
Pascal Brandc639ac82015-07-02 08:53:34 +0200730 {
731 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
732
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300733 if (ADBG_EXPECT_TEEC_SUCCESS(c,
734 xtest_teec_open_session(&session, &os_test_ta_uuid,
735 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200736
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300737 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c,
738 TEEC_ORIGIN_TRUSTED_APP,
739 ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200740
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300741 op.params[0].value.a = timeout;
742 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
743 TEEC_NONE,
744 TEEC_NONE, TEEC_NONE);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300745 if (cancel) {
746 (void)ADBG_EXPECT(c, 0,
747 pthread_create(&thr, NULL,
748 cancellation_thread, &op));
Pascal Brandc639ac82015-07-02 08:53:34 +0200749
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300750 (void)ADBG_EXPECT_TEEC_RESULT(c,
751 TEEC_ERROR_CANCEL,
752 TEEC_InvokeCommand(&session,
753 TA_OS_TEST_CMD_WAIT,
754 &op,
755 &ret_orig));
756 } else
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300757
758 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
759 TEEC_InvokeCommand(&session,
760 TA_OS_TEST_CMD_WAIT,
761 &op,
762 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300763 if (cancel)
764 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300765
766 TEEC_CloseSession(&session);
767 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200768 }
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300769 Do_ADBG_EndSubCase(c, "%s", subcase);
770}
771
772static void xtest_tee_test_1009(ADBG_Case_t *c)
773{
774 xtest_tee_test_1009_subcase(c, "TEE Wait 0.1s", 100, false);
775 xtest_tee_test_1009_subcase(c, "TEE Wait 0.5s", 500, false);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300776 xtest_tee_test_1009_subcase(c, "TEE Wait 2s cancel", 2000, true);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300777 xtest_tee_test_1009_subcase(c, "TEE Wait 2s", 2000, false);
Pascal Brandc639ac82015-07-02 08:53:34 +0200778}
779
780static void xtest_tee_test_1010(ADBG_Case_t *c)
781{
782 unsigned n;
783
784 for (n = 1; n <= 5; n++) {
785 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
786 xtest_tee_test_invalid_mem_access(c, n);
787 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
788 }
789}
790
791static void xtest_tee_test_1011(ADBG_Case_t *c)
792{
793 TEEC_Session session = { 0 };
794 uint32_t ret_orig;
795 struct xtest_crypto_session cs = {
796 c, &session, TA_RPC_CMD_CRYPT_SHA256,
797 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
798 TA_RPC_CMD_CRYPT_AES256ECB_DEC
799 };
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100800 struct xtest_crypto_session cs_privmem = {
801 c, &session,
802 TA_RPC_CMD_CRYPT_PRIVMEM_SHA256,
803 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_ENC,
804 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_DEC
805 };
Pascal Brandc639ac82015-07-02 08:53:34 +0200806 TEEC_UUID uuid = rpc_test_ta_uuid;
807
808 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
809 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
810 return;
811
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100812 Do_ADBG_BeginSubCase(c, "TA-to-TA via non-secure shared memory");
Pascal Brandc639ac82015-07-02 08:53:34 +0200813 /*
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100814 * Run the "complete crypto test suite" using TA-to-TA
815 * communication
Pascal Brandc639ac82015-07-02 08:53:34 +0200816 */
817 xtest_crypto_test(&cs);
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100818 Do_ADBG_EndSubCase(c, "TA-to-TA via non-secure shared memory");
819
820 Do_ADBG_BeginSubCase(c, "TA-to-TA via TA private memory");
821 /*
822 * Run the "complete crypto test suite" using TA-to-TA
823 * communication via TA private memory.
824 */
825 xtest_crypto_test(&cs_privmem);
826 Do_ADBG_EndSubCase(c, "TA-to-TA via TA private memory");
827
Pascal Brandc639ac82015-07-02 08:53:34 +0200828 TEEC_CloseSession(&session);
829}
830
831/*
832 * Note that this test is failing when
833 * - running twice in a raw
834 * - and the user TA is statically linked
835 * This is because the counter is not reseted when opening the first session
836 * in case the TA is statically linked
837 */
838static void xtest_tee_test_1012(ADBG_Case_t *c)
839{
840 TEEC_Session session1 = { 0 };
841 TEEC_Session session2 = { 0 };
842 uint32_t ret_orig;
843 TEEC_UUID uuid = sims_test_ta_uuid;
844
845 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
846 {
847 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
848 static const uint8_t in[] = {
849 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
850 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
851 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
852 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
853 };
854 uint8_t out[32] = { 0 };
855 int i;
856
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300857 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200858 xtest_teec_open_session(&session1, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300859 &ret_orig)))
860 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200861
862 op.params[0].value.a = 0;
863 op.params[1].tmpref.buffer = (void *)in;
864 op.params[1].tmpref.size = sizeof(in);
865 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
866 TEEC_MEMREF_TEMP_INPUT,
867 TEEC_NONE, TEEC_NONE);
868
869 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
870 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
871 &ret_orig));
872
873 for (i = 1; i < 1000; i++) {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300874 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200875 xtest_teec_open_session(&session2, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300876 &ret_orig)))
877 continue;
Pascal Brandc639ac82015-07-02 08:53:34 +0200878
879 op.params[0].value.a = 0;
880 op.params[1].tmpref.buffer = out;
881 op.params[1].tmpref.size = sizeof(out);
882 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
883 TEEC_MEMREF_TEMP_OUTPUT,
884 TEEC_NONE, TEEC_NONE);
885
886 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
887 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
888 &op, &ret_orig));
889
890 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
891 sizeof(out))) {
892 Do_ADBG_Log("in:");
893 Do_ADBG_HexLog(in, sizeof(in), 16);
894 Do_ADBG_Log("out:");
895 Do_ADBG_HexLog(out, sizeof(out), 16);
896 }
897
898 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
899 TEEC_NONE, TEEC_NONE,
900 TEEC_NONE);
901
902 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
903 TEEC_InvokeCommand(&session1,
904 TA_SIMS_CMD_GET_COUNTER,
905 &op, &ret_orig));
906
907 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
908
909 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
910 TEEC_InvokeCommand(&session2,
911 TA_SIMS_CMD_GET_COUNTER, &op,
912 &ret_orig));
913
914 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
915 TEEC_CloseSession(&session2);
916 }
917
918 memset(out, 0, sizeof(out));
919 op.params[0].value.a = 0;
920 op.params[1].tmpref.buffer = out;
921 op.params[1].tmpref.size = sizeof(out);
922 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
923 TEEC_MEMREF_TEMP_OUTPUT,
924 TEEC_NONE, TEEC_NONE);
925
926 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
927 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
928 &ret_orig));
929
930 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
931 Do_ADBG_Log("in:");
932 Do_ADBG_HexLog(in, sizeof(in), 16);
933 Do_ADBG_Log("out:");
934 Do_ADBG_HexLog(out, sizeof(out), 16);
935 }
936
937 TEEC_CloseSession(&session1);
938 }
939}
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200940
941struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +0200942 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200943 uint32_t cmd;
944 uint32_t repeat;
945 TEEC_SharedMemory *shm;
946 uint32_t error_orig;
947 TEEC_Result res;
948 uint32_t max_concurrency;
949 const uint8_t *in;
950 size_t in_len;
951 uint8_t *out;
952 size_t out_len;
953};
954
955static void *test_1013_thread(void *arg)
956{
957 struct test_1013_thread_arg *a = arg;
958 TEEC_Session session = { 0 };
959 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
960 uint8_t p2 = TEEC_NONE;
961 uint8_t p3 = TEEC_NONE;
962
Jens Wiklander70672972016-04-06 00:01:45 +0200963 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200964 &a->error_orig);
965 if (a->res != TEEC_SUCCESS)
966 return NULL;
967
968 op.params[0].memref.parent = a->shm;
969 op.params[0].memref.size = a->shm->size;
970 op.params[0].memref.offset = 0;
971 op.params[1].value.a = a->repeat;
972 op.params[1].value.b = 0;
973 op.params[2].tmpref.buffer = (void *)a->in;
974 op.params[2].tmpref.size = a->in_len;
975 op.params[3].tmpref.buffer = a->out;
976 op.params[3].tmpref.size = a->out_len;
977
978 if (a->in_len)
979 p2 = TEEC_MEMREF_TEMP_INPUT;
980 if (a->out_len)
981 p3 = TEEC_MEMREF_TEMP_OUTPUT;
982
983 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
984 TEEC_VALUE_INOUT, p2, p3);
985
986 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
987 a->max_concurrency = op.params[1].value.b;
988 a->out_len = op.params[3].tmpref.size;
989 TEEC_CloseSession(&session);
990 return NULL;
991}
992
Pascal Brand4fa35582015-12-17 10:59:12 +0100993#define NUM_THREADS 3
994
Jens Wiklander70672972016-04-06 00:01:45 +0200995static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
996 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200997{
Pascal Brand4fa35582015-12-17 10:59:12 +0100998 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200999 size_t nt;
1000 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +02001001 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001002 pthread_t thr[num_threads];
1003 TEEC_SharedMemory shm;
1004 size_t max_concurrency;
1005 struct test_1013_thread_arg arg[num_threads];
1006 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
1007 static const uint8_t sha256_out[] = {
1008 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
1009 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
1010 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
1011 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
1012 };
1013 uint8_t out[32] = { 0 };
1014
Jens Wiklander70672972016-04-06 00:01:45 +02001015 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +01001016 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001017
1018 memset(&shm, 0, sizeof(shm));
1019 shm.size = sizeof(struct ta_concurrent_shm);
1020 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1021 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1022 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
1023 return;
1024
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001025 memset(shm.buffer, 0, shm.size);
1026 memset(arg, 0, sizeof(arg));
1027 max_concurrency = 0;
1028 nt = num_threads;
1029
1030 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001031 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001032 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +02001033 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001034 arg[n].shm = &shm;
1035 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1036 test_1013_thread, arg + n)))
1037 nt = n; /* break loop and start cleanup */
1038 }
1039
1040 for (n = 0; n < nt; n++) {
1041 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
1042 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
1043 if (arg[n].max_concurrency > max_concurrency)
1044 max_concurrency = arg[n].max_concurrency;
1045 }
1046
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001047 /*
1048 * Concurrency can be limited by several factors, for instance in a
1049 * single CPU system it's dependent on the Preemtion Model used by
1050 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
1051 * best result there).
1052 */
1053 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
1054 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +01001055 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001056 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001057
Jens Wiklander70672972016-04-06 00:01:45 +02001058 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001059 memset(shm.buffer, 0, shm.size);
1060 memset(arg, 0, sizeof(arg));
1061 max_concurrency = 0;
1062 nt = num_threads;
1063
1064 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001065 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001066 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +02001067 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001068 arg[n].shm = &shm;
1069 arg[n].in = sha256_in;
1070 arg[n].in_len = sizeof(sha256_in);
1071 arg[n].out = out;
1072 arg[n].out_len = sizeof(out);
1073 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1074 test_1013_thread, arg + n)))
1075 nt = n; /* break loop and start cleanup */
1076 }
1077
1078 for (n = 0; n < nt; n++) {
1079 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1080 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1081 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1082 arg[n].out, arg[n].out_len);
1083 if (arg[n].max_concurrency > max_concurrency)
1084 max_concurrency = arg[n].max_concurrency;
1085 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001086 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001087 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001088
Pascal Brand4fa35582015-12-17 10:59:12 +01001089 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001090 TEEC_ReleaseSharedMemory(&shm);
1091}
Pascal Brand4fa35582015-12-17 10:59:12 +01001092
1093static void xtest_tee_test_1013(ADBG_Case_t *c)
1094{
1095 int i;
1096 double mean_concurrency;
1097 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001098 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001099
1100 if (level == 0)
1101 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001102
Jens Wiklander70672972016-04-06 00:01:45 +02001103 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001104 mean_concurrency = 0;
1105 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001106 xtest_tee_test_1013_single(c, &concurrency,
1107 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001108 mean_concurrency += concurrency;
1109 }
1110 mean_concurrency /= nb_loops;
1111
1112 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1113 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001114 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001115
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001116#ifndef CFG_PAGED_USER_TA
Jens Wiklander70672972016-04-06 00:01:45 +02001117 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1118 mean_concurrency = 0;
1119 for (i = 0; i < nb_loops; i++) {
1120 xtest_tee_test_1013_single(c, &concurrency,
1121 &concurrent_large_ta_uuid);
1122 mean_concurrency += concurrency;
1123 }
1124 mean_concurrency /= nb_loops;
1125
1126 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1127 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1128 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001129#endif
Jens Wiklander70672972016-04-06 00:01:45 +02001130}
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001131
1132#ifdef CFG_SECURE_DATA_PATH
1133static void xtest_tee_test_1014(ADBG_Case_t *c)
1134{
1135 UNUSED(c);
1136
1137 int size = 17000;
1138 int loop = 10;
1139 int ion_heap = DEFAULT_ION_HEAP_TYPE;
1140 int rnd_offset = 1;
1141 int test;
1142 int ret;
1143
1144 test = TEST_NS_TO_TA;
1145 Do_ADBG_BeginSubCase(c, "SDP: NonSecure client invokes a SDP TA");
Etienne Carriereb9a95822017-04-26 15:03:53 +02001146 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001147 ADBG_EXPECT(c, 0, ret);
1148 Do_ADBG_EndSubCase(c, "SDP: NonSecure client invokes a SDP TA");
1149
1150 test = TEST_TA_TO_TA;
1151 Do_ADBG_BeginSubCase(c, "SDP: SDP TA invokes a SDP TA");
Etienne Carriereb9a95822017-04-26 15:03:53 +02001152 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001153 ADBG_EXPECT(c, 0, ret);
1154 Do_ADBG_EndSubCase(c, "SDP: SDP TA invokes a SDP TA");
1155
1156 test = TEST_TA_TO_PTA;
1157 Do_ADBG_BeginSubCase(c, "SDP: SDP TA invokes a SDP pTA");
Etienne Carriereb9a95822017-04-26 15:03:53 +02001158 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001159 ADBG_EXPECT(c, 0, ret);
1160 Do_ADBG_EndSubCase(c, "SDP: SDP TA invokes a SDP pTA");
1161
1162 test = TEST_NS_TO_PTA;
1163 Do_ADBG_BeginSubCase(c, "SDP: NonSecure client invokes SDP pTA (should fail)");
Etienne Carriereb9a95822017-04-26 15:03:53 +02001164 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001165 ADBG_EXPECT(c, 1, ret);
1166 Do_ADBG_EndSubCase(c, "SDP: NonSecure client invokes SDP pTA (should fail)");
1167}
1168#endif
Jens Wiklander272d3642017-04-03 13:03:47 +02001169
1170static void xtest_tee_test_1015(ADBG_Case_t *c)
1171{
1172 TEEC_Result res;
1173 TEEC_Session session = { 0 };
1174 uint32_t ret_orig;
1175
1176 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
1177 &ret_orig);
1178 /*
1179 * If the static TA (which is optional) isn't available, skip this
1180 * test.
1181 */
1182 if (res != TEEC_SUCCESS)
1183 return;
1184
1185 ADBG_EXPECT_TEEC_SUCCESS(c,
1186 TEEC_InvokeCommand(&session, PTA_INVOKE_TESTS_CMD_FS_HTREE,
1187 NULL, &ret_orig));
1188 TEEC_CloseSession(&session);
1189}
Jerome Forissiere916b102017-06-07 17:55:52 +02001190
1191static void xtest_tee_test_1016(ADBG_Case_t *c)
1192{
1193 TEEC_Session session = { 0 };
1194 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1195 uint32_t ret_orig;
1196
1197 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1198 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
1199 &ret_orig)))
1200 return;
1201
1202 op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE,
1203 TEEC_NONE);
1204
1205 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1206 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_TA2TA_MEMREF, &op,
1207 &ret_orig));
1208
1209 TEEC_CloseSession(&session);
1210}