blob: 610c4cec0264760a2538c5d65c999f47a2900259 [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
Etienne Carrierea3198522017-10-26 09:48:55 +0200184 Do_ADBG_BeginSubCase(cs->c, "AES-256 ECB encrypt (32B, fixed key)");
Pascal Brandc639ac82015-07-02 08:53:34 +0200185 {
186 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
187 static const uint8_t in[] = {
188 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
189 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
190 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
191 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
192 };
193 static const uint8_t exp_out[] = {
194 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
195 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
196 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
197 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
198 };
199 uint8_t out[sizeof(exp_out)];
200
201 op.params[0].tmpref.buffer = (void *)in;
202 op.params[0].tmpref.size = sizeof(in);
203 op.params[1].tmpref.buffer = out;
204 op.params[1].tmpref.size = sizeof(out);
205 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
206 TEEC_MEMREF_TEMP_OUTPUT,
207 TEEC_NONE, TEEC_NONE);
208
209 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
210 TEEC_InvokeCommand(cs->session,
211 cs->
212 cmd_id_aes256ecb_encrypt,
213 &op,
214 &ret_orig));
215
216 if (!ADBG_EXPECT(cs->c, 0,
217 memcmp(exp_out, out, sizeof(exp_out)))) {
218 Do_ADBG_Log("exp_out:");
219 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
220 Do_ADBG_Log("out:");
221 Do_ADBG_HexLog(out, sizeof(out), 16);
222 }
223 }
Etienne Carrierea3198522017-10-26 09:48:55 +0200224 Do_ADBG_EndSubCase(cs->c, "AES-256 ECB encrypt (32B, fixed key)");
Pascal Brandc639ac82015-07-02 08:53:34 +0200225
Etienne Carrierea3198522017-10-26 09:48:55 +0200226 Do_ADBG_BeginSubCase(cs->c, "AES-256 ECB decrypt (32B, fixed key)");
Pascal Brandc639ac82015-07-02 08:53:34 +0200227 {
228 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
229 static const uint8_t in[] = {
230 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
231 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
232 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
233 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
234 };
235 static const uint8_t exp_out[] = {
236 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
237 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
238 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
239 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
240 };
241 uint8_t out[sizeof(exp_out)];
242
243 op.params[0].tmpref.buffer = (void *)in;
244 op.params[0].tmpref.size = sizeof(in);
245 op.params[1].tmpref.buffer = out;
246 op.params[1].tmpref.size = sizeof(out);
247 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
248 TEEC_MEMREF_TEMP_OUTPUT,
249 TEEC_NONE, TEEC_NONE);
250
251 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
252 TEEC_InvokeCommand(cs->session,
253 cs->
254 cmd_id_aes256ecb_decrypt,
255 &op,
256 &ret_orig));
257
258 if (!ADBG_EXPECT(cs->c, 0,
259 memcmp(exp_out, out, sizeof(exp_out)))) {
260 Do_ADBG_Log("exp_out:");
261 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
262 Do_ADBG_Log("out:");
263 Do_ADBG_HexLog(out, sizeof(out), 16);
264 }
265 }
Etienne Carrierea3198522017-10-26 09:48:55 +0200266 Do_ADBG_EndSubCase(cs->c, "AES-256 ECB decrypt (32B, fixed key)");
Pascal Brandc639ac82015-07-02 08:53:34 +0200267}
268
269static void xtest_tee_test_1001(ADBG_Case_t *c)
270{
Jens Wiklandercf16e842016-02-10 09:07:09 +0100271 TEEC_Result res;
272 TEEC_Session session = { 0 };
273 uint32_t ret_orig;
Pascal Brandc639ac82015-07-02 08:53:34 +0200274
Etienne Carriere726d8bc2017-03-21 15:45:59 +0100275 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
Jens Wiklandercf16e842016-02-10 09:07:09 +0100276 &ret_orig);
277 /*
278 * If the static TA (which is optional) isn't available, skip this
279 * test.
280 */
281 if (res != TEEC_SUCCESS)
282 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200283
Jens Wiklandercf16e842016-02-10 09:07:09 +0100284 (void)ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
Etienne Carriere726d8bc2017-03-21 15:45:59 +0100285 &session, PTA_INVOKE_TESTS_CMD_SELF_TESTS, NULL, &ret_orig));
Jens Wiklandercf16e842016-02-10 09:07:09 +0100286 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200287}
288
Jens Wiklander1d70a112017-10-16 15:16:39 +0200289static void xtest_tee_test_1002(ADBG_Case_t *c)
290{
291 TEEC_Result res;
292 TEEC_Session session = { 0 };
293 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
294 uint32_t ret_orig;
295 uint8_t buf[16 * 1024];
296 uint8_t exp_sum = 0;
297 size_t n;
298
299 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
300 &ret_orig);
301 /*
302 * If the pseudo TA (which is optional) isn't available, skip this
303 * test.
304 */
305 if (res != TEEC_SUCCESS)
306 return;
307
308 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE,
309 TEEC_NONE, TEEC_NONE);
310 op.params[0].tmpref.size = sizeof(buf);
311 op.params[0].tmpref.buffer = buf;
312
313 for (n = 0; n < sizeof(buf); n++)
314 buf[n] = n + 1;
315 for (n = 0; n < sizeof(buf); n++)
316 exp_sum += buf[n];
317
318 if (!ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
319 &session, PTA_INVOKE_TESTS_CMD_PARAMS, &op, &ret_orig)))
320 goto out;
321
322 ADBG_EXPECT_COMPARE_SIGNED(c, exp_sum, ==, buf[0]);
323out:
324 TEEC_CloseSession(&session);
325}
326
327
328
Pascal Brandc639ac82015-07-02 08:53:34 +0200329static void xtest_tee_test_1004(ADBG_Case_t *c)
330{
331 TEEC_Session session = { 0 };
332 uint32_t ret_orig;
333 struct xtest_crypto_session cs = { c, &session, TA_CRYPT_CMD_SHA256,
334 TA_CRYPT_CMD_AES256ECB_ENC,
335 TA_CRYPT_CMD_AES256ECB_DEC };
336
337 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
338 &session, &crypt_user_ta_uuid,
339 NULL, &ret_orig)))
340 return;
341
342 /* Run the "complete crypto test suite" */
343 xtest_crypto_test(&cs);
344
345 TEEC_CloseSession(&session);
346}
347
348#ifndef TEEC_ERROR_TARGET_DEAD
349/* To be removed when we have TEEC_ERROR_TARGET_DEAD from tee_client_api.h */
350#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024
351#endif
352
353static void xtest_tee_test_invalid_mem_access(ADBG_Case_t *c, uint32_t n)
354{
355 TEEC_Session session = { 0 };
356 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
357 uint32_t ret_orig;
358
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300359 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200360 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300361 &ret_orig)))
362 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200363
364 op.params[0].value.a = n;
365 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
366 TEEC_NONE);
367
368 (void)ADBG_EXPECT_TEEC_RESULT(c,
369 TEEC_ERROR_TARGET_DEAD,
370 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
371 &ret_orig));
372
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300373 (void)ADBG_EXPECT_TEEC_RESULT(c,
374 TEEC_ERROR_TARGET_DEAD,
375 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
Pascal Brandc639ac82015-07-02 08:53:34 +0200376 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300377
Pascal Brandc639ac82015-07-02 08:53:34 +0200378 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
379
380 TEEC_CloseSession(&session);
381}
382
383static void xtest_tee_test_1005(ADBG_Case_t *c)
384{
385 uint32_t ret_orig;
386#define MAX_SESSIONS 3
387 TEEC_Session sessions[MAX_SESSIONS];
388 int i;
389
390 for (i = 0; i < MAX_SESSIONS; i++) {
391 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Jens Wiklandereb6bce72016-09-23 11:37:33 +0200392 xtest_teec_open_session(&sessions[i],
393 &concurrent_ta_uuid,
Pascal Brandc639ac82015-07-02 08:53:34 +0200394 NULL, &ret_orig)))
395 break;
396 }
397
398 for (; --i >= 0; )
399 TEEC_CloseSession(&sessions[i]);
400}
401
402static void xtest_tee_test_1006(ADBG_Case_t *c)
403{
404 TEEC_Session session = { 0 };
405 uint32_t ret_orig;
406 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
407 uint8_t buf[32];
408
409 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
410 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
411 &ret_orig)))
412 return;
413
414 op.params[0].tmpref.buffer = buf;
415 op.params[0].tmpref.size = sizeof(buf);
416 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
417 TEEC_NONE, TEEC_NONE);
418
419 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
420 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
421 &ret_orig));
422
423 TEEC_CloseSession(&session);
424}
425
426static void xtest_tee_test_1007(ADBG_Case_t *c)
427{
428 TEEC_Session session = { 0 };
429 uint32_t ret_orig;
430
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300431 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200432 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300433 &ret_orig)))
434 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200435
436 (void)ADBG_EXPECT_TEEC_RESULT(c,
437 TEEC_ERROR_TARGET_DEAD,
438 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
439 &ret_orig));
440
441 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
442
443 (void)ADBG_EXPECT_TEEC_RESULT(c,
444 TEEC_ERROR_TARGET_DEAD,
445 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
446 &ret_orig));
447
448 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
449
450 TEEC_CloseSession(&session);
451}
452
Jerome Forissierf02a2212015-10-29 14:33:35 +0100453#ifndef TA_DIR
Victor Chong3d8798f2017-03-01 18:31:48 +0000454# ifdef __ANDROID__
455#define TA_DIR "/system/lib/optee_armtz"
456# else
Jerome Forissierf02a2212015-10-29 14:33:35 +0100457#define TA_DIR "/lib/optee_armtz"
Victor Chong3d8798f2017-03-01 18:31:48 +0000458# endif
Jerome Forissierf02a2212015-10-29 14:33:35 +0100459#endif
460
David Brownb2865ab2016-08-02 11:44:41 -0600461#ifndef TA_TEST_DIR
462# ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200463# define TA_TEST_DIR "/data/tee/optee_armtz"
David Brownb2865ab2016-08-02 11:44:41 -0600464# else
465# define TA_TEST_DIR "/tmp/optee_armtz"
466# endif
467#endif
Jens Wiklanderb7940892015-10-23 16:02:40 +0200468
David Brownb2865ab2016-08-02 11:44:41 -0600469static void make_test_ta_dir(void)
470{
471#ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200472 (void)mkdir("/data/tee", 0755);
David Brownb2865ab2016-08-02 11:44:41 -0600473#endif
474 (void)mkdir(TA_TEST_DIR, 0755);
475}
476
477static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
478 bool for_write)
479{
Jens Wiklanderb7940892015-10-23 16:02:40 +0200480 snprintf(buf, blen,
Jens Wiklander6203b872016-12-08 19:18:29 +0100481 "%s/%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x.ta",
David Brownb2865ab2016-08-02 11:44:41 -0600482 for_write ? TA_TEST_DIR : TA_DIR,
483 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
Jens Wiklanderb7940892015-10-23 16:02:40 +0200484 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
485 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
486 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
David Brownb2865ab2016-08-02 11:44:41 -0600487 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200488}
489
David Brownb2865ab2016-08-02 11:44:41 -0600490static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode,
491 bool for_write)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200492{
493 char buf[PATH_MAX];
494
David Brownb2865ab2016-08-02 11:44:41 -0600495 uuid_to_full_name(buf, sizeof(buf), uuid, for_write);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200496 return fopen(buf, mode);
497}
498
David Brownb2865ab2016-08-02 11:44:41 -0600499static bool rm_file(const TEEC_UUID *uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200500{
501 char buf[PATH_MAX];
502
David Brownb2865ab2016-08-02 11:44:41 -0600503 uuid_to_full_name(buf, sizeof(buf), uuid, true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200504 return !unlink(buf);
505}
506
David Brownb2865ab2016-08-02 11:44:41 -0600507static bool copy_file(const TEEC_UUID *src_uuid, const TEEC_UUID *dst_uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200508{
509 char buf[4 * 1024];
David Brownb2865ab2016-08-02 11:44:41 -0600510 FILE *src = open_ta_file(src_uuid, "r", false);
511 FILE *dst = open_ta_file(dst_uuid, "w", true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200512 size_t r;
513 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200514 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200515
Jens Wiklander4441fe22015-10-23 16:53:02 +0200516 if (src && dst) {
517 do {
518 r = fread(buf, 1, sizeof(buf), src);
519 if (!r) {
520 ret = !!feof(src);
521 break;
522 }
523 w = fwrite(buf, 1, r, dst);
524 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200525 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200526
527 if (src)
528 fclose(src);
529 if (dst)
530 fclose(dst);
531 return ret;
532}
533
534static bool corrupt_file(FILE *f, long offs, uint8_t mask)
535{
536 uint8_t b;
537
538 if (fseek(f, offs, SEEK_SET))
539 return false;
540
541 if (fread(&b, 1, 1, f) != 1)
542 return false;
543
544 b ^= mask;
545
546 if (fseek(f, offs, SEEK_SET))
547 return false;
548
549 if (fwrite(&b, 1, 1, f) != 1)
550 return false;
551
552 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200553}
554
555static void load_fake_ta(ADBG_Case_t *c)
556{
557 static const TEEC_UUID fake_uuid = {
558 0x7e0a0900, 0x586b, 0x11e5,
559 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
560 };
561 TEEC_Session session = { 0 };
562 TEEC_Result res;
563 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200564 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200565
David Brownb2865ab2016-08-02 11:44:41 -0600566 r = copy_file(&create_fail_test_ta_uuid, &fake_uuid);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200567
568 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200569 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
570 &ret_orig);
571 if (res == TEEC_SUCCESS)
572 TEEC_CloseSession(&session);
573 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200574 }
575
David Brownb2865ab2016-08-02 11:44:41 -0600576 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid));
Jens Wiklanderb7940892015-10-23 16:02:40 +0200577}
578
Jens Wiklander4441fe22015-10-23 16:53:02 +0200579static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
580{
581 TEEC_Session session = { 0 };
582 TEEC_Result res;
583 uint32_t ret_orig;
584 FILE *f;
585 bool r;
586
David Brownb2865ab2016-08-02 11:44:41 -0600587 r = copy_file(&create_fail_test_ta_uuid, &create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200588 if (!ADBG_EXPECT_TRUE(c, r)) {
David Brownb2865ab2016-08-02 11:44:41 -0600589 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200590 return false;
591 }
592
David Brownb2865ab2016-08-02 11:44:41 -0600593 f = open_ta_file(&create_fail_test_ta_uuid, "r+", true);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200594 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
David Brownb2865ab2016-08-02 11:44:41 -0600595 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200596 return false;
597 }
598 r = corrupt_file(f, offs, mask);
599 fclose(f);
600
601 if (ADBG_EXPECT_TRUE(c, r)) {
602 res = xtest_teec_open_session(&session,
603 &create_fail_test_ta_uuid,
604 NULL, &ret_orig);
605 if (res == TEEC_SUCCESS)
606 TEEC_CloseSession(&session);
607 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
608 }
609
David Brownb2865ab2016-08-02 11:44:41 -0600610 r &= ADBG_EXPECT_TRUE(c, rm_file(&create_fail_test_ta_uuid));
Jens Wiklander4441fe22015-10-23 16:53:02 +0200611 return r;
612}
613
Pascal Brandc639ac82015-07-02 08:53:34 +0200614static void xtest_tee_test_1008(ADBG_Case_t *c)
615{
616 TEEC_Session session = { 0 };
617 TEEC_Session session_crypt = { 0 };
618 uint32_t ret_orig;
619
620 Do_ADBG_BeginSubCase(c, "Invoke command");
621 {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300622 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200623 xtest_teec_open_session(&session, &os_test_ta_uuid,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300624 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200625
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300626 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
627 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
628 NULL, &ret_orig));
629 TEEC_CloseSession(&session);
630 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200631
Pascal Brandc639ac82015-07-02 08:53:34 +0200632 }
633 Do_ADBG_EndSubCase(c, "Invoke command");
634
635 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
636 {
637 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
638
639 op.params[0].value.a = 2000;
640 op.paramTypes = TEEC_PARAM_TYPES(
641 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
642
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300643 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200644 xtest_teec_open_session(&session,
645 &os_test_ta_uuid,
646 NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300647 &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200648
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300649 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
650 TEEC_InvokeCommand(&session,
651 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
652 &op, &ret_orig));
653 TEEC_CloseSession(&session);
654 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200655 }
656 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
657
658 Do_ADBG_BeginSubCase(c, "Create session fail");
659 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200660 size_t n;
661
Pascal Brandc639ac82015-07-02 08:53:34 +0200662 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
663 xtest_teec_open_session(&session_crypt,
664 &create_fail_test_ta_uuid, NULL,
665 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200666 /*
667 * Run this several times to see that there's no memory leakage.
668 */
669 for (n = 0; n < 100; n++) {
670 Do_ADBG_Log("n = %zu", n);
671 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
672 xtest_teec_open_session(&session_crypt,
673 &create_fail_test_ta_uuid,
674 NULL, &ret_orig));
675 }
676 }
677 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200678
David Brownb2865ab2016-08-02 11:44:41 -0600679 make_test_ta_dir();
680
Jens Wiklanderb7940892015-10-23 16:02:40 +0200681 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
682 load_fake_ta(c);
683 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
684
Jens Wiklander4441fe22015-10-23 16:53:02 +0200685 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
686 ADBG_EXPECT_TRUE(c,
687 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
688 ADBG_EXPECT_TRUE(c,
689 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
690 ADBG_EXPECT_TRUE(c,
691 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
692 ADBG_EXPECT_TRUE(c,
693 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
694 ADBG_EXPECT_TRUE(c,
695 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
696 ADBG_EXPECT_TRUE(c,
697 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
698 ADBG_EXPECT_TRUE(c,
699 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
700 ADBG_EXPECT_TRUE(c,
701 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
702 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
703 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
704 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200705}
706
Pascal Brandc639ac82015-07-02 08:53:34 +0200707static void *cancellation_thread(void *arg)
708{
709 /*
710 * Sleep 0.5 seconds before cancellation to make sure that the other
711 * thread is in RPC_WAIT.
712 */
713 (void)usleep(500000);
714 TEEC_RequestCancellation(arg);
715 return NULL;
716}
Pascal Brandc639ac82015-07-02 08:53:34 +0200717
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300718static void xtest_tee_test_1009_subcase(ADBG_Case_t *c, const char *subcase,
719 uint32_t timeout, bool cancel)
Pascal Brandc639ac82015-07-02 08:53:34 +0200720{
721 TEEC_Session session = { 0 };
722 uint32_t ret_orig;
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300723 pthread_t thr;
Pascal Brandc639ac82015-07-02 08:53:34 +0200724
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300725 Do_ADBG_BeginSubCase(c, "%s", subcase);
Pascal Brandc639ac82015-07-02 08:53:34 +0200726 {
727 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
728
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300729 if (ADBG_EXPECT_TEEC_SUCCESS(c,
730 xtest_teec_open_session(&session, &os_test_ta_uuid,
731 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200732
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300733 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c,
734 TEEC_ORIGIN_TRUSTED_APP,
735 ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200736
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300737 op.params[0].value.a = timeout;
738 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
739 TEEC_NONE,
740 TEEC_NONE, TEEC_NONE);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300741 if (cancel) {
742 (void)ADBG_EXPECT(c, 0,
743 pthread_create(&thr, NULL,
744 cancellation_thread, &op));
Pascal Brandc639ac82015-07-02 08:53:34 +0200745
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300746 (void)ADBG_EXPECT_TEEC_RESULT(c,
747 TEEC_ERROR_CANCEL,
748 TEEC_InvokeCommand(&session,
749 TA_OS_TEST_CMD_WAIT,
750 &op,
751 &ret_orig));
752 } else
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300753
754 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
755 TEEC_InvokeCommand(&session,
756 TA_OS_TEST_CMD_WAIT,
757 &op,
758 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300759 if (cancel)
760 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300761
762 TEEC_CloseSession(&session);
763 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200764 }
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300765 Do_ADBG_EndSubCase(c, "%s", subcase);
766}
767
768static void xtest_tee_test_1009(ADBG_Case_t *c)
769{
770 xtest_tee_test_1009_subcase(c, "TEE Wait 0.1s", 100, false);
771 xtest_tee_test_1009_subcase(c, "TEE Wait 0.5s", 500, false);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300772 xtest_tee_test_1009_subcase(c, "TEE Wait 2s cancel", 2000, true);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300773 xtest_tee_test_1009_subcase(c, "TEE Wait 2s", 2000, false);
Pascal Brandc639ac82015-07-02 08:53:34 +0200774}
775
776static void xtest_tee_test_1010(ADBG_Case_t *c)
777{
778 unsigned n;
779
780 for (n = 1; n <= 5; n++) {
781 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
782 xtest_tee_test_invalid_mem_access(c, n);
783 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
784 }
785}
786
787static void xtest_tee_test_1011(ADBG_Case_t *c)
788{
789 TEEC_Session session = { 0 };
790 uint32_t ret_orig;
791 struct xtest_crypto_session cs = {
792 c, &session, TA_RPC_CMD_CRYPT_SHA256,
793 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
794 TA_RPC_CMD_CRYPT_AES256ECB_DEC
795 };
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100796 struct xtest_crypto_session cs_privmem = {
797 c, &session,
798 TA_RPC_CMD_CRYPT_PRIVMEM_SHA256,
799 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_ENC,
800 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_DEC
801 };
Pascal Brandc639ac82015-07-02 08:53:34 +0200802 TEEC_UUID uuid = rpc_test_ta_uuid;
803
804 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
805 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
806 return;
807
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100808 Do_ADBG_BeginSubCase(c, "TA-to-TA via non-secure shared memory");
Pascal Brandc639ac82015-07-02 08:53:34 +0200809 /*
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100810 * Run the "complete crypto test suite" using TA-to-TA
811 * communication
Pascal Brandc639ac82015-07-02 08:53:34 +0200812 */
813 xtest_crypto_test(&cs);
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100814 Do_ADBG_EndSubCase(c, "TA-to-TA via non-secure shared memory");
815
816 Do_ADBG_BeginSubCase(c, "TA-to-TA via TA private memory");
817 /*
818 * Run the "complete crypto test suite" using TA-to-TA
819 * communication via TA private memory.
820 */
821 xtest_crypto_test(&cs_privmem);
822 Do_ADBG_EndSubCase(c, "TA-to-TA via TA private memory");
823
Pascal Brandc639ac82015-07-02 08:53:34 +0200824 TEEC_CloseSession(&session);
825}
826
827/*
828 * Note that this test is failing when
829 * - running twice in a raw
830 * - and the user TA is statically linked
831 * This is because the counter is not reseted when opening the first session
832 * in case the TA is statically linked
833 */
834static void xtest_tee_test_1012(ADBG_Case_t *c)
835{
836 TEEC_Session session1 = { 0 };
837 TEEC_Session session2 = { 0 };
838 uint32_t ret_orig;
839 TEEC_UUID uuid = sims_test_ta_uuid;
840
841 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
842 {
843 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
844 static const uint8_t in[] = {
845 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
846 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
847 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
848 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
849 };
850 uint8_t out[32] = { 0 };
851 int i;
852
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300853 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200854 xtest_teec_open_session(&session1, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300855 &ret_orig)))
856 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200857
858 op.params[0].value.a = 0;
859 op.params[1].tmpref.buffer = (void *)in;
860 op.params[1].tmpref.size = sizeof(in);
861 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
862 TEEC_MEMREF_TEMP_INPUT,
863 TEEC_NONE, TEEC_NONE);
864
865 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
866 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
867 &ret_orig));
868
869 for (i = 1; i < 1000; i++) {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300870 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200871 xtest_teec_open_session(&session2, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300872 &ret_orig)))
873 continue;
Pascal Brandc639ac82015-07-02 08:53:34 +0200874
875 op.params[0].value.a = 0;
876 op.params[1].tmpref.buffer = out;
877 op.params[1].tmpref.size = sizeof(out);
878 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
879 TEEC_MEMREF_TEMP_OUTPUT,
880 TEEC_NONE, TEEC_NONE);
881
882 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
883 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
884 &op, &ret_orig));
885
886 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
887 sizeof(out))) {
888 Do_ADBG_Log("in:");
889 Do_ADBG_HexLog(in, sizeof(in), 16);
890 Do_ADBG_Log("out:");
891 Do_ADBG_HexLog(out, sizeof(out), 16);
892 }
893
894 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
895 TEEC_NONE, TEEC_NONE,
896 TEEC_NONE);
897
898 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
899 TEEC_InvokeCommand(&session1,
900 TA_SIMS_CMD_GET_COUNTER,
901 &op, &ret_orig));
902
903 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
904
905 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
906 TEEC_InvokeCommand(&session2,
907 TA_SIMS_CMD_GET_COUNTER, &op,
908 &ret_orig));
909
910 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
911 TEEC_CloseSession(&session2);
912 }
913
914 memset(out, 0, sizeof(out));
915 op.params[0].value.a = 0;
916 op.params[1].tmpref.buffer = out;
917 op.params[1].tmpref.size = sizeof(out);
918 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
919 TEEC_MEMREF_TEMP_OUTPUT,
920 TEEC_NONE, TEEC_NONE);
921
922 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
923 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
924 &ret_orig));
925
926 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
927 Do_ADBG_Log("in:");
928 Do_ADBG_HexLog(in, sizeof(in), 16);
929 Do_ADBG_Log("out:");
930 Do_ADBG_HexLog(out, sizeof(out), 16);
931 }
932
933 TEEC_CloseSession(&session1);
934 }
935}
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200936
937struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +0200938 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200939 uint32_t cmd;
940 uint32_t repeat;
941 TEEC_SharedMemory *shm;
942 uint32_t error_orig;
943 TEEC_Result res;
944 uint32_t max_concurrency;
945 const uint8_t *in;
946 size_t in_len;
947 uint8_t *out;
948 size_t out_len;
949};
950
951static void *test_1013_thread(void *arg)
952{
953 struct test_1013_thread_arg *a = arg;
954 TEEC_Session session = { 0 };
955 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
956 uint8_t p2 = TEEC_NONE;
957 uint8_t p3 = TEEC_NONE;
958
Jens Wiklander70672972016-04-06 00:01:45 +0200959 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200960 &a->error_orig);
961 if (a->res != TEEC_SUCCESS)
962 return NULL;
963
964 op.params[0].memref.parent = a->shm;
965 op.params[0].memref.size = a->shm->size;
966 op.params[0].memref.offset = 0;
967 op.params[1].value.a = a->repeat;
968 op.params[1].value.b = 0;
969 op.params[2].tmpref.buffer = (void *)a->in;
970 op.params[2].tmpref.size = a->in_len;
971 op.params[3].tmpref.buffer = a->out;
972 op.params[3].tmpref.size = a->out_len;
973
974 if (a->in_len)
975 p2 = TEEC_MEMREF_TEMP_INPUT;
976 if (a->out_len)
977 p3 = TEEC_MEMREF_TEMP_OUTPUT;
978
979 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
980 TEEC_VALUE_INOUT, p2, p3);
981
982 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
983 a->max_concurrency = op.params[1].value.b;
984 a->out_len = op.params[3].tmpref.size;
985 TEEC_CloseSession(&session);
986 return NULL;
987}
988
Pascal Brand4fa35582015-12-17 10:59:12 +0100989#define NUM_THREADS 3
990
Jens Wiklander70672972016-04-06 00:01:45 +0200991static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
992 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200993{
Pascal Brand4fa35582015-12-17 10:59:12 +0100994 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200995 size_t nt;
996 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +0200997 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200998 pthread_t thr[num_threads];
999 TEEC_SharedMemory shm;
1000 size_t max_concurrency;
1001 struct test_1013_thread_arg arg[num_threads];
1002 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
1003 static const uint8_t sha256_out[] = {
1004 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
1005 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
1006 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
1007 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
1008 };
1009 uint8_t out[32] = { 0 };
1010
Jens Wiklander70672972016-04-06 00:01:45 +02001011 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +01001012 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001013
1014 memset(&shm, 0, sizeof(shm));
1015 shm.size = sizeof(struct ta_concurrent_shm);
1016 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
1017 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1018 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
1019 return;
1020
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001021 memset(shm.buffer, 0, shm.size);
1022 memset(arg, 0, sizeof(arg));
1023 max_concurrency = 0;
1024 nt = num_threads;
1025
1026 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001027 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001028 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +02001029 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001030 arg[n].shm = &shm;
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 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
1038 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
1039 if (arg[n].max_concurrency > max_concurrency)
1040 max_concurrency = arg[n].max_concurrency;
1041 }
1042
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001043 /*
1044 * Concurrency can be limited by several factors, for instance in a
1045 * single CPU system it's dependent on the Preemtion Model used by
1046 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
1047 * best result there).
1048 */
1049 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
1050 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +01001051 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001052 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001053
Jens Wiklander70672972016-04-06 00:01:45 +02001054 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001055 memset(shm.buffer, 0, shm.size);
1056 memset(arg, 0, sizeof(arg));
1057 max_concurrency = 0;
1058 nt = num_threads;
1059
1060 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001061 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001062 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +02001063 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001064 arg[n].shm = &shm;
1065 arg[n].in = sha256_in;
1066 arg[n].in_len = sizeof(sha256_in);
1067 arg[n].out = out;
1068 arg[n].out_len = sizeof(out);
1069 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1070 test_1013_thread, arg + n)))
1071 nt = n; /* break loop and start cleanup */
1072 }
1073
1074 for (n = 0; n < nt; n++) {
1075 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1076 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1077 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1078 arg[n].out, arg[n].out_len);
1079 if (arg[n].max_concurrency > max_concurrency)
1080 max_concurrency = arg[n].max_concurrency;
1081 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001082 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001083 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001084
Pascal Brand4fa35582015-12-17 10:59:12 +01001085 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001086 TEEC_ReleaseSharedMemory(&shm);
1087}
Pascal Brand4fa35582015-12-17 10:59:12 +01001088
1089static void xtest_tee_test_1013(ADBG_Case_t *c)
1090{
1091 int i;
1092 double mean_concurrency;
1093 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001094 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001095
1096 if (level == 0)
1097 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001098
Jens Wiklander70672972016-04-06 00:01:45 +02001099 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001100 mean_concurrency = 0;
1101 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001102 xtest_tee_test_1013_single(c, &concurrency,
1103 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001104 mean_concurrency += concurrency;
1105 }
1106 mean_concurrency /= nb_loops;
1107
1108 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1109 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001110 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001111
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001112#ifndef CFG_PAGED_USER_TA
Jens Wiklander70672972016-04-06 00:01:45 +02001113 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1114 mean_concurrency = 0;
1115 for (i = 0; i < nb_loops; i++) {
1116 xtest_tee_test_1013_single(c, &concurrency,
1117 &concurrent_large_ta_uuid);
1118 mean_concurrency += concurrency;
1119 }
1120 mean_concurrency /= nb_loops;
1121
1122 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1123 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1124 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001125#endif
Jens Wiklander70672972016-04-06 00:01:45 +02001126}
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001127
1128#ifdef CFG_SECURE_DATA_PATH
1129static void xtest_tee_test_1014(ADBG_Case_t *c)
1130{
1131 UNUSED(c);
1132
1133 int size = 17000;
1134 int loop = 10;
1135 int ion_heap = DEFAULT_ION_HEAP_TYPE;
1136 int rnd_offset = 1;
1137 int test;
1138 int ret;
1139
1140 test = TEST_NS_TO_TA;
1141 Do_ADBG_BeginSubCase(c, "SDP: NonSecure client invokes a SDP TA");
Etienne Carriereb9a95822017-04-26 15:03:53 +02001142 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001143 ADBG_EXPECT(c, 0, ret);
1144 Do_ADBG_EndSubCase(c, "SDP: NonSecure client invokes a SDP TA");
1145
1146 test = TEST_TA_TO_TA;
1147 Do_ADBG_BeginSubCase(c, "SDP: SDP TA invokes a SDP TA");
Etienne Carriereb9a95822017-04-26 15:03:53 +02001148 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001149 ADBG_EXPECT(c, 0, ret);
1150 Do_ADBG_EndSubCase(c, "SDP: SDP TA invokes a SDP TA");
1151
1152 test = TEST_TA_TO_PTA;
1153 Do_ADBG_BeginSubCase(c, "SDP: SDP TA invokes a SDP pTA");
Etienne Carriereb9a95822017-04-26 15:03:53 +02001154 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001155 ADBG_EXPECT(c, 0, ret);
1156 Do_ADBG_EndSubCase(c, "SDP: SDP TA invokes a SDP pTA");
1157
1158 test = TEST_NS_TO_PTA;
Etienne Carrierea3198522017-10-26 09:48:55 +02001159 Do_ADBG_BeginSubCase(c, "SDP: NSec CA invokes SDP pTA (should fail)");
Etienne Carriereb9a95822017-04-26 15:03:53 +02001160 ret = sdp_basic_test(test, size, loop, ion_heap, rnd_offset, 0);
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001161 ADBG_EXPECT(c, 1, ret);
Etienne Carrierea3198522017-10-26 09:48:55 +02001162 Do_ADBG_EndSubCase(c, "SDP: NSec CA invokes SDP pTA (should fail)");
Etienne Carriere50abf9a2017-03-24 11:33:50 +01001163}
1164#endif
Jens Wiklander272d3642017-04-03 13:03:47 +02001165
1166static void xtest_tee_test_1015(ADBG_Case_t *c)
1167{
1168 TEEC_Result res;
1169 TEEC_Session session = { 0 };
1170 uint32_t ret_orig;
1171
1172 res = xtest_teec_open_session(&session, &pta_invoke_tests_ta_uuid, NULL,
1173 &ret_orig);
1174 /*
1175 * If the static TA (which is optional) isn't available, skip this
1176 * test.
1177 */
1178 if (res != TEEC_SUCCESS)
1179 return;
1180
1181 ADBG_EXPECT_TEEC_SUCCESS(c,
1182 TEEC_InvokeCommand(&session, PTA_INVOKE_TESTS_CMD_FS_HTREE,
1183 NULL, &ret_orig));
1184 TEEC_CloseSession(&session);
1185}
Jerome Forissiere916b102017-06-07 17:55:52 +02001186
1187static void xtest_tee_test_1016(ADBG_Case_t *c)
1188{
1189 TEEC_Session session = { 0 };
1190 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
1191 uint32_t ret_orig;
1192
1193 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
1194 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
1195 &ret_orig)))
1196 return;
1197
1198 op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE,
1199 TEEC_NONE);
1200
1201 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
1202 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_TA2TA_MEMREF, &op,
1203 &ret_orig));
1204
1205 TEEC_CloseSession(&session);
1206}