blob: ccd2761ca592220842fc555a794e2eadfea18c57 [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 Wiklander25a57fe2016-12-26 21:46:24 +010057 "Test RPC 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 };
741 TEEC_UUID uuid = rpc_test_ta_uuid;
742
743 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
744 xtest_teec_open_session(&session, &uuid, NULL, &ret_orig)))
745 return;
746
747 /*
748 * Run the "complete crypto test suite" using RPC
749 */
750 xtest_crypto_test(&cs);
751 TEEC_CloseSession(&session);
752}
753
754/*
755 * Note that this test is failing when
756 * - running twice in a raw
757 * - and the user TA is statically linked
758 * This is because the counter is not reseted when opening the first session
759 * in case the TA is statically linked
760 */
761static void xtest_tee_test_1012(ADBG_Case_t *c)
762{
763 TEEC_Session session1 = { 0 };
764 TEEC_Session session2 = { 0 };
765 uint32_t ret_orig;
766 TEEC_UUID uuid = sims_test_ta_uuid;
767
768 Do_ADBG_BeginSubCase(c, "Single Instance Multi Session");
769 {
770 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
771 static const uint8_t in[] = {
772 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
773 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
774 0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
775 0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
776 };
777 uint8_t out[32] = { 0 };
778 int i;
779
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300780 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200781 xtest_teec_open_session(&session1, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300782 &ret_orig)))
783 return;
Pascal Brandc639ac82015-07-02 08:53:34 +0200784
785 op.params[0].value.a = 0;
786 op.params[1].tmpref.buffer = (void *)in;
787 op.params[1].tmpref.size = sizeof(in);
788 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
789 TEEC_MEMREF_TEMP_INPUT,
790 TEEC_NONE, TEEC_NONE);
791
792 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
793 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_WRITE, &op,
794 &ret_orig));
795
796 for (i = 1; i < 1000; i++) {
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300797 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
Pascal Brandc639ac82015-07-02 08:53:34 +0200798 xtest_teec_open_session(&session2, &uuid, NULL,
Volodymyr Babchukae3dcd72016-10-20 16:51:59 +0300799 &ret_orig)))
800 continue;
Pascal Brandc639ac82015-07-02 08:53:34 +0200801
802 op.params[0].value.a = 0;
803 op.params[1].tmpref.buffer = out;
804 op.params[1].tmpref.size = sizeof(out);
805 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
806 TEEC_MEMREF_TEMP_OUTPUT,
807 TEEC_NONE, TEEC_NONE);
808
809 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
810 TEEC_InvokeCommand(&session2, TA_SIMS_CMD_READ,
811 &op, &ret_orig));
812
813 if (!ADBG_EXPECT_BUFFER(c, in, sizeof(in), out,
814 sizeof(out))) {
815 Do_ADBG_Log("in:");
816 Do_ADBG_HexLog(in, sizeof(in), 16);
817 Do_ADBG_Log("out:");
818 Do_ADBG_HexLog(out, sizeof(out), 16);
819 }
820
821 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
822 TEEC_NONE, TEEC_NONE,
823 TEEC_NONE);
824
825 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
826 TEEC_InvokeCommand(&session1,
827 TA_SIMS_CMD_GET_COUNTER,
828 &op, &ret_orig));
829
830 (void)ADBG_EXPECT(c, 0, op.params[0].value.a);
831
832 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
833 TEEC_InvokeCommand(&session2,
834 TA_SIMS_CMD_GET_COUNTER, &op,
835 &ret_orig));
836
837 (void)ADBG_EXPECT(c, i, op.params[0].value.a);
838 TEEC_CloseSession(&session2);
839 }
840
841 memset(out, 0, sizeof(out));
842 op.params[0].value.a = 0;
843 op.params[1].tmpref.buffer = out;
844 op.params[1].tmpref.size = sizeof(out);
845 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
846 TEEC_MEMREF_TEMP_OUTPUT,
847 TEEC_NONE, TEEC_NONE);
848
849 (void)ADBG_EXPECT_TEEC_SUCCESS(c,
850 TEEC_InvokeCommand(&session1, TA_SIMS_CMD_READ, &op,
851 &ret_orig));
852
853 if (!ADBG_EXPECT(c, 0, memcmp(in, out, sizeof(in)))) {
854 Do_ADBG_Log("in:");
855 Do_ADBG_HexLog(in, sizeof(in), 16);
856 Do_ADBG_Log("out:");
857 Do_ADBG_HexLog(out, sizeof(out), 16);
858 }
859
860 TEEC_CloseSession(&session1);
861 }
862}
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200863
864struct test_1013_thread_arg {
Jens Wiklander70672972016-04-06 00:01:45 +0200865 const TEEC_UUID *uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200866 uint32_t cmd;
867 uint32_t repeat;
868 TEEC_SharedMemory *shm;
869 uint32_t error_orig;
870 TEEC_Result res;
871 uint32_t max_concurrency;
872 const uint8_t *in;
873 size_t in_len;
874 uint8_t *out;
875 size_t out_len;
876};
877
878static void *test_1013_thread(void *arg)
879{
880 struct test_1013_thread_arg *a = arg;
881 TEEC_Session session = { 0 };
882 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
883 uint8_t p2 = TEEC_NONE;
884 uint8_t p3 = TEEC_NONE;
885
Jens Wiklander70672972016-04-06 00:01:45 +0200886 a->res = xtest_teec_open_session(&session, a->uuid, NULL,
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200887 &a->error_orig);
888 if (a->res != TEEC_SUCCESS)
889 return NULL;
890
891 op.params[0].memref.parent = a->shm;
892 op.params[0].memref.size = a->shm->size;
893 op.params[0].memref.offset = 0;
894 op.params[1].value.a = a->repeat;
895 op.params[1].value.b = 0;
896 op.params[2].tmpref.buffer = (void *)a->in;
897 op.params[2].tmpref.size = a->in_len;
898 op.params[3].tmpref.buffer = a->out;
899 op.params[3].tmpref.size = a->out_len;
900
901 if (a->in_len)
902 p2 = TEEC_MEMREF_TEMP_INPUT;
903 if (a->out_len)
904 p3 = TEEC_MEMREF_TEMP_OUTPUT;
905
906 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
907 TEEC_VALUE_INOUT, p2, p3);
908
909 a->res = TEEC_InvokeCommand(&session, a->cmd, &op, &a->error_orig);
910 a->max_concurrency = op.params[1].value.b;
911 a->out_len = op.params[3].tmpref.size;
912 TEEC_CloseSession(&session);
913 return NULL;
914}
915
Pascal Brand4fa35582015-12-17 10:59:12 +0100916#define NUM_THREADS 3
917
Jens Wiklander70672972016-04-06 00:01:45 +0200918static void xtest_tee_test_1013_single(ADBG_Case_t *c, double *mean_concurrency,
919 const TEEC_UUID *uuid)
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200920{
Pascal Brand4fa35582015-12-17 10:59:12 +0100921 size_t num_threads = NUM_THREADS;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200922 size_t nt;
923 size_t n;
Jens Wiklander70672972016-04-06 00:01:45 +0200924 size_t repeat = 1000;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200925 pthread_t thr[num_threads];
926 TEEC_SharedMemory shm;
927 size_t max_concurrency;
928 struct test_1013_thread_arg arg[num_threads];
929 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
930 static const uint8_t sha256_out[] = {
931 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
932 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
933 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
934 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
935 };
936 uint8_t out[32] = { 0 };
937
Jens Wiklander70672972016-04-06 00:01:45 +0200938 Do_ADBG_BeginSubCase(c, "Busy loop repeat %zu", repeat * 10);
Pascal Brand4fa35582015-12-17 10:59:12 +0100939 *mean_concurrency = 0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200940
941 memset(&shm, 0, sizeof(shm));
942 shm.size = sizeof(struct ta_concurrent_shm);
943 shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
944 if (!ADBG_EXPECT_TEEC_SUCCESS(c,
945 TEEC_AllocateSharedMemory(&xtest_teec_ctx, &shm)))
946 return;
947
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200948 memset(shm.buffer, 0, shm.size);
949 memset(arg, 0, sizeof(arg));
950 max_concurrency = 0;
951 nt = num_threads;
952
953 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +0200954 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200955 arg[n].cmd = TA_CONCURRENT_CMD_BUSY_LOOP;
Jens Wiklander70672972016-04-06 00:01:45 +0200956 arg[n].repeat = repeat * 10;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200957 arg[n].shm = &shm;
958 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
959 test_1013_thread, arg + n)))
960 nt = n; /* break loop and start cleanup */
961 }
962
963 for (n = 0; n < nt; n++) {
964 ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
965 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res);
966 if (arg[n].max_concurrency > max_concurrency)
967 max_concurrency = arg[n].max_concurrency;
968 }
969
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200970 /*
971 * Concurrency can be limited by several factors, for instance in a
972 * single CPU system it's dependent on the Preemtion Model used by
973 * the kernel (Preemptible Kernel (Low-Latency Desktop) gives the
974 * best result there).
975 */
976 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, >, 0);
977 (void)ADBG_EXPECT_COMPARE_UNSIGNED(c, max_concurrency, <=, num_threads);
Pascal Brand4fa35582015-12-17 10:59:12 +0100978 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +0200979 Do_ADBG_EndSubCase(c, "Busy loop repeat %zu", repeat * 10);
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200980
Jens Wiklander70672972016-04-06 00:01:45 +0200981 Do_ADBG_BeginSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200982 memset(shm.buffer, 0, shm.size);
983 memset(arg, 0, sizeof(arg));
984 max_concurrency = 0;
985 nt = num_threads;
986
987 for (n = 0; n < nt; n++) {
Jens Wiklander70672972016-04-06 00:01:45 +0200988 arg[n].uuid = uuid;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200989 arg[n].cmd = TA_CONCURRENT_CMD_SHA256;
Jens Wiklander70672972016-04-06 00:01:45 +0200990 arg[n].repeat = repeat;
Jens Wiklanderac27ec12015-07-15 15:23:14 +0200991 arg[n].shm = &shm;
992 arg[n].in = sha256_in;
993 arg[n].in_len = sizeof(sha256_in);
994 arg[n].out = out;
995 arg[n].out_len = sizeof(out);
996 if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
997 test_1013_thread, arg + n)))
998 nt = n; /* break loop and start cleanup */
999 }
1000
1001 for (n = 0; n < nt; n++) {
1002 if (ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL)) &&
1003 ADBG_EXPECT_TEEC_SUCCESS(c, arg[n].res))
1004 ADBG_EXPECT_BUFFER(c, sha256_out, sizeof(sha256_out),
1005 arg[n].out, arg[n].out_len);
1006 if (arg[n].max_concurrency > max_concurrency)
1007 max_concurrency = arg[n].max_concurrency;
1008 }
Pascal Brand4fa35582015-12-17 10:59:12 +01001009 *mean_concurrency += max_concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001010 Do_ADBG_EndSubCase(c, "SHA-256 loop repeat %zu", repeat);
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001011
Pascal Brand4fa35582015-12-17 10:59:12 +01001012 *mean_concurrency /= 2.0;
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001013 TEEC_ReleaseSharedMemory(&shm);
1014}
Pascal Brand4fa35582015-12-17 10:59:12 +01001015
1016static void xtest_tee_test_1013(ADBG_Case_t *c)
1017{
1018 int i;
1019 double mean_concurrency;
1020 double concurrency;
Jens Wiklander70672972016-04-06 00:01:45 +02001021 int nb_loops = 24;
Jens Wiklander6a9d15a2016-02-01 10:29:42 +01001022
1023 if (level == 0)
1024 nb_loops /= 2;
Pascal Brand4fa35582015-12-17 10:59:12 +01001025
Jens Wiklander70672972016-04-06 00:01:45 +02001026 Do_ADBG_BeginSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001027 mean_concurrency = 0;
1028 for (i = 0; i < nb_loops; i++) {
Jens Wiklander70672972016-04-06 00:01:45 +02001029 xtest_tee_test_1013_single(c, &concurrency,
1030 &concurrent_ta_uuid);
Pascal Brand4fa35582015-12-17 10:59:12 +01001031 mean_concurrency += concurrency;
1032 }
1033 mean_concurrency /= nb_loops;
1034
1035 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1036 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
Jens Wiklander70672972016-04-06 00:01:45 +02001037 Do_ADBG_EndSubCase(c, "Using small concurrency TA");
Pascal Brand4fa35582015-12-17 10:59:12 +01001038
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001039#ifndef CFG_PAGED_USER_TA
Jens Wiklander70672972016-04-06 00:01:45 +02001040 Do_ADBG_BeginSubCase(c, "Using large concurrency TA");
1041 mean_concurrency = 0;
1042 for (i = 0; i < nb_loops; i++) {
1043 xtest_tee_test_1013_single(c, &concurrency,
1044 &concurrent_large_ta_uuid);
1045 mean_concurrency += concurrency;
1046 }
1047 mean_concurrency /= nb_loops;
1048
1049 Do_ADBG_Log(" Number of parallel threads: %d", NUM_THREADS);
1050 Do_ADBG_Log(" Mean concurrency: %g", mean_concurrency);
1051 Do_ADBG_EndSubCase(c, "Using large concurrency TA");
Jens Wiklanderc9d7b242016-06-28 18:35:08 +02001052#endif
Jens Wiklander70672972016-04-06 00:01:45 +02001053}