blob: afadf3b5373e3a353147ef4c13a3d4f084a46167 [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
403#define TA_DIR "/lib/optee_armtz"
404#endif
405
David Brownb2865ab2016-08-02 11:44:41 -0600406#ifndef TA_TEST_DIR
407# ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200408# define TA_TEST_DIR "/data/tee/optee_armtz"
David Brownb2865ab2016-08-02 11:44:41 -0600409# else
410# define TA_TEST_DIR "/tmp/optee_armtz"
411# endif
412#endif
Jens Wiklanderb7940892015-10-23 16:02:40 +0200413
David Brownb2865ab2016-08-02 11:44:41 -0600414static void make_test_ta_dir(void)
415{
416#ifdef __ANDROID__
Zoltan Kuscsikd5796152016-10-27 10:09:12 +0200417 (void)mkdir("/data/tee", 0755);
David Brownb2865ab2016-08-02 11:44:41 -0600418#endif
419 (void)mkdir(TA_TEST_DIR, 0755);
420}
421
422static void uuid_to_full_name(char *buf, size_t blen, const TEEC_UUID *uuid,
423 bool for_write)
424{
Jens Wiklanderb7940892015-10-23 16:02:40 +0200425 snprintf(buf, blen,
Jens Wiklander6203b872016-12-08 19:18:29 +0100426 "%s/%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x.ta",
David Brownb2865ab2016-08-02 11:44:41 -0600427 for_write ? TA_TEST_DIR : TA_DIR,
428 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
Jens Wiklanderb7940892015-10-23 16:02:40 +0200429 uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1],
430 uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
431 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5],
David Brownb2865ab2016-08-02 11:44:41 -0600432 uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200433}
434
David Brownb2865ab2016-08-02 11:44:41 -0600435static FILE *open_ta_file(const TEEC_UUID *uuid, const char *mode,
436 bool for_write)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200437{
438 char buf[PATH_MAX];
439
David Brownb2865ab2016-08-02 11:44:41 -0600440 uuid_to_full_name(buf, sizeof(buf), uuid, for_write);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200441 return fopen(buf, mode);
442}
443
David Brownb2865ab2016-08-02 11:44:41 -0600444static bool rm_file(const TEEC_UUID *uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200445{
446 char buf[PATH_MAX];
447
David Brownb2865ab2016-08-02 11:44:41 -0600448 uuid_to_full_name(buf, sizeof(buf), uuid, true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200449 return !unlink(buf);
450}
451
David Brownb2865ab2016-08-02 11:44:41 -0600452static bool copy_file(const TEEC_UUID *src_uuid, const TEEC_UUID *dst_uuid)
Jens Wiklanderb7940892015-10-23 16:02:40 +0200453{
454 char buf[4 * 1024];
David Brownb2865ab2016-08-02 11:44:41 -0600455 FILE *src = open_ta_file(src_uuid, "r", false);
456 FILE *dst = open_ta_file(dst_uuid, "w", true);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200457 size_t r;
458 size_t w;
Jens Wiklander4441fe22015-10-23 16:53:02 +0200459 bool ret = false;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200460
Jens Wiklander4441fe22015-10-23 16:53:02 +0200461 if (src && dst) {
462 do {
463 r = fread(buf, 1, sizeof(buf), src);
464 if (!r) {
465 ret = !!feof(src);
466 break;
467 }
468 w = fwrite(buf, 1, r, dst);
469 } while (w == r);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200470 }
Jens Wiklander4441fe22015-10-23 16:53:02 +0200471
472 if (src)
473 fclose(src);
474 if (dst)
475 fclose(dst);
476 return ret;
477}
478
479static bool corrupt_file(FILE *f, long offs, uint8_t mask)
480{
481 uint8_t b;
482
483 if (fseek(f, offs, SEEK_SET))
484 return false;
485
486 if (fread(&b, 1, 1, f) != 1)
487 return false;
488
489 b ^= mask;
490
491 if (fseek(f, offs, SEEK_SET))
492 return false;
493
494 if (fwrite(&b, 1, 1, f) != 1)
495 return false;
496
497 return true;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200498}
499
500static void load_fake_ta(ADBG_Case_t *c)
501{
502 static const TEEC_UUID fake_uuid = {
503 0x7e0a0900, 0x586b, 0x11e5,
504 { 0x93, 0x1f, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }
505 };
506 TEEC_Session session = { 0 };
507 TEEC_Result res;
508 uint32_t ret_orig;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200509 bool r;
Jens Wiklanderb7940892015-10-23 16:02:40 +0200510
David Brownb2865ab2016-08-02 11:44:41 -0600511 r = copy_file(&create_fail_test_ta_uuid, &fake_uuid);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200512
513 if (ADBG_EXPECT_TRUE(c, r)) {
Jens Wiklander4441fe22015-10-23 16:53:02 +0200514 res = xtest_teec_open_session(&session, &fake_uuid, NULL,
515 &ret_orig);
516 if (res == TEEC_SUCCESS)
517 TEEC_CloseSession(&session);
518 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
Jens Wiklanderb7940892015-10-23 16:02:40 +0200519 }
520
David Brownb2865ab2016-08-02 11:44:41 -0600521 ADBG_EXPECT_TRUE(c, rm_file(&fake_uuid));
Jens Wiklanderb7940892015-10-23 16:02:40 +0200522}
523
Jens Wiklander4441fe22015-10-23 16:53:02 +0200524static bool load_corrupt_ta(ADBG_Case_t *c, long offs, uint8_t mask)
525{
526 TEEC_Session session = { 0 };
527 TEEC_Result res;
528 uint32_t ret_orig;
529 FILE *f;
530 bool r;
531
David Brownb2865ab2016-08-02 11:44:41 -0600532 r = copy_file(&create_fail_test_ta_uuid, &create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200533 if (!ADBG_EXPECT_TRUE(c, r)) {
David Brownb2865ab2016-08-02 11:44:41 -0600534 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200535 return false;
536 }
537
David Brownb2865ab2016-08-02 11:44:41 -0600538 f = open_ta_file(&create_fail_test_ta_uuid, "r+", true);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200539 if (!ADBG_EXPECT_NOT_NULL(c, f)) {
David Brownb2865ab2016-08-02 11:44:41 -0600540 rm_file(&create_fail_test_ta_uuid);
Jens Wiklander4441fe22015-10-23 16:53:02 +0200541 return false;
542 }
543 r = corrupt_file(f, offs, mask);
544 fclose(f);
545
546 if (ADBG_EXPECT_TRUE(c, r)) {
547 res = xtest_teec_open_session(&session,
548 &create_fail_test_ta_uuid,
549 NULL, &ret_orig);
550 if (res == TEEC_SUCCESS)
551 TEEC_CloseSession(&session);
552 r &= ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_SECURITY, res);
553 }
554
David Brownb2865ab2016-08-02 11:44:41 -0600555 r &= ADBG_EXPECT_TRUE(c, rm_file(&create_fail_test_ta_uuid));
Jens Wiklander4441fe22015-10-23 16:53:02 +0200556 return r;
557}
558
Pascal Brandc639ac82015-07-02 08:53:34 +0200559static void xtest_tee_test_1008(ADBG_Case_t *c)
560{
561 TEEC_Session session = { 0 };
562 TEEC_Session session_crypt = { 0 };
563 uint32_t ret_orig;
564
565 Do_ADBG_BeginSubCase(c, "Invoke command");
566 {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300567 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200568 xtest_teec_open_session(&session, &os_test_ta_uuid,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300569 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200570
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300571 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
572 TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CLIENT,
573 NULL, &ret_orig));
574 TEEC_CloseSession(&session);
575 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200576
Pascal Brandc639ac82015-07-02 08:53:34 +0200577 }
578 Do_ADBG_EndSubCase(c, "Invoke command");
579
580 Do_ADBG_BeginSubCase(c, "Invoke command with timeout");
581 {
582 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
583
584 op.params[0].value.a = 2000;
585 op.paramTypes = TEEC_PARAM_TYPES(
586 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
587
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300588 if (ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200589 xtest_teec_open_session(&session,
590 &os_test_ta_uuid,
591 NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300592 &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200593
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300594 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
595 TEEC_InvokeCommand(&session,
596 TA_OS_TEST_CMD_CLIENT_WITH_TIMEOUT,
597 &op, &ret_orig));
598 TEEC_CloseSession(&session);
599 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200600 }
601 Do_ADBG_EndSubCase(c, "Invoke command with timeout");
602
603 Do_ADBG_BeginSubCase(c, "Create session fail");
604 {
Jens Wiklanderb7940892015-10-23 16:02:40 +0200605 size_t n;
606
Pascal Brandc639ac82015-07-02 08:53:34 +0200607 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
608 xtest_teec_open_session(&session_crypt,
609 &create_fail_test_ta_uuid, NULL,
610 &ret_orig));
Pascal Brandc639ac82015-07-02 08:53:34 +0200611 /*
612 * Run this several times to see that there's no memory leakage.
613 */
614 for (n = 0; n < 100; n++) {
615 Do_ADBG_Log("n = %zu", n);
616 (void)ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_GENERIC,
617 xtest_teec_open_session(&session_crypt,
618 &create_fail_test_ta_uuid,
619 NULL, &ret_orig));
620 }
621 }
622 Do_ADBG_EndSubCase(c, "Create session fail");
Jens Wiklanderb7940892015-10-23 16:02:40 +0200623
David Brownb2865ab2016-08-02 11:44:41 -0600624 make_test_ta_dir();
625
Jens Wiklanderb7940892015-10-23 16:02:40 +0200626 Do_ADBG_BeginSubCase(c, "Load fake uuid TA");
627 load_fake_ta(c);
628 Do_ADBG_EndSubCase(c, "Load fake uuid TA");
629
Jens Wiklander4441fe22015-10-23 16:53:02 +0200630 Do_ADBG_BeginSubCase(c, "Load corrupt TA");
631 ADBG_EXPECT_TRUE(c,
632 load_corrupt_ta(c, offsetof(struct shdr, magic), 1));
633 ADBG_EXPECT_TRUE(c,
634 load_corrupt_ta(c, offsetof(struct shdr, img_type), 1));
635 ADBG_EXPECT_TRUE(c,
636 load_corrupt_ta(c, offsetof(struct shdr, img_size), 1));
637 ADBG_EXPECT_TRUE(c,
638 load_corrupt_ta(c, offsetof(struct shdr, algo), 1));
639 ADBG_EXPECT_TRUE(c,
640 load_corrupt_ta(c, offsetof(struct shdr, hash_size), 1));
641 ADBG_EXPECT_TRUE(c,
642 load_corrupt_ta(c, offsetof(struct shdr, sig_size), 1));
643 ADBG_EXPECT_TRUE(c,
644 load_corrupt_ta(c, sizeof(struct shdr), 1)); /* hash */
645 ADBG_EXPECT_TRUE(c,
646 load_corrupt_ta(c, sizeof(struct shdr) + 32, 1)); /* sig */
647 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 3000, 1)); /* payload */
648 ADBG_EXPECT_TRUE(c, load_corrupt_ta(c, 30000, 1)); /* payload */
649 Do_ADBG_EndSubCase(c, "Load corrupt TA");
Pascal Brandc639ac82015-07-02 08:53:34 +0200650}
651
Pascal Brandc639ac82015-07-02 08:53:34 +0200652static void *cancellation_thread(void *arg)
653{
654 /*
655 * Sleep 0.5 seconds before cancellation to make sure that the other
656 * thread is in RPC_WAIT.
657 */
658 (void)usleep(500000);
659 TEEC_RequestCancellation(arg);
660 return NULL;
661}
Pascal Brandc639ac82015-07-02 08:53:34 +0200662
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300663static void xtest_tee_test_1009_subcase(ADBG_Case_t *c, const char *subcase,
664 uint32_t timeout, bool cancel)
Pascal Brandc639ac82015-07-02 08:53:34 +0200665{
666 TEEC_Session session = { 0 };
667 uint32_t ret_orig;
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300668 pthread_t thr;
Pascal Brandc639ac82015-07-02 08:53:34 +0200669
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300670 Do_ADBG_BeginSubCase(c, "%s", subcase);
Pascal Brandc639ac82015-07-02 08:53:34 +0200671 {
672 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
673
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300674 if (ADBG_EXPECT_TEEC_SUCCESS(c,
675 xtest_teec_open_session(&session, &os_test_ta_uuid,
676 NULL, &ret_orig))) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200677
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300678 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c,
679 TEEC_ORIGIN_TRUSTED_APP,
680 ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200681
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300682 op.params[0].value.a = timeout;
683 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
684 TEEC_NONE,
685 TEEC_NONE, TEEC_NONE);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300686 if (cancel) {
687 (void)ADBG_EXPECT(c, 0,
688 pthread_create(&thr, NULL,
689 cancellation_thread, &op));
Pascal Brandc639ac82015-07-02 08:53:34 +0200690
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300691 (void)ADBG_EXPECT_TEEC_RESULT(c,
692 TEEC_ERROR_CANCEL,
693 TEEC_InvokeCommand(&session,
694 TA_OS_TEST_CMD_WAIT,
695 &op,
696 &ret_orig));
697 } else
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300698
699 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
700 TEEC_InvokeCommand(&session,
701 TA_OS_TEST_CMD_WAIT,
702 &op,
703 &ret_orig));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300704 if (cancel)
705 (void)ADBG_EXPECT(c, 0, pthread_join(thr, NULL));
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300706
707 TEEC_CloseSession(&session);
708 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200709 }
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300710 Do_ADBG_EndSubCase(c, "%s", subcase);
711}
712
713static void xtest_tee_test_1009(ADBG_Case_t *c)
714{
715 xtest_tee_test_1009_subcase(c, "TEE Wait 0.1s", 100, false);
716 xtest_tee_test_1009_subcase(c, "TEE Wait 0.5s", 500, false);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300717 xtest_tee_test_1009_subcase(c, "TEE Wait 2s cancel", 2000, true);
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300718 xtest_tee_test_1009_subcase(c, "TEE Wait 2s", 2000, false);
Pascal Brandc639ac82015-07-02 08:53:34 +0200719}
720
721static void xtest_tee_test_1010(ADBG_Case_t *c)
722{
723 unsigned n;
724
725 for (n = 1; n <= 5; n++) {
726 Do_ADBG_BeginSubCase(c, "Invalid memory access %u", n);
727 xtest_tee_test_invalid_mem_access(c, n);
728 Do_ADBG_EndSubCase(c, "Invalid memory access %u", n);
729 }
730}
731
732static void xtest_tee_test_1011(ADBG_Case_t *c)
733{
734 TEEC_Session session = { 0 };
735 uint32_t ret_orig;
736 struct xtest_crypto_session cs = {
737 c, &session, TA_RPC_CMD_CRYPT_SHA256,
738 TA_RPC_CMD_CRYPT_AES256ECB_ENC,
739 TA_RPC_CMD_CRYPT_AES256ECB_DEC
740 };
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100741 struct xtest_crypto_session cs_privmem = {
742 c, &session,
743 TA_RPC_CMD_CRYPT_PRIVMEM_SHA256,
744 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_ENC,
745 TA_RPC_CMD_CRYPT_PRIVMEM_AES256ECB_DEC
746 };
Pascal Brandc639ac82015-07-02 08:53:34 +0200747 TEEC_UUID uuid = rpc_test_ta_uuid;
748
749 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
750 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
751 return;
752
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100753 Do_ADBG_BeginSubCase(c, "TA-to-TA via non-secure shared memory");
Pascal Brandc639ac82015-07-02 08:53:34 +0200754 /*
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100755 * Run the "complete crypto test suite" using TA-to-TA
756 * communication
Pascal Brandc639ac82015-07-02 08:53:34 +0200757 */
758 xtest_crypto_test(&cs);
Jens Wiklanderf7b9c632017-01-03 17:32:26 +0100759 Do_ADBG_EndSubCase(c, "TA-to-TA via non-secure shared memory");
760
761 Do_ADBG_BeginSubCase(c, "TA-to-TA via TA private memory");
762 /*
763 * Run the "complete crypto test suite" using TA-to-TA
764 * communication via TA private memory.
765 */
766 xtest_crypto_test(&cs_privmem);
767 Do_ADBG_EndSubCase(c, "TA-to-TA via TA private memory");
768
Pascal Brandc639ac82015-07-02 08:53:34 +0200769 TEEC_CloseSession(&session);
770}
771
772/*
773 * Note that this test is failing when
774 * - running twice in a raw
775 * - and the user TA is statically linked
776 * This is because the counter is not reseted when opening the first session
777 * in case the TA is statically linked
778 */
779static void xtest_tee_test_1012(ADBG_Case_t *c)
780{
781 TEEC_Session session1 = { 0 };
782 TEEC_Session session2 = { 0 };
783 uint32_t ret_orig;
784 TEEC_UUID uuid = sims_test_ta_uuid;
785
786 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
787 {
788 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
789 static const uint8_t in[] = {
790 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
791 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
792 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
793 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
794 };
795 uint8_t out[32] = { 0 };
796 int i;
797
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300798 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200799 xtest_teec_open_session(&session1, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300800 &ret_orig)))
801 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200802
803 op.params[0].value.a = 0;
804 op.params[1].tmpref.buffer = (void *)in;
805 op.params[1].tmpref.size = sizeof(in);
806 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
807 TEEC_MEMREF_TEMP_INPUT,
808 TEEC_NONE, TEEC_NONE);
809
810 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
811 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
812 &ret_orig));
813
814 for (i = 1; i < 1000; i++) {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300815 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200816 xtest_teec_open_session(&session2, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300817 &ret_orig)))
818 continue;
Pascal Brandc639ac82015-07-02 08:53:34 +0200819
820 op.params[0].value.a = 0;
821 op.params[1].tmpref.buffer = out;
822 op.params[1].tmpref.size = sizeof(out);
823 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
824 TEEC_MEMREF_TEMP_OUTPUT,
825 TEEC_NONE, TEEC_NONE);
826
827 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
828 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
829 &op, &ret_orig));
830
831 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
832 sizeof(out))) {
833 Do_ADBG_Log("in:");
834 Do_ADBG_HexLog(in, sizeof(in), 16);
835 Do_ADBG_Log("out:");
836 Do_ADBG_HexLog(out, sizeof(out), 16);
837 }
838
839 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
840 TEEC_NONE, TEEC_NONE,
841 TEEC_NONE);
842
843 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
844 TEEC_InvokeCommand(&session1,
845 TA_SIMS_CMD_GET_COUNTER,
846 &op, &ret_orig));
847
848 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
849
850 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
851 TEEC_InvokeCommand(&session2,
852 TA_SIMS_CMD_GET_COUNTER, &op,
853 &ret_orig));
854
855 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
856 TEEC_CloseSession(&session2);
857 }
858
859 memset(out, 0, sizeof(out));
860 op.params[0].value.a = 0;
861 op.params[1].tmpref.buffer = out;
862 op.params[1].tmpref.size = sizeof(out);
863 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
864 TEEC_MEMREF_TEMP_OUTPUT,
865 TEEC_NONE, TEEC_NONE);
866
867 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
868 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
869 &ret_orig));
870
871 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
872 Do_ADBG_Log("in:");
873 Do_ADBG_HexLog(in, sizeof(in), 16);
874 Do_ADBG_Log("out:");
875 Do_ADBG_HexLog(out, sizeof(out), 16);
876 }
877
878 TEEC_CloseSession(&session1);
879 }
880}
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200881
882struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +0200883 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200884 uint32_t cmd;
885 uint32_t repeat;
886 TEEC_SharedMemory *shm;
887 uint32_t error_orig;
888 TEEC_Result res;
889 uint32_t max_concurrency;
890 const uint8_t *in;
891 size_t in_len;
892 uint8_t *out;
893 size_t out_len;
894};
895
896static void *test_1013_thread(void *arg)
897{
898 struct test_1013_thread_arg *a = arg;
899 TEEC_Session session = { 0 };
900 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
901 uint8_t p2 = TEEC_NONE;
902 uint8_t p3 = TEEC_NONE;
903
Jens Wiklander70672972016-04-06 00:01:45 +0200904 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200905 &a->error_orig);
906 if (a->res != TEEC_SUCCESS)
907 return NULL;
908
909 op.params[0].memref.parent = a->shm;
910 op.params[0].memref.size = a->shm->size;
911 op.params[0].memref.offset = 0;
912 op.params[1].value.a = a->repeat;
913 op.params[1].value.b = 0;
914 op.params[2].tmpref.buffer = (void *)a->in;
915 op.params[2].tmpref.size = a->in_len;
916 op.params[3].tmpref.buffer = a->out;
917 op.params[3].tmpref.size = a->out_len;
918
919 if (a->in_len)
920 p2 = TEEC_MEMREF_TEMP_INPUT;
921 if (a->out_len)
922 p3 = TEEC_MEMREF_TEMP_OUTPUT;
923
924 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
925 TEEC_VALUE_INOUT, p2, p3);
926
927 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
928 a->max_concurrency = op.params[1].value.b;
929 a->out_len = op.params[3].tmpref.size;
930 TEEC_CloseSession(&session);
931 return NULL;
932}
933
Pascal Brand4fa35582015-12-17 10:59:12 +0100934#define NUM_THREADS 3
935
Jens Wiklander70672972016-04-06 00:01:45 +0200936static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
937 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200938{
Pascal Brand4fa35582015-12-17 10:59:12 +0100939 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200940 size_t nt;
941 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +0200942 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200943 pthread_t thr[num_threads];
944 TEEC_SharedMemory shm;
945 size_t max_concurrency;
946 struct test_1013_thread_arg arg[num_threads];
947 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
948 static const uint8_t sha256_out[] = {
949 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
950 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
951 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
952 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
953 };
954 uint8_t out[32] = { 0 };
955
Jens Wiklander70672972016-04-06 00:01:45 +0200956 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +0100957 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200958
959 memset(&shm, 0, sizeof(shm));
960 shm.size = sizeof(struct ta_concurrent_shm);
961 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
962 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
963 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
964 return;
965
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200966 memset(shm.buffer, 0, shm.size);
967 memset(arg, 0, sizeof(arg));
968 max_concurrency = 0;
969 nt = num_threads;
970
971 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +0200972 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200973 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +0200974 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200975 arg[n].shm = &shm;
976 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
977 test_1013_thread, arg + n)))
978 nt = n; /* break loop and start cleanup */
979 }
980
981 for (n = 0; n < nt; n++) {
982 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
983 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
984 if (arg[n].max_concurrency > max_concurrency)
985 max_concurrency = arg[n].max_concurrency;
986 }
987
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200988 /*
989 * Concurrency can be limited by several factors, for instance in a
990 * single CPU system it's dependent on the Preemtion Model used by
991 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
992 * best result there).
993 */
994 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
995 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +0100996 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +0200997 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200998
Jens Wiklander70672972016-04-06 00:01:45 +0200999 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001000 memset(shm.buffer, 0, shm.size);
1001 memset(arg, 0, sizeof(arg));
1002 max_concurrency = 0;
1003 nt = num_threads;
1004
1005 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001006 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001007 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +02001008 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001009 arg[n].shm = &shm;
1010 arg[n].in = sha256_in;
1011 arg[n].in_len = sizeof(sha256_in);
1012 arg[n].out = out;
1013 arg[n].out_len = sizeof(out);
1014 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
1015 test_1013_thread, arg + n)))
1016 nt = n; /* break loop and start cleanup */
1017 }
1018
1019 for (n = 0; n < nt; n++) {
1020 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1021 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1022 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1023 arg[n].out, arg[n].out_len);
1024 if (arg[n].max_concurrency > max_concurrency)
1025 max_concurrency = arg[n].max_concurrency;
1026 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001027 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001028 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001029
Pascal Brand4fa35582015-12-17 10:59:12 +01001030 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001031 TEEC_ReleaseSharedMemory(&shm);
1032}
Pascal Brand4fa35582015-12-17 10:59:12 +01001033
1034static void xtest_tee_test_1013(ADBG_Case_t *c)
1035{
1036 int i;
1037 double mean_concurrency;
1038 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001039 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001040
1041 if (level == 0)
1042 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001043
Jens Wiklander70672972016-04-06 00:01:45 +02001044 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001045 mean_concurrency = 0;
1046 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001047 xtest_tee_test_1013_single(c, &concurrency,
1048 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001049 mean_concurrency += concurrency;
1050 }
1051 mean_concurrency /= nb_loops;
1052
1053 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1054 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001055 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001056
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001057#ifndef CFG_PAGED_USER_TA
Jens Wiklander70672972016-04-06 00:01:45 +02001058 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1059 mean_concurrency = 0;
1060 for (i = 0; i < nb_loops; i++) {
1061 xtest_tee_test_1013_single(c, &concurrency,
1062 &concurrent_large_ta_uuid);
1063 mean_concurrency += concurrency;
1064 }
1065 mean_concurrency /= nb_loops;
1066
1067 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1068 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1069 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001070#endif
Jens Wiklander70672972016-04-06 00:01:45 +02001071}