blob: 737ca321401ecdd7410229a2155bbadf64253b16 [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
Pascal Brandc639ac82015-07-02 08:53:34 +020054static TEE_Result print_properties(TEE_PropSetHandle h,
55 TEE_PropSetHandle prop_set,
56 struct p_attr *p_attrs, size_t num_p_attrs)
57{
Etienne Carriere102092e2019-03-28 15:24:22 +010058TEE_Result res = TEE_ERROR_GENERIC;
59size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +020060
61TEE_StartPropertyEnumerator(h, prop_set);
62
63while (true) {
Etienne Carriere102092e2019-03-28 15:24:22 +010064 char nbuf[256] = { };
65 char nbuf_small[256] = { };
66 char vbuf[256] = { };
67 char vbuf2[256] = { };
Jens Wiklanderc5231592015-11-11 09:27:27 +010068 uint32_t nblen = sizeof(nbuf);
Etienne Carriere102092e2019-03-28 15:24:22 +010069 uint32_t nblen_small = 0;
Jens Wiklanderc5231592015-11-11 09:27:27 +010070 uint32_t vblen = sizeof(vbuf);
71 uint32_t vblen2 = sizeof(vbuf2);
Pascal Brandc639ac82015-07-02 08:53:34 +020072
73 res = TEE_GetPropertyName(h, nbuf, &nblen);
74 if (res != TEE_SUCCESS) {
75 EMSG("TEE_GetPropertyName returned 0x%x\n",
76 (unsigned int)res);
77 return res;
78 }
Pascal Brand624b6a32016-02-16 12:51:34 +010079 if (nblen != strlen(nbuf) + 1) {
Pascal Brand5b68cd62016-02-22 10:31:01 +010080 EMSG("Name has wrong size: %u vs %zu", nblen, strlen(nbuf) + 1);
Pascal Brand624b6a32016-02-16 12:51:34 +010081 return TEE_ERROR_GENERIC;
82 }
Pascal Brandc639ac82015-07-02 08:53:34 +020083
Pascal Brand624b6a32016-02-16 12:51:34 +010084
85 /* Get the property name with a very small buffer */
86 nblen_small = 2;
87 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
88 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
89 nblen_small, nblen);
90 if (res != TEE_SUCCESS)
91 return res;
92
93 /* Get the property name with almost the correct buffer */
94 nblen_small = nblen - 1;
95 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
96 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
97 nblen_small, nblen);
98 if (res != TEE_SUCCESS)
99 return res;
100
101 /* Get the property name with the exact buffer length */
102 nblen_small = nblen;
103 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
104 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
105 nblen_small, nblen);
106 if (res != TEE_SUCCESS)
107 return res;
108
109 /* Get the property value */
Pascal Brandc639ac82015-07-02 08:53:34 +0200110 res = TEE_GetPropertyAsString(h, NULL, vbuf, &vblen);
Pascal Brand624b6a32016-02-16 12:51:34 +0100111 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
112 vblen, strlen(vbuf) + 1);
113 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200114 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100115
Pascal Brandc639ac82015-07-02 08:53:34 +0200116 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
Pascal Brand624b6a32016-02-16 12:51:34 +0100117 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
118 vblen2, strlen(vbuf2) + 1);
119 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200120 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100121
Jens Wiklander8324ff22018-11-21 14:16:04 +0100122 if (strcmp(vbuf, vbuf2) != 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200123 EMSG("String of \"%s\" differs\n", nbuf);
124 return TEE_ERROR_GENERIC;
125 }
126
Pascal Brand624b6a32016-02-16 12:51:34 +0100127 /* Get the property with a very small buffer */
128 vblen2 = 1;
129 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
130 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
131 vblen2, vblen);
132 if (res != TEE_SUCCESS)
133 return res;
134
135 /* Get the property with almost the correct buffer */
136 vblen2 = vblen - 1;
137 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
138 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
139 vblen2, vblen);
140 if (res != TEE_SUCCESS)
141 return res;
142
143 /* Get the property name with the exact buffer length */
144 vblen2 = vblen;
145 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
146 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS, vblen2, vblen);
147 if (res != TEE_SUCCESS)
148 return res;
149
150 /* check specific myprop.hello property, which is larger than 80 */
151 if (!strcmp("myprop.hello", nbuf) &&
152 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")) {
153 EMSG("TEE_GetPropertyAsString(\"%s\") is truncated - returned \"%s\"\n",
154 nbuf, vbuf);
155 return TEE_ERROR_GENERIC;
156 }
157
Pascal Brandc639ac82015-07-02 08:53:34 +0200158 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
159
160 for (n = 0; n < num_p_attrs; n++) {
Jens Wiklander8324ff22018-11-21 14:16:04 +0100161 if (strcmp(nbuf, p_attrs[n].str) != 0)
Pascal Brandc639ac82015-07-02 08:53:34 +0200162 continue;
163
164 if (p_attrs[n].retrieved) {
165 EMSG("Value \"%s\" already retrieved\n",
166 p_attrs[n].str);
167 return TEE_ERROR_GENERIC;
168 }
169 p_attrs[n].retrieved = true;
170
171 switch (p_attrs[n].type) {
172 case P_TYPE_BOOL:
173 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100174 bool v = false;
Pascal Brandc639ac82015-07-02 08:53:34 +0200175
176 res =
177 TEE_GetPropertyAsBool(h, NULL, &v);
178 if (res != TEE_SUCCESS) {
179 EMSG(
180 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
181 nbuf, (unsigned int)res);
182 return res;
183 }
184 }
185 break;
186
187 case P_TYPE_INT:
188 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100189 uint32_t v = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200190
191 res = TEE_GetPropertyAsU32(h, NULL, &v);
192 if (res != TEE_SUCCESS) {
193 EMSG(
194 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
195 nbuf, (unsigned int)res);
196 return res;
197 }
198 }
199 break;
200
201 case P_TYPE_UUID:
202 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100203 TEE_UUID v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200204
205 res =
206 TEE_GetPropertyAsUUID(h, NULL, &v);
207 if (res != TEE_SUCCESS) {
208 EMSG(
209 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
210 nbuf, (unsigned int)res);
211 return res;
212 }
213 }
214 break;
215
216 case P_TYPE_IDENTITY:
217 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100218 TEE_Identity v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200219
220 res =
221 TEE_GetPropertyAsIdentity(h, NULL,
222 &v);
223 if (res != TEE_SUCCESS) {
224 EMSG(
225 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
226 nbuf, (unsigned int)res);
227 return res;
228 }
229 }
230 break;
231
232 case P_TYPE_STRING:
233 /* Already read as string */
234 break;
235
236 case P_TYPE_BINARY_BLOCK:
237 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100238 char bbuf[80] = { };
Jens Wiklanderc5231592015-11-11 09:27:27 +0100239 uint32_t bblen = sizeof(bbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200240
241 res =
242 TEE_GetPropertyAsBinaryBlock(h,
243 NULL,
244 bbuf,
245 &bblen);
246 if (res != TEE_SUCCESS) {
247 EMSG(
248 "TEE_GetPropertyAsBinaryBlock(\"%s\") returned 0x%x\n",
249 nbuf, (unsigned int)res);
250 return res;
251 }
Jens Wiklander8324ff22018-11-21 14:16:04 +0100252 if (strcmp("myprop.binaryblock", nbuf) == 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200253 const char exp_bin_value[] =
254 "Hello world!";
255
Etienne Carriere102092e2019-03-28 15:24:22 +0100256 if (bblen != strlen(exp_bin_value) ||
257 TEE_MemCompare(exp_bin_value, bbuf,
258 bblen) != 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200259 EMSG(
260 "Binary buffer of \"%s\" differs from \"%s\"\n",
261 nbuf, exp_bin_value);
262 EMSG(
263 "Got \"%s\"\n",
264 bbuf);
265 return
266 TEE_ERROR_GENERIC;
267 }
268 }
269
270 }
271 break;
272
273 default:
274 EMSG("Unknown type (%d) for \"%s\"\n",
275 p_attrs[n].type, p_attrs[n].str);
276 return TEE_ERROR_GENERIC;
277 }
278 }
279
280 res = TEE_GetNextProperty(h);
281 if (res != TEE_SUCCESS) {
282 if (res == TEE_ERROR_ITEM_NOT_FOUND)
283 return TEE_SUCCESS;
284 return res;
285 }
286}
287}
288
289static TEE_Result test_malloc(void)
290{
291 void *p = TEE_Malloc(4, 0);
292
293 if (p == NULL) {
294 EMSG("TEE_Malloc failed\n");
295 return TEE_ERROR_OUT_OF_MEMORY;
296 }
297 TEE_Free(p);
298 TEE_Free(NULL);
299
300 return TEE_SUCCESS;
301}
302
303static TEE_Result test_properties(void)
304{
305 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriere102092e2019-03-28 15:24:22 +0100306 TEE_PropSetHandle h = TEE_HANDLE_NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200307 struct p_attr p_attrs[] = {
308 {"gpd.ta.appID", P_TYPE_UUID},
309 {"gpd.ta.singleInstance", P_TYPE_BOOL},
310 {"gpd.ta.multiSession", P_TYPE_BOOL},
311 {"gpd.ta.instanceKeepAlive", P_TYPE_BOOL},
312 {"gpd.ta.dataSize", P_TYPE_INT},
313 {"gpd.ta.stackSize", P_TYPE_INT},
314 {"gpd.ta.version", P_TYPE_STRING},
315 {"gpd.ta.description", P_TYPE_STRING},
316 {"gpd.client.identity", P_TYPE_IDENTITY},
317 {"gpd.tee.apiversion", P_TYPE_STRING},
318 {"gpd.tee.description", P_TYPE_STRING},
319 {"gpd.tee.deviceID", P_TYPE_UUID},
320 {"gpd.tee.systemTime.protectionLevel", P_TYPE_INT},
321 {"gpd.tee.TAPersistentTime.protectionLevel", P_TYPE_INT},
322 {"gpd.tee.arith.maxBigIntSize", P_TYPE_INT},
323 {"gpd.tee.cryptography.ecc", P_TYPE_BOOL},
324 {"gpd.tee.trustedStorage.antiRollback.protectionLevel", P_TYPE_INT},
325 {"gpd.tee.trustedos.implementation.version", P_TYPE_STRING},
326 {"gpd.tee.trustedos.implementation.binaryversion", P_TYPE_INT},
327 {"gpd.tee.trustedos.manufacturer", P_TYPE_STRING},
328 {"gpd.tee.firmware.implementation.version", P_TYPE_STRING},
329 {"gpd.tee.firmware.implementation.binaryversion", P_TYPE_INT},
330 {"gpd.tee.firmware.manufacturer", P_TYPE_STRING},
331 {"myprop.true", P_TYPE_BOOL},
332 {"myprop.42", P_TYPE_INT},
333 {"myprop.123", P_TYPE_UUID},
334 {"myprop.1234", P_TYPE_IDENTITY},
335 {"myprop.hello", P_TYPE_STRING},
336 {"myprop.binaryblock", P_TYPE_BINARY_BLOCK},
337 };
338 const size_t num_p_attrs = sizeof(p_attrs) / sizeof(p_attrs[0]);
Etienne Carriere102092e2019-03-28 15:24:22 +0100339 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200340
341 res = TEE_AllocatePropertyEnumerator(&h);
342 if (res != TEE_SUCCESS) {
343 EMSG("TEE_AllocatePropertyEnumerator: returned 0x%x\n",
344 (unsigned int)res);
345 return TEE_ERROR_GENERIC;
346 }
347
348 printf("Getting properties for current TA\n");
349 res = print_properties(h, TEE_PROPSET_CURRENT_TA, p_attrs, num_p_attrs);
350 if (res != TEE_SUCCESS)
351 goto cleanup_return;
352
353 printf("Getting properties for current client\n");
354 res = print_properties(h, TEE_PROPSET_CURRENT_CLIENT, p_attrs,
355 num_p_attrs);
356 if (res != TEE_SUCCESS)
357 goto cleanup_return;
358
359 printf("Getting properties for implementation\n");
360 res = print_properties(h, TEE_PROPSET_TEE_IMPLEMENTATION, p_attrs,
361 num_p_attrs);
362 if (res != TEE_SUCCESS)
363 goto cleanup_return;
364
365 for (n = 0; n < num_p_attrs; n++) {
366 if (!p_attrs[n].retrieved) {
367 EMSG("\"%s\" not retrieved\n", p_attrs[n].str);
368 res = TEE_ERROR_GENERIC;
369 goto cleanup_return;
370 }
371 }
372
373cleanup_return:
374 TEE_FreePropertyEnumerator(h);
375 return res;
376}
377
378static TEE_Result test_mem_access_right(uint32_t param_types,
379 TEE_Param params[4])
380{
381 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100382 TEE_Result res = TEE_ERROR_GENERIC;
383 uint32_t ret_orig = 0;
384 uint32_t l_pts = 0;
385 TEE_Param l_params[4] = { };
386 uint8_t buf[32] = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200387 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100388 TEE_UUID *uuid = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200389
390 if (param_types !=
391 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
392 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200393
394 /* test access rights on memref parameter */
395 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
396 TEE_MEMORY_ACCESS_ANY_OWNER,
397 params[0].memref.buffer,
398 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200399 if (res != TEE_SUCCESS)
400 return res;
Etienne Carriere281065d2016-10-28 15:41:33 +0200401
Pascal Brandc639ac82015-07-02 08:53:34 +0200402 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
403 params[0].memref.buffer,
404 params[0].memref.size);
405 if (res != TEE_ERROR_ACCESS_DENIED)
406 return TEE_ERROR_GENERIC;
407
Etienne Carriere281065d2016-10-28 15:41:33 +0200408 /* test access rights on private read-only and read-write memory */
409 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
410 (void *)&test_uuid, sizeof(test_uuid));
411 if (res != TEE_SUCCESS)
412 return res;
413
414 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_WRITE,
415 (void *)&test_uuid, sizeof(test_uuid));
416 if (res == TEE_SUCCESS)
417 return TEE_ERROR_GENERIC;
418
419 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
420 TEE_MEMORY_ACCESS_WRITE,
421 &ret_orig, sizeof(ret_orig));
422 if (res != TEE_SUCCESS)
423 return res;
424
425 uuid = TEE_Malloc(sizeof(*uuid), 0);
426 if (!uuid)
427 return TEE_ERROR_OUT_OF_MEMORY;
428
429 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
430 TEE_MEMORY_ACCESS_WRITE,
431 uuid, sizeof(*uuid));
432 TEE_Free(uuid);
433 if (res != TEE_SUCCESS)
434 return res;
435
436 /* test access rights on invalid memory (at least lower 256kB) */
437 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
438 NULL, 1);
439 if (res == TEE_SUCCESS)
440 return TEE_ERROR_GENERIC;
441
442 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
443 (void*)(256 * 1024), 1);
444 if (res == TEE_SUCCESS)
445 return TEE_ERROR_GENERIC;
446
Cedric Augere668b3f2019-09-11 13:41:21 +0200447 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
448 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200449 if (res != TEE_SUCCESS) {
450 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
451 goto cleanup_return;
452 }
453
Jerome Forissier04511d82018-01-30 14:33:49 +0100454 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
455 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200456 l_params[0].memref.buffer = buf;
457 l_params[0].memref.size = sizeof(buf);
Jerome Forissier04511d82018-01-30 14:33:49 +0100458 l_params[1].memref.buffer = NULL;
459 l_params[1].memref.size = 0;
Cedric Augere668b3f2019-09-11 13:41:21 +0200460 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
461 TA_OS_TEST_CMD_PARAMS_ACCESS,
Pascal Brandc639ac82015-07-02 08:53:34 +0200462 l_pts, l_params, &ret_orig);
463 if (res != TEE_SUCCESS) {
464 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
465 goto cleanup_return;
466 }
467
468cleanup_return:
469 TEE_CloseTASession(sess);
470 return res;
471}
472
473static TEE_Result test_time(void)
474{
Etienne Carriere102092e2019-03-28 15:24:22 +0100475 TEE_Result res = TEE_ERROR_GENERIC;
476 TEE_Time t = { };
477 TEE_Time sys_t = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200478 static const TEE_Time null_time = { 0, 0 };
479 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
480
481 TEE_GetSystemTime(&sys_t);
482 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
483 (unsigned int)sys_t.millis);
484
485 TEE_GetREETime(&t);
486 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
487 (unsigned int)t.millis);
488
489 res = TEE_GetTAPersistentTime(&t);
490 switch (res) {
491 case TEE_SUCCESS:
492 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
493 (unsigned int)t.millis);
494 break;
495 case TEE_ERROR_OVERFLOW:
496 EMSG("Stored TA time overflowed %u.%03u\n",
497 (unsigned int)t.seconds, (unsigned int)t.millis);
498 break;
499 case TEE_ERROR_TIME_NOT_SET:
500 EMSG("TA time not stored\n");
501 break;
502 case TEE_ERROR_TIME_NEEDS_RESET:
503 EMSG("TA time needs reset\n");
504 break;
505 default:
506 return res;
507 }
508
509 res = TEE_SetTAPersistentTime(&null_time);
510 if (res != TEE_SUCCESS) {
511 EMSG("TEE_SetTAPersistentTime: failed\n");
512 return res;
513 }
514
515 res = TEE_GetTAPersistentTime(&t);
516 if (res != TEE_SUCCESS) {
517 EMSG("TEE_GetTAPersistentTime null: failed\n");
518 return res;
519 }
520 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
521 (unsigned int)t.millis);
522 /*
523 * The time between TEE_SetTAPersistentTime() and
524 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
525 * it's not even a millisecond.
526 */
527 if (t.seconds > 1 || t.millis >= 1000) {
528 EMSG("Unexpected stored TA time %u.%03u\n",
529 (unsigned int)t.seconds, (unsigned int)t.millis);
530 return TEE_ERROR_BAD_STATE;
531 }
532
533 res = TEE_SetTAPersistentTime(&wrap_time);
534 if (res != TEE_SUCCESS) {
535 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
536 return res;
537 }
538
539 res = TEE_Wait(1000);
540 if (res != TEE_SUCCESS)
541 EMSG("TEE_Wait wrap: failed\n");
542
543 res = TEE_GetTAPersistentTime(&t);
544 if (res != TEE_ERROR_OVERFLOW) {
545 EMSG("TEE_GetTAPersistentTime: failed\n");
546 return TEE_ERROR_BAD_STATE;
547 }
548 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
549 (unsigned int)t.millis);
550
551 if (t.seconds > sys_t.seconds) {
552 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
553 (unsigned int)t.seconds, (unsigned int)t.millis,
554 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
555 return TEE_ERROR_BAD_STATE;
556 }
557
558 return TEE_SUCCESS;
559}
560
Jens Wiklander246184a2015-12-11 08:28:59 +0100561#ifdef CFG_TA_FLOAT_SUPPORT
562static bool my_dcmpeq(double v1, double v2, double prec)
563{
564 return v1 > (v2 - prec) && v1 < (v2 + prec);
565}
566
567static bool my_fcmpeq(float v1, float v2, float prec)
568{
569 return v1 > (v2 - prec) && v1 < (v2 + prec);
570}
571
572
573static TEE_Result test_float(void)
574{
575#define VAL1 2.6
576#define VAL1_INT 2
577#define VAL2 5.3
578#define DPREC 0.000000000000001
579#define FPREC 0.000001
580#define EXPECT(expr) do { \
581 if (!(expr)) { \
582 EMSG("Expression %s failed", #expr); \
583 return TEE_ERROR_GENERIC; \
584 } \
585 } while (0)
586
587 IMSG("Testing floating point operations");
588
589 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
590 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
591 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
592 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
593 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
594
595 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
596 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
597 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
598 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
599 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
600
601 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
602 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
603 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
604 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
605 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
606
607 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
608 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
609 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
610 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
611 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
612
613 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
614 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
615 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
616 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
617
618 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
619 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
620 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
621 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
622
623 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
624 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
625
626 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
627 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
628 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
629 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
630
631 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
632 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
633 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
634 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
635 return TEE_SUCCESS;
636}
637#else /*CFG_TA_FLOAT_SUPPORT*/
638static TEE_Result test_float(void)
639{
640 IMSG("Floating point disabled");
641 return TEE_SUCCESS;
642}
643#endif /*CFG_TA_FLOAT_SUPPORT*/
644
Jerome Forissier892ae4d2020-03-09 09:58:09 +0100645static __noinline __noreturn void call_longjmp(jmp_buf env)
Jens Wiklander9f682c62016-03-27 20:23:06 +0200646{
647 DMSG("Calling longjmp");
648 longjmp(env, 1);
649 EMSG("error: longjmp returned to calling function");
650}
651
652static TEE_Result test_setjmp(void)
653{
Etienne Carriere102092e2019-03-28 15:24:22 +0100654 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200655
656 if (setjmp(env)) {
657 IMSG("Returned via longjmp");
658 return TEE_SUCCESS;
659 } else {
660 call_longjmp(env);
661 return TEE_ERROR_GENERIC;
662 }
663}
664
Pascal Brandc639ac82015-07-02 08:53:34 +0200665TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
666{
667 TEE_Result res = TEE_ERROR_GENERIC;
668
669 printf("ta_entry_basic: enter\n");
670
671 res = test_malloc();
672 if (res != TEE_SUCCESS)
673 return res;
674
675 res = test_properties();
676 if (res != TEE_SUCCESS)
677 return res;
678
679 res = test_mem_access_right(param_types, params);
680 if (res != TEE_SUCCESS)
681 return res;
682
683 res = test_time();
684 if (res != TEE_SUCCESS)
685 return res;
686
Jens Wiklander246184a2015-12-11 08:28:59 +0100687 res = test_float();
688 if (res != TEE_SUCCESS)
689 return res;
690
Jens Wiklander9f682c62016-03-27 20:23:06 +0200691 res = test_setjmp();
692 if (res != TEE_SUCCESS)
693 return res;
694
Pascal Brandc639ac82015-07-02 08:53:34 +0200695 return TEE_SUCCESS;
696}
697
698TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
699{
700 volatile bool mytrue = true;
701 (void)param_types;
702 (void)params;
703
704 printf("ta_entry_panic: enter\n");
705 /*
706 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
707 * the __noreturn attribute.
708 */
709 if (mytrue)
710 TEE_Panic(0xbeef);
711
712 /*
713 * Should not be reached, but if it is the testsuite can detect that
714 * TEE_Panic() returned instead of panicking the TA.
715 */
716 return TEE_SUCCESS;
717}
718
719TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
720 TEE_Param params[4])
721{
722 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100723 TEE_Result res = TEE_ERROR_GENERIC;
724 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
725 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200726
727 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
728 TEE_PARAM_TYPE_NONE,
729 TEE_PARAM_TYPE_NONE,
730 TEE_PARAM_TYPE_NONE)) {
731 EMSG("ta_entry_client_with_timeout: bad parameters\n");
732 return TEE_ERROR_BAD_PARAMETERS;
733 }
734
Cedric Augere668b3f2019-09-11 13:41:21 +0200735 res = TEE_OpenTASession(&os_test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
736 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200737 if (res != TEE_SUCCESS) {
738 EMSG(
739 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
740 return res;
741 }
742
743 res =
744 TEE_InvokeTACommand(sess, params[0].value.a / 2,
745 TA_OS_TEST_CMD_WAIT, param_types, params,
746 &ret_orig);
747
748 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
749 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
750 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
751 (unsigned int)ret_orig);
752 res = TEE_ERROR_GENERIC;
753 } else
754 res = TEE_SUCCESS;
755
756 TEE_CloseTASession(sess);
757 return res;
758
759}
760
761TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
762{
763 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100764 TEE_Result res = TEE_ERROR_GENERIC;
765 uint32_t l_pts = 0;
766 TEE_Param l_params[4] = { };
767 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
768 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200769 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
770 static const uint8_t sha256_out[] = {
771 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
772 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
773 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
774 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
775 };
776 uint8_t out[32] = { 0 };
777 void *in = NULL;
778
779 (void)param_types;
780 (void)params;
781
782 printf("ta_entry_client: enter\n");
783
784 in = TEE_Malloc(sizeof(sha256_in), 0);
785 if (in == NULL)
786 return TEE_ERROR_OUT_OF_MEMORY;
787 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
788
Cedric Augere668b3f2019-09-11 13:41:21 +0200789 res = TEE_OpenTASession(&crypt_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
790 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200791 if (res != TEE_SUCCESS) {
792 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
793 goto cleanup_return;
794 }
795
796 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
797 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
798 l_params[0].memref.buffer = in;
799 l_params[0].memref.size = sizeof(sha256_in);
800 l_params[1].memref.buffer = out;
801 l_params[1].memref.size = sizeof(out);
802
Cedric Augere668b3f2019-09-11 13:41:21 +0200803 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
804 TA_CRYPT_CMD_SHA256, l_pts, l_params,
Pascal Brandc639ac82015-07-02 08:53:34 +0200805 &ret_orig);
806 if (res != TEE_SUCCESS) {
807 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
808 goto cleanup_return;
809 }
810
811 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
812 EMSG("ta_entry_client: out parameter failed\n");
813 res = TEE_ERROR_GENERIC;
814 goto cleanup_return;
815 }
816
817cleanup_return:
818 TEE_Free(in);
819 TEE_CloseTASession(sess);
820 return res;
821}
822
Etienne Carriere281065d2016-10-28 15:41:33 +0200823TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200824{
Etienne Carriere102092e2019-03-28 15:24:22 +0100825 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200826
827 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100828 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
829 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200830 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200831
832 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
833 TEE_MEMORY_ACCESS_ANY_OWNER,
834 params[0].memref.buffer,
835 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200836 if (res != TEE_SUCCESS)
837 return res;
838
839 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
840 params[0].memref.buffer,
841 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200842 if (res != TEE_ERROR_ACCESS_DENIED)
843 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +0100844 if (params[1].memref.buffer || params[1].memref.size)
845 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200846
Etienne Carriere281065d2016-10-28 15:41:33 +0200847 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200848}
849
850TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
851{
852 TEE_Result res = TEE_SUCCESS;
853 (void)param_types;
854
855 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
856 /* Wait */
857 res = TEE_Wait(params[0].value.a);
858
859 return res;
860}
861
Jens Wiklander1425f952016-07-21 09:02:30 +0200862static void undef_instr(void)
863{
864#if defined(ARM64)
865 __asm__(".word 0x0");
866#elif defined(ARM32)
867 __asm__(".word 0xe7ffffff");
868#else
869#error "Unsupported architecture"
870#endif
871}
872
Pascal Brandc639ac82015-07-02 08:53:34 +0200873TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
874{
Etienne Carriere102092e2019-03-28 15:24:22 +0100875 long int stack = 0;
876 long int stack_addr = (long int)&stack;
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200877 void (*volatile null_fn_ptr)(void) = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200878
Etienne Carriere92c34422018-02-09 13:11:40 +0100879 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
880 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
881 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200882 return TEE_ERROR_GENERIC;
883
884 switch (params[0].value.a) {
885 case 1:
Jerome Forissier71da60f2019-09-19 15:59:56 +0200886 *((volatile uint32_t *)0) = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200887 break;
888 case 2:
889 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
890 break;
891 case 3:
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200892 null_fn_ptr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200893 break;
894 case 4:
895 ((void (*)(void))(stack_addr + 0x40000000)) ();
896 break;
897 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +0200898 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200899 break;
900 default:
901 break;
902 }
903
904 return TEE_SUCCESS;
905}
Jerome Forissiere916b102017-06-07 17:55:52 +0200906
907static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
908{
Etienne Carriere102092e2019-03-28 15:24:22 +0100909 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +0200910
911 for (i = 0; i < bufsize; i++) {
912 a[i]++; b[i]++; c[i]++;
913 }
914}
915
Etienne Carriere102092e2019-03-28 15:24:22 +0100916#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +0200917TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
918{
919 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
920 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100921 TEE_Param l_params[4] = { };
922 uint8_t in[TA2TA_BUF_SIZE] = { };
923 uint8_t inout[TA2TA_BUF_SIZE] = { };
924 uint8_t out[TA2TA_BUF_SIZE] = { };
925 TEE_Result res = TEE_ERROR_GENERIC;
926 uint32_t ret_orig = 0;
927 uint32_t l_pts = 0;
928 size_t i = 0;
929
Jerome Forissiere916b102017-06-07 17:55:52 +0200930 (void)params;
931
932 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
933 return TEE_ERROR_GENERIC;
934
Cedric Augere668b3f2019-09-11 13:41:21 +0200935 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
936 &sess, &ret_orig);
Jerome Forissiere916b102017-06-07 17:55:52 +0200937 if (res != TEE_SUCCESS) {
938 EMSG("TEE_OpenTASession failed");
939 goto cleanup_return;
940 }
941
942 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
943 TEE_PARAM_TYPE_MEMREF_INOUT,
944 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
945 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +0100946 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200947 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +0100948 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200949 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +0100950 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200951
952 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +0100953 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +0200954 in[i] = 5;
955 inout[i] = 10;
956 out[i] = 0;
957 }
958
959 /*
960 * TA will compute: out = ++inout + in
961 * Expected values after this step: in: 5, inout: 11, out: 16
962 */
Cedric Augere668b3f2019-09-11 13:41:21 +0200963 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
964 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +0200965 l_pts, l_params, &ret_orig);
966 if (res != TEE_SUCCESS) {
967 EMSG("TEE_InvokeTACommand failed");
968 goto cleanup_return;
969 }
Etienne Carriere102092e2019-03-28 15:24:22 +0100970
Jerome Forissiere916b102017-06-07 17:55:52 +0200971 /*
972 * Increment all values by one.
973 * Expected values after this step: in: 6, inout: 12, out: 17
974 */
Etienne Carriere102092e2019-03-28 15:24:22 +0100975 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +0200976
977 /*
978 * TA will compute: out = ++inout + in
979 * Expected values after this step: in: 6, inout: 13, out: 19
980 */
Cedric Augere668b3f2019-09-11 13:41:21 +0200981 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
982 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +0200983 l_pts, l_params, &ret_orig);
984 if (res != TEE_SUCCESS) {
985 EMSG("TEE_InvokeTACommand failed");
986 goto cleanup_return;
987 }
988
989 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +0100990 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +0200991 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
992 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +0100993 DHEXDUMP(in, TA2TA_BUF_SIZE);
994 DHEXDUMP(inout, TA2TA_BUF_SIZE);
995 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +0200996 return TEE_ERROR_GENERIC;
997 }
998 }
999
1000cleanup_return:
1001 TEE_CloseTASession(sess);
1002 return res;
1003}
1004
1005TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1006{
Etienne Carriere102092e2019-03-28 15:24:22 +01001007 uint8_t *in = NULL;
1008 uint8_t *inout = NULL;
1009 uint8_t *out = NULL;
1010 size_t bufsize = 0;
1011 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001012
1013 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1014 TEE_PARAM_TYPE_MEMREF_INOUT,
1015 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1016 return TEE_ERROR_GENERIC;
1017
1018 bufsize = params[0].memref.size;
1019 if (params[1].memref.size != bufsize ||
1020 params[2].memref.size != bufsize)
1021 return TEE_ERROR_GENERIC;
1022
1023 in = params[0].memref.buffer;
1024 inout = params[1].memref.buffer;
1025 out = params[2].memref.buffer;
1026
1027 for (i = 0; i < bufsize; i++)
1028 out[i] = ++inout[i] + in[i];
1029
1030 return TEE_SUCCESS;
1031}
Jens Wiklander87e81702018-03-20 12:00:00 +08001032
1033TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1034{
Etienne Carriere102092e2019-03-28 15:24:22 +01001035 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001036
1037 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1038 TEE_PARAM_TYPE_MEMREF_INPUT,
1039 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1040 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1041 return TEE_ERROR_BAD_PARAMETERS;
1042
1043 for (n = 0; n < TEE_NUM_PARAMS; n++)
1044 if (!params[n].memref.buffer || !params[n].memref.size)
1045 return TEE_ERROR_BAD_PARAMETERS;
1046
1047 return TEE_SUCCESS;
1048}
Jerome Forissier53bde722018-05-31 09:14:54 +02001049
Cedric Neveux9f483bb2019-03-04 08:58:06 +01001050TEE_Result ta_entry_null_memref(uint32_t param_types, TEE_Param params[4])
1051{
1052 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1053 TEE_PARAM_TYPE_MEMREF_INPUT,
1054 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1055 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1056 return TEE_ERROR_BAD_PARAMETERS;
1057
1058 /*
1059 * Tests how client can provide null or non-null memref parameters
1060 * param[0] expected as a 0 byte input mapped memeref.
1061 * param[1] expected as a 0 byte input not-mapped memeref.
1062 * param[2] expected as a 0 byte output mapped memeref.
1063 * param[3] expected as a 0 byte output not-mapped memeref.
1064 */
1065 if (!params[0].memref.buffer || params[0].memref.size ||
1066 params[1].memref.buffer || params[1].memref.size ||
1067 !params[2].memref.buffer || params[2].memref.size ||
1068 params[3].memref.buffer || params[3].memref.size)
1069 return TEE_ERROR_BAD_PARAMETERS;
1070
1071 return TEE_SUCCESS;
1072}
1073
Jerome Forissier53bde722018-05-31 09:14:54 +02001074TEE_Result ta_entry_call_lib(uint32_t param_types,
1075 TEE_Param params[4] __unused)
1076{
1077 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1078 TEE_PARAM_TYPE_NONE,
1079 TEE_PARAM_TYPE_NONE,
1080 TEE_PARAM_TYPE_NONE))
1081 return TEE_ERROR_BAD_PARAMETERS;
1082
1083 if (os_test_shlib_add(1, 2) != 3)
1084 return TEE_ERROR_GENERIC;
1085
1086 return TEE_SUCCESS;
1087}
1088
1089TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1090 TEE_Param params[4] __unused)
1091{
1092 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1093 TEE_PARAM_TYPE_NONE,
1094 TEE_PARAM_TYPE_NONE,
1095 TEE_PARAM_TYPE_NONE))
1096 return TEE_ERROR_BAD_PARAMETERS;
1097
1098 os_test_shlib_panic();
1099
1100 return TEE_ERROR_GENERIC;
1101}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001102
1103TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1104 TEE_Param params[4] __unused)
1105{
1106 int (*add_func)(int a, int b) = NULL;
1107 TEE_Result res = TEE_ERROR_GENERIC;
1108 void *handle = NULL;
1109 void *hnull = NULL;
1110
1111 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1112 TEE_PARAM_TYPE_NONE,
1113 TEE_PARAM_TYPE_NONE,
1114 TEE_PARAM_TYPE_NONE))
1115 return TEE_ERROR_BAD_PARAMETERS;
1116
1117 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1118 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1119 if (!handle)
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001120 return TEE_ERROR_GENERIC;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001121
1122 add_func = dlsym(handle, "os_test_shlib_dl_add");
1123 if (!add_func)
1124 goto err;
1125 if (add_func(3, 4) != 7)
1126 goto err;
1127
1128 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001129 if (!hnull)
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001130 goto err;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001131
1132 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1133 if (!add_func)
1134 goto err;
1135 if (add_func(5, 6) != 11)
1136 goto err;
1137
1138 res = TEE_SUCCESS;
1139 dlclose(hnull);
1140err:
1141 dlclose(handle);
1142 return res;
1143}
1144
1145TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1146 TEE_Param params[4] __unused)
1147{
1148 int (*panic_func)(void) = NULL;
1149 void *handle = NULL;
1150 TEE_Result res = TEE_ERROR_GENERIC;
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 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1159 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1160 if (!handle)
1161 return res;
1162
1163 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1164 if (!panic_func)
1165 goto err;
1166 panic_func();
1167 return TEE_ERROR_GENERIC;
1168err:
1169 dlclose(handle);
1170 return res;
1171}
Jerome Forissiere9571e82020-02-18 15:26:20 +01001172
1173/* ELF initialization/finalization test */
1174
1175int os_test_global;
1176
1177static void __attribute__((constructor)) os_test_init(void)
1178{
1179 os_test_global *= 10;
1180 os_test_global += 1;
1181 DMSG("os_test_global=%d", os_test_global);
1182}
1183
1184TEE_Result ta_entry_get_global_var(uint32_t param_types, TEE_Param params[4])
1185{
1186 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1187 TEE_PARAM_TYPE_NONE,
1188 TEE_PARAM_TYPE_NONE,
1189 TEE_PARAM_TYPE_NONE))
1190 return TEE_ERROR_BAD_PARAMETERS;
1191
1192 params[0].value.a = os_test_global;
1193
1194 return TEE_SUCCESS;
1195}
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001196
1197TEE_Result ta_entry_client_identity(uint32_t param_types, TEE_Param params[4])
1198{
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001199 TEE_Result res = TEE_ERROR_GENERIC;
1200 TEE_Identity identity = { };
1201
1202 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1203 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1204 TEE_PARAM_TYPE_NONE,
1205 TEE_PARAM_TYPE_NONE))
1206 return TEE_ERROR_BAD_PARAMETERS;
1207
1208 if (params[1].memref.size < sizeof(TEE_UUID)) {
1209 params[1].memref.size = sizeof(TEE_UUID);
1210 return TEE_ERROR_SHORT_BUFFER;
1211 }
1212
1213 res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
1214 "gpd.client.identity", &identity);
1215 if (res != TEE_SUCCESS) {
1216 EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32, res);
1217 return res;
1218 }
1219
1220 params[0].value.a = identity.login;
1221 memcpy(params[1].memref.buffer, &identity.uuid, sizeof(TEE_UUID));
1222 params[1].memref.size = sizeof(TEE_UUID);
1223
1224 return res;
1225}