blob: 7b3956f50e370e0f186682269535e3427ec9168d [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
26#include <ta_crypt.h>
27#include <ta_os_test.h>
28#include <ta_create_fail_test.h>
29#include <ta_rpc_test.h>
30#include <ta_sims_test.h>
Jens Wiklanderac27ec12015-07-15 15:23:14 +020031#include <ta_concurrent.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020032
33static void xtest_tee_test_1001(ADBG_Case_t *Case_p);
34static void xtest_tee_test_1004(ADBG_Case_t *Case_p);
35static void xtest_tee_test_1005(ADBG_Case_t *Case_p);
36static void xtest_tee_test_1006(ADBG_Case_t *Case_p);
37static void xtest_tee_test_1007(ADBG_Case_t *Case_p);
38static void xtest_tee_test_1008(ADBG_Case_t *Case_p);
39static void xtest_tee_test_1009(ADBG_Case_t *Case_p);
40static void xtest_tee_test_1010(ADBG_Case_t *Case_p);
41static void xtest_tee_test_1011(ADBG_Case_t *Case_p);
42static void xtest_tee_test_1012(ADBG_Case_t *Case_p);
Jens Wiklanderac27ec12015-07-15 15:23:14 +020043static void xtest_tee_test_1013(ADBG_Case_t *Case_p);
Pascal Brandc639ac82015-07-02 08:53:34 +020044
Jens Wiklander74abfe32017-01-03 14:17:47 +010045ADBG_CASE_DEFINE(regression, 1001, xtest_tee_test_1001, "Core self tests");
46ADBG_CASE_DEFINE(regression, 1004, xtest_tee_test_1004, "Test User Crypt TA");
47ADBG_CASE_DEFINE(regression, 1005, xtest_tee_test_1005, "Many sessions");
48ADBG_CASE_DEFINE(regression, 1006, xtest_tee_test_1006,
49 "Test Basic OS features");
50ADBG_CASE_DEFINE(regression, 1007, xtest_tee_test_1007, "Test Panic");
51ADBG_CASE_DEFINE(regression, 1008, xtest_tee_test_1008,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010052 "TEE internal client API");
Jens Wiklander74abfe32017-01-03 14:17:47 +010053ADBG_CASE_DEFINE(regression, 1009, xtest_tee_test_1009, "TEE Wait");
54ADBG_CASE_DEFINE(regression, 1010, xtest_tee_test_1010,
55 "Invalid memory access");
56ADBG_CASE_DEFINE(regression, 1011, xtest_tee_test_1011,
Jens Wiklanderf7b9c632017-01-03 17:32:26 +010057 "Test TA-to-TA features with User Crypt TA");
Jens Wiklander74abfe32017-01-03 14:17:47 +010058ADBG_CASE_DEFINE(regression, 1012, xtest_tee_test_1012,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010059 "Test Single Instance Multi Session features with SIMS TA");
Jens Wiklander74abfe32017-01-03 14:17:47 +010060ADBG_CASE_DEFINE(regression, 1013, xtest_tee_test_1013,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010061 "Test concurency with concurrent TA");
Jens Wiklanderac27ec12015-07-15 15:23:14 +020062
Pascal Brandc639ac82015-07-02 08:53:34 +020063struct xtest_crypto_session {
64 ADBG_Case_t *c;
65 TEEC_Session *session;
66 uint32_t cmd_id_sha256;
67 uint32_t cmd_id_aes256ecb_encrypt;
68 uint32_t cmd_id_aes256ecb_decrypt;
69};
70
71static void xtest_crypto_test(struct xtest_crypto_session *cs)
72{
73 uint32_t ret_orig;
74 uint8_t crypt_out[16];
75 uint8_t crypt_in[16] = { 22, 17 };
76
77 crypt_in[15] = 60;
78
79 Do_ADBG_BeginSubCase(cs->c, "AES encrypt");
80 {
81 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
82
83 op.params[0].tmpref.buffer = crypt_in;
84 op.params[0].tmpref.size = sizeof(crypt_in);
85 op.params[1].tmpref.buffer = crypt_out;
86 op.params[1].tmpref.size = sizeof(crypt_out);
87 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
88 TEEC_MEMREF_TEMP_OUTPUT,
89 TEEC_NONE, TEEC_NONE);
90
91 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
92 TEEC_InvokeCommand(cs->session,
93 cs->
94 cmd_id_aes256ecb_encrypt,
95 &op,
96 &ret_orig));
97 }
98 Do_ADBG_EndSubCase(cs->c, "AES encrypt");
99
100 Do_ADBG_BeginSubCase(cs->c, "AES decrypt");
101 {
102 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
103 uint8_t out[16];
104
105 op.params[0].tmpref.buffer = crypt_out;
106 op.params[0].tmpref.size = sizeof(crypt_out);
107 op.params[1].tmpref.buffer = out;
108 op.params[1].tmpref.size = sizeof(out);
109 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
110 TEEC_MEMREF_TEMP_OUTPUT,
111 TEEC_NONE, TEEC_NONE);
112
113 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
114 TEEC_InvokeCommand(cs->session,
115 cs->
116 cmd_id_aes256ecb_decrypt,
117 &op,
118 &ret_orig));
119
120 if (!ADBG_EXPECT(cs->c, 0,
121 memcmp(crypt_in, out, sizeof(crypt_in)))) {
122 Do_ADBG_Log("crypt_in:");
123 Do_ADBG_HexLog(crypt_in, sizeof(crypt_in), 16);
124 Do_ADBG_Log("out:");
125 Do_ADBG_HexLog(out, sizeof(out), 16);
126 }
127 }
128 Do_ADBG_EndSubCase(cs->c, "AES decrypt");
129
130 Do_ADBG_BeginSubCase(cs->c, "SHA-256 test, 3 bytes input");
131 {
132 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
133 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
134 static const uint8_t sha256_out[] = {
135 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
136 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
137 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
138 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
139 };
140 uint8_t out[32] = { 0 };
141
142 op.params[0].tmpref.buffer = (void *)sha256_in;
143 op.params[0].tmpref.size = sizeof(sha256_in);
144 op.params[1].tmpref.buffer = out;
145 op.params[1].tmpref.size = sizeof(out);
146 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
147 TEEC_MEMREF_TEMP_OUTPUT,
148 TEEC_NONE, TEEC_NONE);
149
150 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
151 TEEC_InvokeCommand(cs->session,
152 cs->
153 cmd_id_sha256,
154 &op,
155 &ret_orig));
156
157 if (!ADBG_EXPECT(cs->c, 0, memcmp(sha256_out, out,
158 sizeof(sha256_out)))) {
159 Do_ADBG_Log("sha256_out:");
160 Do_ADBG_HexLog(sha256_out, sizeof(sha256_out), 16);
161 Do_ADBG_Log("out:");
162 Do_ADBG_HexLog(out, sizeof(out), 16);
163 }
164 }
165 Do_ADBG_EndSubCase(cs->c, "SHA-256 test, 3 bytes input");
166
167 Do_ADBG_BeginSubCase(cs->c,
168 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
169 {
170 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
171 static const uint8_t in[] = {
172 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
173 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
174 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
175 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
176 };
177 static const uint8_t exp_out[] = {
178 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
179 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
180 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
181 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
182 };
183 uint8_t out[sizeof(exp_out)];
184
185 op.params[0].tmpref.buffer = (void *)in;
186 op.params[0].tmpref.size = sizeof(in);
187 op.params[1].tmpref.buffer = out;
188 op.params[1].tmpref.size = sizeof(out);
189 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
190 TEEC_MEMREF_TEMP_OUTPUT,
191 TEEC_NONE, TEEC_NONE);
192
193 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
194 TEEC_InvokeCommand(cs->session,
195 cs->
196 cmd_id_aes256ecb_encrypt,
197 &op,
198 &ret_orig));
199
200 if (!ADBG_EXPECT(cs->c, 0,
201 memcmp(exp_out, out, sizeof(exp_out)))) {
202 Do_ADBG_Log("exp_out:");
203 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
204 Do_ADBG_Log("out:");
205 Do_ADBG_HexLog(out, sizeof(out), 16);
206 }
207 }
208 Do_ADBG_EndSubCase(cs->c,
209 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
210
211 Do_ADBG_BeginSubCase(cs->c,
212 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
213 {
214 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
215 static const uint8_t in[] = {
216 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
217 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
218 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
219 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
220 };
221 static const uint8_t exp_out[] = {
222 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
223 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
224 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
225 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
226 };
227 uint8_t out[sizeof(exp_out)];
228
229 op.params[0].tmpref.buffer = (void *)in;
230 op.params[0].tmpref.size = sizeof(in);
231 op.params[1].tmpref.buffer = out;
232 op.params[1].tmpref.size = sizeof(out);
233 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
234 TEEC_MEMREF_TEMP_OUTPUT,
235 TEEC_NONE, TEEC_NONE);
236
237 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
238 TEEC_InvokeCommand(cs->session,
239 cs->
240 cmd_id_aes256ecb_decrypt,
241 &op,
242 &ret_orig));
243
244 if (!ADBG_EXPECT(cs->c, 0,
245 memcmp(exp_out, out, sizeof(exp_out)))) {
246 Do_ADBG_Log("exp_out:");
247 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
248 Do_ADBG_Log("out:");
249 Do_ADBG_HexLog(out, sizeof(out), 16);
250 }
251 }
252 Do_ADBG_EndSubCase(cs->c,
253 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
254}
255
256static void xtest_tee_test_1001(ADBG_Case_t *c)
257{
Jens Wiklandercf16e842016-02-10 09:07:09 +0100258 TEEC_Result res;
259 TEEC_Session session = { 0 };
260 uint32_t ret_orig;
Pascal Brandc639ac82015-07-02 08:53:34 +0200261
Jens Wiklandercf16e842016-02-10 09:07:09 +0100262#define CMD_SELF_TESTS 2
Pascal Brandc639ac82015-07-02 08:53:34 +0200263
Jens Wiklandercf16e842016-02-10 09:07:09 +0100264 res = xtest_teec_open_session(&session, &sta_test_ta_uuid, NULL,
265 &ret_orig);
266 /*
267 * If the static TA (which is optional) isn't available, skip this
268 * test.
269 */
270 if (res != TEEC_SUCCESS)
271 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200272
Jens Wiklandercf16e842016-02-10 09:07:09 +0100273 (void)ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
274 &session, CMD_SELF_TESTS, NULL, &ret_orig));
275 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200276}
277
278static void xtest_tee_test_1004(ADBG_Case_t *c)
279{
280 TEEC_Session session = { 0 };
281 uint32_t ret_orig;
282 struct xtest_crypto_session cs = { c, &session, TA_CRYPT_CMD_SHA256,
283 TA_CRYPT_CMD_AES256ECB_ENC,
284 TA_CRYPT_CMD_AES256ECB_DEC };
285
286 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
287 &session, &crypt_user_ta_uuid,
288 NULL, &ret_orig)))
289 return;
290
291 /* Run the "complete crypto test suite" */
292 xtest_crypto_test(&cs);
293
294 TEEC_CloseSession(&session);
295}
296
297#ifndef TEEC_ERROR_TARGET_DEAD
298/* To be removed when we have TEEC_ERROR_TARGET_DEAD from tee_client_api.h */
299#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024
300#endif
301
302static void xtest_tee_test_invalid_mem_access(ADBG_Case_t *c, uint32_t n)
303{
304 TEEC_Session session = { 0 };
305 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
306 uint32_t ret_orig;
307
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300308 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200309 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300310 &ret_orig)))
311 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200312
313 op.params[0].value.a = n;
314 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
315 TEEC_NONE);
316
317 (void)ADBG_EXPECT_TEEC_RESULT(c,
318 TEEC_ERROR_TARGET_DEAD,
319 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
320 &ret_orig));
321
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300322 (void)ADBG_EXPECT_TEEC_RESULT(c,
323 TEEC_ERROR_TARGET_DEAD,
324 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
Pascal Brandc639ac82015-07-02 08:53:34 +0200325 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300326
Pascal Brandc639ac82015-07-02 08:53:34 +0200327 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
328
329 TEEC_CloseSession(&session);
330}
331
332static void xtest_tee_test_1005(ADBG_Case_t *c)
333{
334 uint32_t ret_orig;
335#define MAX_SESSIONS 3
336 TEEC_Session sessions[MAX_SESSIONS];
337 int i;
338
339 for (i = 0; i < MAX_SESSIONS; i++) {
340 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Jens Wiklandereb6bce72016-09-23 11:37:33 +0200341 xtest_teec_open_session(&sessions[i],
342 &concurrent_ta_uuid,
Pascal Brandc639ac82015-07-02 08:53:34 +0200343 NULL, &ret_orig)))
344 break;
345 }
346
347 for (; --i >= 0; )
348 TEEC_CloseSession(&sessions[i]);
349}
350
351static void xtest_tee_test_1006(ADBG_Case_t *c)
352{
353 TEEC_Session session = { 0 };
354 uint32_t ret_orig;
355 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
356 uint8_t buf[32];
357
358 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
359 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
360 &ret_orig)))
361 return;
362
363 op.params[0].tmpref.buffer = buf;
364 op.params[0].tmpref.size = sizeof(buf);
365 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
366 TEEC_NONE, TEEC_NONE);
367
368 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
369 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
370 &ret_orig));
371
372 TEEC_CloseSession(&session);
373}
374
375static void xtest_tee_test_1007(ADBG_Case_t *c)
376{
377 TEEC_Session session = { 0 };
378 uint32_t ret_orig;
379
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300380 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200381 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300382 &ret_orig)))
383 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200384
385 (void)ADBG_EXPECT_TEEC_RESULT(c,
386 TEEC_ERROR_TARGET_DEAD,
387 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
388 &ret_orig));
389
390 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
391
392 (void)ADBG_EXPECT_TEEC_RESULT(c,
393 TEEC_ERROR_TARGET_DEAD,
394 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
395 &ret_orig));
396
397 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
398
399 TEEC_CloseSession(&session);
400}
401
Jerome Forissierf02a2212015-10-29 14:33:35 +0100402#ifndef TA_DIR
Victor Chong3d8798f2017-03-01 18:31:48 +0000403# ifdef __ANDROID__
404#define TA_DIR "/system/lib/optee_armtz"
405# else
Jerome Forissierf02a2212015-10-29 14:33:35 +0100406#define TA_DIR "/lib/optee_armtz"
Victor Chong3d8798f2017-03-01 18:31:48 +0000407# endif
Jerome Forissierf02a2212015-10-29 14:33:35 +0100408#endif
409
David Brownb2865ab2016-08-02 11:44:41 -0600410#ifndef TA_TEST_DIR
411# ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200412# define TA_TEST_DIR "/data/tee/optee_armtz"
David Brownb2865ab2016-08-02 11:44:41 -0600413# else
414# define TA_TEST_DIR "/tmp/optee_armtz"
415# endif
416#endif
Jens Wiklanderb7940892015-10-23 16:02:40 +0200417
David Brownb2865ab2016-08-02 11:44:41 -0600418static void make_test_ta_dir(void)
419{
420#ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200421 (void)mkdir("/data/tee", 0755);
David Brownb2865ab2016-08-02 11:44:41 -0600422#endif
423 (void)mkdir(TA_TEST_DIR, 0755);
424}
425
426static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
427 bool for_write)
428{
Jens Wiklanderb7940892015-10-23 16:02:40 +0200429 snprintf(buf, blen,
Jens Wiklander6203b872016-12-08 19:18:29 +0100430 "%s/%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x.ta",
David Brownb2865ab2016-08-02 11:44:41 -0600431 for_write ? TA_TEST_DIR : TA_DIR,
432 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
Jens Wiklanderb7940892015-10-23 16:02:40 +0200433 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
434 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
435 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
David Brownb2865ab2016-08-02 11:44:41 -0600436 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200437}
438
David Brownb2865ab2016-08-02 11:44:41 -0600439static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode,
440 bool for_write)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200441{
442 char buf[PATH_MAX];
443
David Brownb2865ab2016-08-02 11:44:41 -0600444 uuid_to_full_name(buf, sizeof(buf), uuid, for_write);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200445 return fopen(buf, mode);
446}
447
David Brownb2865ab2016-08-02 11:44:41 -0600448static bool rm_file(const TEEC_UUID *uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200449{
450 char buf[PATH_MAX];
451
David Brownb2865ab2016-08-02 11:44:41 -0600452 uuid_to_full_name(buf, sizeof(buf), uuid, true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200453 return !unlink(buf);
454}
455
David Brownb2865ab2016-08-02 11:44:41 -0600456static bool copy_file(const TEEC_UUID *src_uuid, const TEEC_UUID *dst_uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200457{
458 char buf[4 * 1024];
David Brownb2865ab2016-08-02 11:44:41 -0600459 FILE *src = open_ta_file(src_uuid, "r", false);
460 FILE *dst = open_ta_file(dst_uuid, "w", true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200461 size_t r;
462 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200463 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200464
Jens Wiklander4441fe22015-10-23 16:53:02 +0200465 if (src && dst) {
466 do {
467 r = fread(buf, 1, sizeof(buf), src);
468 if (!r) {
469 ret = !!feof(src);
470 break;
471 }
472 w = fwrite(buf, 1, r, dst);
473 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200474 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200475
476 if (src)
477 fclose(src);
478 if (dst)
479 fclose(dst);
480 return ret;
481}
482
483static bool corrupt_file(FILE *f, long offs, uint8_t mask)
484{
485 uint8_t b;
486
487 if (fseek(f, offs, SEEK_SET))
488 return false;
489
490 if (fread(&b, 1, 1, f) != 1)
491 return false;
492
493 b ^= mask;
494
495 if (fseek(f, offs, SEEK_SET))
496 return false;
497
498 if (fwrite(&b, 1, 1, f) != 1)
499 return false;
500
501 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200502}
503
504static void load_fake_ta(ADBG_Case_t *c)
505{
506 static const TEEC_UUID fake_uuid = {
507 0x7e0a0900, 0x586b, 0x11e5,
508 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
509 };
510 TEEC_Session session = { 0 };
511 TEEC_Result res;
512 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200513 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200514
David Brownb2865ab2016-08-02 11:44:41 -0600515 r = copy_file(&create_fail_test_ta_uuid, &fake_uuid);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200516
517 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200518 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
519 &ret_orig);
520 if (res == TEEC_SUCCESS)
521 TEEC_CloseSession(&session);
522 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200523 }
524
David Brownb2865ab2016-08-02 11:44:41 -0600525 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid));
Jens Wiklanderb7940892015-10-23 16:02:40 +0200526}
527
Jens Wiklander4441fe22015-10-23 16:53:02 +0200528static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
529{
530 TEEC_Session session = { 0 };
531 TEEC_Result res;
532 uint32_t ret_orig;
533 FILE *f;
534 bool r;
535
David Brownb2865ab2016-08-02 11:44:41 -0600536 r = copy_file(&create_fail_test_ta_uuid, &create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200537 if (!ADBG_EXPECT_TRUE(c, r)) {
David Brownb2865ab2016-08-02 11:44:41 -0600538 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200539 return false;
540 }
541
David Brownb2865ab2016-08-02 11:44:41 -0600542 f = open_ta_file(&create_fail_test_ta_uuid, "r+", true);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200543 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
David Brownb2865ab2016-08-02 11:44:41 -0600544 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200545 return false;
546 }
547 r = corrupt_file(f, offs, mask);
548 fclose(f);
549
550 if (ADBG_EXPECT_TRUE(c, r)) {
551 res = xtest_teec_open_session(&session,
552 &create_fail_test_ta_uuid,
553 NULL, &ret_orig);
554 if (res == TEEC_SUCCESS)
555 TEEC_CloseSession(&session);
556 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
557 }
558
David Brownb2865ab2016-08-02 11:44:41 -0600559 r &= ADBG_EXPECT_TRUE(c, rm_file(&create_fail_test_ta_uuid));
Jens Wiklander4441fe22015-10-23 16:53:02 +0200560 return r;
561}
562
Pascal Brandc639ac82015-07-02 08:53:34 +0200563static void xtest_tee_test_1008(ADBG_Case_t *c)
564{
565 TEEC_Session session = { 0 };
566 TEEC_Session session_crypt = { 0 };
567 uint32_t ret_orig;
568
569 Do_ADBG_BeginSubCase(c, "Invoke command");
570 {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300571 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200572 xtest_teec_open_session(&session, &os_test_ta_uuid,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300573 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200574
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300575 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
576 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
577 NULL, &ret_orig));
578 TEEC_CloseSession(&session);
579 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200580
Pascal Brandc639ac82015-07-02 08:53:34 +0200581 }
582 Do_ADBG_EndSubCase(c, "Invoke command");
583
584 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
585 {
586 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
587
588 op.params[0].value.a = 2000;
589 op.paramTypes = TEEC_PARAM_TYPES(
590 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
591
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300592 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200593 xtest_teec_open_session(&session,
594 &os_test_ta_uuid,
595 NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300596 &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200597
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300598 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
599 TEEC_InvokeCommand(&session,
600 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
601 &op, &ret_orig));
602 TEEC_CloseSession(&session);
603 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200604 }
605 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
606
607 Do_ADBG_BeginSubCase(c, "Create session fail");
608 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200609 size_t n;
610
Pascal Brandc639ac82015-07-02 08:53:34 +0200611 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
612 xtest_teec_open_session(&session_crypt,
613 &create_fail_test_ta_uuid, NULL,
614 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200615 /*
616 * Run this several times to see that there's no memory leakage.
617 */
618 for (n = 0; n < 100; n++) {
619 Do_ADBG_Log("n = %zu", n);
620 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
621 xtest_teec_open_session(&session_crypt,
622 &create_fail_test_ta_uuid,
623 NULL, &ret_orig));
624 }
625 }
626 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200627
David Brownb2865ab2016-08-02 11:44:41 -0600628 make_test_ta_dir();
629
Jens Wiklanderb7940892015-10-23 16:02:40 +0200630 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
631 load_fake_ta(c);
632 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
633
Jens Wiklander4441fe22015-10-23 16:53:02 +0200634 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
635 ADBG_EXPECT_TRUE(c,
636 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
637 ADBG_EXPECT_TRUE(c,
638 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
639 ADBG_EXPECT_TRUE(c,
640 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
641 ADBG_EXPECT_TRUE(c,
642 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
643 ADBG_EXPECT_TRUE(c,
644 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
645 ADBG_EXPECT_TRUE(c,
646 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
647 ADBG_EXPECT_TRUE(c,
648 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
649 ADBG_EXPECT_TRUE(c,
650 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
651 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
652 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
653 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200654}
655
Pascal Brandc639ac82015-07-02 08:53:34 +0200656static void *cancellation_thread(void *arg)
657{
658 /*
659 * Sleep 0.5 seconds before cancellation to make sure that the other
660 * thread is in RPC_WAIT.
661 */
662 (void)usleep(500000);
663 TEEC_RequestCancellation(arg);
664 return NULL;
665}
Pascal Brandc639ac82015-07-02 08:53:34 +0200666
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300667static void xtest_tee_test_1009_subcase(ADBG_Case_t *c, const char *subcase,
668 uint32_t timeout, bool cancel)
Pascal Brandc639ac82015-07-02 08:53:34 +0200669{
670 TEEC_Session session = { 0 };
671 uint32_t ret_orig;
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300672 pthread_t thr;
Pascal Brandc639ac82015-07-02 08:53:34 +0200673
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300674 Do_ADBG_BeginSubCase(c, "%s", subcase);
Pascal Brandc639ac82015-07-02 08:53:34 +0200675 {
676 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
677
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300678 if (ADBG_EXPECT_TEEC_SUCCESS(c,
679 xtest_teec_open_session(&session, &os_test_ta_uuid,
680 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200681
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300682 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c,
683 TEEC_ORIGIN_TRUSTED_APP,
684 ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200685
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300686 op.params[0].value.a = timeout;
687 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
688 TEEC_NONE,
689 TEEC_NONE, TEEC_NONE);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300690 if (cancel) {
691 (void)ADBG_EXPECT(c, 0,
692 pthread_create(&thr, NULL,
693 cancellation_thread, &op));
Pascal Brandc639ac82015-07-02 08:53:34 +0200694
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300695 (void)ADBG_EXPECT_TEEC_RESULT(c,
696 TEEC_ERROR_CANCEL,
697 TEEC_InvokeCommand(&session,
698 TA_OS_TEST_CMD_WAIT,
699 &op,
700 &ret_orig));
701 } else
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300702
703 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
704 TEEC_InvokeCommand(&session,
705 TA_OS_TEST_CMD_WAIT,
706 &op,
707 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300708 if (cancel)
709 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300710
711 TEEC_CloseSession(&session);
712 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200713 }
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300714 Do_ADBG_EndSubCase(c, "%s", subcase);
715}
716
717static void xtest_tee_test_1009(ADBG_Case_t *c)
718{
719 xtest_tee_test_1009_subcase(c, "TEE Wait 0.1s", 100, false);
720 xtest_tee_test_1009_subcase(c, "TEE Wait 0.5s", 500, false);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300721 xtest_tee_test_1009_subcase(c, "TEE Wait 2s cancel", 2000, true);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300722 xtest_tee_test_1009_subcase(c, "TEE Wait 2s", 2000, false);
Pascal Brandc639ac82015-07-02 08:53:34 +0200723}
724
725static void xtest_tee_test_1010(ADBG_Case_t *c)
726{
727 unsigned n;
728
729 for (n = 1; n <= 5; n++) {
730 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
731 xtest_tee_test_invalid_mem_access(c, n);
732 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
733 }
734}
735
736static void xtest_tee_test_1011(ADBG_Case_t *c)
737{
738 TEEC_Session session = { 0 };
739 uint32_t ret_orig;
740 struct xtest_crypto_session cs = {
741 c, &session, TA_RPC_CMD_CRYPT_SHA256,
742 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
743 TA_RPC_CMD_CRYPT_AES256ECB_DEC
744 };
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100745 struct xtest_crypto_session cs_privmem = {
746 c, &session,
747 TA_RPC_CMD_CRYPT_PRIVMEM_SHA256,
748 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_ENC,
749 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_DEC
750 };
Pascal Brandc639ac82015-07-02 08:53:34 +0200751 TEEC_UUID uuid = rpc_test_ta_uuid;
752
753 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
754 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
755 return;
756
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100757 Do_ADBG_BeginSubCase(c, "TA-to-TA via non-secure shared memory");
Pascal Brandc639ac82015-07-02 08:53:34 +0200758 /*
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100759 * Run the "complete crypto test suite" using TA-to-TA
760 * communication
Pascal Brandc639ac82015-07-02 08:53:34 +0200761 */
762 xtest_crypto_test(&cs);
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100763 Do_ADBG_EndSubCase(c, "TA-to-TA via non-secure shared memory");
764
765 Do_ADBG_BeginSubCase(c, "TA-to-TA via TA private memory");
766 /*
767 * Run the "complete crypto test suite" using TA-to-TA
768 * communication via TA private memory.
769 */
770 xtest_crypto_test(&cs_privmem);
771 Do_ADBG_EndSubCase(c, "TA-to-TA via TA private memory");
772
Pascal Brandc639ac82015-07-02 08:53:34 +0200773 TEEC_CloseSession(&session);
774}
775
776/*
777 * Note that this test is failing when
778 * - running twice in a raw
779 * - and the user TA is statically linked
780 * This is because the counter is not reseted when opening the first session
781 * in case the TA is statically linked
782 */
783static void xtest_tee_test_1012(ADBG_Case_t *c)
784{
785 TEEC_Session session1 = { 0 };
786 TEEC_Session session2 = { 0 };
787 uint32_t ret_orig;
788 TEEC_UUID uuid = sims_test_ta_uuid;
789
790 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
791 {
792 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
793 static const uint8_t in[] = {
794 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
795 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
796 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
797 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
798 };
799 uint8_t out[32] = { 0 };
800 int i;
801
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300802 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200803 xtest_teec_open_session(&session1, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300804 &ret_orig)))
805 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200806
807 op.params[0].value.a = 0;
808 op.params[1].tmpref.buffer = (void *)in;
809 op.params[1].tmpref.size = sizeof(in);
810 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
811 TEEC_MEMREF_TEMP_INPUT,
812 TEEC_NONE, TEEC_NONE);
813
814 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
815 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
816 &ret_orig));
817
818 for (i = 1; i < 1000; i++) {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300819 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200820 xtest_teec_open_session(&session2, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300821 &ret_orig)))
822 continue;
Pascal Brandc639ac82015-07-02 08:53:34 +0200823
824 op.params[0].value.a = 0;
825 op.params[1].tmpref.buffer = out;
826 op.params[1].tmpref.size = sizeof(out);
827 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
828 TEEC_MEMREF_TEMP_OUTPUT,
829 TEEC_NONE, TEEC_NONE);
830
831 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
832 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
833 &op, &ret_orig));
834
835 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
836 sizeof(out))) {
837 Do_ADBG_Log("in:");
838 Do_ADBG_HexLog(in, sizeof(in), 16);
839 Do_ADBG_Log("out:");
840 Do_ADBG_HexLog(out, sizeof(out), 16);
841 }
842
843 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
844 TEEC_NONE, TEEC_NONE,
845 TEEC_NONE);
846
847 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
848 TEEC_InvokeCommand(&session1,
849 TA_SIMS_CMD_GET_COUNTER,
850 &op, &ret_orig));
851
852 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
853
854 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
855 TEEC_InvokeCommand(&session2,
856 TA_SIMS_CMD_GET_COUNTER, &op,
857 &ret_orig));
858
859 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
860 TEEC_CloseSession(&session2);
861 }
862
863 memset(out, 0, sizeof(out));
864 op.params[0].value.a = 0;
865 op.params[1].tmpref.buffer = out;
866 op.params[1].tmpref.size = sizeof(out);
867 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
868 TEEC_MEMREF_TEMP_OUTPUT,
869 TEEC_NONE, TEEC_NONE);
870
871 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
872 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
873 &ret_orig));
874
875 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
876 Do_ADBG_Log("in:");
877 Do_ADBG_HexLog(in, sizeof(in), 16);
878 Do_ADBG_Log("out:");
879 Do_ADBG_HexLog(out, sizeof(out), 16);
880 }
881
882 TEEC_CloseSession(&session1);
883 }
884}
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200885
886struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +0200887 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200888 uint32_t cmd;
889 uint32_t repeat;
890 TEEC_SharedMemory *shm;
891 uint32_t error_orig;
892 TEEC_Result res;
893 uint32_t max_concurrency;
894 const uint8_t *in;
895 size_t in_len;
896 uint8_t *out;
897 size_t out_len;
898};
899
900static void *test_1013_thread(void *arg)
901{
902 struct test_1013_thread_arg *a = arg;
903 TEEC_Session session = { 0 };
904 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
905 uint8_t p2 = TEEC_NONE;
906 uint8_t p3 = TEEC_NONE;
907
Jens Wiklander70672972016-04-06 00:01:45 +0200908 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200909 &a->error_orig);
910 if (a->res != TEEC_SUCCESS)
911 return NULL;
912
913 op.params[0].memref.parent = a->shm;
914 op.params[0].memref.size = a->shm->size;
915 op.params[0].memref.offset = 0;
916 op.params[1].value.a = a->repeat;
917 op.params[1].value.b = 0;
918 op.params[2].tmpref.buffer = (void *)a->in;
919 op.params[2].tmpref.size = a->in_len;
920 op.params[3].tmpref.buffer = a->out;
921 op.params[3].tmpref.size = a->out_len;
922
923 if (a->in_len)
924 p2 = TEEC_MEMREF_TEMP_INPUT;
925 if (a->out_len)
926 p3 = TEEC_MEMREF_TEMP_OUTPUT;
927
928 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
929 TEEC_VALUE_INOUT, p2, p3);
930
931 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
932 a->max_concurrency = op.params[1].value.b;
933 a->out_len = op.params[3].tmpref.size;
934 TEEC_CloseSession(&session);
935 return NULL;
936}
937
Pascal Brand4fa35582015-12-17 10:59:12 +0100938#define NUM_THREADS 3
939
Jens Wiklander70672972016-04-06 00:01:45 +0200940static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
941 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200942{
Pascal Brand4fa35582015-12-17 10:59:12 +0100943 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200944 size_t nt;
945 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +0200946 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200947 pthread_t thr[num_threads];
948 TEEC_SharedMemory shm;
949 size_t max_concurrency;
950 struct test_1013_thread_arg arg[num_threads];
951 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
952 static const uint8_t sha256_out[] = {
953 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
954 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
955 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
956 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
957 };
958 uint8_t out[32] = { 0 };
959
Jens Wiklander70672972016-04-06 00:01:45 +0200960 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +0100961 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200962
963 memset(&shm, 0, sizeof(shm));
964 shm.size = sizeof(struct ta_concurrent_shm);
965 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
966 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
967 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
968 return;
969
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200970 memset(shm.buffer, 0, shm.size);
971 memset(arg, 0, sizeof(arg));
972 max_concurrency = 0;
973 nt = num_threads;
974
975 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +0200976 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200977 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +0200978 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200979 arg[n].shm = &shm;
980 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
981 test_1013_thread, arg + n)))
982 nt = n; /* break loop and start cleanup */
983 }
984
985 for (n = 0; n < nt; n++) {
986 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
987 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
988 if (arg[n].max_concurrency > max_concurrency)
989 max_concurrency = arg[n].max_concurrency;
990 }
991
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200992 /*
993 * Concurrency can be limited by several factors, for instance in a
994 * single CPU system it's dependent on the Preemtion Model used by
995 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
996 * best result there).
997 */
998 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
999 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +01001000 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001001 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001002
Jens Wiklander70672972016-04-06 00:01:45 +02001003 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001004 memset(shm.buffer, 0, shm.size);
1005 memset(arg, 0, sizeof(arg));
1006 max_concurrency = 0;
1007 nt = num_threads;
1008
1009 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001010 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001011 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +02001012 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001013 arg[n].shm = &shm;
1014 arg[n].in = sha256_in;
1015 arg[n].in_len = sizeof(sha256_in);
1016 arg[n].out = out;
1017 arg[n].out_len = sizeof(out);
1018 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1019 test_1013_thread, arg + n)))
1020 nt = n; /* break loop and start cleanup */
1021 }
1022
1023 for (n = 0; n < nt; n++) {
1024 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1025 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1026 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1027 arg[n].out, arg[n].out_len);
1028 if (arg[n].max_concurrency > max_concurrency)
1029 max_concurrency = arg[n].max_concurrency;
1030 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001031 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001032 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001033
Pascal Brand4fa35582015-12-17 10:59:12 +01001034 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001035 TEEC_ReleaseSharedMemory(&shm);
1036}
Pascal Brand4fa35582015-12-17 10:59:12 +01001037
1038static void xtest_tee_test_1013(ADBG_Case_t *c)
1039{
1040 int i;
1041 double mean_concurrency;
1042 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001043 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001044
1045 if (level == 0)
1046 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001047
Jens Wiklander70672972016-04-06 00:01:45 +02001048 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001049 mean_concurrency = 0;
1050 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001051 xtest_tee_test_1013_single(c, &concurrency,
1052 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001053 mean_concurrency += concurrency;
1054 }
1055 mean_concurrency /= nb_loops;
1056
1057 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1058 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001059 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001060
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001061#ifndef CFG_PAGED_USER_TA
Jens Wiklander70672972016-04-06 00:01:45 +02001062 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1063 mean_concurrency = 0;
1064 for (i = 0; i < nb_loops; i++) {
1065 xtest_tee_test_1013_single(c, &concurrency,
1066 &concurrent_large_ta_uuid);
1067 mean_concurrency += concurrency;
1068 }
1069 mean_concurrency /= nb_loops;
1070
1071 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1072 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1073 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001074#endif
Jens Wiklander70672972016-04-06 00:01:45 +02001075}