blob: d3efe62e7e81a5a2279c46517a5d9523c44344bf [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 */
178 vblen2 = 1;
179 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
180 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
181 vblen2, vblen);
182 if (res != TEE_SUCCESS)
183 return res;
184
185 /* Get the property with almost the correct buffer */
186 vblen2 = vblen - 1;
187 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
188 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
189 vblen2, vblen);
190 if (res != TEE_SUCCESS)
191 return res;
192
193 /* Get the property name with the exact buffer length */
194 vblen2 = vblen;
195 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
196 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS, vblen2, vblen);
197 if (res != TEE_SUCCESS)
198 return res;
199
200 /* check specific myprop.hello property, which is larger than 80 */
201 if (!strcmp("myprop.hello", nbuf) &&
202 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")) {
203 EMSG("TEE_GetPropertyAsString(\"%s\") is truncated - returned \"%s\"\n",
204 nbuf, vbuf);
205 return TEE_ERROR_GENERIC;
206 }
207
Pascal Brandc639ac82015-07-02 08:53:34 +0200208 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
209
210 for (n = 0; n < num_p_attrs; n++) {
Jens Wiklander8324ff22018-11-21 14:16:04 +0100211 if (strcmp(nbuf, p_attrs[n].str) != 0)
Pascal Brandc639ac82015-07-02 08:53:34 +0200212 continue;
213
214 if (p_attrs[n].retrieved) {
215 EMSG("Value \"%s\" already retrieved\n",
216 p_attrs[n].str);
217 return TEE_ERROR_GENERIC;
218 }
219 p_attrs[n].retrieved = true;
220
221 switch (p_attrs[n].type) {
222 case P_TYPE_BOOL:
223 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100224 bool v = false;
Pascal Brandc639ac82015-07-02 08:53:34 +0200225
226 res =
227 TEE_GetPropertyAsBool(h, NULL, &v);
228 if (res != TEE_SUCCESS) {
229 EMSG(
230 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
231 nbuf, (unsigned int)res);
232 return res;
233 }
234 }
235 break;
236
237 case P_TYPE_INT:
238 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100239 uint32_t v = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200240
241 res = TEE_GetPropertyAsU32(h, NULL, &v);
242 if (res != TEE_SUCCESS) {
243 EMSG(
244 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
245 nbuf, (unsigned int)res);
246 return res;
247 }
248 }
249 break;
250
251 case P_TYPE_UUID:
252 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100253 TEE_UUID v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200254
255 res =
256 TEE_GetPropertyAsUUID(h, NULL, &v);
257 if (res != TEE_SUCCESS) {
258 EMSG(
259 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
260 nbuf, (unsigned int)res);
261 return res;
262 }
263 }
264 break;
265
266 case P_TYPE_IDENTITY:
267 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100268 TEE_Identity v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200269
270 res =
271 TEE_GetPropertyAsIdentity(h, NULL,
272 &v);
273 if (res != TEE_SUCCESS) {
274 EMSG(
275 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
276 nbuf, (unsigned int)res);
277 return res;
278 }
279 }
280 break;
281
282 case P_TYPE_STRING:
283 /* Already read as string */
284 break;
285
286 case P_TYPE_BINARY_BLOCK:
Etienne Carriereb34caff2020-05-26 09:25:35 +0200287 res = get_binblock_property(h, nbuf, &bbuf, &bblen);
288 if (res)
289 return res;
Pascal Brandc639ac82015-07-02 08:53:34 +0200290
Etienne Carriereb34caff2020-05-26 09:25:35 +0200291 if (!strcmp("myprop.binaryblock", nbuf)) {
292 const char exp_bin_value[] = "Hello world!";
293
294 if (bblen != strlen(exp_bin_value) ||
295 TEE_MemCompare(exp_bin_value, bbuf,
296 bblen)) {
297 EMSG("Binary buffer of \"%s\" differs from \"%s\"",
298 nbuf, exp_bin_value);
299 EMSG("Got \"%s\"", bbuf);
300 return TEE_ERROR_GENERIC;
301 }
302 } else if (!strcmp("myprop.binaryblock.1byte-ones",
303 nbuf)) {
304 res = check_binprop_ones(1, bbuf, bblen);
305 if (res)
Pascal Brandc639ac82015-07-02 08:53:34 +0200306 return res;
Etienne Carriereb34caff2020-05-26 09:25:35 +0200307 } else if (!strcmp("myprop.binaryblock.2byte-ones",
308 nbuf)) {
309 res = check_binprop_ones(2, bbuf, bblen);
310 if (res)
311 return res;
312 } else if (!strcmp("myprop.binaryblock.3byte-ones",
313 nbuf)) {
314 res = check_binprop_ones(3, bbuf, bblen);
315 if (res)
316 return res;
317 } else if (!strcmp("myprop.binaryblock.4byte-ones",
318 nbuf)) {
319 res = check_binprop_ones(4, bbuf, bblen);
320 if (res)
321 return res;
322 } else {
323 EMSG("Unexpected property \"%s\"", nbuf);
324 TEE_Panic(0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200325 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200326
327 TEE_Free(bbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200328 break;
329
330 default:
331 EMSG("Unknown type (%d) for \"%s\"\n",
332 p_attrs[n].type, p_attrs[n].str);
333 return TEE_ERROR_GENERIC;
334 }
335 }
336
337 res = TEE_GetNextProperty(h);
338 if (res != TEE_SUCCESS) {
339 if (res == TEE_ERROR_ITEM_NOT_FOUND)
340 return TEE_SUCCESS;
341 return res;
342 }
343}
344}
345
346static TEE_Result test_malloc(void)
347{
348 void *p = TEE_Malloc(4, 0);
349
350 if (p == NULL) {
351 EMSG("TEE_Malloc failed\n");
352 return TEE_ERROR_OUT_OF_MEMORY;
353 }
354 TEE_Free(p);
355 TEE_Free(NULL);
356
357 return TEE_SUCCESS;
358}
359
360static TEE_Result test_properties(void)
361{
362 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriere102092e2019-03-28 15:24:22 +0100363 TEE_PropSetHandle h = TEE_HANDLE_NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200364 struct p_attr p_attrs[] = {
365 {"gpd.ta.appID", P_TYPE_UUID},
366 {"gpd.ta.singleInstance", P_TYPE_BOOL},
367 {"gpd.ta.multiSession", P_TYPE_BOOL},
368 {"gpd.ta.instanceKeepAlive", P_TYPE_BOOL},
369 {"gpd.ta.dataSize", P_TYPE_INT},
370 {"gpd.ta.stackSize", P_TYPE_INT},
371 {"gpd.ta.version", P_TYPE_STRING},
372 {"gpd.ta.description", P_TYPE_STRING},
373 {"gpd.client.identity", P_TYPE_IDENTITY},
374 {"gpd.tee.apiversion", P_TYPE_STRING},
375 {"gpd.tee.description", P_TYPE_STRING},
376 {"gpd.tee.deviceID", P_TYPE_UUID},
377 {"gpd.tee.systemTime.protectionLevel", P_TYPE_INT},
378 {"gpd.tee.TAPersistentTime.protectionLevel", P_TYPE_INT},
379 {"gpd.tee.arith.maxBigIntSize", P_TYPE_INT},
380 {"gpd.tee.cryptography.ecc", P_TYPE_BOOL},
381 {"gpd.tee.trustedStorage.antiRollback.protectionLevel", P_TYPE_INT},
382 {"gpd.tee.trustedos.implementation.version", P_TYPE_STRING},
383 {"gpd.tee.trustedos.implementation.binaryversion", P_TYPE_INT},
384 {"gpd.tee.trustedos.manufacturer", P_TYPE_STRING},
385 {"gpd.tee.firmware.implementation.version", P_TYPE_STRING},
386 {"gpd.tee.firmware.implementation.binaryversion", P_TYPE_INT},
387 {"gpd.tee.firmware.manufacturer", P_TYPE_STRING},
388 {"myprop.true", P_TYPE_BOOL},
389 {"myprop.42", P_TYPE_INT},
390 {"myprop.123", P_TYPE_UUID},
391 {"myprop.1234", P_TYPE_IDENTITY},
392 {"myprop.hello", P_TYPE_STRING},
393 {"myprop.binaryblock", P_TYPE_BINARY_BLOCK},
Etienne Carriereb34caff2020-05-26 09:25:35 +0200394 {"myprop.binaryblock.1byte-ones", P_TYPE_BINARY_BLOCK},
395 {"myprop.binaryblock.2byte-ones", P_TYPE_BINARY_BLOCK},
396 {"myprop.binaryblock.3byte-ones", P_TYPE_BINARY_BLOCK},
397 {"myprop.binaryblock.4byte-ones", P_TYPE_BINARY_BLOCK},
Pascal Brandc639ac82015-07-02 08:53:34 +0200398 };
399 const size_t num_p_attrs = sizeof(p_attrs) / sizeof(p_attrs[0]);
Etienne Carriere102092e2019-03-28 15:24:22 +0100400 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200401
402 res = TEE_AllocatePropertyEnumerator(&h);
403 if (res != TEE_SUCCESS) {
404 EMSG("TEE_AllocatePropertyEnumerator: returned 0x%x\n",
405 (unsigned int)res);
406 return TEE_ERROR_GENERIC;
407 }
408
409 printf("Getting properties for current TA\n");
410 res = print_properties(h, TEE_PROPSET_CURRENT_TA, p_attrs, num_p_attrs);
411 if (res != TEE_SUCCESS)
412 goto cleanup_return;
413
414 printf("Getting properties for current client\n");
415 res = print_properties(h, TEE_PROPSET_CURRENT_CLIENT, p_attrs,
416 num_p_attrs);
417 if (res != TEE_SUCCESS)
418 goto cleanup_return;
419
420 printf("Getting properties for implementation\n");
421 res = print_properties(h, TEE_PROPSET_TEE_IMPLEMENTATION, p_attrs,
422 num_p_attrs);
423 if (res != TEE_SUCCESS)
424 goto cleanup_return;
425
426 for (n = 0; n < num_p_attrs; n++) {
427 if (!p_attrs[n].retrieved) {
428 EMSG("\"%s\" not retrieved\n", p_attrs[n].str);
429 res = TEE_ERROR_GENERIC;
430 goto cleanup_return;
431 }
432 }
433
434cleanup_return:
435 TEE_FreePropertyEnumerator(h);
436 return res;
437}
438
439static TEE_Result test_mem_access_right(uint32_t param_types,
440 TEE_Param params[4])
441{
442 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100443 TEE_Result res = TEE_ERROR_GENERIC;
444 uint32_t ret_orig = 0;
445 uint32_t l_pts = 0;
446 TEE_Param l_params[4] = { };
447 uint8_t buf[32] = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200448 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100449 TEE_UUID *uuid = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200450
451 if (param_types !=
452 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
453 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200454
455 /* test access rights on memref parameter */
456 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
457 TEE_MEMORY_ACCESS_ANY_OWNER,
458 params[0].memref.buffer,
459 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200460 if (res != TEE_SUCCESS)
461 return res;
Etienne Carriere281065d2016-10-28 15:41:33 +0200462
Pascal Brandc639ac82015-07-02 08:53:34 +0200463 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
464 params[0].memref.buffer,
465 params[0].memref.size);
466 if (res != TEE_ERROR_ACCESS_DENIED)
467 return TEE_ERROR_GENERIC;
468
Etienne Carriere281065d2016-10-28 15:41:33 +0200469 /* test access rights on private read-only and read-write memory */
470 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
471 (void *)&test_uuid, sizeof(test_uuid));
472 if (res != TEE_SUCCESS)
473 return res;
474
475 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_WRITE,
476 (void *)&test_uuid, sizeof(test_uuid));
477 if (res == TEE_SUCCESS)
478 return TEE_ERROR_GENERIC;
479
480 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
481 TEE_MEMORY_ACCESS_WRITE,
482 &ret_orig, sizeof(ret_orig));
483 if (res != TEE_SUCCESS)
484 return res;
485
486 uuid = TEE_Malloc(sizeof(*uuid), 0);
487 if (!uuid)
488 return TEE_ERROR_OUT_OF_MEMORY;
489
490 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
491 TEE_MEMORY_ACCESS_WRITE,
492 uuid, sizeof(*uuid));
493 TEE_Free(uuid);
494 if (res != TEE_SUCCESS)
495 return res;
496
497 /* test access rights on invalid memory (at least lower 256kB) */
498 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
499 NULL, 1);
500 if (res == TEE_SUCCESS)
501 return TEE_ERROR_GENERIC;
502
503 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
504 (void*)(256 * 1024), 1);
505 if (res == TEE_SUCCESS)
506 return TEE_ERROR_GENERIC;
507
Cedric Augere668b3f2019-09-11 13:41:21 +0200508 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
509 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200510 if (res != TEE_SUCCESS) {
511 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
512 goto cleanup_return;
513 }
514
Jerome Forissier04511d82018-01-30 14:33:49 +0100515 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
516 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200517 l_params[0].memref.buffer = buf;
518 l_params[0].memref.size = sizeof(buf);
Jerome Forissier04511d82018-01-30 14:33:49 +0100519 l_params[1].memref.buffer = NULL;
520 l_params[1].memref.size = 0;
Cedric Augere668b3f2019-09-11 13:41:21 +0200521 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
522 TA_OS_TEST_CMD_PARAMS_ACCESS,
Pascal Brandc639ac82015-07-02 08:53:34 +0200523 l_pts, l_params, &ret_orig);
524 if (res != TEE_SUCCESS) {
525 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
526 goto cleanup_return;
527 }
528
529cleanup_return:
530 TEE_CloseTASession(sess);
531 return res;
532}
533
534static TEE_Result test_time(void)
535{
Etienne Carriere102092e2019-03-28 15:24:22 +0100536 TEE_Result res = TEE_ERROR_GENERIC;
537 TEE_Time t = { };
538 TEE_Time sys_t = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200539 static const TEE_Time null_time = { 0, 0 };
540 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
541
542 TEE_GetSystemTime(&sys_t);
543 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
544 (unsigned int)sys_t.millis);
545
546 TEE_GetREETime(&t);
547 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
548 (unsigned int)t.millis);
549
550 res = TEE_GetTAPersistentTime(&t);
551 switch (res) {
552 case TEE_SUCCESS:
553 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
554 (unsigned int)t.millis);
555 break;
556 case TEE_ERROR_OVERFLOW:
557 EMSG("Stored TA time overflowed %u.%03u\n",
558 (unsigned int)t.seconds, (unsigned int)t.millis);
559 break;
560 case TEE_ERROR_TIME_NOT_SET:
561 EMSG("TA time not stored\n");
562 break;
563 case TEE_ERROR_TIME_NEEDS_RESET:
564 EMSG("TA time needs reset\n");
565 break;
566 default:
567 return res;
568 }
569
570 res = TEE_SetTAPersistentTime(&null_time);
571 if (res != TEE_SUCCESS) {
572 EMSG("TEE_SetTAPersistentTime: failed\n");
573 return res;
574 }
575
576 res = TEE_GetTAPersistentTime(&t);
577 if (res != TEE_SUCCESS) {
578 EMSG("TEE_GetTAPersistentTime null: failed\n");
579 return res;
580 }
581 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
582 (unsigned int)t.millis);
583 /*
584 * The time between TEE_SetTAPersistentTime() and
585 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
586 * it's not even a millisecond.
587 */
588 if (t.seconds > 1 || t.millis >= 1000) {
589 EMSG("Unexpected stored TA time %u.%03u\n",
590 (unsigned int)t.seconds, (unsigned int)t.millis);
591 return TEE_ERROR_BAD_STATE;
592 }
593
594 res = TEE_SetTAPersistentTime(&wrap_time);
595 if (res != TEE_SUCCESS) {
596 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
597 return res;
598 }
599
600 res = TEE_Wait(1000);
601 if (res != TEE_SUCCESS)
602 EMSG("TEE_Wait wrap: failed\n");
603
604 res = TEE_GetTAPersistentTime(&t);
605 if (res != TEE_ERROR_OVERFLOW) {
606 EMSG("TEE_GetTAPersistentTime: failed\n");
607 return TEE_ERROR_BAD_STATE;
608 }
609 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
610 (unsigned int)t.millis);
611
612 if (t.seconds > sys_t.seconds) {
613 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
614 (unsigned int)t.seconds, (unsigned int)t.millis,
615 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
616 return TEE_ERROR_BAD_STATE;
617 }
618
619 return TEE_SUCCESS;
620}
621
Jens Wiklander246184a2015-12-11 08:28:59 +0100622#ifdef CFG_TA_FLOAT_SUPPORT
623static bool my_dcmpeq(double v1, double v2, double prec)
624{
625 return v1 > (v2 - prec) && v1 < (v2 + prec);
626}
627
628static bool my_fcmpeq(float v1, float v2, float prec)
629{
630 return v1 > (v2 - prec) && v1 < (v2 + prec);
631}
632
633
634static TEE_Result test_float(void)
635{
636#define VAL1 2.6
637#define VAL1_INT 2
638#define VAL2 5.3
639#define DPREC 0.000000000000001
640#define FPREC 0.000001
641#define EXPECT(expr) do { \
642 if (!(expr)) { \
643 EMSG("Expression %s failed", #expr); \
644 return TEE_ERROR_GENERIC; \
645 } \
646 } while (0)
647
648 IMSG("Testing floating point operations");
649
650 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
651 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
652 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
653 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
654 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
655
656 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
657 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
658 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
659 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
660 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
661
662 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
663 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
664 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
665 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
666 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
667
668 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
669 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
670 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
671 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
672 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
673
674 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
675 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
676 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
677 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
678
679 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
680 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
681 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
682 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
683
684 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
685 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
686
687 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
688 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
689 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
690 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
691
692 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
693 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
694 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
695 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
696 return TEE_SUCCESS;
697}
698#else /*CFG_TA_FLOAT_SUPPORT*/
699static TEE_Result test_float(void)
700{
701 IMSG("Floating point disabled");
702 return TEE_SUCCESS;
703}
704#endif /*CFG_TA_FLOAT_SUPPORT*/
705
Jerome Forissier892ae4d2020-03-09 09:58:09 +0100706static __noinline __noreturn void call_longjmp(jmp_buf env)
Jens Wiklander9f682c62016-03-27 20:23:06 +0200707{
708 DMSG("Calling longjmp");
709 longjmp(env, 1);
710 EMSG("error: longjmp returned to calling function");
711}
712
713static TEE_Result test_setjmp(void)
714{
Etienne Carriere102092e2019-03-28 15:24:22 +0100715 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200716
717 if (setjmp(env)) {
718 IMSG("Returned via longjmp");
719 return TEE_SUCCESS;
720 } else {
721 call_longjmp(env);
722 return TEE_ERROR_GENERIC;
723 }
724}
725
Pascal Brandc639ac82015-07-02 08:53:34 +0200726TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
727{
728 TEE_Result res = TEE_ERROR_GENERIC;
729
730 printf("ta_entry_basic: enter\n");
731
732 res = test_malloc();
733 if (res != TEE_SUCCESS)
734 return res;
735
736 res = test_properties();
737 if (res != TEE_SUCCESS)
738 return res;
739
740 res = test_mem_access_right(param_types, params);
741 if (res != TEE_SUCCESS)
742 return res;
743
744 res = test_time();
745 if (res != TEE_SUCCESS)
746 return res;
747
Jens Wiklander246184a2015-12-11 08:28:59 +0100748 res = test_float();
749 if (res != TEE_SUCCESS)
750 return res;
751
Jens Wiklander9f682c62016-03-27 20:23:06 +0200752 res = test_setjmp();
753 if (res != TEE_SUCCESS)
754 return res;
755
Pascal Brandc639ac82015-07-02 08:53:34 +0200756 return TEE_SUCCESS;
757}
758
759TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
760{
761 volatile bool mytrue = true;
762 (void)param_types;
763 (void)params;
764
765 printf("ta_entry_panic: enter\n");
766 /*
767 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
768 * the __noreturn attribute.
769 */
770 if (mytrue)
771 TEE_Panic(0xbeef);
772
773 /*
774 * Should not be reached, but if it is the testsuite can detect that
775 * TEE_Panic() returned instead of panicking the TA.
776 */
777 return TEE_SUCCESS;
778}
779
780TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
781 TEE_Param params[4])
782{
783 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100784 TEE_Result res = TEE_ERROR_GENERIC;
785 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
786 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200787
788 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
789 TEE_PARAM_TYPE_NONE,
790 TEE_PARAM_TYPE_NONE,
791 TEE_PARAM_TYPE_NONE)) {
792 EMSG("ta_entry_client_with_timeout: bad parameters\n");
793 return TEE_ERROR_BAD_PARAMETERS;
794 }
795
Cedric Augere668b3f2019-09-11 13:41:21 +0200796 res = TEE_OpenTASession(&os_test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
797 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200798 if (res != TEE_SUCCESS) {
799 EMSG(
800 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
801 return res;
802 }
803
804 res =
805 TEE_InvokeTACommand(sess, params[0].value.a / 2,
806 TA_OS_TEST_CMD_WAIT, param_types, params,
807 &ret_orig);
808
809 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
810 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
811 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
812 (unsigned int)ret_orig);
813 res = TEE_ERROR_GENERIC;
814 } else
815 res = TEE_SUCCESS;
816
817 TEE_CloseTASession(sess);
818 return res;
819
820}
821
822TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
823{
824 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100825 TEE_Result res = TEE_ERROR_GENERIC;
826 uint32_t l_pts = 0;
827 TEE_Param l_params[4] = { };
828 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
829 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200830 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
831 static const uint8_t sha256_out[] = {
832 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
833 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
834 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
835 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
836 };
837 uint8_t out[32] = { 0 };
838 void *in = NULL;
839
840 (void)param_types;
841 (void)params;
842
843 printf("ta_entry_client: enter\n");
844
845 in = TEE_Malloc(sizeof(sha256_in), 0);
846 if (in == NULL)
847 return TEE_ERROR_OUT_OF_MEMORY;
848 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
849
Cedric Augere668b3f2019-09-11 13:41:21 +0200850 res = TEE_OpenTASession(&crypt_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
851 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200852 if (res != TEE_SUCCESS) {
853 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
854 goto cleanup_return;
855 }
856
857 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
858 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
859 l_params[0].memref.buffer = in;
860 l_params[0].memref.size = sizeof(sha256_in);
861 l_params[1].memref.buffer = out;
862 l_params[1].memref.size = sizeof(out);
863
Cedric Augere668b3f2019-09-11 13:41:21 +0200864 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
865 TA_CRYPT_CMD_SHA256, l_pts, l_params,
Pascal Brandc639ac82015-07-02 08:53:34 +0200866 &ret_orig);
867 if (res != TEE_SUCCESS) {
868 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
869 goto cleanup_return;
870 }
871
872 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
873 EMSG("ta_entry_client: out parameter failed\n");
874 res = TEE_ERROR_GENERIC;
875 goto cleanup_return;
876 }
877
878cleanup_return:
879 TEE_Free(in);
880 TEE_CloseTASession(sess);
881 return res;
882}
883
Etienne Carriere281065d2016-10-28 15:41:33 +0200884TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200885{
Etienne Carriere102092e2019-03-28 15:24:22 +0100886 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200887
888 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100889 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
890 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200891 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200892
893 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
894 TEE_MEMORY_ACCESS_ANY_OWNER,
895 params[0].memref.buffer,
896 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200897 if (res != TEE_SUCCESS)
898 return res;
899
900 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
901 params[0].memref.buffer,
902 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200903 if (res != TEE_ERROR_ACCESS_DENIED)
904 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +0100905 if (params[1].memref.buffer || params[1].memref.size)
906 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200907
Etienne Carriere281065d2016-10-28 15:41:33 +0200908 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200909}
910
911TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
912{
913 TEE_Result res = TEE_SUCCESS;
914 (void)param_types;
915
916 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
917 /* Wait */
918 res = TEE_Wait(params[0].value.a);
919
920 return res;
921}
922
Jens Wiklander1425f952016-07-21 09:02:30 +0200923static void undef_instr(void)
924{
925#if defined(ARM64)
926 __asm__(".word 0x0");
927#elif defined(ARM32)
928 __asm__(".word 0xe7ffffff");
929#else
930#error "Unsupported architecture"
931#endif
932}
933
Pascal Brandc639ac82015-07-02 08:53:34 +0200934TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
935{
Etienne Carriere102092e2019-03-28 15:24:22 +0100936 long int stack = 0;
937 long int stack_addr = (long int)&stack;
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200938 void (*volatile null_fn_ptr)(void) = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200939
Etienne Carriere92c34422018-02-09 13:11:40 +0100940 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
941 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
942 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200943 return TEE_ERROR_GENERIC;
944
945 switch (params[0].value.a) {
946 case 1:
Jerome Forissier71da60f2019-09-19 15:59:56 +0200947 *((volatile uint32_t *)0) = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200948 break;
949 case 2:
950 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
951 break;
952 case 3:
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200953 null_fn_ptr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200954 break;
955 case 4:
956 ((void (*)(void))(stack_addr + 0x40000000)) ();
957 break;
958 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +0200959 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200960 break;
961 default:
962 break;
963 }
964
965 return TEE_SUCCESS;
966}
Jerome Forissiere916b102017-06-07 17:55:52 +0200967
968static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
969{
Etienne Carriere102092e2019-03-28 15:24:22 +0100970 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +0200971
972 for (i = 0; i < bufsize; i++) {
973 a[i]++; b[i]++; c[i]++;
974 }
975}
976
Etienne Carriere102092e2019-03-28 15:24:22 +0100977#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +0200978TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
979{
980 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
981 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100982 TEE_Param l_params[4] = { };
983 uint8_t in[TA2TA_BUF_SIZE] = { };
984 uint8_t inout[TA2TA_BUF_SIZE] = { };
985 uint8_t out[TA2TA_BUF_SIZE] = { };
986 TEE_Result res = TEE_ERROR_GENERIC;
987 uint32_t ret_orig = 0;
988 uint32_t l_pts = 0;
989 size_t i = 0;
990
Jerome Forissiere916b102017-06-07 17:55:52 +0200991 (void)params;
992
993 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
994 return TEE_ERROR_GENERIC;
995
Cedric Augere668b3f2019-09-11 13:41:21 +0200996 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
997 &sess, &ret_orig);
Jerome Forissiere916b102017-06-07 17:55:52 +0200998 if (res != TEE_SUCCESS) {
999 EMSG("TEE_OpenTASession failed");
1000 goto cleanup_return;
1001 }
1002
1003 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1004 TEE_PARAM_TYPE_MEMREF_INOUT,
1005 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
1006 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +01001007 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001008 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +01001009 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001010 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +01001011 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001012
1013 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +01001014 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001015 in[i] = 5;
1016 inout[i] = 10;
1017 out[i] = 0;
1018 }
1019
1020 /*
1021 * TA will compute: out = ++inout + in
1022 * Expected values after this step: in: 5, inout: 11, out: 16
1023 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001024 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1025 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001026 l_pts, l_params, &ret_orig);
1027 if (res != TEE_SUCCESS) {
1028 EMSG("TEE_InvokeTACommand failed");
1029 goto cleanup_return;
1030 }
Etienne Carriere102092e2019-03-28 15:24:22 +01001031
Jerome Forissiere916b102017-06-07 17:55:52 +02001032 /*
1033 * Increment all values by one.
1034 * Expected values after this step: in: 6, inout: 12, out: 17
1035 */
Etienne Carriere102092e2019-03-28 15:24:22 +01001036 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +02001037
1038 /*
1039 * TA will compute: out = ++inout + in
1040 * Expected values after this step: in: 6, inout: 13, out: 19
1041 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001042 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1043 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001044 l_pts, l_params, &ret_orig);
1045 if (res != TEE_SUCCESS) {
1046 EMSG("TEE_InvokeTACommand failed");
1047 goto cleanup_return;
1048 }
1049
1050 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001051 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001052 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1053 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001054 DHEXDUMP(in, TA2TA_BUF_SIZE);
1055 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1056 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001057 return TEE_ERROR_GENERIC;
1058 }
1059 }
1060
1061cleanup_return:
1062 TEE_CloseTASession(sess);
1063 return res;
1064}
1065
1066TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1067{
Etienne Carriere102092e2019-03-28 15:24:22 +01001068 uint8_t *in = NULL;
1069 uint8_t *inout = NULL;
1070 uint8_t *out = NULL;
1071 size_t bufsize = 0;
1072 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001073
1074 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1075 TEE_PARAM_TYPE_MEMREF_INOUT,
1076 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1077 return TEE_ERROR_GENERIC;
1078
1079 bufsize = params[0].memref.size;
1080 if (params[1].memref.size != bufsize ||
1081 params[2].memref.size != bufsize)
1082 return TEE_ERROR_GENERIC;
1083
1084 in = params[0].memref.buffer;
1085 inout = params[1].memref.buffer;
1086 out = params[2].memref.buffer;
1087
1088 for (i = 0; i < bufsize; i++)
1089 out[i] = ++inout[i] + in[i];
1090
1091 return TEE_SUCCESS;
1092}
Jens Wiklander87e81702018-03-20 12:00:00 +08001093
1094TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1095{
Etienne Carriere102092e2019-03-28 15:24:22 +01001096 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001097
1098 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1099 TEE_PARAM_TYPE_MEMREF_INPUT,
1100 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1101 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1102 return TEE_ERROR_BAD_PARAMETERS;
1103
1104 for (n = 0; n < TEE_NUM_PARAMS; n++)
1105 if (!params[n].memref.buffer || !params[n].memref.size)
1106 return TEE_ERROR_BAD_PARAMETERS;
1107
1108 return TEE_SUCCESS;
1109}
Jerome Forissier53bde722018-05-31 09:14:54 +02001110
Cedric Neveux9f483bb2019-03-04 08:58:06 +01001111TEE_Result ta_entry_null_memref(uint32_t param_types, TEE_Param params[4])
1112{
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 /*
1120 * Tests how client can provide null or non-null memref parameters
1121 * param[0] expected as a 0 byte input mapped memeref.
1122 * param[1] expected as a 0 byte input not-mapped memeref.
1123 * param[2] expected as a 0 byte output mapped memeref.
1124 * param[3] expected as a 0 byte output not-mapped memeref.
1125 */
1126 if (!params[0].memref.buffer || params[0].memref.size ||
1127 params[1].memref.buffer || params[1].memref.size ||
1128 !params[2].memref.buffer || params[2].memref.size ||
1129 params[3].memref.buffer || params[3].memref.size)
1130 return TEE_ERROR_BAD_PARAMETERS;
1131
1132 return TEE_SUCCESS;
1133}
1134
Jerome Forissier53bde722018-05-31 09:14:54 +02001135TEE_Result ta_entry_call_lib(uint32_t param_types,
1136 TEE_Param params[4] __unused)
1137{
1138 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1139 TEE_PARAM_TYPE_NONE,
1140 TEE_PARAM_TYPE_NONE,
1141 TEE_PARAM_TYPE_NONE))
1142 return TEE_ERROR_BAD_PARAMETERS;
1143
1144 if (os_test_shlib_add(1, 2) != 3)
1145 return TEE_ERROR_GENERIC;
1146
1147 return TEE_SUCCESS;
1148}
1149
1150TEE_Result ta_entry_call_lib_panic(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 os_test_shlib_panic();
1160
1161 return TEE_ERROR_GENERIC;
1162}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001163
1164TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1165 TEE_Param params[4] __unused)
1166{
1167 int (*add_func)(int a, int b) = NULL;
1168 TEE_Result res = TEE_ERROR_GENERIC;
1169 void *handle = NULL;
1170 void *hnull = NULL;
1171
1172 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1173 TEE_PARAM_TYPE_NONE,
1174 TEE_PARAM_TYPE_NONE,
1175 TEE_PARAM_TYPE_NONE))
1176 return TEE_ERROR_BAD_PARAMETERS;
1177
1178 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1179 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1180 if (!handle)
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001181 return TEE_ERROR_GENERIC;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001182
1183 add_func = dlsym(handle, "os_test_shlib_dl_add");
1184 if (!add_func)
1185 goto err;
1186 if (add_func(3, 4) != 7)
1187 goto err;
1188
1189 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001190 if (!hnull)
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001191 goto err;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001192
1193 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1194 if (!add_func)
1195 goto err;
1196 if (add_func(5, 6) != 11)
1197 goto err;
1198
1199 res = TEE_SUCCESS;
1200 dlclose(hnull);
1201err:
1202 dlclose(handle);
1203 return res;
1204}
1205
1206TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1207 TEE_Param params[4] __unused)
1208{
1209 int (*panic_func)(void) = NULL;
1210 void *handle = NULL;
1211 TEE_Result res = TEE_ERROR_GENERIC;
1212
1213 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1214 TEE_PARAM_TYPE_NONE,
1215 TEE_PARAM_TYPE_NONE,
1216 TEE_PARAM_TYPE_NONE))
1217 return TEE_ERROR_BAD_PARAMETERS;
1218
1219 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1220 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1221 if (!handle)
1222 return res;
1223
1224 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1225 if (!panic_func)
1226 goto err;
1227 panic_func();
1228 return TEE_ERROR_GENERIC;
1229err:
1230 dlclose(handle);
1231 return res;
1232}
Jerome Forissiere9571e82020-02-18 15:26:20 +01001233
1234/* ELF initialization/finalization test */
1235
1236int os_test_global;
1237
1238static void __attribute__((constructor)) os_test_init(void)
1239{
1240 os_test_global *= 10;
1241 os_test_global += 1;
1242 DMSG("os_test_global=%d", os_test_global);
1243}
1244
1245TEE_Result ta_entry_get_global_var(uint32_t param_types, TEE_Param params[4])
1246{
1247 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1248 TEE_PARAM_TYPE_NONE,
1249 TEE_PARAM_TYPE_NONE,
1250 TEE_PARAM_TYPE_NONE))
1251 return TEE_ERROR_BAD_PARAMETERS;
1252
1253 params[0].value.a = os_test_global;
1254
1255 return TEE_SUCCESS;
1256}
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001257
1258TEE_Result ta_entry_client_identity(uint32_t param_types, TEE_Param params[4])
1259{
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001260 TEE_Result res = TEE_ERROR_GENERIC;
1261 TEE_Identity identity = { };
1262
1263 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1264 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1265 TEE_PARAM_TYPE_NONE,
1266 TEE_PARAM_TYPE_NONE))
1267 return TEE_ERROR_BAD_PARAMETERS;
1268
1269 if (params[1].memref.size < sizeof(TEE_UUID)) {
1270 params[1].memref.size = sizeof(TEE_UUID);
1271 return TEE_ERROR_SHORT_BUFFER;
1272 }
1273
1274 res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
1275 "gpd.client.identity", &identity);
1276 if (res != TEE_SUCCESS) {
1277 EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32, res);
1278 return res;
1279 }
1280
1281 params[0].value.a = identity.login;
1282 memcpy(params[1].memref.buffer, &identity.uuid, sizeof(TEE_UUID));
1283 params[1].memref.size = sizeof(TEE_UUID);
1284
1285 return res;
1286}