blob: c8e5e29c2d84e6ab04b75cb281d813604ee4b390 [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 Wiklander25a57fe2016-12-26 21:46:24 +010045ADBG_CASE_DEFINE(XTEST_TEE_1001, xtest_tee_test_1001, "Core self tests");
46ADBG_CASE_DEFINE(XTEST_TEE_1004, xtest_tee_test_1004, "Test User Crypt TA");
47ADBG_CASE_DEFINE(XTEST_TEE_1005, xtest_tee_test_1005, "Many sessions");
48ADBG_CASE_DEFINE(XTEST_TEE_1006, xtest_tee_test_1006, "Test Basic OS features");
49ADBG_CASE_DEFINE(XTEST_TEE_1007, xtest_tee_test_1007, "Test Panic");
Pascal Brandc639ac82015-07-02 08:53:34 +020050ADBG_CASE_DEFINE(XTEST_TEE_1008, xtest_tee_test_1008,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010051 "TEE internal client API");
52ADBG_CASE_DEFINE(XTEST_TEE_1009, xtest_tee_test_1009, "TEE Wait");
53ADBG_CASE_DEFINE(XTEST_TEE_1010, xtest_tee_test_1010, "Invalid memory access");
Pascal Brandc639ac82015-07-02 08:53:34 +020054ADBG_CASE_DEFINE(XTEST_TEE_1011, xtest_tee_test_1011,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010055 "Test RPC features with User Crypt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +020056ADBG_CASE_DEFINE(XTEST_TEE_1012, xtest_tee_test_1012,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010057 "Test Single Instance Multi Session features with SIMS TA");
Jens Wiklanderac27ec12015-07-15 15:23:14 +020058ADBG_CASE_DEFINE(XTEST_TEE_1013, xtest_tee_test_1013,
Jens Wiklander25a57fe2016-12-26 21:46:24 +010059 "Test concurency with concurrent TA");
Jens Wiklanderac27ec12015-07-15 15:23:14 +020060
Pascal Brandc639ac82015-07-02 08:53:34 +020061struct xtest_crypto_session {
62 ADBG_Case_t *c;
63 TEEC_Session *session;
64 uint32_t cmd_id_sha256;
65 uint32_t cmd_id_aes256ecb_encrypt;
66 uint32_t cmd_id_aes256ecb_decrypt;
67};
68
69static void xtest_crypto_test(struct xtest_crypto_session *cs)
70{
71 uint32_t ret_orig;
72 uint8_t crypt_out[16];
73 uint8_t crypt_in[16] = { 22, 17 };
74
75 crypt_in[15] = 60;
76
77 Do_ADBG_BeginSubCase(cs->c, "AES encrypt");
78 {
79 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
80
81 op.params[0].tmpref.buffer = crypt_in;
82 op.params[0].tmpref.size = sizeof(crypt_in);
83 op.params[1].tmpref.buffer = crypt_out;
84 op.params[1].tmpref.size = sizeof(crypt_out);
85 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
86 TEEC_MEMREF_TEMP_OUTPUT,
87 TEEC_NONE, TEEC_NONE);
88
89 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
90 TEEC_InvokeCommand(cs->session,
91 cs->
92 cmd_id_aes256ecb_encrypt,
93 &op,
94 &ret_orig));
95 }
96 Do_ADBG_EndSubCase(cs->c, "AES encrypt");
97
98 Do_ADBG_BeginSubCase(cs->c, "AES decrypt");
99 {
100 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
101 uint8_t out[16];
102
103 op.params[0].tmpref.buffer = crypt_out;
104 op.params[0].tmpref.size = sizeof(crypt_out);
105 op.params[1].tmpref.buffer = out;
106 op.params[1].tmpref.size = sizeof(out);
107 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
108 TEEC_MEMREF_TEMP_OUTPUT,
109 TEEC_NONE, TEEC_NONE);
110
111 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
112 TEEC_InvokeCommand(cs->session,
113 cs->
114 cmd_id_aes256ecb_decrypt,
115 &op,
116 &ret_orig));
117
118 if (!ADBG_EXPECT(cs->c, 0,
119 memcmp(crypt_in, out, sizeof(crypt_in)))) {
120 Do_ADBG_Log("crypt_in:");
121 Do_ADBG_HexLog(crypt_in, sizeof(crypt_in), 16);
122 Do_ADBG_Log("out:");
123 Do_ADBG_HexLog(out, sizeof(out), 16);
124 }
125 }
126 Do_ADBG_EndSubCase(cs->c, "AES decrypt");
127
128 Do_ADBG_BeginSubCase(cs->c, "SHA-256 test, 3 bytes input");
129 {
130 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
131 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
132 static const uint8_t sha256_out[] = {
133 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
134 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
135 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
136 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
137 };
138 uint8_t out[32] = { 0 };
139
140 op.params[0].tmpref.buffer = (void *)sha256_in;
141 op.params[0].tmpref.size = sizeof(sha256_in);
142 op.params[1].tmpref.buffer = out;
143 op.params[1].tmpref.size = sizeof(out);
144 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
145 TEEC_MEMREF_TEMP_OUTPUT,
146 TEEC_NONE, TEEC_NONE);
147
148 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
149 TEEC_InvokeCommand(cs->session,
150 cs->
151 cmd_id_sha256,
152 &op,
153 &ret_orig));
154
155 if (!ADBG_EXPECT(cs->c, 0, memcmp(sha256_out, out,
156 sizeof(sha256_out)))) {
157 Do_ADBG_Log("sha256_out:");
158 Do_ADBG_HexLog(sha256_out, sizeof(sha256_out), 16);
159 Do_ADBG_Log("out:");
160 Do_ADBG_HexLog(out, sizeof(out), 16);
161 }
162 }
163 Do_ADBG_EndSubCase(cs->c, "SHA-256 test, 3 bytes input");
164
165 Do_ADBG_BeginSubCase(cs->c,
166 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
167 {
168 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
169 static const uint8_t in[] = {
170 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
171 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
172 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
173 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
174 };
175 static const uint8_t exp_out[] = {
176 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
177 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
178 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
179 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
180 };
181 uint8_t out[sizeof(exp_out)];
182
183 op.params[0].tmpref.buffer = (void *)in;
184 op.params[0].tmpref.size = sizeof(in);
185 op.params[1].tmpref.buffer = out;
186 op.params[1].tmpref.size = sizeof(out);
187 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
188 TEEC_MEMREF_TEMP_OUTPUT,
189 TEEC_NONE, TEEC_NONE);
190
191 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
192 TEEC_InvokeCommand(cs->session,
193 cs->
194 cmd_id_aes256ecb_encrypt,
195 &op,
196 &ret_orig));
197
198 if (!ADBG_EXPECT(cs->c, 0,
199 memcmp(exp_out, out, sizeof(exp_out)))) {
200 Do_ADBG_Log("exp_out:");
201 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
202 Do_ADBG_Log("out:");
203 Do_ADBG_HexLog(out, sizeof(out), 16);
204 }
205 }
206 Do_ADBG_EndSubCase(cs->c,
207 "AES-256 ECB encrypt test, 32 bytes input, with fixed key");
208
209 Do_ADBG_BeginSubCase(cs->c,
210 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
211 {
212 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
213 static const uint8_t in[] = {
214 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
215 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
216 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
217 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
218 };
219 static const uint8_t exp_out[] = {
220 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
221 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
222 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
223 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
224 };
225 uint8_t out[sizeof(exp_out)];
226
227 op.params[0].tmpref.buffer = (void *)in;
228 op.params[0].tmpref.size = sizeof(in);
229 op.params[1].tmpref.buffer = out;
230 op.params[1].tmpref.size = sizeof(out);
231 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
232 TEEC_MEMREF_TEMP_OUTPUT,
233 TEEC_NONE, TEEC_NONE);
234
235 (void)ADBG_EXPECT_TEEC_SUCCESS(cs->c,
236 TEEC_InvokeCommand(cs->session,
237 cs->
238 cmd_id_aes256ecb_decrypt,
239 &op,
240 &ret_orig));
241
242 if (!ADBG_EXPECT(cs->c, 0,
243 memcmp(exp_out, out, sizeof(exp_out)))) {
244 Do_ADBG_Log("exp_out:");
245 Do_ADBG_HexLog(exp_out, sizeof(exp_out), 16);
246 Do_ADBG_Log("out:");
247 Do_ADBG_HexLog(out, sizeof(out), 16);
248 }
249 }
250 Do_ADBG_EndSubCase(cs->c,
251 "AES-256 ECB decrypt test, 32 bytes input, with fixed key");
252}
253
254static void xtest_tee_test_1001(ADBG_Case_t *c)
255{
Jens Wiklandercf16e842016-02-10 09:07:09 +0100256 TEEC_Result res;
257 TEEC_Session session = { 0 };
258 uint32_t ret_orig;
Pascal Brandc639ac82015-07-02 08:53:34 +0200259
Jens Wiklandercf16e842016-02-10 09:07:09 +0100260#define CMD_SELF_TESTS 2
Pascal Brandc639ac82015-07-02 08:53:34 +0200261
Jens Wiklandercf16e842016-02-10 09:07:09 +0100262 res = xtest_teec_open_session(&session, &sta_test_ta_uuid, NULL,
263 &ret_orig);
264 /*
265 * If the static TA (which is optional) isn't available, skip this
266 * test.
267 */
268 if (res != TEEC_SUCCESS)
269 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200270
Jens Wiklandercf16e842016-02-10 09:07:09 +0100271 (void)ADBG_EXPECT_TEEC_SUCCESS(c, TEEC_InvokeCommand(
272 &session, CMD_SELF_TESTS, NULL, &ret_orig));
273 TEEC_CloseSession(&session);
Pascal Brandc639ac82015-07-02 08:53:34 +0200274}
275
276static void xtest_tee_test_1004(ADBG_Case_t *c)
277{
278 TEEC_Session session = { 0 };
279 uint32_t ret_orig;
280 struct xtest_crypto_session cs = { c, &session, TA_CRYPT_CMD_SHA256,
281 TA_CRYPT_CMD_AES256ECB_ENC,
282 TA_CRYPT_CMD_AES256ECB_DEC };
283
284 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
285 &session, &crypt_user_ta_uuid,
286 NULL, &ret_orig)))
287 return;
288
289 /* Run the "complete crypto test suite" */
290 xtest_crypto_test(&cs);
291
292 TEEC_CloseSession(&session);
293}
294
295#ifndef TEEC_ERROR_TARGET_DEAD
296/* To be removed when we have TEEC_ERROR_TARGET_DEAD from tee_client_api.h */
297#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024
298#endif
299
300static void xtest_tee_test_invalid_mem_access(ADBG_Case_t *c, uint32_t n)
301{
302 TEEC_Session session = { 0 };
303 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
304 uint32_t ret_orig;
305
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300306 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200307 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300308 &ret_orig)))
309 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200310
311 op.params[0].value.a = n;
312 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
313 TEEC_NONE);
314
315 (void)ADBG_EXPECT_TEEC_RESULT(c,
316 TEEC_ERROR_TARGET_DEAD,
317 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
318 &ret_orig));
319
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300320 (void)ADBG_EXPECT_TEEC_RESULT(c,
321 TEEC_ERROR_TARGET_DEAD,
322 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BAD_MEM_ACCESS, &op,
Pascal Brandc639ac82015-07-02 08:53:34 +0200323 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300324
Pascal Brandc639ac82015-07-02 08:53:34 +0200325 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
326
327 TEEC_CloseSession(&session);
328}
329
330static void xtest_tee_test_1005(ADBG_Case_t *c)
331{
332 uint32_t ret_orig;
333#define MAX_SESSIONS 3
334 TEEC_Session sessions[MAX_SESSIONS];
335 int i;
336
337 for (i = 0; i < MAX_SESSIONS; i++) {
338 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Jens Wiklandereb6bce72016-09-23 11:37:33 +0200339 xtest_teec_open_session(&sessions[i],
340 &concurrent_ta_uuid,
Pascal Brandc639ac82015-07-02 08:53:34 +0200341 NULL, &ret_orig)))
342 break;
343 }
344
345 for (; --i >= 0; )
346 TEEC_CloseSession(&sessions[i]);
347}
348
349static void xtest_tee_test_1006(ADBG_Case_t *c)
350{
351 TEEC_Session session = { 0 };
352 uint32_t ret_orig;
353 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
354 uint8_t buf[32];
355
356 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
357 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
358 &ret_orig)))
359 return;
360
361 op.params[0].tmpref.buffer = buf;
362 op.params[0].tmpref.size = sizeof(buf);
363 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
364 TEEC_NONE, TEEC_NONE);
365
366 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
367 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_BASIC, &op,
368 &ret_orig));
369
370 TEEC_CloseSession(&session);
371}
372
373static void xtest_tee_test_1007(ADBG_Case_t *c)
374{
375 TEEC_Session session = { 0 };
376 uint32_t ret_orig;
377
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300378 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200379 xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300380 &ret_orig)))
381 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200382
383 (void)ADBG_EXPECT_TEEC_RESULT(c,
384 TEEC_ERROR_TARGET_DEAD,
385 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_PANIC, NULL,
386 &ret_orig));
387
388 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
389
390 (void)ADBG_EXPECT_TEEC_RESULT(c,
391 TEEC_ERROR_TARGET_DEAD,
392 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_INIT, NULL,
393 &ret_orig));
394
395 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
396
397 TEEC_CloseSession(&session);
398}
399
Jerome Forissierf02a2212015-10-29 14:33:35 +0100400#ifndef TA_DIR
401#define TA_DIR "/lib/optee_armtz"
402#endif
403
David Brownb2865ab2016-08-02 11:44:41 -0600404#ifndef TA_TEST_DIR
405# ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200406# define TA_TEST_DIR "/data/tee/optee_armtz"
David Brownb2865ab2016-08-02 11:44:41 -0600407# else
408# define TA_TEST_DIR "/tmp/optee_armtz"
409# endif
410#endif
Jens Wiklanderb7940892015-10-23 16:02:40 +0200411
David Brownb2865ab2016-08-02 11:44:41 -0600412static void make_test_ta_dir(void)
413{
414#ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200415 (void)mkdir("/data/tee", 0755);
David Brownb2865ab2016-08-02 11:44:41 -0600416#endif
417 (void)mkdir(TA_TEST_DIR, 0755);
418}
419
420static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
421 bool for_write)
422{
Jens Wiklanderb7940892015-10-23 16:02:40 +0200423 snprintf(buf, blen,
Jens Wiklander6203b872016-12-08 19:18:29 +0100424 "%s/%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x.ta",
David Brownb2865ab2016-08-02 11:44:41 -0600425 for_write ? TA_TEST_DIR : TA_DIR,
426 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
Jens Wiklanderb7940892015-10-23 16:02:40 +0200427 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
428 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
429 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
David Brownb2865ab2016-08-02 11:44:41 -0600430 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200431}
432
David Brownb2865ab2016-08-02 11:44:41 -0600433static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode,
434 bool for_write)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200435{
436 char buf[PATH_MAX];
437
David Brownb2865ab2016-08-02 11:44:41 -0600438 uuid_to_full_name(buf, sizeof(buf), uuid, for_write);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200439 return fopen(buf, mode);
440}
441
David Brownb2865ab2016-08-02 11:44:41 -0600442static bool rm_file(const TEEC_UUID *uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200443{
444 char buf[PATH_MAX];
445
David Brownb2865ab2016-08-02 11:44:41 -0600446 uuid_to_full_name(buf, sizeof(buf), uuid, true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200447 return !unlink(buf);
448}
449
David Brownb2865ab2016-08-02 11:44:41 -0600450static bool copy_file(const TEEC_UUID *src_uuid, const TEEC_UUID *dst_uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200451{
452 char buf[4 * 1024];
David Brownb2865ab2016-08-02 11:44:41 -0600453 FILE *src = open_ta_file(src_uuid, "r", false);
454 FILE *dst = open_ta_file(dst_uuid, "w", true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200455 size_t r;
456 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200457 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200458
Jens Wiklander4441fe22015-10-23 16:53:02 +0200459 if (src && dst) {
460 do {
461 r = fread(buf, 1, sizeof(buf), src);
462 if (!r) {
463 ret = !!feof(src);
464 break;
465 }
466 w = fwrite(buf, 1, r, dst);
467 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200468 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200469
470 if (src)
471 fclose(src);
472 if (dst)
473 fclose(dst);
474 return ret;
475}
476
477static bool corrupt_file(FILE *f, long offs, uint8_t mask)
478{
479 uint8_t b;
480
481 if (fseek(f, offs, SEEK_SET))
482 return false;
483
484 if (fread(&b, 1, 1, f) != 1)
485 return false;
486
487 b ^= mask;
488
489 if (fseek(f, offs, SEEK_SET))
490 return false;
491
492 if (fwrite(&b, 1, 1, f) != 1)
493 return false;
494
495 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200496}
497
498static void load_fake_ta(ADBG_Case_t *c)
499{
500 static const TEEC_UUID fake_uuid = {
501 0x7e0a0900, 0x586b, 0x11e5,
502 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
503 };
504 TEEC_Session session = { 0 };
505 TEEC_Result res;
506 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200507 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200508
David Brownb2865ab2016-08-02 11:44:41 -0600509 r = copy_file(&create_fail_test_ta_uuid, &fake_uuid);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200510
511 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200512 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
513 &ret_orig);
514 if (res == TEEC_SUCCESS)
515 TEEC_CloseSession(&session);
516 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200517 }
518
David Brownb2865ab2016-08-02 11:44:41 -0600519 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid));
Jens Wiklanderb7940892015-10-23 16:02:40 +0200520}
521
Jens Wiklander4441fe22015-10-23 16:53:02 +0200522static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
523{
524 TEEC_Session session = { 0 };
525 TEEC_Result res;
526 uint32_t ret_orig;
527 FILE *f;
528 bool r;
529
David Brownb2865ab2016-08-02 11:44:41 -0600530 r = copy_file(&create_fail_test_ta_uuid, &create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200531 if (!ADBG_EXPECT_TRUE(c, r)) {
David Brownb2865ab2016-08-02 11:44:41 -0600532 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200533 return false;
534 }
535
David Brownb2865ab2016-08-02 11:44:41 -0600536 f = open_ta_file(&create_fail_test_ta_uuid, "r+", true);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200537 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
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 r = corrupt_file(f, offs, mask);
542 fclose(f);
543
544 if (ADBG_EXPECT_TRUE(c, r)) {
545 res = xtest_teec_open_session(&session,
546 &create_fail_test_ta_uuid,
547 NULL, &ret_orig);
548 if (res == TEEC_SUCCESS)
549 TEEC_CloseSession(&session);
550 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
551 }
552
David Brownb2865ab2016-08-02 11:44:41 -0600553 r &= ADBG_EXPECT_TRUE(c, rm_file(&create_fail_test_ta_uuid));
Jens Wiklander4441fe22015-10-23 16:53:02 +0200554 return r;
555}
556
Pascal Brandc639ac82015-07-02 08:53:34 +0200557static void xtest_tee_test_1008(ADBG_Case_t *c)
558{
559 TEEC_Session session = { 0 };
560 TEEC_Session session_crypt = { 0 };
561 uint32_t ret_orig;
562
563 Do_ADBG_BeginSubCase(c, "Invoke command");
564 {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300565 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200566 xtest_teec_open_session(&session, &os_test_ta_uuid,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300567 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200568
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300569 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
570 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
571 NULL, &ret_orig));
572 TEEC_CloseSession(&session);
573 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200574
Pascal Brandc639ac82015-07-02 08:53:34 +0200575 }
576 Do_ADBG_EndSubCase(c, "Invoke command");
577
578 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
579 {
580 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
581
582 op.params[0].value.a = 2000;
583 op.paramTypes = TEEC_PARAM_TYPES(
584 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
585
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300586 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200587 xtest_teec_open_session(&session,
588 &os_test_ta_uuid,
589 NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300590 &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200591
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300592 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
593 TEEC_InvokeCommand(&session,
594 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
595 &op, &ret_orig));
596 TEEC_CloseSession(&session);
597 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200598 }
599 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
600
601 Do_ADBG_BeginSubCase(c, "Create session fail");
602 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200603 size_t n;
604
Pascal Brandc639ac82015-07-02 08:53:34 +0200605 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
606 xtest_teec_open_session(&session_crypt,
607 &create_fail_test_ta_uuid, NULL,
608 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200609 /*
610 * Run this several times to see that there's no memory leakage.
611 */
612 for (n = 0; n < 100; n++) {
613 Do_ADBG_Log("n = %zu", n);
614 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
615 xtest_teec_open_session(&session_crypt,
616 &create_fail_test_ta_uuid,
617 NULL, &ret_orig));
618 }
619 }
620 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200621
David Brownb2865ab2016-08-02 11:44:41 -0600622 make_test_ta_dir();
623
Jens Wiklanderb7940892015-10-23 16:02:40 +0200624 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
625 load_fake_ta(c);
626 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
627
Jens Wiklander4441fe22015-10-23 16:53:02 +0200628 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
629 ADBG_EXPECT_TRUE(c,
630 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
631 ADBG_EXPECT_TRUE(c,
632 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
633 ADBG_EXPECT_TRUE(c,
634 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
635 ADBG_EXPECT_TRUE(c,
636 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
637 ADBG_EXPECT_TRUE(c,
638 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
639 ADBG_EXPECT_TRUE(c,
640 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
641 ADBG_EXPECT_TRUE(c,
642 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
643 ADBG_EXPECT_TRUE(c,
644 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
645 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
646 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
647 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200648}
649
Pascal Brandc639ac82015-07-02 08:53:34 +0200650static void *cancellation_thread(void *arg)
651{
652 /*
653 * Sleep 0.5 seconds before cancellation to make sure that the other
654 * thread is in RPC_WAIT.
655 */
656 (void)usleep(500000);
657 TEEC_RequestCancellation(arg);
658 return NULL;
659}
Pascal Brandc639ac82015-07-02 08:53:34 +0200660
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300661static void xtest_tee_test_1009_subcase(ADBG_Case_t *c, const char *subcase,
662 uint32_t timeout, bool cancel)
Pascal Brandc639ac82015-07-02 08:53:34 +0200663{
664 TEEC_Session session = { 0 };
665 uint32_t ret_orig;
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300666 pthread_t thr;
Pascal Brandc639ac82015-07-02 08:53:34 +0200667
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300668 Do_ADBG_BeginSubCase(c, "%s", subcase);
Pascal Brandc639ac82015-07-02 08:53:34 +0200669 {
670 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
671
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300672 if (ADBG_EXPECT_TEEC_SUCCESS(c,
673 xtest_teec_open_session(&session, &os_test_ta_uuid,
674 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200675
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300676 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c,
677 TEEC_ORIGIN_TRUSTED_APP,
678 ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200679
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300680 op.params[0].value.a = timeout;
681 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
682 TEEC_NONE,
683 TEEC_NONE, TEEC_NONE);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300684 if (cancel) {
685 (void)ADBG_EXPECT(c, 0,
686 pthread_create(&thr, NULL,
687 cancellation_thread, &op));
Pascal Brandc639ac82015-07-02 08:53:34 +0200688
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300689 (void)ADBG_EXPECT_TEEC_RESULT(c,
690 TEEC_ERROR_CANCEL,
691 TEEC_InvokeCommand(&session,
692 TA_OS_TEST_CMD_WAIT,
693 &op,
694 &ret_orig));
695 } else
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300696
697 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
698 TEEC_InvokeCommand(&session,
699 TA_OS_TEST_CMD_WAIT,
700 &op,
701 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300702 if (cancel)
703 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300704
705 TEEC_CloseSession(&session);
706 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200707 }
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300708 Do_ADBG_EndSubCase(c, "%s", subcase);
709}
710
711static void xtest_tee_test_1009(ADBG_Case_t *c)
712{
713 xtest_tee_test_1009_subcase(c, "TEE Wait 0.1s", 100, false);
714 xtest_tee_test_1009_subcase(c, "TEE Wait 0.5s", 500, false);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300715 xtest_tee_test_1009_subcase(c, "TEE Wait 2s cancel", 2000, true);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300716 xtest_tee_test_1009_subcase(c, "TEE Wait 2s", 2000, false);
Pascal Brandc639ac82015-07-02 08:53:34 +0200717}
718
719static void xtest_tee_test_1010(ADBG_Case_t *c)
720{
721 unsigned n;
722
723 for (n = 1; n <= 5; n++) {
724 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
725 xtest_tee_test_invalid_mem_access(c, n);
726 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
727 }
728}
729
730static void xtest_tee_test_1011(ADBG_Case_t *c)
731{
732 TEEC_Session session = { 0 };
733 uint32_t ret_orig;
734 struct xtest_crypto_session cs = {
735 c, &session, TA_RPC_CMD_CRYPT_SHA256,
736 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
737 TA_RPC_CMD_CRYPT_AES256ECB_DEC
738 };
739 TEEC_UUID uuid = rpc_test_ta_uuid;
740
741 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
742 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
743 return;
744
745 /*
746 * Run the "complete crypto test suite" using RPC
747 */
748 xtest_crypto_test(&cs);
749 TEEC_CloseSession(&session);
750}
751
752/*
753 * Note that this test is failing when
754 * - running twice in a raw
755 * - and the user TA is statically linked
756 * This is because the counter is not reseted when opening the first session
757 * in case the TA is statically linked
758 */
759static void xtest_tee_test_1012(ADBG_Case_t *c)
760{
761 TEEC_Session session1 = { 0 };
762 TEEC_Session session2 = { 0 };
763 uint32_t ret_orig;
764 TEEC_UUID uuid = sims_test_ta_uuid;
765
766 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
767 {
768 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
769 static const uint8_t in[] = {
770 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
771 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
772 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
773 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
774 };
775 uint8_t out[32] = { 0 };
776 int i;
777
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300778 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200779 xtest_teec_open_session(&session1, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300780 &ret_orig)))
781 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200782
783 op.params[0].value.a = 0;
784 op.params[1].tmpref.buffer = (void *)in;
785 op.params[1].tmpref.size = sizeof(in);
786 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
787 TEEC_MEMREF_TEMP_INPUT,
788 TEEC_NONE, TEEC_NONE);
789
790 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
791 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
792 &ret_orig));
793
794 for (i = 1; i < 1000; i++) {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300795 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200796 xtest_teec_open_session(&session2, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300797 &ret_orig)))
798 continue;
Pascal Brandc639ac82015-07-02 08:53:34 +0200799
800 op.params[0].value.a = 0;
801 op.params[1].tmpref.buffer = out;
802 op.params[1].tmpref.size = sizeof(out);
803 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
804 TEEC_MEMREF_TEMP_OUTPUT,
805 TEEC_NONE, TEEC_NONE);
806
807 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
808 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
809 &op, &ret_orig));
810
811 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
812 sizeof(out))) {
813 Do_ADBG_Log("in:");
814 Do_ADBG_HexLog(in, sizeof(in), 16);
815 Do_ADBG_Log("out:");
816 Do_ADBG_HexLog(out, sizeof(out), 16);
817 }
818
819 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
820 TEEC_NONE, TEEC_NONE,
821 TEEC_NONE);
822
823 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
824 TEEC_InvokeCommand(&session1,
825 TA_SIMS_CMD_GET_COUNTER,
826 &op, &ret_orig));
827
828 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
829
830 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
831 TEEC_InvokeCommand(&session2,
832 TA_SIMS_CMD_GET_COUNTER, &op,
833 &ret_orig));
834
835 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
836 TEEC_CloseSession(&session2);
837 }
838
839 memset(out, 0, sizeof(out));
840 op.params[0].value.a = 0;
841 op.params[1].tmpref.buffer = out;
842 op.params[1].tmpref.size = sizeof(out);
843 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
844 TEEC_MEMREF_TEMP_OUTPUT,
845 TEEC_NONE, TEEC_NONE);
846
847 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
848 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
849 &ret_orig));
850
851 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
852 Do_ADBG_Log("in:");
853 Do_ADBG_HexLog(in, sizeof(in), 16);
854 Do_ADBG_Log("out:");
855 Do_ADBG_HexLog(out, sizeof(out), 16);
856 }
857
858 TEEC_CloseSession(&session1);
859 }
860}
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200861
862struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +0200863 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200864 uint32_t cmd;
865 uint32_t repeat;
866 TEEC_SharedMemory *shm;
867 uint32_t error_orig;
868 TEEC_Result res;
869 uint32_t max_concurrency;
870 const uint8_t *in;
871 size_t in_len;
872 uint8_t *out;
873 size_t out_len;
874};
875
876static void *test_1013_thread(void *arg)
877{
878 struct test_1013_thread_arg *a = arg;
879 TEEC_Session session = { 0 };
880 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
881 uint8_t p2 = TEEC_NONE;
882 uint8_t p3 = TEEC_NONE;
883
Jens Wiklander70672972016-04-06 00:01:45 +0200884 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200885 &a->error_orig);
886 if (a->res != TEEC_SUCCESS)
887 return NULL;
888
889 op.params[0].memref.parent = a->shm;
890 op.params[0].memref.size = a->shm->size;
891 op.params[0].memref.offset = 0;
892 op.params[1].value.a = a->repeat;
893 op.params[1].value.b = 0;
894 op.params[2].tmpref.buffer = (void *)a->in;
895 op.params[2].tmpref.size = a->in_len;
896 op.params[3].tmpref.buffer = a->out;
897 op.params[3].tmpref.size = a->out_len;
898
899 if (a->in_len)
900 p2 = TEEC_MEMREF_TEMP_INPUT;
901 if (a->out_len)
902 p3 = TEEC_MEMREF_TEMP_OUTPUT;
903
904 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
905 TEEC_VALUE_INOUT, p2, p3);
906
907 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
908 a->max_concurrency = op.params[1].value.b;
909 a->out_len = op.params[3].tmpref.size;
910 TEEC_CloseSession(&session);
911 return NULL;
912}
913
Pascal Brand4fa35582015-12-17 10:59:12 +0100914#define NUM_THREADS 3
915
Jens Wiklander70672972016-04-06 00:01:45 +0200916static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
917 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200918{
Pascal Brand4fa35582015-12-17 10:59:12 +0100919 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200920 size_t nt;
921 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +0200922 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200923 pthread_t thr[num_threads];
924 TEEC_SharedMemory shm;
925 size_t max_concurrency;
926 struct test_1013_thread_arg arg[num_threads];
927 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
928 static const uint8_t sha256_out[] = {
929 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
930 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
931 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
932 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
933 };
934 uint8_t out[32] = { 0 };
935
Jens Wiklander70672972016-04-06 00:01:45 +0200936 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +0100937 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200938
939 memset(&shm, 0, sizeof(shm));
940 shm.size = sizeof(struct ta_concurrent_shm);
941 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
942 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
943 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
944 return;
945
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200946 memset(shm.buffer, 0, shm.size);
947 memset(arg, 0, sizeof(arg));
948 max_concurrency = 0;
949 nt = num_threads;
950
951 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +0200952 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200953 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +0200954 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200955 arg[n].shm = &shm;
956 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
957 test_1013_thread, arg + n)))
958 nt = n; /* break loop and start cleanup */
959 }
960
961 for (n = 0; n < nt; n++) {
962 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
963 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
964 if (arg[n].max_concurrency > max_concurrency)
965 max_concurrency = arg[n].max_concurrency;
966 }
967
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200968 /*
969 * Concurrency can be limited by several factors, for instance in a
970 * single CPU system it's dependent on the Preemtion Model used by
971 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
972 * best result there).
973 */
974 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
975 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +0100976 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +0200977 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200978
Jens Wiklander70672972016-04-06 00:01:45 +0200979 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200980 memset(shm.buffer, 0, shm.size);
981 memset(arg, 0, sizeof(arg));
982 max_concurrency = 0;
983 nt = num_threads;
984
985 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +0200986 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200987 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +0200988 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200989 arg[n].shm = &shm;
990 arg[n].in = sha256_in;
991 arg[n].in_len = sizeof(sha256_in);
992 arg[n].out = out;
993 arg[n].out_len = sizeof(out);
994 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
995 test_1013_thread, arg + n)))
996 nt = n; /* break loop and start cleanup */
997 }
998
999 for (n = 0; n < nt; n++) {
1000 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1001 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1002 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1003 arg[n].out, arg[n].out_len);
1004 if (arg[n].max_concurrency > max_concurrency)
1005 max_concurrency = arg[n].max_concurrency;
1006 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001007 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001008 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001009
Pascal Brand4fa35582015-12-17 10:59:12 +01001010 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001011 TEEC_ReleaseSharedMemory(&shm);
1012}
Pascal Brand4fa35582015-12-17 10:59:12 +01001013
1014static void xtest_tee_test_1013(ADBG_Case_t *c)
1015{
1016 int i;
1017 double mean_concurrency;
1018 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001019 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001020
1021 if (level == 0)
1022 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001023
Jens Wiklander70672972016-04-06 00:01:45 +02001024 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001025 mean_concurrency = 0;
1026 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001027 xtest_tee_test_1013_single(c, &concurrency,
1028 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001029 mean_concurrency += concurrency;
1030 }
1031 mean_concurrency /= nb_loops;
1032
1033 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1034 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001035 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001036
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001037#ifndef CFG_PAGED_USER_TA
Jens Wiklander70672972016-04-06 00:01:45 +02001038 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1039 mean_concurrency = 0;
1040 for (i = 0; i < nb_loops; i++) {
1041 xtest_tee_test_1013_single(c, &concurrency,
1042 &concurrent_large_ta_uuid);
1043 mean_concurrency += concurrency;
1044 }
1045 mean_concurrency /= nb_loops;
1046
1047 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1048 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1049 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001050#endif
Jens Wiklander70672972016-04-06 00:01:45 +02001051}