blob: 9eca1dfe2d48f9e49ff8aa70ba2a455ebb5612a5 [file] [log] [blame]
Etienne Carriere75141172020-05-16 11:58:23 +02001// SPDX-License-Identifier: BSD-2-Clause
Pascal Brandc639ac82015-07-02 08:53:34 +02002/*
3 * Copyright (c) 2014, STMicroelectronics International N.V.
4 * All rights reserved.
Pascal Brandc639ac82015-07-02 08:53:34 +02005 */
Pascal Brandc639ac82015-07-02 08:53:34 +02006#include <compiler.h>
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01007#include <dlfcn.h>
Jerome Forissier4565c452020-06-17 17:55:00 +02008#include <link.h>
Jens Wiklander8324ff22018-11-21 14:16:04 +01009#include <setjmp.h>
10#include <stdint.h>
11#include <string.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020012#include <ta_crypt.h>
13#include <ta_os_test.h>
14#include <tee_internal_api_extensions.h>
15
16#include "os_test.h"
Jens Wiklander246184a2015-12-11 08:28:59 +010017#include "test_float_subj.h"
Jerome Forissier53bde722018-05-31 09:14:54 +020018#include "os_test_lib.h"
Pascal Brandc639ac82015-07-02 08:53:34 +020019
20enum p_type {
21 P_TYPE_BOOL,
22 P_TYPE_INT,
23 P_TYPE_UUID,
24 P_TYPE_IDENTITY,
25 P_TYPE_STRING,
26 P_TYPE_BINARY_BLOCK,
27};
28
29struct p_attr {
30 const char *str;
31 enum p_type type;
32 bool retrieved;
33};
34
Pascal Brand624b6a32016-02-16 12:51:34 +010035static TEE_Result check_returned_prop(
Pascal Brandaf77fdd2016-03-08 13:59:01 +010036 int line __maybe_unused, char *prop_name __maybe_unused,
Pascal Brand624b6a32016-02-16 12:51:34 +010037 TEE_Result return_res, TEE_Result expected_res,
38 uint32_t return_len, uint32_t expected_len)
39{
40 if (return_res != expected_res) {
41 EMSG("From line %d (property name=%s): return_res=0x%x vs expected_res=0x%x",
42 line, (prop_name ? prop_name : "unknown"),
43 (unsigned int)return_res, (unsigned int)expected_res);
44 return TEE_ERROR_GENERIC;
45 }
46 if (return_len != expected_len) {
Pascal Brand07bb09f2016-02-19 16:04:10 +010047 EMSG("From line %d (property name=%s): return_len=%u vs expected_res=%u",
48 line, (prop_name ? prop_name : "unknown"),
49 return_len, expected_len);
Pascal Brand624b6a32016-02-16 12:51:34 +010050 return TEE_ERROR_GENERIC;
51 }
52 return TEE_SUCCESS;
53}
54
Etienne Carriereb34caff2020-05-26 09:25:35 +020055static TEE_Result check_binprop_ones(size_t size, uint8_t *bbuf, size_t bblen)
56{
57 uint8_t ones[4] = { 0xff, 0xff, 0xff, 0xff };
58
59 if (size > 4 || bblen != size) {
60 EMSG("Size error (size=%zu, bblen=%zu)", size, bblen);
61 return TEE_ERROR_GENERIC;
62 }
63 if (strncmp(bbuf, ones, bblen)) {
64 EMSG("Unexpected content");
65 DHEXDUMP(bbuf, bblen);
66 return TEE_ERROR_GENERIC;
67 }
68 return TEE_SUCCESS;
69}
70
71static TEE_Result get_binblock_property(TEE_PropSetHandle h,
72 char *nbuf,
73 uint8_t **bbuf,
74 size_t *bblen)
75{
76 TEE_Result res = TEE_ERROR_GENERIC;
77
78 *bbuf = NULL;
79 *bblen = 0;
80 res = TEE_GetPropertyAsBinaryBlock(h, NULL, *bbuf, bblen);
81
82 if (res == TEE_SUCCESS && !*bblen)
83 return TEE_SUCCESS;
84
85 if (res != TEE_ERROR_SHORT_BUFFER) {
86 EMSG("TEE_GetPropertyAsBinaryBlock() size query returned 0x%x",
87 (unsigned int)res);
88 return res ? res : TEE_ERROR_GENERIC;
89 }
90
91 *bbuf = TEE_Malloc(*bblen, TEE_MALLOC_FILL_ZERO);
92 if (!bbuf)
93 return TEE_ERROR_OUT_OF_MEMORY;
94
95 res = TEE_GetPropertyAsBinaryBlock(h, NULL, *bbuf, bblen);
96 if (res != TEE_SUCCESS)
97 EMSG("TEE_GetPropertyAsBinaryBlock(\"%s\") returned 0x%x",
98 nbuf, (unsigned int)res);
99
100 return res;
101}
102
Pascal Brandc639ac82015-07-02 08:53:34 +0200103static TEE_Result print_properties(TEE_PropSetHandle h,
104 TEE_PropSetHandle prop_set,
105 struct p_attr *p_attrs, size_t num_p_attrs)
106{
Etienne Carriere102092e2019-03-28 15:24:22 +0100107TEE_Result res = TEE_ERROR_GENERIC;
108size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200109
110TEE_StartPropertyEnumerator(h, prop_set);
111
112while (true) {
Etienne Carriere102092e2019-03-28 15:24:22 +0100113 char nbuf[256] = { };
114 char nbuf_small[256] = { };
115 char vbuf[256] = { };
116 char vbuf2[256] = { };
Jens Wiklanderc5231592015-11-11 09:27:27 +0100117 uint32_t nblen = sizeof(nbuf);
Etienne Carriere102092e2019-03-28 15:24:22 +0100118 uint32_t nblen_small = 0;
Jens Wiklanderc5231592015-11-11 09:27:27 +0100119 uint32_t vblen = sizeof(vbuf);
120 uint32_t vblen2 = sizeof(vbuf2);
Etienne Carriereb34caff2020-05-26 09:25:35 +0200121 uint8_t *bbuf = NULL;
122 size_t bblen = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200123
124 res = TEE_GetPropertyName(h, nbuf, &nblen);
125 if (res != TEE_SUCCESS) {
126 EMSG("TEE_GetPropertyName returned 0x%x\n",
127 (unsigned int)res);
128 return res;
129 }
Pascal Brand624b6a32016-02-16 12:51:34 +0100130 if (nblen != strlen(nbuf) + 1) {
Pascal Brand5b68cd62016-02-22 10:31:01 +0100131 EMSG("Name has wrong size: %u vs %zu", nblen, strlen(nbuf) + 1);
Pascal Brand624b6a32016-02-16 12:51:34 +0100132 return TEE_ERROR_GENERIC;
133 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200134
Pascal Brand624b6a32016-02-16 12:51:34 +0100135
136 /* Get the property name with a very small buffer */
137 nblen_small = 2;
138 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
139 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
140 nblen_small, nblen);
141 if (res != TEE_SUCCESS)
142 return res;
143
144 /* Get the property name with almost the correct buffer */
145 nblen_small = nblen - 1;
146 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
147 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
148 nblen_small, nblen);
149 if (res != TEE_SUCCESS)
150 return res;
151
152 /* Get the property name with the exact buffer length */
153 nblen_small = nblen;
154 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
155 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
156 nblen_small, nblen);
157 if (res != TEE_SUCCESS)
158 return res;
159
160 /* Get the property value */
Pascal Brandc639ac82015-07-02 08:53:34 +0200161 res = TEE_GetPropertyAsString(h, NULL, vbuf, &vblen);
Pascal Brand624b6a32016-02-16 12:51:34 +0100162 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
163 vblen, strlen(vbuf) + 1);
164 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200165 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100166
Pascal Brandc639ac82015-07-02 08:53:34 +0200167 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
Pascal Brand624b6a32016-02-16 12:51:34 +0100168 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
169 vblen2, strlen(vbuf2) + 1);
170 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200171 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100172
Jens Wiklander8324ff22018-11-21 14:16:04 +0100173 if (strcmp(vbuf, vbuf2) != 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200174 EMSG("String of \"%s\" differs\n", nbuf);
175 return TEE_ERROR_GENERIC;
176 }
177
Pascal Brand624b6a32016-02-16 12:51:34 +0100178 /* Get the property with a very small buffer */
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200179 if (vblen > 1) {
180 vblen2 = 1;
181 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
182 res = check_returned_prop(__LINE__, nbuf, res,
183 TEE_ERROR_SHORT_BUFFER,
184 vblen2, vblen);
185 if (res != TEE_SUCCESS)
186 return res;
187 }
Pascal Brand624b6a32016-02-16 12:51:34 +0100188
189 /* Get the property with almost the correct buffer */
190 vblen2 = vblen - 1;
191 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
192 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
193 vblen2, vblen);
194 if (res != TEE_SUCCESS)
195 return res;
196
197 /* Get the property name with the exact buffer length */
198 vblen2 = vblen;
199 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
200 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS, vblen2, vblen);
201 if (res != TEE_SUCCESS)
202 return res;
203
204 /* check specific myprop.hello property, which is larger than 80 */
205 if (!strcmp("myprop.hello", nbuf) &&
206 vblen2 != 1 + strlen("hello property, larger than 80 characters, so that it checks that it is not truncated by anything in the source code which may be wrong")) {
207 EMSG("TEE_GetPropertyAsString(\"%s\") is truncated - returned \"%s\"\n",
208 nbuf, vbuf);
209 return TEE_ERROR_GENERIC;
210 }
211
Pascal Brandc639ac82015-07-02 08:53:34 +0200212 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
213
214 for (n = 0; n < num_p_attrs; n++) {
Jens Wiklander8324ff22018-11-21 14:16:04 +0100215 if (strcmp(nbuf, p_attrs[n].str) != 0)
Pascal Brandc639ac82015-07-02 08:53:34 +0200216 continue;
217
218 if (p_attrs[n].retrieved) {
219 EMSG("Value \"%s\" already retrieved\n",
220 p_attrs[n].str);
221 return TEE_ERROR_GENERIC;
222 }
223 p_attrs[n].retrieved = true;
224
225 switch (p_attrs[n].type) {
226 case P_TYPE_BOOL:
227 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100228 bool v = false;
Pascal Brandc639ac82015-07-02 08:53:34 +0200229
230 res =
231 TEE_GetPropertyAsBool(h, NULL, &v);
232 if (res != TEE_SUCCESS) {
233 EMSG(
234 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
235 nbuf, (unsigned int)res);
236 return res;
237 }
238 }
239 break;
240
241 case P_TYPE_INT:
242 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100243 uint32_t v = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200244
245 res = TEE_GetPropertyAsU32(h, NULL, &v);
246 if (res != TEE_SUCCESS) {
247 EMSG(
248 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
249 nbuf, (unsigned int)res);
250 return res;
251 }
252 }
253 break;
254
255 case P_TYPE_UUID:
256 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100257 TEE_UUID v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200258
259 res =
260 TEE_GetPropertyAsUUID(h, NULL, &v);
261 if (res != TEE_SUCCESS) {
262 EMSG(
263 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
264 nbuf, (unsigned int)res);
265 return res;
266 }
267 }
268 break;
269
270 case P_TYPE_IDENTITY:
271 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100272 TEE_Identity v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200273
274 res =
275 TEE_GetPropertyAsIdentity(h, NULL,
276 &v);
277 if (res != TEE_SUCCESS) {
278 EMSG(
279 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
280 nbuf, (unsigned int)res);
281 return res;
282 }
283 }
284 break;
285
286 case P_TYPE_STRING:
287 /* Already read as string */
288 break;
289
290 case P_TYPE_BINARY_BLOCK:
Etienne Carriereb34caff2020-05-26 09:25:35 +0200291 res = get_binblock_property(h, nbuf, &bbuf, &bblen);
292 if (res)
293 return res;
Pascal Brandc639ac82015-07-02 08:53:34 +0200294
Etienne Carriereb34caff2020-05-26 09:25:35 +0200295 if (!strcmp("myprop.binaryblock", nbuf)) {
296 const char exp_bin_value[] = "Hello world!";
297
298 if (bblen != strlen(exp_bin_value) ||
299 TEE_MemCompare(exp_bin_value, bbuf,
300 bblen)) {
301 EMSG("Binary buffer of \"%s\" differs from \"%s\"",
302 nbuf, exp_bin_value);
303 EMSG("Got \"%s\"", bbuf);
304 return TEE_ERROR_GENERIC;
305 }
306 } else if (!strcmp("myprop.binaryblock.1byte-ones",
307 nbuf)) {
308 res = check_binprop_ones(1, bbuf, bblen);
309 if (res)
Pascal Brandc639ac82015-07-02 08:53:34 +0200310 return res;
Etienne Carriereb34caff2020-05-26 09:25:35 +0200311 } else if (!strcmp("myprop.binaryblock.2byte-ones",
312 nbuf)) {
313 res = check_binprop_ones(2, bbuf, bblen);
314 if (res)
315 return res;
316 } else if (!strcmp("myprop.binaryblock.3byte-ones",
317 nbuf)) {
318 res = check_binprop_ones(3, bbuf, bblen);
319 if (res)
320 return res;
321 } else if (!strcmp("myprop.binaryblock.4byte-ones",
322 nbuf)) {
323 res = check_binprop_ones(4, bbuf, bblen);
324 if (res)
325 return res;
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200326 } else if (!strcmp("myprop.binaryblock.empty1", nbuf) ||
327 !strcmp("myprop.binaryblock.empty2", nbuf) ||
328 !strcmp("myprop.binaryblock.empty3", nbuf)) {
329 if (bblen) {
330 EMSG("Property \"%s\": %zu byte(s)",
331 nbuf, bblen);
332 return TEE_ERROR_GENERIC;
333 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200334 } else {
335 EMSG("Unexpected property \"%s\"", nbuf);
336 TEE_Panic(0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200337 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200338
339 TEE_Free(bbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200340 break;
341
342 default:
343 EMSG("Unknown type (%d) for \"%s\"\n",
344 p_attrs[n].type, p_attrs[n].str);
345 return TEE_ERROR_GENERIC;
346 }
347 }
348
349 res = TEE_GetNextProperty(h);
350 if (res != TEE_SUCCESS) {
351 if (res == TEE_ERROR_ITEM_NOT_FOUND)
352 return TEE_SUCCESS;
353 return res;
354 }
355}
356}
357
358static TEE_Result test_malloc(void)
359{
360 void *p = TEE_Malloc(4, 0);
361
362 if (p == NULL) {
363 EMSG("TEE_Malloc failed\n");
364 return TEE_ERROR_OUT_OF_MEMORY;
365 }
366 TEE_Free(p);
367 TEE_Free(NULL);
368
369 return TEE_SUCCESS;
370}
371
372static TEE_Result test_properties(void)
373{
374 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriere102092e2019-03-28 15:24:22 +0100375 TEE_PropSetHandle h = TEE_HANDLE_NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200376 struct p_attr p_attrs[] = {
377 {"gpd.ta.appID", P_TYPE_UUID},
378 {"gpd.ta.singleInstance", P_TYPE_BOOL},
379 {"gpd.ta.multiSession", P_TYPE_BOOL},
380 {"gpd.ta.instanceKeepAlive", P_TYPE_BOOL},
381 {"gpd.ta.dataSize", P_TYPE_INT},
382 {"gpd.ta.stackSize", P_TYPE_INT},
383 {"gpd.ta.version", P_TYPE_STRING},
384 {"gpd.ta.description", P_TYPE_STRING},
385 {"gpd.client.identity", P_TYPE_IDENTITY},
386 {"gpd.tee.apiversion", P_TYPE_STRING},
387 {"gpd.tee.description", P_TYPE_STRING},
388 {"gpd.tee.deviceID", P_TYPE_UUID},
389 {"gpd.tee.systemTime.protectionLevel", P_TYPE_INT},
390 {"gpd.tee.TAPersistentTime.protectionLevel", P_TYPE_INT},
391 {"gpd.tee.arith.maxBigIntSize", P_TYPE_INT},
392 {"gpd.tee.cryptography.ecc", P_TYPE_BOOL},
393 {"gpd.tee.trustedStorage.antiRollback.protectionLevel", P_TYPE_INT},
394 {"gpd.tee.trustedos.implementation.version", P_TYPE_STRING},
395 {"gpd.tee.trustedos.implementation.binaryversion", P_TYPE_INT},
396 {"gpd.tee.trustedos.manufacturer", P_TYPE_STRING},
397 {"gpd.tee.firmware.implementation.version", P_TYPE_STRING},
398 {"gpd.tee.firmware.implementation.binaryversion", P_TYPE_INT},
399 {"gpd.tee.firmware.manufacturer", P_TYPE_STRING},
400 {"myprop.true", P_TYPE_BOOL},
401 {"myprop.42", P_TYPE_INT},
402 {"myprop.123", P_TYPE_UUID},
403 {"myprop.1234", P_TYPE_IDENTITY},
404 {"myprop.hello", P_TYPE_STRING},
405 {"myprop.binaryblock", P_TYPE_BINARY_BLOCK},
Etienne Carriereb34caff2020-05-26 09:25:35 +0200406 {"myprop.binaryblock.1byte-ones", P_TYPE_BINARY_BLOCK},
407 {"myprop.binaryblock.2byte-ones", P_TYPE_BINARY_BLOCK},
408 {"myprop.binaryblock.3byte-ones", P_TYPE_BINARY_BLOCK},
409 {"myprop.binaryblock.4byte-ones", P_TYPE_BINARY_BLOCK},
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200410 {"myprop.binaryblock.empty1", P_TYPE_BINARY_BLOCK},
411 {"myprop.binaryblock.empty2", P_TYPE_BINARY_BLOCK},
412 {"myprop.binaryblock.empty3", P_TYPE_BINARY_BLOCK},
Pascal Brandc639ac82015-07-02 08:53:34 +0200413 };
414 const size_t num_p_attrs = sizeof(p_attrs) / sizeof(p_attrs[0]);
Etienne Carriere102092e2019-03-28 15:24:22 +0100415 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200416
417 res = TEE_AllocatePropertyEnumerator(&h);
418 if (res != TEE_SUCCESS) {
419 EMSG("TEE_AllocatePropertyEnumerator: returned 0x%x\n",
420 (unsigned int)res);
421 return TEE_ERROR_GENERIC;
422 }
423
424 printf("Getting properties for current TA\n");
425 res = print_properties(h, TEE_PROPSET_CURRENT_TA, p_attrs, num_p_attrs);
426 if (res != TEE_SUCCESS)
427 goto cleanup_return;
428
429 printf("Getting properties for current client\n");
430 res = print_properties(h, TEE_PROPSET_CURRENT_CLIENT, p_attrs,
431 num_p_attrs);
432 if (res != TEE_SUCCESS)
433 goto cleanup_return;
434
435 printf("Getting properties for implementation\n");
436 res = print_properties(h, TEE_PROPSET_TEE_IMPLEMENTATION, p_attrs,
437 num_p_attrs);
438 if (res != TEE_SUCCESS)
439 goto cleanup_return;
440
441 for (n = 0; n < num_p_attrs; n++) {
442 if (!p_attrs[n].retrieved) {
443 EMSG("\"%s\" not retrieved\n", p_attrs[n].str);
444 res = TEE_ERROR_GENERIC;
445 goto cleanup_return;
446 }
447 }
448
449cleanup_return:
450 TEE_FreePropertyEnumerator(h);
451 return res;
452}
453
454static TEE_Result test_mem_access_right(uint32_t param_types,
455 TEE_Param params[4])
456{
457 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100458 TEE_Result res = TEE_ERROR_GENERIC;
459 uint32_t ret_orig = 0;
460 uint32_t l_pts = 0;
461 TEE_Param l_params[4] = { };
462 uint8_t buf[32] = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200463 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100464 TEE_UUID *uuid = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200465
466 if (param_types !=
467 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
468 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200469
470 /* test access rights on memref parameter */
471 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
472 TEE_MEMORY_ACCESS_ANY_OWNER,
473 params[0].memref.buffer,
474 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200475 if (res != TEE_SUCCESS)
476 return res;
Etienne Carriere281065d2016-10-28 15:41:33 +0200477
Pascal Brandc639ac82015-07-02 08:53:34 +0200478 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
479 params[0].memref.buffer,
480 params[0].memref.size);
481 if (res != TEE_ERROR_ACCESS_DENIED)
482 return TEE_ERROR_GENERIC;
483
Etienne Carriere281065d2016-10-28 15:41:33 +0200484 /* test access rights on private read-only and read-write memory */
485 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
486 (void *)&test_uuid, sizeof(test_uuid));
487 if (res != TEE_SUCCESS)
488 return res;
489
490 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_WRITE,
491 (void *)&test_uuid, sizeof(test_uuid));
492 if (res == TEE_SUCCESS)
493 return TEE_ERROR_GENERIC;
494
495 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
496 TEE_MEMORY_ACCESS_WRITE,
497 &ret_orig, sizeof(ret_orig));
498 if (res != TEE_SUCCESS)
499 return res;
500
501 uuid = TEE_Malloc(sizeof(*uuid), 0);
502 if (!uuid)
503 return TEE_ERROR_OUT_OF_MEMORY;
504
505 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
506 TEE_MEMORY_ACCESS_WRITE,
507 uuid, sizeof(*uuid));
508 TEE_Free(uuid);
509 if (res != TEE_SUCCESS)
510 return res;
511
512 /* test access rights on invalid memory (at least lower 256kB) */
513 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
514 NULL, 1);
515 if (res == TEE_SUCCESS)
516 return TEE_ERROR_GENERIC;
517
518 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
519 (void*)(256 * 1024), 1);
520 if (res == TEE_SUCCESS)
521 return TEE_ERROR_GENERIC;
522
Cedric Augere668b3f2019-09-11 13:41:21 +0200523 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
524 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200525 if (res != TEE_SUCCESS) {
526 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
527 goto cleanup_return;
528 }
529
Jerome Forissier04511d82018-01-30 14:33:49 +0100530 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
531 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200532 l_params[0].memref.buffer = buf;
533 l_params[0].memref.size = sizeof(buf);
Jerome Forissier04511d82018-01-30 14:33:49 +0100534 l_params[1].memref.buffer = NULL;
535 l_params[1].memref.size = 0;
Cedric Augere668b3f2019-09-11 13:41:21 +0200536 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
537 TA_OS_TEST_CMD_PARAMS_ACCESS,
Pascal Brandc639ac82015-07-02 08:53:34 +0200538 l_pts, l_params, &ret_orig);
539 if (res != TEE_SUCCESS) {
540 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
541 goto cleanup_return;
542 }
543
544cleanup_return:
545 TEE_CloseTASession(sess);
546 return res;
547}
548
549static TEE_Result test_time(void)
550{
Etienne Carriere102092e2019-03-28 15:24:22 +0100551 TEE_Result res = TEE_ERROR_GENERIC;
552 TEE_Time t = { };
553 TEE_Time sys_t = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200554 static const TEE_Time null_time = { 0, 0 };
555 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
556
557 TEE_GetSystemTime(&sys_t);
558 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
559 (unsigned int)sys_t.millis);
560
561 TEE_GetREETime(&t);
562 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
563 (unsigned int)t.millis);
564
565 res = TEE_GetTAPersistentTime(&t);
566 switch (res) {
567 case TEE_SUCCESS:
568 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
569 (unsigned int)t.millis);
570 break;
571 case TEE_ERROR_OVERFLOW:
572 EMSG("Stored TA time overflowed %u.%03u\n",
573 (unsigned int)t.seconds, (unsigned int)t.millis);
574 break;
575 case TEE_ERROR_TIME_NOT_SET:
576 EMSG("TA time not stored\n");
577 break;
578 case TEE_ERROR_TIME_NEEDS_RESET:
579 EMSG("TA time needs reset\n");
580 break;
581 default:
582 return res;
583 }
584
585 res = TEE_SetTAPersistentTime(&null_time);
586 if (res != TEE_SUCCESS) {
587 EMSG("TEE_SetTAPersistentTime: failed\n");
588 return res;
589 }
590
591 res = TEE_GetTAPersistentTime(&t);
592 if (res != TEE_SUCCESS) {
593 EMSG("TEE_GetTAPersistentTime null: failed\n");
594 return res;
595 }
596 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
597 (unsigned int)t.millis);
598 /*
599 * The time between TEE_SetTAPersistentTime() and
600 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
601 * it's not even a millisecond.
602 */
603 if (t.seconds > 1 || t.millis >= 1000) {
604 EMSG("Unexpected stored TA time %u.%03u\n",
605 (unsigned int)t.seconds, (unsigned int)t.millis);
606 return TEE_ERROR_BAD_STATE;
607 }
608
609 res = TEE_SetTAPersistentTime(&wrap_time);
610 if (res != TEE_SUCCESS) {
611 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
612 return res;
613 }
614
615 res = TEE_Wait(1000);
616 if (res != TEE_SUCCESS)
617 EMSG("TEE_Wait wrap: failed\n");
618
619 res = TEE_GetTAPersistentTime(&t);
620 if (res != TEE_ERROR_OVERFLOW) {
621 EMSG("TEE_GetTAPersistentTime: failed\n");
622 return TEE_ERROR_BAD_STATE;
623 }
624 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
625 (unsigned int)t.millis);
626
627 if (t.seconds > sys_t.seconds) {
628 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
629 (unsigned int)t.seconds, (unsigned int)t.millis,
630 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
631 return TEE_ERROR_BAD_STATE;
632 }
633
634 return TEE_SUCCESS;
635}
636
Jens Wiklander246184a2015-12-11 08:28:59 +0100637#ifdef CFG_TA_FLOAT_SUPPORT
638static bool my_dcmpeq(double v1, double v2, double prec)
639{
640 return v1 > (v2 - prec) && v1 < (v2 + prec);
641}
642
643static bool my_fcmpeq(float v1, float v2, float prec)
644{
645 return v1 > (v2 - prec) && v1 < (v2 + prec);
646}
647
648
649static TEE_Result test_float(void)
650{
651#define VAL1 2.6
652#define VAL1_INT 2
653#define VAL2 5.3
654#define DPREC 0.000000000000001
655#define FPREC 0.000001
656#define EXPECT(expr) do { \
657 if (!(expr)) { \
658 EMSG("Expression %s failed", #expr); \
659 return TEE_ERROR_GENERIC; \
660 } \
661 } while (0)
662
663 IMSG("Testing floating point operations");
664
665 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
666 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
667 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
668 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
669 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
670
671 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
672 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
673 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
674 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
675 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
676
677 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
678 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
679 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
680 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
681 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
682
683 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
684 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
685 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
686 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
687 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
688
689 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
690 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
691 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
692 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
693
694 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
695 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
696 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
697 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
698
699 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
700 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
701
702 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
703 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
704 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
705 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
706
707 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
708 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
709 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
710 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
711 return TEE_SUCCESS;
712}
713#else /*CFG_TA_FLOAT_SUPPORT*/
714static TEE_Result test_float(void)
715{
716 IMSG("Floating point disabled");
717 return TEE_SUCCESS;
718}
719#endif /*CFG_TA_FLOAT_SUPPORT*/
720
Jerome Forissier892ae4d2020-03-09 09:58:09 +0100721static __noinline __noreturn void call_longjmp(jmp_buf env)
Jens Wiklander9f682c62016-03-27 20:23:06 +0200722{
723 DMSG("Calling longjmp");
724 longjmp(env, 1);
725 EMSG("error: longjmp returned to calling function");
726}
727
728static TEE_Result test_setjmp(void)
729{
Etienne Carriere102092e2019-03-28 15:24:22 +0100730 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200731
732 if (setjmp(env)) {
733 IMSG("Returned via longjmp");
734 return TEE_SUCCESS;
735 } else {
736 call_longjmp(env);
737 return TEE_ERROR_GENERIC;
738 }
739}
740
Pascal Brandc639ac82015-07-02 08:53:34 +0200741TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
742{
743 TEE_Result res = TEE_ERROR_GENERIC;
744
745 printf("ta_entry_basic: enter\n");
746
747 res = test_malloc();
748 if (res != TEE_SUCCESS)
749 return res;
750
751 res = test_properties();
752 if (res != TEE_SUCCESS)
753 return res;
754
755 res = test_mem_access_right(param_types, params);
756 if (res != TEE_SUCCESS)
757 return res;
758
759 res = test_time();
760 if (res != TEE_SUCCESS)
761 return res;
762
Jens Wiklander246184a2015-12-11 08:28:59 +0100763 res = test_float();
764 if (res != TEE_SUCCESS)
765 return res;
766
Jens Wiklander9f682c62016-03-27 20:23:06 +0200767 res = test_setjmp();
768 if (res != TEE_SUCCESS)
769 return res;
770
Pascal Brandc639ac82015-07-02 08:53:34 +0200771 return TEE_SUCCESS;
772}
773
774TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
775{
776 volatile bool mytrue = true;
777 (void)param_types;
778 (void)params;
779
780 printf("ta_entry_panic: enter\n");
781 /*
782 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
783 * the __noreturn attribute.
784 */
785 if (mytrue)
786 TEE_Panic(0xbeef);
787
788 /*
789 * Should not be reached, but if it is the testsuite can detect that
790 * TEE_Panic() returned instead of panicking the TA.
791 */
792 return TEE_SUCCESS;
793}
794
795TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
796 TEE_Param params[4])
797{
798 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100799 TEE_Result res = TEE_ERROR_GENERIC;
800 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
801 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200802
803 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
804 TEE_PARAM_TYPE_NONE,
805 TEE_PARAM_TYPE_NONE,
806 TEE_PARAM_TYPE_NONE)) {
807 EMSG("ta_entry_client_with_timeout: bad parameters\n");
808 return TEE_ERROR_BAD_PARAMETERS;
809 }
810
Cedric Augere668b3f2019-09-11 13:41:21 +0200811 res = TEE_OpenTASession(&os_test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
812 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200813 if (res != TEE_SUCCESS) {
814 EMSG(
815 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
816 return res;
817 }
818
819 res =
820 TEE_InvokeTACommand(sess, params[0].value.a / 2,
821 TA_OS_TEST_CMD_WAIT, param_types, params,
822 &ret_orig);
823
824 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
825 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
826 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
827 (unsigned int)ret_orig);
828 res = TEE_ERROR_GENERIC;
829 } else
830 res = TEE_SUCCESS;
831
832 TEE_CloseTASession(sess);
833 return res;
834
835}
836
837TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
838{
839 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100840 TEE_Result res = TEE_ERROR_GENERIC;
841 uint32_t l_pts = 0;
842 TEE_Param l_params[4] = { };
843 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
844 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200845 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
846 static const uint8_t sha256_out[] = {
847 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
848 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
849 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
850 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
851 };
852 uint8_t out[32] = { 0 };
853 void *in = NULL;
854
855 (void)param_types;
856 (void)params;
857
858 printf("ta_entry_client: enter\n");
859
860 in = TEE_Malloc(sizeof(sha256_in), 0);
861 if (in == NULL)
862 return TEE_ERROR_OUT_OF_MEMORY;
863 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
864
Cedric Augere668b3f2019-09-11 13:41:21 +0200865 res = TEE_OpenTASession(&crypt_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
866 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200867 if (res != TEE_SUCCESS) {
868 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
869 goto cleanup_return;
870 }
871
872 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
873 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
874 l_params[0].memref.buffer = in;
875 l_params[0].memref.size = sizeof(sha256_in);
876 l_params[1].memref.buffer = out;
877 l_params[1].memref.size = sizeof(out);
878
Cedric Augere668b3f2019-09-11 13:41:21 +0200879 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
880 TA_CRYPT_CMD_SHA256, l_pts, l_params,
Pascal Brandc639ac82015-07-02 08:53:34 +0200881 &ret_orig);
882 if (res != TEE_SUCCESS) {
883 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
884 goto cleanup_return;
885 }
886
887 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
888 EMSG("ta_entry_client: out parameter failed\n");
889 res = TEE_ERROR_GENERIC;
890 goto cleanup_return;
891 }
892
893cleanup_return:
894 TEE_Free(in);
895 TEE_CloseTASession(sess);
896 return res;
897}
898
Etienne Carriere281065d2016-10-28 15:41:33 +0200899TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200900{
Etienne Carriere102092e2019-03-28 15:24:22 +0100901 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200902
903 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100904 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
905 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200906 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200907
908 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
909 TEE_MEMORY_ACCESS_ANY_OWNER,
910 params[0].memref.buffer,
911 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200912 if (res != TEE_SUCCESS)
913 return res;
914
915 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
916 params[0].memref.buffer,
917 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200918 if (res != TEE_ERROR_ACCESS_DENIED)
919 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +0100920 if (params[1].memref.buffer || params[1].memref.size)
921 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200922
Etienne Carriere281065d2016-10-28 15:41:33 +0200923 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200924}
925
926TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
927{
928 TEE_Result res = TEE_SUCCESS;
929 (void)param_types;
930
931 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
932 /* Wait */
933 res = TEE_Wait(params[0].value.a);
934
935 return res;
936}
937
Jens Wiklander1425f952016-07-21 09:02:30 +0200938static void undef_instr(void)
939{
940#if defined(ARM64)
941 __asm__(".word 0x0");
942#elif defined(ARM32)
943 __asm__(".word 0xe7ffffff");
944#else
945#error "Unsupported architecture"
946#endif
947}
948
Pascal Brandc639ac82015-07-02 08:53:34 +0200949TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
950{
Etienne Carriere102092e2019-03-28 15:24:22 +0100951 long int stack = 0;
952 long int stack_addr = (long int)&stack;
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200953 void (*volatile null_fn_ptr)(void) = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200954
Etienne Carriere92c34422018-02-09 13:11:40 +0100955 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
956 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
957 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200958 return TEE_ERROR_GENERIC;
959
960 switch (params[0].value.a) {
961 case 1:
Jerome Forissier71da60f2019-09-19 15:59:56 +0200962 *((volatile uint32_t *)0) = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200963 break;
964 case 2:
965 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
966 break;
967 case 3:
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200968 null_fn_ptr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200969 break;
970 case 4:
971 ((void (*)(void))(stack_addr + 0x40000000)) ();
972 break;
973 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +0200974 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200975 break;
976 default:
977 break;
978 }
979
980 return TEE_SUCCESS;
981}
Jerome Forissiere916b102017-06-07 17:55:52 +0200982
983static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
984{
Etienne Carriere102092e2019-03-28 15:24:22 +0100985 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +0200986
987 for (i = 0; i < bufsize; i++) {
988 a[i]++; b[i]++; c[i]++;
989 }
990}
991
Etienne Carriere102092e2019-03-28 15:24:22 +0100992#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +0200993TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
994{
995 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
996 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100997 TEE_Param l_params[4] = { };
998 uint8_t in[TA2TA_BUF_SIZE] = { };
999 uint8_t inout[TA2TA_BUF_SIZE] = { };
1000 uint8_t out[TA2TA_BUF_SIZE] = { };
1001 TEE_Result res = TEE_ERROR_GENERIC;
1002 uint32_t ret_orig = 0;
1003 uint32_t l_pts = 0;
1004 size_t i = 0;
1005
Jerome Forissiere916b102017-06-07 17:55:52 +02001006 (void)params;
1007
1008 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
1009 return TEE_ERROR_GENERIC;
1010
Cedric Augere668b3f2019-09-11 13:41:21 +02001011 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
1012 &sess, &ret_orig);
Jerome Forissiere916b102017-06-07 17:55:52 +02001013 if (res != TEE_SUCCESS) {
1014 EMSG("TEE_OpenTASession failed");
1015 goto cleanup_return;
1016 }
1017
1018 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1019 TEE_PARAM_TYPE_MEMREF_INOUT,
1020 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
1021 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +01001022 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001023 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +01001024 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001025 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +01001026 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001027
1028 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +01001029 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001030 in[i] = 5;
1031 inout[i] = 10;
1032 out[i] = 0;
1033 }
1034
1035 /*
1036 * TA will compute: out = ++inout + in
1037 * Expected values after this step: in: 5, inout: 11, out: 16
1038 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001039 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1040 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001041 l_pts, l_params, &ret_orig);
1042 if (res != TEE_SUCCESS) {
1043 EMSG("TEE_InvokeTACommand failed");
1044 goto cleanup_return;
1045 }
Etienne Carriere102092e2019-03-28 15:24:22 +01001046
Jerome Forissiere916b102017-06-07 17:55:52 +02001047 /*
1048 * Increment all values by one.
1049 * Expected values after this step: in: 6, inout: 12, out: 17
1050 */
Etienne Carriere102092e2019-03-28 15:24:22 +01001051 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +02001052
1053 /*
1054 * TA will compute: out = ++inout + in
1055 * Expected values after this step: in: 6, inout: 13, out: 19
1056 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001057 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1058 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001059 l_pts, l_params, &ret_orig);
1060 if (res != TEE_SUCCESS) {
1061 EMSG("TEE_InvokeTACommand failed");
1062 goto cleanup_return;
1063 }
1064
1065 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001066 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001067 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1068 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001069 DHEXDUMP(in, TA2TA_BUF_SIZE);
1070 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1071 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001072 return TEE_ERROR_GENERIC;
1073 }
1074 }
1075
1076cleanup_return:
1077 TEE_CloseTASession(sess);
1078 return res;
1079}
1080
1081TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1082{
Etienne Carriere102092e2019-03-28 15:24:22 +01001083 uint8_t *in = NULL;
1084 uint8_t *inout = NULL;
1085 uint8_t *out = NULL;
1086 size_t bufsize = 0;
1087 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001088
1089 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1090 TEE_PARAM_TYPE_MEMREF_INOUT,
1091 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1092 return TEE_ERROR_GENERIC;
1093
1094 bufsize = params[0].memref.size;
1095 if (params[1].memref.size != bufsize ||
1096 params[2].memref.size != bufsize)
1097 return TEE_ERROR_GENERIC;
1098
1099 in = params[0].memref.buffer;
1100 inout = params[1].memref.buffer;
1101 out = params[2].memref.buffer;
1102
1103 for (i = 0; i < bufsize; i++)
1104 out[i] = ++inout[i] + in[i];
1105
1106 return TEE_SUCCESS;
1107}
Jens Wiklander87e81702018-03-20 12:00:00 +08001108
1109TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1110{
Etienne Carriere102092e2019-03-28 15:24:22 +01001111 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001112
1113 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1114 TEE_PARAM_TYPE_MEMREF_INPUT,
1115 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1116 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1117 return TEE_ERROR_BAD_PARAMETERS;
1118
1119 for (n = 0; n < TEE_NUM_PARAMS; n++)
1120 if (!params[n].memref.buffer || !params[n].memref.size)
1121 return TEE_ERROR_BAD_PARAMETERS;
1122
1123 return TEE_SUCCESS;
1124}
Jerome Forissier53bde722018-05-31 09:14:54 +02001125
Cedric Neveux9f483bb2019-03-04 08:58:06 +01001126TEE_Result ta_entry_null_memref(uint32_t param_types, TEE_Param params[4])
1127{
1128 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1129 TEE_PARAM_TYPE_MEMREF_INPUT,
1130 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1131 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1132 return TEE_ERROR_BAD_PARAMETERS;
1133
1134 /*
1135 * Tests how client can provide null or non-null memref parameters
1136 * param[0] expected as a 0 byte input mapped memeref.
1137 * param[1] expected as a 0 byte input not-mapped memeref.
1138 * param[2] expected as a 0 byte output mapped memeref.
1139 * param[3] expected as a 0 byte output not-mapped memeref.
1140 */
1141 if (!params[0].memref.buffer || params[0].memref.size ||
1142 params[1].memref.buffer || params[1].memref.size ||
1143 !params[2].memref.buffer || params[2].memref.size ||
1144 params[3].memref.buffer || params[3].memref.size)
1145 return TEE_ERROR_BAD_PARAMETERS;
1146
1147 return TEE_SUCCESS;
1148}
1149
Jerome Forissier53bde722018-05-31 09:14:54 +02001150TEE_Result ta_entry_call_lib(uint32_t param_types,
1151 TEE_Param params[4] __unused)
1152{
1153 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1154 TEE_PARAM_TYPE_NONE,
1155 TEE_PARAM_TYPE_NONE,
1156 TEE_PARAM_TYPE_NONE))
1157 return TEE_ERROR_BAD_PARAMETERS;
1158
1159 if (os_test_shlib_add(1, 2) != 3)
1160 return TEE_ERROR_GENERIC;
1161
1162 return TEE_SUCCESS;
1163}
1164
1165TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1166 TEE_Param params[4] __unused)
1167{
1168 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1169 TEE_PARAM_TYPE_NONE,
1170 TEE_PARAM_TYPE_NONE,
1171 TEE_PARAM_TYPE_NONE))
1172 return TEE_ERROR_BAD_PARAMETERS;
1173
1174 os_test_shlib_panic();
1175
1176 return TEE_ERROR_GENERIC;
1177}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001178
1179TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1180 TEE_Param params[4] __unused)
1181{
1182 int (*add_func)(int a, int b) = NULL;
1183 TEE_Result res = TEE_ERROR_GENERIC;
1184 void *handle = NULL;
1185 void *hnull = NULL;
1186
1187 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1188 TEE_PARAM_TYPE_NONE,
1189 TEE_PARAM_TYPE_NONE,
1190 TEE_PARAM_TYPE_NONE))
1191 return TEE_ERROR_BAD_PARAMETERS;
1192
1193 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1194 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1195 if (!handle)
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001196 return TEE_ERROR_GENERIC;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001197
1198 add_func = dlsym(handle, "os_test_shlib_dl_add");
1199 if (!add_func)
1200 goto err;
1201 if (add_func(3, 4) != 7)
1202 goto err;
1203
1204 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001205 if (!hnull)
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001206 goto err;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001207
1208 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1209 if (!add_func)
1210 goto err;
1211 if (add_func(5, 6) != 11)
1212 goto err;
1213
1214 res = TEE_SUCCESS;
1215 dlclose(hnull);
1216err:
1217 dlclose(handle);
1218 return res;
1219}
1220
1221TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1222 TEE_Param params[4] __unused)
1223{
1224 int (*panic_func)(void) = NULL;
1225 void *handle = NULL;
1226 TEE_Result res = TEE_ERROR_GENERIC;
1227
1228 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1229 TEE_PARAM_TYPE_NONE,
1230 TEE_PARAM_TYPE_NONE,
1231 TEE_PARAM_TYPE_NONE))
1232 return TEE_ERROR_BAD_PARAMETERS;
1233
1234 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1235 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1236 if (!handle)
1237 return res;
1238
1239 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1240 if (!panic_func)
1241 goto err;
1242 panic_func();
1243 return TEE_ERROR_GENERIC;
1244err:
1245 dlclose(handle);
1246 return res;
1247}
Jerome Forissiere9571e82020-02-18 15:26:20 +01001248
1249/* ELF initialization/finalization test */
1250
Jerome Forissier391168e2020-06-15 09:52:25 +02001251volatile int os_test_global;
Jerome Forissiere9571e82020-02-18 15:26:20 +01001252
1253static void __attribute__((constructor)) os_test_init(void)
1254{
1255 os_test_global *= 10;
1256 os_test_global += 1;
1257 DMSG("os_test_global=%d", os_test_global);
1258}
1259
1260TEE_Result ta_entry_get_global_var(uint32_t param_types, TEE_Param params[4])
1261{
1262 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1263 TEE_PARAM_TYPE_NONE,
1264 TEE_PARAM_TYPE_NONE,
1265 TEE_PARAM_TYPE_NONE))
1266 return TEE_ERROR_BAD_PARAMETERS;
1267
1268 params[0].value.a = os_test_global;
1269
1270 return TEE_SUCCESS;
1271}
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001272
1273TEE_Result ta_entry_client_identity(uint32_t param_types, TEE_Param params[4])
1274{
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001275 TEE_Result res = TEE_ERROR_GENERIC;
1276 TEE_Identity identity = { };
1277
1278 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1279 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1280 TEE_PARAM_TYPE_NONE,
1281 TEE_PARAM_TYPE_NONE))
1282 return TEE_ERROR_BAD_PARAMETERS;
1283
1284 if (params[1].memref.size < sizeof(TEE_UUID)) {
1285 params[1].memref.size = sizeof(TEE_UUID);
1286 return TEE_ERROR_SHORT_BUFFER;
1287 }
1288
1289 res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
1290 "gpd.client.identity", &identity);
1291 if (res != TEE_SUCCESS) {
1292 EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32, res);
1293 return res;
1294 }
1295
1296 params[0].value.a = identity.login;
1297 memcpy(params[1].memref.buffer, &identity.uuid, sizeof(TEE_UUID));
1298 params[1].memref.size = sizeof(TEE_UUID);
1299
1300 return res;
1301}
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001302
1303__thread int os_test_tls_a;
1304__thread int os_test_tls_b = 42;
1305
1306TEE_Result ta_entry_tls_test_main(void)
1307{
1308 if (os_test_tls_a != 0) {
1309 EMSG("os_test_tls_a=%d, expected 0", os_test_tls_a);
1310 return TEE_ERROR_GENERIC;
1311 }
1312 if (os_test_tls_b != 42) {
1313 EMSG("os_test_tls_b=%d, expected 42", os_test_tls_b);
1314 return TEE_ERROR_GENERIC;
1315 }
1316
1317 return TEE_SUCCESS;
1318}
1319
1320TEE_Result ta_entry_tls_test_shlib(void)
1321{
1322 if (os_test_shlib_tls_a != 0) {
1323 EMSG("os_test_shlib_tls_a=%d, expected 0", os_test_shlib_tls_a);
1324 return TEE_ERROR_GENERIC;
1325 }
1326 if (os_test_shlib_tls_b != 123) {
1327 EMSG("os_test_shlib_tls_b=%d, expected 123",
1328 os_test_shlib_tls_b);
1329 return TEE_ERROR_GENERIC;
1330 }
1331
1332 return TEE_SUCCESS;
1333}
Jerome Forissier4565c452020-06-17 17:55:00 +02001334
1335static int iterate_hdr_cb(struct dl_phdr_info *info __maybe_unused,
1336 size_t size __unused, void *data)
1337{
1338 int *count = data;
1339
1340 (*count)++;
1341 IMSG("ELF module index: %d", *count);
1342 IMSG(" dlpi_addr=%p", (void *)info->dlpi_addr);
1343 IMSG(" dlpi_name='%s'", info->dlpi_name);
1344 IMSG(" dlpi_phdr=%p", (void *)info->dlpi_phdr);
1345 IMSG(" dlpi_phnum=%hu", info->dlpi_phnum);
1346 IMSG(" dlpi_adds=%llu", info->dlpi_adds);
1347 IMSG(" dlpi_subs=%llu", info->dlpi_subs);
1348 IMSG(" dlpi_tls_modid=%zu", info->dlpi_tls_modid);
1349 IMSG(" dlpi_tls_data=%p", info->dlpi_tls_data);
1350
1351 return 123;
1352}
1353
1354static TEE_Result expect_dl_count_ge(size_t exp_count)
1355{
1356 int st = 0;
1357 size_t count = 0;
1358
1359 st = dl_iterate_phdr(iterate_hdr_cb, (void *)&count);
1360 if (st != 123) {
1361 /*
1362 * dl_iterate_phdr() should return the last value returned by
1363 * the callback
1364 */
1365 EMSG("Expected return value 123, got %d", st);
1366 return TEE_ERROR_GENERIC;
1367 }
1368 if (count < exp_count) {
1369 /*
1370 * Expect >= and not == since there could be more shared
1371 * libraries (for instance, CFG_ULIBS_SHARED=y)
1372 */
1373 EMSG("Expected count > %zu, got: %zu", exp_count, count);
1374 return TEE_ERROR_GENERIC;
1375 }
1376
1377 return TEE_SUCCESS;
1378}
1379
1380TEE_Result ta_entry_dl_phdr(void)
1381{
1382 return expect_dl_count_ge(2);
1383}
1384
1385TEE_Result ta_entry_dl_phdr_dl(void)
1386{
1387 TEE_Result res = TEE_ERROR_GENERIC;
1388 void *handle = NULL;
1389
1390 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1391 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1392 if (!handle)
1393 return TEE_ERROR_GENERIC;
1394
1395 res = expect_dl_count_ge(3);
1396 dlclose(handle);
1397
1398 return res;
1399}