blob: 9c92195240ef8a82813649bf0208b979451d7ca7 [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
14#include <stdio.h>
15#include <string.h>
Jens Wiklanderb7940892015-10-23 16:02:40 +020016#include <limits.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020017
18#ifdef USER_SPACE
19#include <pthread.h>
20#include <unistd.h>
David Brownb2865ab2016-08-02 11:44:41 -060021#include <sys/stat.h>
22#include <sys/types.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020023#endif
24
25#include "xtest_test.h"
26#include "xtest_helpers.h"
Jens Wiklander4441fe22015-10-23 16:53:02 +020027#include <signed_hdr.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020028
29#include <ta_crypt.h>
30#include <ta_os_test.h>
31#include <ta_create_fail_test.h>
32#include <ta_rpc_test.h>
33#include <ta_sims_test.h>
Jens Wiklanderac27ec12015-07-15 15:23:14 +020034#include <ta_concurrent.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020035
36static void xtest_tee_test_1001(ADBG_Case_t *Case_p);
37static 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);
Pascal Brandc639ac82015-07-02 08:53:34 +020047
Jens Wiklander25a57fe2016-12-26 21:46:24 +010048ADBG_CASE_DEFINE(XTEST_TEE_1001, xtest_tee_test_1001, "Core self tests");
49ADBG_CASE_DEFINE(XTEST_TEE_1004, xtest_tee_test_1004, "Test User Crypt TA");
50ADBG_CASE_DEFINE(XTEST_TEE_1005, xtest_tee_test_1005, "Many sessions");
51ADBG_CASE_DEFINE(XTEST_TEE_1006, xtest_tee_test_1006, "Test Basic OS features");
52ADBG_CASE_DEFINE(XTEST_TEE_1007, xtest_tee_test_1007, "Test Panic");
Pascal Brandc639ac82015-07-02 08:53:34 +020053ADBG_CASE_DEFINE(XTEST_TEE_1008, xtest_tee_test_1008,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010054 "TEE internal client API");
55ADBG_CASE_DEFINE(XTEST_TEE_1009, xtest_tee_test_1009, "TEE Wait");
56ADBG_CASE_DEFINE(XTEST_TEE_1010, xtest_tee_test_1010, "Invalid memory access");
Pascal Brandc639ac82015-07-02 08:53:34 +020057ADBG_CASE_DEFINE(XTEST_TEE_1011, xtest_tee_test_1011,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010058 "Test RPC features with User Crypt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +020059ADBG_CASE_DEFINE(XTEST_TEE_1012, xtest_tee_test_1012,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010060 "Test Single Instance Multi Session features with SIMS TA");
Jens Wiklanderac27ec12015-07-15 15:23:14 +020061ADBG_CASE_DEFINE(XTEST_TEE_1013, xtest_tee_test_1013,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010062 "Test concurency with concurrent TA");
Jens Wiklanderac27ec12015-07-15 15:23:14 +020063
Pascal Brandc639ac82015-07-02 08:53:34 +020064struct xtest_crypto_session {
65 ADBG_Case_t *c;
66 TEEC_Session *session;
67 uint32_t cmd_id_sha256;
68 uint32_t cmd_id_aes256ecb_encrypt;
69 uint32_t cmd_id_aes256ecb_decrypt;
70};
71
72static void xtest_crypto_test(struct xtest_crypto_session *cs)
73{
74 uint32_t ret_orig;
75 uint8_t crypt_out[16];
76 uint8_t crypt_in[16] = { 22, 17 };
77
78 crypt_in[15] = 60;
79
80 Do_ADBG_BeginSubCase(cs->c, "AES encrypt");
81 {
82 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
83
84 op.params[0].tmpref.buffer = crypt_in;
85 op.params[0].tmpref.size = sizeof(crypt_in);
86 op.params[1].tmpref.buffer = crypt_out;
87 op.params[1].tmpref.size = sizeof(crypt_out);
88 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
89 TEEC_MEMREF_TEMP_OUTPUT,
90 TEEC_NONE, TEEC_NONE);
91
92 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
93 TEEC_InvokeCommand(cs->session,
94 cs->
95 cmd_id_aes256ecb_encrypt,
96 &op,
97 &ret_orig));
98 }
99 Do_ADBG_EndSubCase(cs->c, "AES encrypt");
100
101 Do_ADBG_BeginSubCase(cs->c, "AES decrypt");
102 {
103 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
104 uint8_t out[16];
105
106 op.params[0].tmpref.buffer = crypt_out;
107 op.params[0].tmpref.size = sizeof(crypt_out);
108 op.params[1].tmpref.buffer = out;
109 op.params[1].tmpref.size = sizeof(out);
110 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
111 TEEC_MEMREF_TEMP_OUTPUT,
112 TEEC_NONE, TEEC_NONE);
113
114 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
115 TEEC_InvokeCommand(cs->session,
116 cs->
117 cmd_id_aes256ecb_decrypt,
118 &op,
119 &ret_orig));
120
121 if (!ADBG_EXPECT(cs->c, 0,
122 memcmp(crypt_in, out, sizeof(crypt_in)))) {
123 Do_ADBG_Log("crypt_in:");
124 Do_ADBG_HexLog(crypt_in, sizeof(crypt_in), 16);
125 Do_ADBG_Log("out:");
126 Do_ADBG_HexLog(out, sizeof(out), 16);
127 }
128 }
129 Do_ADBG_EndSubCase(cs->c, "AES decrypt");
130
131 Do_ADBG_BeginSubCase(cs->c, "SHA-256 test, 3 bytes input");
132 {
133 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
134 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
135 static const uint8_t sha256_out[] = {
136 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
137 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
138 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
139 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
140 };
141 uint8_t out[32] = { 0 };
142
143 op.params[0].tmpref.buffer = (void *)sha256_in;
144 op.params[0].tmpref.size = sizeof(sha256_in);
145 op.params[1].tmpref.buffer = out;
146 op.params[1].tmpref.size = sizeof(out);
147 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
148 TEEC_MEMREF_TEMP_OUTPUT,
149 TEEC_NONE, TEEC_NONE);
150
151 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
152 TEEC_InvokeCommand(cs->session,
153 cs->
154 cmd_id_sha256,
155 &op,
156 &ret_orig));
157
158 if (!ADBG_EXPECT(cs->c, 0, memcmp(sha256_out, out,
159 sizeof(sha256_out)))) {
160 Do_ADBG_Log("sha256_out:");
161 Do_ADBG_HexLog(sha256_out, sizeof(sha256_out), 16);
162 Do_ADBG_Log("out:");
163 Do_ADBG_HexLog(out, sizeof(out), 16);
164 }
165 }
166 Do_ADBG_EndSubCase(cs->c, "SHA-256 test, 3 bytes input");
167
168 Do_ADBG_BeginSubCase(cs->c,
169 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
170 {
171 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
172 static const uint8_t in[] = {
173 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
174 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
175 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
176 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
177 };
178 static const uint8_t exp_out[] = {
179 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
180 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
181 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
182 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
183 };
184 uint8_t out[sizeof(exp_out)];
185
186 op.params[0].tmpref.buffer = (void *)in;
187 op.params[0].tmpref.size = sizeof(in);
188 op.params[1].tmpref.buffer = out;
189 op.params[1].tmpref.size = sizeof(out);
190 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
191 TEEC_MEMREF_TEMP_OUTPUT,
192 TEEC_NONE, TEEC_NONE);
193
194 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
195 TEEC_InvokeCommand(cs->session,
196 cs->
197 cmd_id_aes256ecb_encrypt,
198 &op,
199 &ret_orig));
200
201 if (!ADBG_EXPECT(cs->c, 0,
202 memcmp(exp_out, out, sizeof(exp_out)))) {
203 Do_ADBG_Log("exp_out:");
204 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
205 Do_ADBG_Log("out:");
206 Do_ADBG_HexLog(out, sizeof(out), 16);
207 }
208 }
209 Do_ADBG_EndSubCase(cs->c,
210 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
211
212 Do_ADBG_BeginSubCase(cs->c,
213 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
214 {
215 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
216 static const uint8_t in[] = {
217 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
218 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
219 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
220 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
221 };
222 static const uint8_t exp_out[] = {
223 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
224 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
225 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
226 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
227 };
228 uint8_t out[sizeof(exp_out)];
229
230 op.params[0].tmpref.buffer = (void *)in;
231 op.params[0].tmpref.size = sizeof(in);
232 op.params[1].tmpref.buffer = out;
233 op.params[1].tmpref.size = sizeof(out);
234 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
235 TEEC_MEMREF_TEMP_OUTPUT,
236 TEEC_NONE, TEEC_NONE);
237
238 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
239 TEEC_InvokeCommand(cs->session,
240 cs->
241 cmd_id_aes256ecb_decrypt,
242 &op,
243 &ret_orig));
244
245 if (!ADBG_EXPECT(cs->c, 0,
246 memcmp(exp_out, out, sizeof(exp_out)))) {
247 Do_ADBG_Log("exp_out:");
248 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
249 Do_ADBG_Log("out:");
250 Do_ADBG_HexLog(out, sizeof(out), 16);
251 }
252 }
253 Do_ADBG_EndSubCase(cs->c,
254 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
255}
256
257static void xtest_tee_test_1001(ADBG_Case_t *c)
258{
Jens Wiklandercf16e842016-02-10 09:07:09 +0100259 TEEC_Result res;
260 TEEC_Session session = { 0 };
261 uint32_t ret_orig;
Pascal Brandc639ac82015-07-02 08:53:34 +0200262
Jens Wiklandercf16e842016-02-10 09:07:09 +0100263#define CMD_SELF_TESTS 2
Pascal Brandc639ac82015-07-02 08:53:34 +0200264
Jens Wiklandercf16e842016-02-10 09:07:09 +0100265 res = xtest_teec_open_session(&session, &sta_test_ta_uuid, NULL,
266 &ret_orig);
267 /*
268 * If the static TA (which is optional) isn't available, skip this
269 * test.
270 */
271 if (res != TEEC_SUCCESS)
272 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200273
Jens Wiklandercf16e842016-02-10 09:07:09 +0100274 (void)ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
275 &session, CMD_SELF_TESTS, NULL, &ret_orig));
276 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200277}
278
279static void xtest_tee_test_1004(ADBG_Case_t *c)
280{
281 TEEC_Session session = { 0 };
282 uint32_t ret_orig;
283 struct xtest_crypto_session cs = { c, &session, TA_CRYPT_CMD_SHA256,
284 TA_CRYPT_CMD_AES256ECB_ENC,
285 TA_CRYPT_CMD_AES256ECB_DEC };
286
287 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
288 &session, &crypt_user_ta_uuid,
289 NULL, &ret_orig)))
290 return;
291
292 /* Run the "complete crypto test suite" */
293 xtest_crypto_test(&cs);
294
295 TEEC_CloseSession(&session);
296}
297
298#ifndef TEEC_ERROR_TARGET_DEAD
299/* To be removed when we have TEEC_ERROR_TARGET_DEAD from tee_client_api.h */
300#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024
301#endif
302
303static void xtest_tee_test_invalid_mem_access(ADBG_Case_t *c, uint32_t n)
304{
305 TEEC_Session session = { 0 };
306 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
307 uint32_t ret_orig;
308
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300309 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200310 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300311 &ret_orig)))
312 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200313
314 op.params[0].value.a = n;
315 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
316 TEEC_NONE);
317
318 (void)ADBG_EXPECT_TEEC_RESULT(c,
319 TEEC_ERROR_TARGET_DEAD,
320 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
321 &ret_orig));
322
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300323 (void)ADBG_EXPECT_TEEC_RESULT(c,
324 TEEC_ERROR_TARGET_DEAD,
325 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
Pascal Brandc639ac82015-07-02 08:53:34 +0200326 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300327
Pascal Brandc639ac82015-07-02 08:53:34 +0200328 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
329
330 TEEC_CloseSession(&session);
331}
332
333static void xtest_tee_test_1005(ADBG_Case_t *c)
334{
335 uint32_t ret_orig;
336#define MAX_SESSIONS 3
337 TEEC_Session sessions[MAX_SESSIONS];
338 int i;
339
340 for (i = 0; i < MAX_SESSIONS; i++) {
341 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Jens Wiklandereb6bce72016-09-23 11:37:33 +0200342 xtest_teec_open_session(&sessions[i],
343 &concurrent_ta_uuid,
Pascal Brandc639ac82015-07-02 08:53:34 +0200344 NULL, &ret_orig)))
345 break;
346 }
347
348 for (; --i >= 0; )
349 TEEC_CloseSession(&sessions[i]);
350}
351
352static void xtest_tee_test_1006(ADBG_Case_t *c)
353{
354 TEEC_Session session = { 0 };
355 uint32_t ret_orig;
356 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
357 uint8_t buf[32];
358
359 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
360 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
361 &ret_orig)))
362 return;
363
364 op.params[0].tmpref.buffer = buf;
365 op.params[0].tmpref.size = sizeof(buf);
366 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
367 TEEC_NONE, TEEC_NONE);
368
369 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
370 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
371 &ret_orig));
372
373 TEEC_CloseSession(&session);
374}
375
376static void xtest_tee_test_1007(ADBG_Case_t *c)
377{
378 TEEC_Session session = { 0 };
379 uint32_t ret_orig;
380
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300381 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200382 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300383 &ret_orig)))
384 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200385
386 (void)ADBG_EXPECT_TEEC_RESULT(c,
387 TEEC_ERROR_TARGET_DEAD,
388 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
389 &ret_orig));
390
391 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
392
393 (void)ADBG_EXPECT_TEEC_RESULT(c,
394 TEEC_ERROR_TARGET_DEAD,
395 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
396 &ret_orig));
397
398 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
399
400 TEEC_CloseSession(&session);
401}
402
Jerome Forissierf02a2212015-10-29 14:33:35 +0100403#ifndef TA_DIR
404#define TA_DIR "/lib/optee_armtz"
405#endif
406
David Brownb2865ab2016-08-02 11:44:41 -0600407#ifndef TA_TEST_DIR
408# ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200409# define TA_TEST_DIR "/data/tee/optee_armtz"
David Brownb2865ab2016-08-02 11:44:41 -0600410# else
411# define TA_TEST_DIR "/tmp/optee_armtz"
412# endif
413#endif
Jens Wiklanderb7940892015-10-23 16:02:40 +0200414
David Brownb2865ab2016-08-02 11:44:41 -0600415static void make_test_ta_dir(void)
416{
417#ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200418 (void)mkdir("/data/tee", 0755);
David Brownb2865ab2016-08-02 11:44:41 -0600419#endif
420 (void)mkdir(TA_TEST_DIR, 0755);
421}
422
423static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
424 bool for_write)
425{
Jens Wiklanderb7940892015-10-23 16:02:40 +0200426 snprintf(buf, blen,
Jens Wiklander6203b872016-12-08 19:18:29 +0100427 "%s/%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x.ta",
David Brownb2865ab2016-08-02 11:44:41 -0600428 for_write ? TA_TEST_DIR : TA_DIR,
429 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
Jens Wiklanderb7940892015-10-23 16:02:40 +0200430 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
431 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
432 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
David Brownb2865ab2016-08-02 11:44:41 -0600433 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200434}
435
David Brownb2865ab2016-08-02 11:44:41 -0600436static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode,
437 bool for_write)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200438{
439 char buf[PATH_MAX];
440
David Brownb2865ab2016-08-02 11:44:41 -0600441 uuid_to_full_name(buf, sizeof(buf), uuid, for_write);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200442 return fopen(buf, mode);
443}
444
David Brownb2865ab2016-08-02 11:44:41 -0600445static bool rm_file(const TEEC_UUID *uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200446{
447 char buf[PATH_MAX];
448
David Brownb2865ab2016-08-02 11:44:41 -0600449 uuid_to_full_name(buf, sizeof(buf), uuid, true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200450 return !unlink(buf);
451}
452
David Brownb2865ab2016-08-02 11:44:41 -0600453static bool copy_file(const TEEC_UUID *src_uuid, const TEEC_UUID *dst_uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200454{
455 char buf[4 * 1024];
David Brownb2865ab2016-08-02 11:44:41 -0600456 FILE *src = open_ta_file(src_uuid, "r", false);
457 FILE *dst = open_ta_file(dst_uuid, "w", true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200458 size_t r;
459 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200460 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200461
Jens Wiklander4441fe22015-10-23 16:53:02 +0200462 if (src && dst) {
463 do {
464 r = fread(buf, 1, sizeof(buf), src);
465 if (!r) {
466 ret = !!feof(src);
467 break;
468 }
469 w = fwrite(buf, 1, r, dst);
470 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200471 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200472
473 if (src)
474 fclose(src);
475 if (dst)
476 fclose(dst);
477 return ret;
478}
479
480static bool corrupt_file(FILE *f, long offs, uint8_t mask)
481{
482 uint8_t b;
483
484 if (fseek(f, offs, SEEK_SET))
485 return false;
486
487 if (fread(&b, 1, 1, f) != 1)
488 return false;
489
490 b ^= mask;
491
492 if (fseek(f, offs, SEEK_SET))
493 return false;
494
495 if (fwrite(&b, 1, 1, f) != 1)
496 return false;
497
498 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200499}
500
501static void load_fake_ta(ADBG_Case_t *c)
502{
503 static const TEEC_UUID fake_uuid = {
504 0x7e0a0900, 0x586b, 0x11e5,
505 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
506 };
507 TEEC_Session session = { 0 };
508 TEEC_Result res;
509 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200510 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200511
David Brownb2865ab2016-08-02 11:44:41 -0600512 r = copy_file(&create_fail_test_ta_uuid, &fake_uuid);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200513
514 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200515 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
516 &ret_orig);
517 if (res == TEEC_SUCCESS)
518 TEEC_CloseSession(&session);
519 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200520 }
521
David Brownb2865ab2016-08-02 11:44:41 -0600522 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid));
Jens Wiklanderb7940892015-10-23 16:02:40 +0200523}
524
Jens Wiklander4441fe22015-10-23 16:53:02 +0200525static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
526{
527 TEEC_Session session = { 0 };
528 TEEC_Result res;
529 uint32_t ret_orig;
530 FILE *f;
531 bool r;
532
David Brownb2865ab2016-08-02 11:44:41 -0600533 r = copy_file(&create_fail_test_ta_uuid, &create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200534 if (!ADBG_EXPECT_TRUE(c, r)) {
David Brownb2865ab2016-08-02 11:44:41 -0600535 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200536 return false;
537 }
538
David Brownb2865ab2016-08-02 11:44:41 -0600539 f = open_ta_file(&create_fail_test_ta_uuid, "r+", true);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200540 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
David Brownb2865ab2016-08-02 11:44:41 -0600541 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200542 return false;
543 }
544 r = corrupt_file(f, offs, mask);
545 fclose(f);
546
547 if (ADBG_EXPECT_TRUE(c, r)) {
548 res = xtest_teec_open_session(&session,
549 &create_fail_test_ta_uuid,
550 NULL, &ret_orig);
551 if (res == TEEC_SUCCESS)
552 TEEC_CloseSession(&session);
553 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
554 }
555
David Brownb2865ab2016-08-02 11:44:41 -0600556 r &= ADBG_EXPECT_TRUE(c, rm_file(&create_fail_test_ta_uuid));
Jens Wiklander4441fe22015-10-23 16:53:02 +0200557 return r;
558}
559
Pascal Brandc639ac82015-07-02 08:53:34 +0200560static void xtest_tee_test_1008(ADBG_Case_t *c)
561{
562 TEEC_Session session = { 0 };
563 TEEC_Session session_crypt = { 0 };
564 uint32_t ret_orig;
565
566 Do_ADBG_BeginSubCase(c, "Invoke command");
567 {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300568 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200569 xtest_teec_open_session(&session, &os_test_ta_uuid,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300570 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200571
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300572 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
573 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
574 NULL, &ret_orig));
575 TEEC_CloseSession(&session);
576 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200577
Pascal Brandc639ac82015-07-02 08:53:34 +0200578 }
579 Do_ADBG_EndSubCase(c, "Invoke command");
580
581 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
582 {
583 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
584
585 op.params[0].value.a = 2000;
586 op.paramTypes = TEEC_PARAM_TYPES(
587 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
588
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300589 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200590 xtest_teec_open_session(&session,
591 &os_test_ta_uuid,
592 NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300593 &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200594
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300595 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
596 TEEC_InvokeCommand(&session,
597 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
598 &op, &ret_orig));
599 TEEC_CloseSession(&session);
600 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200601 }
602 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
603
604 Do_ADBG_BeginSubCase(c, "Create session fail");
605 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200606 size_t n;
607
Pascal Brandc639ac82015-07-02 08:53:34 +0200608 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
609 xtest_teec_open_session(&session_crypt,
610 &create_fail_test_ta_uuid, NULL,
611 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200612 /*
613 * Run this several times to see that there's no memory leakage.
614 */
615 for (n = 0; n < 100; n++) {
616 Do_ADBG_Log("n = %zu", n);
617 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
618 xtest_teec_open_session(&session_crypt,
619 &create_fail_test_ta_uuid,
620 NULL, &ret_orig));
621 }
622 }
623 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200624
David Brownb2865ab2016-08-02 11:44:41 -0600625 make_test_ta_dir();
626
Jens Wiklanderb7940892015-10-23 16:02:40 +0200627 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
628 load_fake_ta(c);
629 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
630
Jens Wiklander4441fe22015-10-23 16:53:02 +0200631 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
632 ADBG_EXPECT_TRUE(c,
633 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
634 ADBG_EXPECT_TRUE(c,
635 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
636 ADBG_EXPECT_TRUE(c,
637 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
638 ADBG_EXPECT_TRUE(c,
639 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
640 ADBG_EXPECT_TRUE(c,
641 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
642 ADBG_EXPECT_TRUE(c,
643 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
644 ADBG_EXPECT_TRUE(c,
645 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
646 ADBG_EXPECT_TRUE(c,
647 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
648 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
649 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
650 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200651}
652
653#ifdef USER_SPACE
654static void *cancellation_thread(void *arg)
655{
656 /*
657 * Sleep 0.5 seconds before cancellation to make sure that the other
658 * thread is in RPC_WAIT.
659 */
660 (void)usleep(500000);
661 TEEC_RequestCancellation(arg);
662 return NULL;
663}
664#endif
665
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300666static void xtest_tee_test_1009_subcase(ADBG_Case_t *c, const char *subcase,
667 uint32_t timeout, bool cancel)
Pascal Brandc639ac82015-07-02 08:53:34 +0200668{
669 TEEC_Session session = { 0 };
670 uint32_t ret_orig;
Pascal Brandc639ac82015-07-02 08:53:34 +0200671#ifdef USER_SPACE
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300672 pthread_t thr;
Pascal Brandc639ac82015-07-02 08:53:34 +0200673#endif
674
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300675 Do_ADBG_BeginSubCase(c, "%s", subcase);
Pascal Brandc639ac82015-07-02 08:53:34 +0200676 {
677 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
678
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300679 if (ADBG_EXPECT_TEEC_SUCCESS(c,
680 xtest_teec_open_session(&session, &os_test_ta_uuid,
681 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200682
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300683 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c,
684 TEEC_ORIGIN_TRUSTED_APP,
685 ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200686
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300687 op.params[0].value.a = timeout;
688 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
689 TEEC_NONE,
690 TEEC_NONE, TEEC_NONE);
691#ifdef USER_SPACE
692 if (cancel) {
693 (void)ADBG_EXPECT(c, 0,
694 pthread_create(&thr, NULL,
695 cancellation_thread, &op));
Pascal Brandc639ac82015-07-02 08:53:34 +0200696
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300697 (void)ADBG_EXPECT_TEEC_RESULT(c,
698 TEEC_ERROR_CANCEL,
699 TEEC_InvokeCommand(&session,
700 TA_OS_TEST_CMD_WAIT,
701 &op,
702 &ret_orig));
703 } else
704#endif
705
706 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
707 TEEC_InvokeCommand(&session,
708 TA_OS_TEST_CMD_WAIT,
709 &op,
710 &ret_orig));
711#ifdef USER_SPACE
712 if (cancel)
713 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
714#endif
715
716 TEEC_CloseSession(&session);
717 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200718 }
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300719 Do_ADBG_EndSubCase(c, "%s", subcase);
720}
721
722static void xtest_tee_test_1009(ADBG_Case_t *c)
723{
724 xtest_tee_test_1009_subcase(c, "TEE Wait 0.1s", 100, false);
725 xtest_tee_test_1009_subcase(c, "TEE Wait 0.5s", 500, false);
726#ifdef USER_SPACE
727 xtest_tee_test_1009_subcase(c, "TEE Wait 2s cancel", 2000, true);
728#endif
729 xtest_tee_test_1009_subcase(c, "TEE Wait 2s", 2000, false);
Pascal Brandc639ac82015-07-02 08:53:34 +0200730}
731
732static void xtest_tee_test_1010(ADBG_Case_t *c)
733{
734 unsigned n;
735
736 for (n = 1; n <= 5; n++) {
737 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
738 xtest_tee_test_invalid_mem_access(c, n);
739 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
740 }
741}
742
743static void xtest_tee_test_1011(ADBG_Case_t *c)
744{
745 TEEC_Session session = { 0 };
746 uint32_t ret_orig;
747 struct xtest_crypto_session cs = {
748 c, &session, TA_RPC_CMD_CRYPT_SHA256,
749 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
750 TA_RPC_CMD_CRYPT_AES256ECB_DEC
751 };
752 TEEC_UUID uuid = rpc_test_ta_uuid;
753
754 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
755 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
756 return;
757
758 /*
759 * Run the "complete crypto test suite" using RPC
760 */
761 xtest_crypto_test(&cs);
762 TEEC_CloseSession(&session);
763}
764
765/*
766 * Note that this test is failing when
767 * - running twice in a raw
768 * - and the user TA is statically linked
769 * This is because the counter is not reseted when opening the first session
770 * in case the TA is statically linked
771 */
772static void xtest_tee_test_1012(ADBG_Case_t *c)
773{
774 TEEC_Session session1 = { 0 };
775 TEEC_Session session2 = { 0 };
776 uint32_t ret_orig;
777 TEEC_UUID uuid = sims_test_ta_uuid;
778
779 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
780 {
781 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
782 static const uint8_t in[] = {
783 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
784 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
785 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
786 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
787 };
788 uint8_t out[32] = { 0 };
789 int i;
790
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300791 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200792 xtest_teec_open_session(&session1, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300793 &ret_orig)))
794 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200795
796 op.params[0].value.a = 0;
797 op.params[1].tmpref.buffer = (void *)in;
798 op.params[1].tmpref.size = sizeof(in);
799 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
800 TEEC_MEMREF_TEMP_INPUT,
801 TEEC_NONE, TEEC_NONE);
802
803 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
804 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
805 &ret_orig));
806
807 for (i = 1; i < 1000; i++) {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300808 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200809 xtest_teec_open_session(&session2, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300810 &ret_orig)))
811 continue;
Pascal Brandc639ac82015-07-02 08:53:34 +0200812
813 op.params[0].value.a = 0;
814 op.params[1].tmpref.buffer = out;
815 op.params[1].tmpref.size = sizeof(out);
816 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
817 TEEC_MEMREF_TEMP_OUTPUT,
818 TEEC_NONE, TEEC_NONE);
819
820 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
821 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
822 &op, &ret_orig));
823
824 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
825 sizeof(out))) {
826 Do_ADBG_Log("in:");
827 Do_ADBG_HexLog(in, sizeof(in), 16);
828 Do_ADBG_Log("out:");
829 Do_ADBG_HexLog(out, sizeof(out), 16);
830 }
831
832 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
833 TEEC_NONE, TEEC_NONE,
834 TEEC_NONE);
835
836 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
837 TEEC_InvokeCommand(&session1,
838 TA_SIMS_CMD_GET_COUNTER,
839 &op, &ret_orig));
840
841 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
842
843 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
844 TEEC_InvokeCommand(&session2,
845 TA_SIMS_CMD_GET_COUNTER, &op,
846 &ret_orig));
847
848 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
849 TEEC_CloseSession(&session2);
850 }
851
852 memset(out, 0, sizeof(out));
853 op.params[0].value.a = 0;
854 op.params[1].tmpref.buffer = out;
855 op.params[1].tmpref.size = sizeof(out);
856 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
857 TEEC_MEMREF_TEMP_OUTPUT,
858 TEEC_NONE, TEEC_NONE);
859
860 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
861 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
862 &ret_orig));
863
864 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
865 Do_ADBG_Log("in:");
866 Do_ADBG_HexLog(in, sizeof(in), 16);
867 Do_ADBG_Log("out:");
868 Do_ADBG_HexLog(out, sizeof(out), 16);
869 }
870
871 TEEC_CloseSession(&session1);
872 }
873}
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200874
875struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +0200876 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200877 uint32_t cmd;
878 uint32_t repeat;
879 TEEC_SharedMemory *shm;
880 uint32_t error_orig;
881 TEEC_Result res;
882 uint32_t max_concurrency;
883 const uint8_t *in;
884 size_t in_len;
885 uint8_t *out;
886 size_t out_len;
887};
888
889static void *test_1013_thread(void *arg)
890{
891 struct test_1013_thread_arg *a = arg;
892 TEEC_Session session = { 0 };
893 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
894 uint8_t p2 = TEEC_NONE;
895 uint8_t p3 = TEEC_NONE;
896
Jens Wiklander70672972016-04-06 00:01:45 +0200897 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200898 &a->error_orig);
899 if (a->res != TEEC_SUCCESS)
900 return NULL;
901
902 op.params[0].memref.parent = a->shm;
903 op.params[0].memref.size = a->shm->size;
904 op.params[0].memref.offset = 0;
905 op.params[1].value.a = a->repeat;
906 op.params[1].value.b = 0;
907 op.params[2].tmpref.buffer = (void *)a->in;
908 op.params[2].tmpref.size = a->in_len;
909 op.params[3].tmpref.buffer = a->out;
910 op.params[3].tmpref.size = a->out_len;
911
912 if (a->in_len)
913 p2 = TEEC_MEMREF_TEMP_INPUT;
914 if (a->out_len)
915 p3 = TEEC_MEMREF_TEMP_OUTPUT;
916
917 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
918 TEEC_VALUE_INOUT, p2, p3);
919
920 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
921 a->max_concurrency = op.params[1].value.b;
922 a->out_len = op.params[3].tmpref.size;
923 TEEC_CloseSession(&session);
924 return NULL;
925}
926
Pascal Brand4fa35582015-12-17 10:59:12 +0100927#define NUM_THREADS 3
928
Jens Wiklander70672972016-04-06 00:01:45 +0200929static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
930 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200931{
Pascal Brand4fa35582015-12-17 10:59:12 +0100932 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200933 size_t nt;
934 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +0200935 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200936 pthread_t thr[num_threads];
937 TEEC_SharedMemory shm;
938 size_t max_concurrency;
939 struct test_1013_thread_arg arg[num_threads];
940 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
941 static const uint8_t sha256_out[] = {
942 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
943 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
944 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
945 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
946 };
947 uint8_t out[32] = { 0 };
948
Jens Wiklander70672972016-04-06 00:01:45 +0200949 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +0100950 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200951
952 memset(&shm, 0, sizeof(shm));
953 shm.size = sizeof(struct ta_concurrent_shm);
954 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
955 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
956 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
957 return;
958
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200959 memset(shm.buffer, 0, shm.size);
960 memset(arg, 0, sizeof(arg));
961 max_concurrency = 0;
962 nt = num_threads;
963
964 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +0200965 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200966 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +0200967 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200968 arg[n].shm = &shm;
969 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
970 test_1013_thread, arg + n)))
971 nt = n; /* break loop and start cleanup */
972 }
973
974 for (n = 0; n < nt; n++) {
975 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
976 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
977 if (arg[n].max_concurrency > max_concurrency)
978 max_concurrency = arg[n].max_concurrency;
979 }
980
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200981 /*
982 * Concurrency can be limited by several factors, for instance in a
983 * single CPU system it's dependent on the Preemtion Model used by
984 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
985 * best result there).
986 */
987 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
988 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +0100989 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +0200990 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200991
Jens Wiklander70672972016-04-06 00:01:45 +0200992 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200993 memset(shm.buffer, 0, shm.size);
994 memset(arg, 0, sizeof(arg));
995 max_concurrency = 0;
996 nt = num_threads;
997
998 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +0200999 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001000 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +02001001 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001002 arg[n].shm = &shm;
1003 arg[n].in = sha256_in;
1004 arg[n].in_len = sizeof(sha256_in);
1005 arg[n].out = out;
1006 arg[n].out_len = sizeof(out);
1007 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1008 test_1013_thread, arg + n)))
1009 nt = n; /* break loop and start cleanup */
1010 }
1011
1012 for (n = 0; n < nt; n++) {
1013 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1014 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1015 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1016 arg[n].out, arg[n].out_len);
1017 if (arg[n].max_concurrency > max_concurrency)
1018 max_concurrency = arg[n].max_concurrency;
1019 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001020 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001021 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001022
Pascal Brand4fa35582015-12-17 10:59:12 +01001023 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001024 TEEC_ReleaseSharedMemory(&shm);
1025}
Pascal Brand4fa35582015-12-17 10:59:12 +01001026
1027static void xtest_tee_test_1013(ADBG_Case_t *c)
1028{
1029 int i;
1030 double mean_concurrency;
1031 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001032 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001033
1034 if (level == 0)
1035 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001036
Jens Wiklander70672972016-04-06 00:01:45 +02001037 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001038 mean_concurrency = 0;
1039 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001040 xtest_tee_test_1013_single(c, &concurrency,
1041 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001042 mean_concurrency += concurrency;
1043 }
1044 mean_concurrency /= nb_loops;
1045
1046 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1047 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001048 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001049
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001050#ifndef CFG_PAGED_USER_TA
Jens Wiklander70672972016-04-06 00:01:45 +02001051 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1052 mean_concurrency = 0;
1053 for (i = 0; i < nb_loops; i++) {
1054 xtest_tee_test_1013_single(c, &concurrency,
1055 &concurrent_large_ta_uuid);
1056 mean_concurrency += concurrency;
1057 }
1058 mean_concurrency /= nb_loops;
1059
1060 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1061 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1062 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001063#endif
Jens Wiklander70672972016-04-06 00:01:45 +02001064}