blob: 7ec23773e616e73243050a0fe9f94d035971d43c [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>
Jens Wiklander8324ff22018-11-21 14:16:04 +01008#include <setjmp.h>
9#include <stdint.h>
10#include <string.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020011#include <ta_crypt.h>
12#include <ta_os_test.h>
13#include <tee_internal_api_extensions.h>
14
15#include "os_test.h"
Jens Wiklander246184a2015-12-11 08:28:59 +010016#include "test_float_subj.h"
Jerome Forissier53bde722018-05-31 09:14:54 +020017#include "os_test_lib.h"
Pascal Brandc639ac82015-07-02 08:53:34 +020018
19enum p_type {
20 P_TYPE_BOOL,
21 P_TYPE_INT,
22 P_TYPE_UUID,
23 P_TYPE_IDENTITY,
24 P_TYPE_STRING,
25 P_TYPE_BINARY_BLOCK,
26};
27
28struct p_attr {
29 const char *str;
30 enum p_type type;
31 bool retrieved;
32};
33
Pascal Brand624b6a32016-02-16 12:51:34 +010034static TEE_Result check_returned_prop(
Pascal Brandaf77fdd2016-03-08 13:59:01 +010035 int line __maybe_unused, char *prop_name __maybe_unused,
Pascal Brand624b6a32016-02-16 12:51:34 +010036 TEE_Result return_res, TEE_Result expected_res,
37 uint32_t return_len, uint32_t expected_len)
38{
39 if (return_res != expected_res) {
40 EMSG("From line %d (property name=%s): return_res=0x%x vs expected_res=0x%x",
41 line, (prop_name ? prop_name : "unknown"),
42 (unsigned int)return_res, (unsigned int)expected_res);
43 return TEE_ERROR_GENERIC;
44 }
45 if (return_len != expected_len) {
Pascal Brand07bb09f2016-02-19 16:04:10 +010046 EMSG("From line %d (property name=%s): return_len=%u vs expected_res=%u",
47 line, (prop_name ? prop_name : "unknown"),
48 return_len, expected_len);
Pascal Brand624b6a32016-02-16 12:51:34 +010049 return TEE_ERROR_GENERIC;
50 }
51 return TEE_SUCCESS;
52}
53
Etienne Carriereb34caff2020-05-26 09:25:35 +020054static TEE_Result check_binprop_ones(size_t size, uint8_t *bbuf, size_t bblen)
55{
56 uint8_t ones[4] = { 0xff, 0xff, 0xff, 0xff };
57
58 if (size > 4 || bblen != size) {
59 EMSG("Size error (size=%zu, bblen=%zu)", size, bblen);
60 return TEE_ERROR_GENERIC;
61 }
62 if (strncmp(bbuf, ones, bblen)) {
63 EMSG("Unexpected content");
64 DHEXDUMP(bbuf, bblen);
65 return TEE_ERROR_GENERIC;
66 }
67 return TEE_SUCCESS;
68}
69
70static TEE_Result get_binblock_property(TEE_PropSetHandle h,
71 char *nbuf,
72 uint8_t **bbuf,
73 size_t *bblen)
74{
75 TEE_Result res = TEE_ERROR_GENERIC;
76
77 *bbuf = NULL;
78 *bblen = 0;
79 res = TEE_GetPropertyAsBinaryBlock(h, NULL, *bbuf, bblen);
80
81 if (res == TEE_SUCCESS && !*bblen)
82 return TEE_SUCCESS;
83
84 if (res != TEE_ERROR_SHORT_BUFFER) {
85 EMSG("TEE_GetPropertyAsBinaryBlock() size query returned 0x%x",
86 (unsigned int)res);
87 return res ? res : TEE_ERROR_GENERIC;
88 }
89
90 *bbuf = TEE_Malloc(*bblen, TEE_MALLOC_FILL_ZERO);
91 if (!bbuf)
92 return TEE_ERROR_OUT_OF_MEMORY;
93
94 res = TEE_GetPropertyAsBinaryBlock(h, NULL, *bbuf, bblen);
95 if (res != TEE_SUCCESS)
96 EMSG("TEE_GetPropertyAsBinaryBlock(\"%s\") returned 0x%x",
97 nbuf, (unsigned int)res);
98
99 return res;
100}
101
Pascal Brandc639ac82015-07-02 08:53:34 +0200102static TEE_Result print_properties(TEE_PropSetHandle h,
103 TEE_PropSetHandle prop_set,
104 struct p_attr *p_attrs, size_t num_p_attrs)
105{
Etienne Carriere102092e2019-03-28 15:24:22 +0100106TEE_Result res = TEE_ERROR_GENERIC;
107size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200108
109TEE_StartPropertyEnumerator(h, prop_set);
110
111while (true) {
Etienne Carriere102092e2019-03-28 15:24:22 +0100112 char nbuf[256] = { };
113 char nbuf_small[256] = { };
114 char vbuf[256] = { };
115 char vbuf2[256] = { };
Jens Wiklanderc5231592015-11-11 09:27:27 +0100116 uint32_t nblen = sizeof(nbuf);
Etienne Carriere102092e2019-03-28 15:24:22 +0100117 uint32_t nblen_small = 0;
Jens Wiklanderc5231592015-11-11 09:27:27 +0100118 uint32_t vblen = sizeof(vbuf);
119 uint32_t vblen2 = sizeof(vbuf2);
Etienne Carriereb34caff2020-05-26 09:25:35 +0200120 uint8_t *bbuf = NULL;
121 size_t bblen = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200122
123 res = TEE_GetPropertyName(h, nbuf, &nblen);
124 if (res != TEE_SUCCESS) {
125 EMSG("TEE_GetPropertyName returned 0x%x\n",
126 (unsigned int)res);
127 return res;
128 }
Pascal Brand624b6a32016-02-16 12:51:34 +0100129 if (nblen != strlen(nbuf) + 1) {
Pascal Brand5b68cd62016-02-22 10:31:01 +0100130 EMSG("Name has wrong size: %u vs %zu", nblen, strlen(nbuf) + 1);
Pascal Brand624b6a32016-02-16 12:51:34 +0100131 return TEE_ERROR_GENERIC;
132 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200133
Pascal Brand624b6a32016-02-16 12:51:34 +0100134
135 /* Get the property name with a very small buffer */
136 nblen_small = 2;
137 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
138 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
139 nblen_small, nblen);
140 if (res != TEE_SUCCESS)
141 return res;
142
143 /* Get the property name with almost the correct buffer */
144 nblen_small = nblen - 1;
145 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
146 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
147 nblen_small, nblen);
148 if (res != TEE_SUCCESS)
149 return res;
150
151 /* Get the property name with the exact buffer length */
152 nblen_small = nblen;
153 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
154 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
155 nblen_small, nblen);
156 if (res != TEE_SUCCESS)
157 return res;
158
159 /* Get the property value */
Pascal Brandc639ac82015-07-02 08:53:34 +0200160 res = TEE_GetPropertyAsString(h, NULL, vbuf, &vblen);
Pascal Brand624b6a32016-02-16 12:51:34 +0100161 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
162 vblen, strlen(vbuf) + 1);
163 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200164 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100165
Pascal Brandc639ac82015-07-02 08:53:34 +0200166 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
Pascal Brand624b6a32016-02-16 12:51:34 +0100167 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
168 vblen2, strlen(vbuf2) + 1);
169 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200170 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100171
Jens Wiklander8324ff22018-11-21 14:16:04 +0100172 if (strcmp(vbuf, vbuf2) != 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200173 EMSG("String of \"%s\" differs\n", nbuf);
174 return TEE_ERROR_GENERIC;
175 }
176
Pascal Brand624b6a32016-02-16 12:51:34 +0100177 /* Get the property with a very small buffer */
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200178 if (vblen > 1) {
179 vblen2 = 1;
180 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
181 res = check_returned_prop(__LINE__, nbuf, res,
182 TEE_ERROR_SHORT_BUFFER,
183 vblen2, vblen);
184 if (res != TEE_SUCCESS)
185 return res;
186 }
Pascal Brand624b6a32016-02-16 12:51:34 +0100187
188 /* Get the property with almost the correct buffer */
189 vblen2 = vblen - 1;
190 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
191 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
192 vblen2, vblen);
193 if (res != TEE_SUCCESS)
194 return res;
195
196 /* Get the property name with the exact buffer length */
197 vblen2 = vblen;
198 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
199 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS, vblen2, vblen);
200 if (res != TEE_SUCCESS)
201 return res;
202
203 /* check specific myprop.hello property, which is larger than 80 */
204 if (!strcmp("myprop.hello", nbuf) &&
205 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")) {
206 EMSG("TEE_GetPropertyAsString(\"%s\") is truncated - returned \"%s\"\n",
207 nbuf, vbuf);
208 return TEE_ERROR_GENERIC;
209 }
210
Pascal Brandc639ac82015-07-02 08:53:34 +0200211 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
212
213 for (n = 0; n < num_p_attrs; n++) {
Jens Wiklander8324ff22018-11-21 14:16:04 +0100214 if (strcmp(nbuf, p_attrs[n].str) != 0)
Pascal Brandc639ac82015-07-02 08:53:34 +0200215 continue;
216
217 if (p_attrs[n].retrieved) {
218 EMSG("Value \"%s\" already retrieved\n",
219 p_attrs[n].str);
220 return TEE_ERROR_GENERIC;
221 }
222 p_attrs[n].retrieved = true;
223
224 switch (p_attrs[n].type) {
225 case P_TYPE_BOOL:
226 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100227 bool v = false;
Pascal Brandc639ac82015-07-02 08:53:34 +0200228
229 res =
230 TEE_GetPropertyAsBool(h, NULL, &v);
231 if (res != TEE_SUCCESS) {
232 EMSG(
233 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
234 nbuf, (unsigned int)res);
235 return res;
236 }
237 }
238 break;
239
240 case P_TYPE_INT:
241 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100242 uint32_t v = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200243
244 res = TEE_GetPropertyAsU32(h, NULL, &v);
245 if (res != TEE_SUCCESS) {
246 EMSG(
247 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
248 nbuf, (unsigned int)res);
249 return res;
250 }
251 }
252 break;
253
254 case P_TYPE_UUID:
255 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100256 TEE_UUID v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200257
258 res =
259 TEE_GetPropertyAsUUID(h, NULL, &v);
260 if (res != TEE_SUCCESS) {
261 EMSG(
262 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
263 nbuf, (unsigned int)res);
264 return res;
265 }
266 }
267 break;
268
269 case P_TYPE_IDENTITY:
270 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100271 TEE_Identity v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200272
273 res =
274 TEE_GetPropertyAsIdentity(h, NULL,
275 &v);
276 if (res != TEE_SUCCESS) {
277 EMSG(
278 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
279 nbuf, (unsigned int)res);
280 return res;
281 }
282 }
283 break;
284
285 case P_TYPE_STRING:
286 /* Already read as string */
287 break;
288
289 case P_TYPE_BINARY_BLOCK:
Etienne Carriereb34caff2020-05-26 09:25:35 +0200290 res = get_binblock_property(h, nbuf, &bbuf, &bblen);
291 if (res)
292 return res;
Pascal Brandc639ac82015-07-02 08:53:34 +0200293
Etienne Carriereb34caff2020-05-26 09:25:35 +0200294 if (!strcmp("myprop.binaryblock", nbuf)) {
295 const char exp_bin_value[] = "Hello world!";
296
297 if (bblen != strlen(exp_bin_value) ||
298 TEE_MemCompare(exp_bin_value, bbuf,
299 bblen)) {
300 EMSG("Binary buffer of \"%s\" differs from \"%s\"",
301 nbuf, exp_bin_value);
302 EMSG("Got \"%s\"", bbuf);
303 return TEE_ERROR_GENERIC;
304 }
305 } else if (!strcmp("myprop.binaryblock.1byte-ones",
306 nbuf)) {
307 res = check_binprop_ones(1, bbuf, bblen);
308 if (res)
Pascal Brandc639ac82015-07-02 08:53:34 +0200309 return res;
Etienne Carriereb34caff2020-05-26 09:25:35 +0200310 } else if (!strcmp("myprop.binaryblock.2byte-ones",
311 nbuf)) {
312 res = check_binprop_ones(2, bbuf, bblen);
313 if (res)
314 return res;
315 } else if (!strcmp("myprop.binaryblock.3byte-ones",
316 nbuf)) {
317 res = check_binprop_ones(3, bbuf, bblen);
318 if (res)
319 return res;
320 } else if (!strcmp("myprop.binaryblock.4byte-ones",
321 nbuf)) {
322 res = check_binprop_ones(4, bbuf, bblen);
323 if (res)
324 return res;
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200325 } else if (!strcmp("myprop.binaryblock.empty1", nbuf) ||
326 !strcmp("myprop.binaryblock.empty2", nbuf) ||
327 !strcmp("myprop.binaryblock.empty3", nbuf)) {
328 if (bblen) {
329 EMSG("Property \"%s\": %zu byte(s)",
330 nbuf, bblen);
331 return TEE_ERROR_GENERIC;
332 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200333 } else {
334 EMSG("Unexpected property \"%s\"", nbuf);
335 TEE_Panic(0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200336 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200337
338 TEE_Free(bbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200339 break;
340
341 default:
342 EMSG("Unknown type (%d) for \"%s\"\n",
343 p_attrs[n].type, p_attrs[n].str);
344 return TEE_ERROR_GENERIC;
345 }
346 }
347
348 res = TEE_GetNextProperty(h);
349 if (res != TEE_SUCCESS) {
350 if (res == TEE_ERROR_ITEM_NOT_FOUND)
351 return TEE_SUCCESS;
352 return res;
353 }
354}
355}
356
357static TEE_Result test_malloc(void)
358{
359 void *p = TEE_Malloc(4, 0);
360
361 if (p == NULL) {
362 EMSG("TEE_Malloc failed\n");
363 return TEE_ERROR_OUT_OF_MEMORY;
364 }
365 TEE_Free(p);
366 TEE_Free(NULL);
367
368 return TEE_SUCCESS;
369}
370
371static TEE_Result test_properties(void)
372{
373 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriere102092e2019-03-28 15:24:22 +0100374 TEE_PropSetHandle h = TEE_HANDLE_NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200375 struct p_attr p_attrs[] = {
376 {"gpd.ta.appID", P_TYPE_UUID},
377 {"gpd.ta.singleInstance", P_TYPE_BOOL},
378 {"gpd.ta.multiSession", P_TYPE_BOOL},
379 {"gpd.ta.instanceKeepAlive", P_TYPE_BOOL},
380 {"gpd.ta.dataSize", P_TYPE_INT},
381 {"gpd.ta.stackSize", P_TYPE_INT},
382 {"gpd.ta.version", P_TYPE_STRING},
383 {"gpd.ta.description", P_TYPE_STRING},
384 {"gpd.client.identity", P_TYPE_IDENTITY},
385 {"gpd.tee.apiversion", P_TYPE_STRING},
386 {"gpd.tee.description", P_TYPE_STRING},
387 {"gpd.tee.deviceID", P_TYPE_UUID},
388 {"gpd.tee.systemTime.protectionLevel", P_TYPE_INT},
389 {"gpd.tee.TAPersistentTime.protectionLevel", P_TYPE_INT},
390 {"gpd.tee.arith.maxBigIntSize", P_TYPE_INT},
391 {"gpd.tee.cryptography.ecc", P_TYPE_BOOL},
392 {"gpd.tee.trustedStorage.antiRollback.protectionLevel", P_TYPE_INT},
393 {"gpd.tee.trustedos.implementation.version", P_TYPE_STRING},
394 {"gpd.tee.trustedos.implementation.binaryversion", P_TYPE_INT},
395 {"gpd.tee.trustedos.manufacturer", P_TYPE_STRING},
396 {"gpd.tee.firmware.implementation.version", P_TYPE_STRING},
397 {"gpd.tee.firmware.implementation.binaryversion", P_TYPE_INT},
398 {"gpd.tee.firmware.manufacturer", P_TYPE_STRING},
399 {"myprop.true", P_TYPE_BOOL},
400 {"myprop.42", P_TYPE_INT},
401 {"myprop.123", P_TYPE_UUID},
402 {"myprop.1234", P_TYPE_IDENTITY},
403 {"myprop.hello", P_TYPE_STRING},
404 {"myprop.binaryblock", P_TYPE_BINARY_BLOCK},
Etienne Carriereb34caff2020-05-26 09:25:35 +0200405 {"myprop.binaryblock.1byte-ones", P_TYPE_BINARY_BLOCK},
406 {"myprop.binaryblock.2byte-ones", P_TYPE_BINARY_BLOCK},
407 {"myprop.binaryblock.3byte-ones", P_TYPE_BINARY_BLOCK},
408 {"myprop.binaryblock.4byte-ones", P_TYPE_BINARY_BLOCK},
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200409 {"myprop.binaryblock.empty1", P_TYPE_BINARY_BLOCK},
410 {"myprop.binaryblock.empty2", P_TYPE_BINARY_BLOCK},
411 {"myprop.binaryblock.empty3", P_TYPE_BINARY_BLOCK},
Pascal Brandc639ac82015-07-02 08:53:34 +0200412 };
413 const size_t num_p_attrs = sizeof(p_attrs) / sizeof(p_attrs[0]);
Etienne Carriere102092e2019-03-28 15:24:22 +0100414 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200415
416 res = TEE_AllocatePropertyEnumerator(&h);
417 if (res != TEE_SUCCESS) {
418 EMSG("TEE_AllocatePropertyEnumerator: returned 0x%x\n",
419 (unsigned int)res);
420 return TEE_ERROR_GENERIC;
421 }
422
423 printf("Getting properties for current TA\n");
424 res = print_properties(h, TEE_PROPSET_CURRENT_TA, p_attrs, num_p_attrs);
425 if (res != TEE_SUCCESS)
426 goto cleanup_return;
427
428 printf("Getting properties for current client\n");
429 res = print_properties(h, TEE_PROPSET_CURRENT_CLIENT, p_attrs,
430 num_p_attrs);
431 if (res != TEE_SUCCESS)
432 goto cleanup_return;
433
434 printf("Getting properties for implementation\n");
435 res = print_properties(h, TEE_PROPSET_TEE_IMPLEMENTATION, p_attrs,
436 num_p_attrs);
437 if (res != TEE_SUCCESS)
438 goto cleanup_return;
439
440 for (n = 0; n < num_p_attrs; n++) {
441 if (!p_attrs[n].retrieved) {
442 EMSG("\"%s\" not retrieved\n", p_attrs[n].str);
443 res = TEE_ERROR_GENERIC;
444 goto cleanup_return;
445 }
446 }
447
448cleanup_return:
449 TEE_FreePropertyEnumerator(h);
450 return res;
451}
452
453static TEE_Result test_mem_access_right(uint32_t param_types,
454 TEE_Param params[4])
455{
456 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100457 TEE_Result res = TEE_ERROR_GENERIC;
458 uint32_t ret_orig = 0;
459 uint32_t l_pts = 0;
460 TEE_Param l_params[4] = { };
461 uint8_t buf[32] = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200462 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100463 TEE_UUID *uuid = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200464
465 if (param_types !=
466 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
467 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200468
469 /* test access rights on memref parameter */
470 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
471 TEE_MEMORY_ACCESS_ANY_OWNER,
472 params[0].memref.buffer,
473 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200474 if (res != TEE_SUCCESS)
475 return res;
Etienne Carriere281065d2016-10-28 15:41:33 +0200476
Pascal Brandc639ac82015-07-02 08:53:34 +0200477 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
478 params[0].memref.buffer,
479 params[0].memref.size);
480 if (res != TEE_ERROR_ACCESS_DENIED)
481 return TEE_ERROR_GENERIC;
482
Etienne Carriere281065d2016-10-28 15:41:33 +0200483 /* test access rights on private read-only and read-write memory */
484 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
485 (void *)&test_uuid, sizeof(test_uuid));
486 if (res != TEE_SUCCESS)
487 return res;
488
489 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_WRITE,
490 (void *)&test_uuid, sizeof(test_uuid));
491 if (res == TEE_SUCCESS)
492 return TEE_ERROR_GENERIC;
493
494 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
495 TEE_MEMORY_ACCESS_WRITE,
496 &ret_orig, sizeof(ret_orig));
497 if (res != TEE_SUCCESS)
498 return res;
499
500 uuid = TEE_Malloc(sizeof(*uuid), 0);
501 if (!uuid)
502 return TEE_ERROR_OUT_OF_MEMORY;
503
504 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
505 TEE_MEMORY_ACCESS_WRITE,
506 uuid, sizeof(*uuid));
507 TEE_Free(uuid);
508 if (res != TEE_SUCCESS)
509 return res;
510
511 /* test access rights on invalid memory (at least lower 256kB) */
512 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
513 NULL, 1);
514 if (res == TEE_SUCCESS)
515 return TEE_ERROR_GENERIC;
516
517 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
518 (void*)(256 * 1024), 1);
519 if (res == TEE_SUCCESS)
520 return TEE_ERROR_GENERIC;
521
Cedric Augere668b3f2019-09-11 13:41:21 +0200522 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
523 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200524 if (res != TEE_SUCCESS) {
525 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
526 goto cleanup_return;
527 }
528
Jerome Forissier04511d82018-01-30 14:33:49 +0100529 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
530 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200531 l_params[0].memref.buffer = buf;
532 l_params[0].memref.size = sizeof(buf);
Jerome Forissier04511d82018-01-30 14:33:49 +0100533 l_params[1].memref.buffer = NULL;
534 l_params[1].memref.size = 0;
Cedric Augere668b3f2019-09-11 13:41:21 +0200535 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
536 TA_OS_TEST_CMD_PARAMS_ACCESS,
Pascal Brandc639ac82015-07-02 08:53:34 +0200537 l_pts, l_params, &ret_orig);
538 if (res != TEE_SUCCESS) {
539 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
540 goto cleanup_return;
541 }
542
543cleanup_return:
544 TEE_CloseTASession(sess);
545 return res;
546}
547
548static TEE_Result test_time(void)
549{
Etienne Carriere102092e2019-03-28 15:24:22 +0100550 TEE_Result res = TEE_ERROR_GENERIC;
551 TEE_Time t = { };
552 TEE_Time sys_t = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200553 static const TEE_Time null_time = { 0, 0 };
554 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
555
556 TEE_GetSystemTime(&sys_t);
557 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
558 (unsigned int)sys_t.millis);
559
560 TEE_GetREETime(&t);
561 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
562 (unsigned int)t.millis);
563
564 res = TEE_GetTAPersistentTime(&t);
565 switch (res) {
566 case TEE_SUCCESS:
567 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
568 (unsigned int)t.millis);
569 break;
570 case TEE_ERROR_OVERFLOW:
571 EMSG("Stored TA time overflowed %u.%03u\n",
572 (unsigned int)t.seconds, (unsigned int)t.millis);
573 break;
574 case TEE_ERROR_TIME_NOT_SET:
575 EMSG("TA time not stored\n");
576 break;
577 case TEE_ERROR_TIME_NEEDS_RESET:
578 EMSG("TA time needs reset\n");
579 break;
580 default:
581 return res;
582 }
583
584 res = TEE_SetTAPersistentTime(&null_time);
585 if (res != TEE_SUCCESS) {
586 EMSG("TEE_SetTAPersistentTime: failed\n");
587 return res;
588 }
589
590 res = TEE_GetTAPersistentTime(&t);
591 if (res != TEE_SUCCESS) {
592 EMSG("TEE_GetTAPersistentTime null: failed\n");
593 return res;
594 }
595 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
596 (unsigned int)t.millis);
597 /*
598 * The time between TEE_SetTAPersistentTime() and
599 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
600 * it's not even a millisecond.
601 */
602 if (t.seconds > 1 || t.millis >= 1000) {
603 EMSG("Unexpected stored TA time %u.%03u\n",
604 (unsigned int)t.seconds, (unsigned int)t.millis);
605 return TEE_ERROR_BAD_STATE;
606 }
607
608 res = TEE_SetTAPersistentTime(&wrap_time);
609 if (res != TEE_SUCCESS) {
610 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
611 return res;
612 }
613
614 res = TEE_Wait(1000);
615 if (res != TEE_SUCCESS)
616 EMSG("TEE_Wait wrap: failed\n");
617
618 res = TEE_GetTAPersistentTime(&t);
619 if (res != TEE_ERROR_OVERFLOW) {
620 EMSG("TEE_GetTAPersistentTime: failed\n");
621 return TEE_ERROR_BAD_STATE;
622 }
623 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
624 (unsigned int)t.millis);
625
626 if (t.seconds > sys_t.seconds) {
627 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
628 (unsigned int)t.seconds, (unsigned int)t.millis,
629 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
630 return TEE_ERROR_BAD_STATE;
631 }
632
633 return TEE_SUCCESS;
634}
635
Jens Wiklander246184a2015-12-11 08:28:59 +0100636#ifdef CFG_TA_FLOAT_SUPPORT
637static bool my_dcmpeq(double v1, double v2, double prec)
638{
639 return v1 > (v2 - prec) && v1 < (v2 + prec);
640}
641
642static bool my_fcmpeq(float v1, float v2, float prec)
643{
644 return v1 > (v2 - prec) && v1 < (v2 + prec);
645}
646
647
648static TEE_Result test_float(void)
649{
650#define VAL1 2.6
651#define VAL1_INT 2
652#define VAL2 5.3
653#define DPREC 0.000000000000001
654#define FPREC 0.000001
655#define EXPECT(expr) do { \
656 if (!(expr)) { \
657 EMSG("Expression %s failed", #expr); \
658 return TEE_ERROR_GENERIC; \
659 } \
660 } while (0)
661
662 IMSG("Testing floating point operations");
663
664 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
665 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
666 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
667 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
668 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
669
670 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
671 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
672 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
673 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
674 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
675
676 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
677 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
678 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
679 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
680 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
681
682 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
683 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
684 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
685 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
686 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
687
688 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
689 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
690 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
691 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
692
693 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
694 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
695 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
696 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
697
698 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
699 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
700
701 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
702 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
703 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
704 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
705
706 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
707 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
708 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
709 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
710 return TEE_SUCCESS;
711}
712#else /*CFG_TA_FLOAT_SUPPORT*/
713static TEE_Result test_float(void)
714{
715 IMSG("Floating point disabled");
716 return TEE_SUCCESS;
717}
718#endif /*CFG_TA_FLOAT_SUPPORT*/
719
Jerome Forissier892ae4d2020-03-09 09:58:09 +0100720static __noinline __noreturn void call_longjmp(jmp_buf env)
Jens Wiklander9f682c62016-03-27 20:23:06 +0200721{
722 DMSG("Calling longjmp");
723 longjmp(env, 1);
724 EMSG("error: longjmp returned to calling function");
725}
726
727static TEE_Result test_setjmp(void)
728{
Etienne Carriere102092e2019-03-28 15:24:22 +0100729 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200730
731 if (setjmp(env)) {
732 IMSG("Returned via longjmp");
733 return TEE_SUCCESS;
734 } else {
735 call_longjmp(env);
736 return TEE_ERROR_GENERIC;
737 }
738}
739
Pascal Brandc639ac82015-07-02 08:53:34 +0200740TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
741{
742 TEE_Result res = TEE_ERROR_GENERIC;
743
744 printf("ta_entry_basic: enter\n");
745
746 res = test_malloc();
747 if (res != TEE_SUCCESS)
748 return res;
749
750 res = test_properties();
751 if (res != TEE_SUCCESS)
752 return res;
753
754 res = test_mem_access_right(param_types, params);
755 if (res != TEE_SUCCESS)
756 return res;
757
758 res = test_time();
759 if (res != TEE_SUCCESS)
760 return res;
761
Jens Wiklander246184a2015-12-11 08:28:59 +0100762 res = test_float();
763 if (res != TEE_SUCCESS)
764 return res;
765
Jens Wiklander9f682c62016-03-27 20:23:06 +0200766 res = test_setjmp();
767 if (res != TEE_SUCCESS)
768 return res;
769
Pascal Brandc639ac82015-07-02 08:53:34 +0200770 return TEE_SUCCESS;
771}
772
773TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
774{
775 volatile bool mytrue = true;
776 (void)param_types;
777 (void)params;
778
779 printf("ta_entry_panic: enter\n");
780 /*
781 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
782 * the __noreturn attribute.
783 */
784 if (mytrue)
785 TEE_Panic(0xbeef);
786
787 /*
788 * Should not be reached, but if it is the testsuite can detect that
789 * TEE_Panic() returned instead of panicking the TA.
790 */
791 return TEE_SUCCESS;
792}
793
794TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
795 TEE_Param params[4])
796{
797 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100798 TEE_Result res = TEE_ERROR_GENERIC;
799 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
800 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200801
802 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
803 TEE_PARAM_TYPE_NONE,
804 TEE_PARAM_TYPE_NONE,
805 TEE_PARAM_TYPE_NONE)) {
806 EMSG("ta_entry_client_with_timeout: bad parameters\n");
807 return TEE_ERROR_BAD_PARAMETERS;
808 }
809
Cedric Augere668b3f2019-09-11 13:41:21 +0200810 res = TEE_OpenTASession(&os_test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
811 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200812 if (res != TEE_SUCCESS) {
813 EMSG(
814 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
815 return res;
816 }
817
818 res =
819 TEE_InvokeTACommand(sess, params[0].value.a / 2,
820 TA_OS_TEST_CMD_WAIT, param_types, params,
821 &ret_orig);
822
823 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
824 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
825 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
826 (unsigned int)ret_orig);
827 res = TEE_ERROR_GENERIC;
828 } else
829 res = TEE_SUCCESS;
830
831 TEE_CloseTASession(sess);
832 return res;
833
834}
835
836TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
837{
838 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100839 TEE_Result res = TEE_ERROR_GENERIC;
840 uint32_t l_pts = 0;
841 TEE_Param l_params[4] = { };
842 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
843 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200844 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
845 static const uint8_t sha256_out[] = {
846 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
847 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
848 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
849 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
850 };
851 uint8_t out[32] = { 0 };
852 void *in = NULL;
853
854 (void)param_types;
855 (void)params;
856
857 printf("ta_entry_client: enter\n");
858
859 in = TEE_Malloc(sizeof(sha256_in), 0);
860 if (in == NULL)
861 return TEE_ERROR_OUT_OF_MEMORY;
862 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
863
Cedric Augere668b3f2019-09-11 13:41:21 +0200864 res = TEE_OpenTASession(&crypt_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
865 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200866 if (res != TEE_SUCCESS) {
867 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
868 goto cleanup_return;
869 }
870
871 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
872 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
873 l_params[0].memref.buffer = in;
874 l_params[0].memref.size = sizeof(sha256_in);
875 l_params[1].memref.buffer = out;
876 l_params[1].memref.size = sizeof(out);
877
Cedric Augere668b3f2019-09-11 13:41:21 +0200878 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
879 TA_CRYPT_CMD_SHA256, l_pts, l_params,
Pascal Brandc639ac82015-07-02 08:53:34 +0200880 &ret_orig);
881 if (res != TEE_SUCCESS) {
882 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
883 goto cleanup_return;
884 }
885
886 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
887 EMSG("ta_entry_client: out parameter failed\n");
888 res = TEE_ERROR_GENERIC;
889 goto cleanup_return;
890 }
891
892cleanup_return:
893 TEE_Free(in);
894 TEE_CloseTASession(sess);
895 return res;
896}
897
Etienne Carriere281065d2016-10-28 15:41:33 +0200898TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200899{
Etienne Carriere102092e2019-03-28 15:24:22 +0100900 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200901
902 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100903 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
904 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200905 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200906
907 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
908 TEE_MEMORY_ACCESS_ANY_OWNER,
909 params[0].memref.buffer,
910 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200911 if (res != TEE_SUCCESS)
912 return res;
913
914 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
915 params[0].memref.buffer,
916 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200917 if (res != TEE_ERROR_ACCESS_DENIED)
918 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +0100919 if (params[1].memref.buffer || params[1].memref.size)
920 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200921
Etienne Carriere281065d2016-10-28 15:41:33 +0200922 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200923}
924
925TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
926{
927 TEE_Result res = TEE_SUCCESS;
928 (void)param_types;
929
930 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
931 /* Wait */
932 res = TEE_Wait(params[0].value.a);
933
934 return res;
935}
936
Jens Wiklander1425f952016-07-21 09:02:30 +0200937static void undef_instr(void)
938{
939#if defined(ARM64)
940 __asm__(".word 0x0");
941#elif defined(ARM32)
942 __asm__(".word 0xe7ffffff");
943#else
944#error "Unsupported architecture"
945#endif
946}
947
Pascal Brandc639ac82015-07-02 08:53:34 +0200948TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
949{
Etienne Carriere102092e2019-03-28 15:24:22 +0100950 long int stack = 0;
951 long int stack_addr = (long int)&stack;
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200952 void (*volatile null_fn_ptr)(void) = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200953
Etienne Carriere92c34422018-02-09 13:11:40 +0100954 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
955 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
956 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200957 return TEE_ERROR_GENERIC;
958
959 switch (params[0].value.a) {
960 case 1:
Jerome Forissier71da60f2019-09-19 15:59:56 +0200961 *((volatile uint32_t *)0) = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200962 break;
963 case 2:
964 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
965 break;
966 case 3:
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200967 null_fn_ptr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200968 break;
969 case 4:
970 ((void (*)(void))(stack_addr + 0x40000000)) ();
971 break;
972 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +0200973 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200974 break;
975 default:
976 break;
977 }
978
979 return TEE_SUCCESS;
980}
Jerome Forissiere916b102017-06-07 17:55:52 +0200981
982static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
983{
Etienne Carriere102092e2019-03-28 15:24:22 +0100984 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +0200985
986 for (i = 0; i < bufsize; i++) {
987 a[i]++; b[i]++; c[i]++;
988 }
989}
990
Etienne Carriere102092e2019-03-28 15:24:22 +0100991#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +0200992TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
993{
994 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
995 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100996 TEE_Param l_params[4] = { };
997 uint8_t in[TA2TA_BUF_SIZE] = { };
998 uint8_t inout[TA2TA_BUF_SIZE] = { };
999 uint8_t out[TA2TA_BUF_SIZE] = { };
1000 TEE_Result res = TEE_ERROR_GENERIC;
1001 uint32_t ret_orig = 0;
1002 uint32_t l_pts = 0;
1003 size_t i = 0;
1004
Jerome Forissiere916b102017-06-07 17:55:52 +02001005 (void)params;
1006
1007 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
1008 return TEE_ERROR_GENERIC;
1009
Cedric Augere668b3f2019-09-11 13:41:21 +02001010 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
1011 &sess, &ret_orig);
Jerome Forissiere916b102017-06-07 17:55:52 +02001012 if (res != TEE_SUCCESS) {
1013 EMSG("TEE_OpenTASession failed");
1014 goto cleanup_return;
1015 }
1016
1017 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1018 TEE_PARAM_TYPE_MEMREF_INOUT,
1019 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
1020 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +01001021 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001022 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +01001023 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001024 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +01001025 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001026
1027 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +01001028 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001029 in[i] = 5;
1030 inout[i] = 10;
1031 out[i] = 0;
1032 }
1033
1034 /*
1035 * TA will compute: out = ++inout + in
1036 * Expected values after this step: in: 5, inout: 11, out: 16
1037 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001038 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1039 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001040 l_pts, l_params, &ret_orig);
1041 if (res != TEE_SUCCESS) {
1042 EMSG("TEE_InvokeTACommand failed");
1043 goto cleanup_return;
1044 }
Etienne Carriere102092e2019-03-28 15:24:22 +01001045
Jerome Forissiere916b102017-06-07 17:55:52 +02001046 /*
1047 * Increment all values by one.
1048 * Expected values after this step: in: 6, inout: 12, out: 17
1049 */
Etienne Carriere102092e2019-03-28 15:24:22 +01001050 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +02001051
1052 /*
1053 * TA will compute: out = ++inout + in
1054 * Expected values after this step: in: 6, inout: 13, out: 19
1055 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001056 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1057 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001058 l_pts, l_params, &ret_orig);
1059 if (res != TEE_SUCCESS) {
1060 EMSG("TEE_InvokeTACommand failed");
1061 goto cleanup_return;
1062 }
1063
1064 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001065 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001066 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1067 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001068 DHEXDUMP(in, TA2TA_BUF_SIZE);
1069 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1070 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001071 return TEE_ERROR_GENERIC;
1072 }
1073 }
1074
1075cleanup_return:
1076 TEE_CloseTASession(sess);
1077 return res;
1078}
1079
1080TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1081{
Etienne Carriere102092e2019-03-28 15:24:22 +01001082 uint8_t *in = NULL;
1083 uint8_t *inout = NULL;
1084 uint8_t *out = NULL;
1085 size_t bufsize = 0;
1086 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001087
1088 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1089 TEE_PARAM_TYPE_MEMREF_INOUT,
1090 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1091 return TEE_ERROR_GENERIC;
1092
1093 bufsize = params[0].memref.size;
1094 if (params[1].memref.size != bufsize ||
1095 params[2].memref.size != bufsize)
1096 return TEE_ERROR_GENERIC;
1097
1098 in = params[0].memref.buffer;
1099 inout = params[1].memref.buffer;
1100 out = params[2].memref.buffer;
1101
1102 for (i = 0; i < bufsize; i++)
1103 out[i] = ++inout[i] + in[i];
1104
1105 return TEE_SUCCESS;
1106}
Jens Wiklander87e81702018-03-20 12:00:00 +08001107
1108TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1109{
Etienne Carriere102092e2019-03-28 15:24:22 +01001110 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001111
1112 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1113 TEE_PARAM_TYPE_MEMREF_INPUT,
1114 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1115 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1116 return TEE_ERROR_BAD_PARAMETERS;
1117
1118 for (n = 0; n < TEE_NUM_PARAMS; n++)
1119 if (!params[n].memref.buffer || !params[n].memref.size)
1120 return TEE_ERROR_BAD_PARAMETERS;
1121
1122 return TEE_SUCCESS;
1123}
Jerome Forissier53bde722018-05-31 09:14:54 +02001124
Cedric Neveux9f483bb2019-03-04 08:58:06 +01001125TEE_Result ta_entry_null_memref(uint32_t param_types, TEE_Param params[4])
1126{
1127 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1128 TEE_PARAM_TYPE_MEMREF_INPUT,
1129 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1130 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1131 return TEE_ERROR_BAD_PARAMETERS;
1132
1133 /*
1134 * Tests how client can provide null or non-null memref parameters
1135 * param[0] expected as a 0 byte input mapped memeref.
1136 * param[1] expected as a 0 byte input not-mapped memeref.
1137 * param[2] expected as a 0 byte output mapped memeref.
1138 * param[3] expected as a 0 byte output not-mapped memeref.
1139 */
1140 if (!params[0].memref.buffer || params[0].memref.size ||
1141 params[1].memref.buffer || params[1].memref.size ||
1142 !params[2].memref.buffer || params[2].memref.size ||
1143 params[3].memref.buffer || params[3].memref.size)
1144 return TEE_ERROR_BAD_PARAMETERS;
1145
1146 return TEE_SUCCESS;
1147}
1148
Jerome Forissier53bde722018-05-31 09:14:54 +02001149TEE_Result ta_entry_call_lib(uint32_t param_types,
1150 TEE_Param params[4] __unused)
1151{
1152 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1153 TEE_PARAM_TYPE_NONE,
1154 TEE_PARAM_TYPE_NONE,
1155 TEE_PARAM_TYPE_NONE))
1156 return TEE_ERROR_BAD_PARAMETERS;
1157
1158 if (os_test_shlib_add(1, 2) != 3)
1159 return TEE_ERROR_GENERIC;
1160
1161 return TEE_SUCCESS;
1162}
1163
1164TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1165 TEE_Param params[4] __unused)
1166{
1167 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1168 TEE_PARAM_TYPE_NONE,
1169 TEE_PARAM_TYPE_NONE,
1170 TEE_PARAM_TYPE_NONE))
1171 return TEE_ERROR_BAD_PARAMETERS;
1172
1173 os_test_shlib_panic();
1174
1175 return TEE_ERROR_GENERIC;
1176}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001177
1178TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1179 TEE_Param params[4] __unused)
1180{
1181 int (*add_func)(int a, int b) = NULL;
1182 TEE_Result res = TEE_ERROR_GENERIC;
1183 void *handle = NULL;
1184 void *hnull = NULL;
1185
1186 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1187 TEE_PARAM_TYPE_NONE,
1188 TEE_PARAM_TYPE_NONE,
1189 TEE_PARAM_TYPE_NONE))
1190 return TEE_ERROR_BAD_PARAMETERS;
1191
1192 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1193 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1194 if (!handle)
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001195 return TEE_ERROR_GENERIC;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001196
1197 add_func = dlsym(handle, "os_test_shlib_dl_add");
1198 if (!add_func)
1199 goto err;
1200 if (add_func(3, 4) != 7)
1201 goto err;
1202
1203 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001204 if (!hnull)
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001205 goto err;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001206
1207 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1208 if (!add_func)
1209 goto err;
1210 if (add_func(5, 6) != 11)
1211 goto err;
1212
1213 res = TEE_SUCCESS;
1214 dlclose(hnull);
1215err:
1216 dlclose(handle);
1217 return res;
1218}
1219
1220TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1221 TEE_Param params[4] __unused)
1222{
1223 int (*panic_func)(void) = NULL;
1224 void *handle = NULL;
1225 TEE_Result res = TEE_ERROR_GENERIC;
1226
1227 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1228 TEE_PARAM_TYPE_NONE,
1229 TEE_PARAM_TYPE_NONE,
1230 TEE_PARAM_TYPE_NONE))
1231 return TEE_ERROR_BAD_PARAMETERS;
1232
1233 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1234 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1235 if (!handle)
1236 return res;
1237
1238 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1239 if (!panic_func)
1240 goto err;
1241 panic_func();
1242 return TEE_ERROR_GENERIC;
1243err:
1244 dlclose(handle);
1245 return res;
1246}
Jerome Forissiere9571e82020-02-18 15:26:20 +01001247
1248/* ELF initialization/finalization test */
1249
Jerome Forissier391168e2020-06-15 09:52:25 +02001250volatile int os_test_global;
Jerome Forissiere9571e82020-02-18 15:26:20 +01001251
1252static void __attribute__((constructor)) os_test_init(void)
1253{
1254 os_test_global *= 10;
1255 os_test_global += 1;
1256 DMSG("os_test_global=%d", os_test_global);
1257}
1258
1259TEE_Result ta_entry_get_global_var(uint32_t param_types, TEE_Param params[4])
1260{
1261 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1262 TEE_PARAM_TYPE_NONE,
1263 TEE_PARAM_TYPE_NONE,
1264 TEE_PARAM_TYPE_NONE))
1265 return TEE_ERROR_BAD_PARAMETERS;
1266
1267 params[0].value.a = os_test_global;
1268
1269 return TEE_SUCCESS;
1270}
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001271
1272TEE_Result ta_entry_client_identity(uint32_t param_types, TEE_Param params[4])
1273{
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001274 TEE_Result res = TEE_ERROR_GENERIC;
1275 TEE_Identity identity = { };
1276
1277 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1278 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1279 TEE_PARAM_TYPE_NONE,
1280 TEE_PARAM_TYPE_NONE))
1281 return TEE_ERROR_BAD_PARAMETERS;
1282
1283 if (params[1].memref.size < sizeof(TEE_UUID)) {
1284 params[1].memref.size = sizeof(TEE_UUID);
1285 return TEE_ERROR_SHORT_BUFFER;
1286 }
1287
1288 res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
1289 "gpd.client.identity", &identity);
1290 if (res != TEE_SUCCESS) {
1291 EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32, res);
1292 return res;
1293 }
1294
1295 params[0].value.a = identity.login;
1296 memcpy(params[1].memref.buffer, &identity.uuid, sizeof(TEE_UUID));
1297 params[1].memref.size = sizeof(TEE_UUID);
1298
1299 return res;
1300}