blob: 6d5f74a1ad258ce9577b4d8bce8c6246faae5c00 [file] [log] [blame]
Pascal Brandc639ac82015-07-02 08:53:34 +02001/*
2 * Copyright (c) 2014, STMicroelectronics International N.V.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
Pascal Brandc639ac82015-07-02 08:53:34 +020027#include <compiler.h>
Jens Wiklander8324ff22018-11-21 14:16:04 +010028#include <setjmp.h>
29#include <stdint.h>
30#include <string.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020031#include <ta_crypt.h>
32#include <ta_os_test.h>
33#include <tee_internal_api_extensions.h>
34
35#include "os_test.h"
Jens Wiklander246184a2015-12-11 08:28:59 +010036#include "test_float_subj.h"
Jerome Forissier53bde722018-05-31 09:14:54 +020037#include "os_test_lib.h"
Pascal Brandc639ac82015-07-02 08:53:34 +020038
39enum p_type {
40 P_TYPE_BOOL,
41 P_TYPE_INT,
42 P_TYPE_UUID,
43 P_TYPE_IDENTITY,
44 P_TYPE_STRING,
45 P_TYPE_BINARY_BLOCK,
46};
47
48struct p_attr {
49 const char *str;
50 enum p_type type;
51 bool retrieved;
52};
53
Pascal Brand624b6a32016-02-16 12:51:34 +010054static TEE_Result check_returned_prop(
Pascal Brandaf77fdd2016-03-08 13:59:01 +010055 int line __maybe_unused, char *prop_name __maybe_unused,
Pascal Brand624b6a32016-02-16 12:51:34 +010056 TEE_Result return_res, TEE_Result expected_res,
57 uint32_t return_len, uint32_t expected_len)
58{
59 if (return_res != expected_res) {
60 EMSG("From line %d (property name=%s): return_res=0x%x vs expected_res=0x%x",
61 line, (prop_name ? prop_name : "unknown"),
62 (unsigned int)return_res, (unsigned int)expected_res);
63 return TEE_ERROR_GENERIC;
64 }
65 if (return_len != expected_len) {
Pascal Brand07bb09f2016-02-19 16:04:10 +010066 EMSG("From line %d (property name=%s): return_len=%u vs expected_res=%u",
67 line, (prop_name ? prop_name : "unknown"),
68 return_len, expected_len);
Pascal Brand624b6a32016-02-16 12:51:34 +010069 return TEE_ERROR_GENERIC;
70 }
71 return TEE_SUCCESS;
72}
73
Pascal Brandc639ac82015-07-02 08:53:34 +020074static TEE_Result print_properties(TEE_PropSetHandle h,
75 TEE_PropSetHandle prop_set,
76 struct p_attr *p_attrs, size_t num_p_attrs)
77{
78TEE_Result res;
79size_t n;
80
81TEE_StartPropertyEnumerator(h, prop_set);
82
83while (true) {
Pascal Brand624b6a32016-02-16 12:51:34 +010084 char nbuf[256];
85 char nbuf_small[256];
86 char vbuf[256];
87 char vbuf2[256];
Jens Wiklanderc5231592015-11-11 09:27:27 +010088 uint32_t nblen = sizeof(nbuf);
Pascal Brand624b6a32016-02-16 12:51:34 +010089 uint32_t nblen_small;
Jens Wiklanderc5231592015-11-11 09:27:27 +010090 uint32_t vblen = sizeof(vbuf);
91 uint32_t vblen2 = sizeof(vbuf2);
Pascal Brandc639ac82015-07-02 08:53:34 +020092
93 res = TEE_GetPropertyName(h, nbuf, &nblen);
94 if (res != TEE_SUCCESS) {
95 EMSG("TEE_GetPropertyName returned 0x%x\n",
96 (unsigned int)res);
97 return res;
98 }
Pascal Brand624b6a32016-02-16 12:51:34 +010099 if (nblen != strlen(nbuf) + 1) {
Pascal Brand5b68cd62016-02-22 10:31:01 +0100100 EMSG("Name has wrong size: %u vs %zu", nblen, strlen(nbuf) + 1);
Pascal Brand624b6a32016-02-16 12:51:34 +0100101 return TEE_ERROR_GENERIC;
102 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200103
Pascal Brand624b6a32016-02-16 12:51:34 +0100104
105 /* Get the property name with a very small buffer */
106 nblen_small = 2;
107 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
108 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
109 nblen_small, nblen);
110 if (res != TEE_SUCCESS)
111 return res;
112
113 /* Get the property name with almost the correct buffer */
114 nblen_small = nblen - 1;
115 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
116 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
117 nblen_small, nblen);
118 if (res != TEE_SUCCESS)
119 return res;
120
121 /* Get the property name with the exact buffer length */
122 nblen_small = nblen;
123 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
124 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
125 nblen_small, nblen);
126 if (res != TEE_SUCCESS)
127 return res;
128
129 /* Get the property value */
Pascal Brandc639ac82015-07-02 08:53:34 +0200130 res = TEE_GetPropertyAsString(h, NULL, vbuf, &vblen);
Pascal Brand624b6a32016-02-16 12:51:34 +0100131 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
132 vblen, strlen(vbuf) + 1);
133 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200134 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100135
Pascal Brandc639ac82015-07-02 08:53:34 +0200136 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
Pascal Brand624b6a32016-02-16 12:51:34 +0100137 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
138 vblen2, strlen(vbuf2) + 1);
139 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200140 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100141
Jens Wiklander8324ff22018-11-21 14:16:04 +0100142 if (strcmp(vbuf, vbuf2) != 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200143 EMSG("String of \"%s\" differs\n", nbuf);
144 return TEE_ERROR_GENERIC;
145 }
146
Pascal Brand624b6a32016-02-16 12:51:34 +0100147 /* Get the property with a very small buffer */
148 vblen2 = 1;
149 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
150 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
151 vblen2, vblen);
152 if (res != TEE_SUCCESS)
153 return res;
154
155 /* Get the property with almost the correct buffer */
156 vblen2 = vblen - 1;
157 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
158 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
159 vblen2, vblen);
160 if (res != TEE_SUCCESS)
161 return res;
162
163 /* Get the property name with the exact buffer length */
164 vblen2 = vblen;
165 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
166 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS, vblen2, vblen);
167 if (res != TEE_SUCCESS)
168 return res;
169
170 /* check specific myprop.hello property, which is larger than 80 */
171 if (!strcmp("myprop.hello", nbuf) &&
172 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")) {
173 EMSG("TEE_GetPropertyAsString(\"%s\") is truncated - returned \"%s\"\n",
174 nbuf, vbuf);
175 return TEE_ERROR_GENERIC;
176 }
177
Pascal Brandc639ac82015-07-02 08:53:34 +0200178 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
179
180 for (n = 0; n < num_p_attrs; n++) {
Jens Wiklander8324ff22018-11-21 14:16:04 +0100181 if (strcmp(nbuf, p_attrs[n].str) != 0)
Pascal Brandc639ac82015-07-02 08:53:34 +0200182 continue;
183
184 if (p_attrs[n].retrieved) {
185 EMSG("Value \"%s\" already retrieved\n",
186 p_attrs[n].str);
187 return TEE_ERROR_GENERIC;
188 }
189 p_attrs[n].retrieved = true;
190
191 switch (p_attrs[n].type) {
192 case P_TYPE_BOOL:
193 {
194 bool v;
195
196 res =
197 TEE_GetPropertyAsBool(h, NULL, &v);
198 if (res != TEE_SUCCESS) {
199 EMSG(
200 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
201 nbuf, (unsigned int)res);
202 return res;
203 }
204 }
205 break;
206
207 case P_TYPE_INT:
208 {
209 uint32_t v;
210
211 res = TEE_GetPropertyAsU32(h, NULL, &v);
212 if (res != TEE_SUCCESS) {
213 EMSG(
214 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
215 nbuf, (unsigned int)res);
216 return res;
217 }
218 }
219 break;
220
221 case P_TYPE_UUID:
222 {
223 TEE_UUID v;
224
225 res =
226 TEE_GetPropertyAsUUID(h, NULL, &v);
227 if (res != TEE_SUCCESS) {
228 EMSG(
229 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
230 nbuf, (unsigned int)res);
231 return res;
232 }
233 }
234 break;
235
236 case P_TYPE_IDENTITY:
237 {
238 TEE_Identity v;
239
240 res =
241 TEE_GetPropertyAsIdentity(h, NULL,
242 &v);
243 if (res != TEE_SUCCESS) {
244 EMSG(
245 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
246 nbuf, (unsigned int)res);
247 return res;
248 }
249 }
250 break;
251
252 case P_TYPE_STRING:
253 /* Already read as string */
254 break;
255
256 case P_TYPE_BINARY_BLOCK:
257 {
258 char bbuf[80];
Jens Wiklanderc5231592015-11-11 09:27:27 +0100259 uint32_t bblen = sizeof(bbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200260
261 res =
262 TEE_GetPropertyAsBinaryBlock(h,
263 NULL,
264 bbuf,
265 &bblen);
266 if (res != TEE_SUCCESS) {
267 EMSG(
268 "TEE_GetPropertyAsBinaryBlock(\"%s\") returned 0x%x\n",
269 nbuf, (unsigned int)res);
270 return res;
271 }
Jens Wiklander8324ff22018-11-21 14:16:04 +0100272 if (strcmp("myprop.binaryblock", nbuf) == 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200273 const char exp_bin_value[] =
274 "Hello world!";
275
Jens Wiklander8324ff22018-11-21 14:16:04 +0100276 if (bblen != strlen(exp_bin_value)
Pascal Brandc639ac82015-07-02 08:53:34 +0200277 ||
278 TEE_MemCompare
279 (exp_bin_value, bbuf,
280 bblen) != 0) {
281 EMSG(
282 "Binary buffer of \"%s\" differs from \"%s\"\n",
283 nbuf, exp_bin_value);
284 EMSG(
285 "Got \"%s\"\n",
286 bbuf);
287 return
288 TEE_ERROR_GENERIC;
289 }
290 }
291
292 }
293 break;
294
295 default:
296 EMSG("Unknown type (%d) for \"%s\"\n",
297 p_attrs[n].type, p_attrs[n].str);
298 return TEE_ERROR_GENERIC;
299 }
300 }
301
302 res = TEE_GetNextProperty(h);
303 if (res != TEE_SUCCESS) {
304 if (res == TEE_ERROR_ITEM_NOT_FOUND)
305 return TEE_SUCCESS;
306 return res;
307 }
308}
309}
310
311static TEE_Result test_malloc(void)
312{
313 void *p = TEE_Malloc(4, 0);
314
315 if (p == NULL) {
316 EMSG("TEE_Malloc failed\n");
317 return TEE_ERROR_OUT_OF_MEMORY;
318 }
319 TEE_Free(p);
320 TEE_Free(NULL);
321
322 return TEE_SUCCESS;
323}
324
325static TEE_Result test_properties(void)
326{
327 TEE_Result res = TEE_ERROR_GENERIC;
328 TEE_PropSetHandle h;
329 struct p_attr p_attrs[] = {
330 {"gpd.ta.appID", P_TYPE_UUID},
331 {"gpd.ta.singleInstance", P_TYPE_BOOL},
332 {"gpd.ta.multiSession", P_TYPE_BOOL},
333 {"gpd.ta.instanceKeepAlive", P_TYPE_BOOL},
334 {"gpd.ta.dataSize", P_TYPE_INT},
335 {"gpd.ta.stackSize", P_TYPE_INT},
336 {"gpd.ta.version", P_TYPE_STRING},
337 {"gpd.ta.description", P_TYPE_STRING},
338 {"gpd.client.identity", P_TYPE_IDENTITY},
339 {"gpd.tee.apiversion", P_TYPE_STRING},
340 {"gpd.tee.description", P_TYPE_STRING},
341 {"gpd.tee.deviceID", P_TYPE_UUID},
342 {"gpd.tee.systemTime.protectionLevel", P_TYPE_INT},
343 {"gpd.tee.TAPersistentTime.protectionLevel", P_TYPE_INT},
344 {"gpd.tee.arith.maxBigIntSize", P_TYPE_INT},
345 {"gpd.tee.cryptography.ecc", P_TYPE_BOOL},
346 {"gpd.tee.trustedStorage.antiRollback.protectionLevel", P_TYPE_INT},
347 {"gpd.tee.trustedos.implementation.version", P_TYPE_STRING},
348 {"gpd.tee.trustedos.implementation.binaryversion", P_TYPE_INT},
349 {"gpd.tee.trustedos.manufacturer", P_TYPE_STRING},
350 {"gpd.tee.firmware.implementation.version", P_TYPE_STRING},
351 {"gpd.tee.firmware.implementation.binaryversion", P_TYPE_INT},
352 {"gpd.tee.firmware.manufacturer", P_TYPE_STRING},
353 {"myprop.true", P_TYPE_BOOL},
354 {"myprop.42", P_TYPE_INT},
355 {"myprop.123", P_TYPE_UUID},
356 {"myprop.1234", P_TYPE_IDENTITY},
357 {"myprop.hello", P_TYPE_STRING},
358 {"myprop.binaryblock", P_TYPE_BINARY_BLOCK},
359 };
360 const size_t num_p_attrs = sizeof(p_attrs) / sizeof(p_attrs[0]);
361 size_t n;
362
363 res = TEE_AllocatePropertyEnumerator(&h);
364 if (res != TEE_SUCCESS) {
365 EMSG("TEE_AllocatePropertyEnumerator: returned 0x%x\n",
366 (unsigned int)res);
367 return TEE_ERROR_GENERIC;
368 }
369
370 printf("Getting properties for current TA\n");
371 res = print_properties(h, TEE_PROPSET_CURRENT_TA, p_attrs, num_p_attrs);
372 if (res != TEE_SUCCESS)
373 goto cleanup_return;
374
375 printf("Getting properties for current client\n");
376 res = print_properties(h, TEE_PROPSET_CURRENT_CLIENT, p_attrs,
377 num_p_attrs);
378 if (res != TEE_SUCCESS)
379 goto cleanup_return;
380
381 printf("Getting properties for implementation\n");
382 res = print_properties(h, TEE_PROPSET_TEE_IMPLEMENTATION, p_attrs,
383 num_p_attrs);
384 if (res != TEE_SUCCESS)
385 goto cleanup_return;
386
387 for (n = 0; n < num_p_attrs; n++) {
388 if (!p_attrs[n].retrieved) {
389 EMSG("\"%s\" not retrieved\n", p_attrs[n].str);
390 res = TEE_ERROR_GENERIC;
391 goto cleanup_return;
392 }
393 }
394
395cleanup_return:
396 TEE_FreePropertyEnumerator(h);
397 return res;
398}
399
400static TEE_Result test_mem_access_right(uint32_t param_types,
401 TEE_Param params[4])
402{
403 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
404 TEE_Result res;
405 uint32_t ret_orig;
406 uint32_t l_pts;
407 TEE_Param l_params[4] = { { {0} } };
408 uint8_t buf[32];
409 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere281065d2016-10-28 15:41:33 +0200410 TEE_UUID *uuid;
Pascal Brandc639ac82015-07-02 08:53:34 +0200411
412 if (param_types !=
413 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
414 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200415
416 /* test access rights on memref parameter */
417 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
418 TEE_MEMORY_ACCESS_ANY_OWNER,
419 params[0].memref.buffer,
420 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200421 if (res != TEE_SUCCESS)
422 return res;
Etienne Carriere281065d2016-10-28 15:41:33 +0200423
Pascal Brandc639ac82015-07-02 08:53:34 +0200424 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
425 params[0].memref.buffer,
426 params[0].memref.size);
427 if (res != TEE_ERROR_ACCESS_DENIED)
428 return TEE_ERROR_GENERIC;
429
Etienne Carriere281065d2016-10-28 15:41:33 +0200430 /* test access rights on private read-only and read-write memory */
431 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
432 (void *)&test_uuid, sizeof(test_uuid));
433 if (res != TEE_SUCCESS)
434 return res;
435
436 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_WRITE,
437 (void *)&test_uuid, sizeof(test_uuid));
438 if (res == TEE_SUCCESS)
439 return TEE_ERROR_GENERIC;
440
441 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
442 TEE_MEMORY_ACCESS_WRITE,
443 &ret_orig, sizeof(ret_orig));
444 if (res != TEE_SUCCESS)
445 return res;
446
447 uuid = TEE_Malloc(sizeof(*uuid), 0);
448 if (!uuid)
449 return TEE_ERROR_OUT_OF_MEMORY;
450
451 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
452 TEE_MEMORY_ACCESS_WRITE,
453 uuid, sizeof(*uuid));
454 TEE_Free(uuid);
455 if (res != TEE_SUCCESS)
456 return res;
457
458 /* test access rights on invalid memory (at least lower 256kB) */
459 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
460 NULL, 1);
461 if (res == TEE_SUCCESS)
462 return TEE_ERROR_GENERIC;
463
464 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
465 (void*)(256 * 1024), 1);
466 if (res == TEE_SUCCESS)
467 return TEE_ERROR_GENERIC;
468
Pascal Brandc639ac82015-07-02 08:53:34 +0200469 res = TEE_OpenTASession(&test_uuid, 0, 0, NULL, &sess, &ret_orig);
470 if (res != TEE_SUCCESS) {
471 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
472 goto cleanup_return;
473 }
474
Jerome Forissier04511d82018-01-30 14:33:49 +0100475 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
476 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200477 l_params[0].memref.buffer = buf;
478 l_params[0].memref.size = sizeof(buf);
Jerome Forissier04511d82018-01-30 14:33:49 +0100479 l_params[1].memref.buffer = NULL;
480 l_params[1].memref.size = 0;
Etienne Carriere281065d2016-10-28 15:41:33 +0200481 res = TEE_InvokeTACommand(sess, 0, TA_OS_TEST_CMD_PARAMS_ACCESS,
Pascal Brandc639ac82015-07-02 08:53:34 +0200482 l_pts, l_params, &ret_orig);
483 if (res != TEE_SUCCESS) {
484 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
485 goto cleanup_return;
486 }
487
488cleanup_return:
489 TEE_CloseTASession(sess);
490 return res;
491}
492
493static TEE_Result test_time(void)
494{
495 TEE_Result res;
496 TEE_Time t;
497 TEE_Time sys_t;
498
499 static const TEE_Time null_time = { 0, 0 };
500 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
501
502 TEE_GetSystemTime(&sys_t);
503 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
504 (unsigned int)sys_t.millis);
505
506 TEE_GetREETime(&t);
507 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
508 (unsigned int)t.millis);
509
510 res = TEE_GetTAPersistentTime(&t);
511 switch (res) {
512 case TEE_SUCCESS:
513 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
514 (unsigned int)t.millis);
515 break;
516 case TEE_ERROR_OVERFLOW:
517 EMSG("Stored TA time overflowed %u.%03u\n",
518 (unsigned int)t.seconds, (unsigned int)t.millis);
519 break;
520 case TEE_ERROR_TIME_NOT_SET:
521 EMSG("TA time not stored\n");
522 break;
523 case TEE_ERROR_TIME_NEEDS_RESET:
524 EMSG("TA time needs reset\n");
525 break;
526 default:
527 return res;
528 }
529
530 res = TEE_SetTAPersistentTime(&null_time);
531 if (res != TEE_SUCCESS) {
532 EMSG("TEE_SetTAPersistentTime: failed\n");
533 return res;
534 }
535
536 res = TEE_GetTAPersistentTime(&t);
537 if (res != TEE_SUCCESS) {
538 EMSG("TEE_GetTAPersistentTime null: failed\n");
539 return res;
540 }
541 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
542 (unsigned int)t.millis);
543 /*
544 * The time between TEE_SetTAPersistentTime() and
545 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
546 * it's not even a millisecond.
547 */
548 if (t.seconds > 1 || t.millis >= 1000) {
549 EMSG("Unexpected stored TA time %u.%03u\n",
550 (unsigned int)t.seconds, (unsigned int)t.millis);
551 return TEE_ERROR_BAD_STATE;
552 }
553
554 res = TEE_SetTAPersistentTime(&wrap_time);
555 if (res != TEE_SUCCESS) {
556 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
557 return res;
558 }
559
560 res = TEE_Wait(1000);
561 if (res != TEE_SUCCESS)
562 EMSG("TEE_Wait wrap: failed\n");
563
564 res = TEE_GetTAPersistentTime(&t);
565 if (res != TEE_ERROR_OVERFLOW) {
566 EMSG("TEE_GetTAPersistentTime: failed\n");
567 return TEE_ERROR_BAD_STATE;
568 }
569 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
570 (unsigned int)t.millis);
571
572 if (t.seconds > sys_t.seconds) {
573 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
574 (unsigned int)t.seconds, (unsigned int)t.millis,
575 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
576 return TEE_ERROR_BAD_STATE;
577 }
578
579 return TEE_SUCCESS;
580}
581
Jens Wiklander246184a2015-12-11 08:28:59 +0100582#ifdef CFG_TA_FLOAT_SUPPORT
583static bool my_dcmpeq(double v1, double v2, double prec)
584{
585 return v1 > (v2 - prec) && v1 < (v2 + prec);
586}
587
588static bool my_fcmpeq(float v1, float v2, float prec)
589{
590 return v1 > (v2 - prec) && v1 < (v2 + prec);
591}
592
593
594static TEE_Result test_float(void)
595{
596#define VAL1 2.6
597#define VAL1_INT 2
598#define VAL2 5.3
599#define DPREC 0.000000000000001
600#define FPREC 0.000001
601#define EXPECT(expr) do { \
602 if (!(expr)) { \
603 EMSG("Expression %s failed", #expr); \
604 return TEE_ERROR_GENERIC; \
605 } \
606 } while (0)
607
608 IMSG("Testing floating point operations");
609
610 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
611 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
612 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
613 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
614 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
615
616 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
617 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
618 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
619 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
620 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
621
622 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
623 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
624 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
625 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
626 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
627
628 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
629 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
630 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
631 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
632 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
633
634 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
635 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
636 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
637 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
638
639 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
640 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
641 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
642 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
643
644 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
645 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
646
647 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
648 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
649 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
650 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
651
652 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
653 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
654 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
655 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
656 return TEE_SUCCESS;
657}
658#else /*CFG_TA_FLOAT_SUPPORT*/
659static TEE_Result test_float(void)
660{
661 IMSG("Floating point disabled");
662 return TEE_SUCCESS;
663}
664#endif /*CFG_TA_FLOAT_SUPPORT*/
665
Jens Wiklander9f682c62016-03-27 20:23:06 +0200666static __noinline void call_longjmp(jmp_buf env)
667{
668 DMSG("Calling longjmp");
669 longjmp(env, 1);
670 EMSG("error: longjmp returned to calling function");
671}
672
673static TEE_Result test_setjmp(void)
674{
675 jmp_buf env;
676
677 if (setjmp(env)) {
678 IMSG("Returned via longjmp");
679 return TEE_SUCCESS;
680 } else {
681 call_longjmp(env);
682 return TEE_ERROR_GENERIC;
683 }
684}
685
Pascal Brandc639ac82015-07-02 08:53:34 +0200686TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
687{
688 TEE_Result res = TEE_ERROR_GENERIC;
689
690 printf("ta_entry_basic: enter\n");
691
692 res = test_malloc();
693 if (res != TEE_SUCCESS)
694 return res;
695
696 res = test_properties();
697 if (res != TEE_SUCCESS)
698 return res;
699
700 res = test_mem_access_right(param_types, params);
701 if (res != TEE_SUCCESS)
702 return res;
703
704 res = test_time();
705 if (res != TEE_SUCCESS)
706 return res;
707
Jens Wiklander246184a2015-12-11 08:28:59 +0100708 res = test_float();
709 if (res != TEE_SUCCESS)
710 return res;
711
Jens Wiklander9f682c62016-03-27 20:23:06 +0200712 res = test_setjmp();
713 if (res != TEE_SUCCESS)
714 return res;
715
Pascal Brandc639ac82015-07-02 08:53:34 +0200716 return TEE_SUCCESS;
717}
718
719TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
720{
721 volatile bool mytrue = true;
722 (void)param_types;
723 (void)params;
724
725 printf("ta_entry_panic: enter\n");
726 /*
727 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
728 * the __noreturn attribute.
729 */
730 if (mytrue)
731 TEE_Panic(0xbeef);
732
733 /*
734 * Should not be reached, but if it is the testsuite can detect that
735 * TEE_Panic() returned instead of panicking the TA.
736 */
737 return TEE_SUCCESS;
738}
739
740TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
741 TEE_Param params[4])
742{
743 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
744 TEE_Result res;
745 TEE_TASessionHandle sess;
746 uint32_t ret_orig;
747
748 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
749 TEE_PARAM_TYPE_NONE,
750 TEE_PARAM_TYPE_NONE,
751 TEE_PARAM_TYPE_NONE)) {
752 EMSG("ta_entry_client_with_timeout: bad parameters\n");
753 return TEE_ERROR_BAD_PARAMETERS;
754 }
755
756 res = TEE_OpenTASession(&os_test_uuid, 0, 0, NULL, &sess, &ret_orig);
757 if (res != TEE_SUCCESS) {
758 EMSG(
759 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
760 return res;
761 }
762
763 res =
764 TEE_InvokeTACommand(sess, params[0].value.a / 2,
765 TA_OS_TEST_CMD_WAIT, param_types, params,
766 &ret_orig);
767
768 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
769 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
770 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
771 (unsigned int)ret_orig);
772 res = TEE_ERROR_GENERIC;
773 } else
774 res = TEE_SUCCESS;
775
776 TEE_CloseTASession(sess);
777 return res;
778
779}
780
781TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
782{
783 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
784 TEE_Result res;
785 uint32_t l_pts;
786 TEE_Param l_params[4] = { { {0} } };
787 TEE_TASessionHandle sess;
788 uint32_t ret_orig;
789 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
790 static const uint8_t sha256_out[] = {
791 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
792 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
793 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
794 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
795 };
796 uint8_t out[32] = { 0 };
797 void *in = NULL;
798
799 (void)param_types;
800 (void)params;
801
802 printf("ta_entry_client: enter\n");
803
804 in = TEE_Malloc(sizeof(sha256_in), 0);
805 if (in == NULL)
806 return TEE_ERROR_OUT_OF_MEMORY;
807 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
808
809 res = TEE_OpenTASession(&crypt_uuid, 0, 0, NULL, &sess, &ret_orig);
810 if (res != TEE_SUCCESS) {
811 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
812 goto cleanup_return;
813 }
814
815 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
816 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
817 l_params[0].memref.buffer = in;
818 l_params[0].memref.size = sizeof(sha256_in);
819 l_params[1].memref.buffer = out;
820 l_params[1].memref.size = sizeof(out);
821
822 res = TEE_InvokeTACommand(sess, 0, TA_CRYPT_CMD_SHA256, l_pts, l_params,
823 &ret_orig);
824 if (res != TEE_SUCCESS) {
825 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
826 goto cleanup_return;
827 }
828
829 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
830 EMSG("ta_entry_client: out parameter failed\n");
831 res = TEE_ERROR_GENERIC;
832 goto cleanup_return;
833 }
834
835cleanup_return:
836 TEE_Free(in);
837 TEE_CloseTASession(sess);
838 return res;
839}
840
Etienne Carriere281065d2016-10-28 15:41:33 +0200841TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200842{
843 TEE_Result res;
844
845 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100846 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
847 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200848 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200849
850 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
851 TEE_MEMORY_ACCESS_ANY_OWNER,
852 params[0].memref.buffer,
853 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200854 if (res != TEE_SUCCESS)
855 return res;
856
857 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
858 params[0].memref.buffer,
859 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200860 if (res != TEE_ERROR_ACCESS_DENIED)
861 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +0100862 if (params[1].memref.buffer || params[1].memref.size)
863 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200864
Etienne Carriere281065d2016-10-28 15:41:33 +0200865 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200866}
867
868TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
869{
870 TEE_Result res = TEE_SUCCESS;
871 (void)param_types;
872
873 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
874 /* Wait */
875 res = TEE_Wait(params[0].value.a);
876
877 return res;
878}
879
Jens Wiklander1425f952016-07-21 09:02:30 +0200880static void undef_instr(void)
881{
882#if defined(ARM64)
883 __asm__(".word 0x0");
884#elif defined(ARM32)
885 __asm__(".word 0xe7ffffff");
886#else
887#error "Unsupported architecture"
888#endif
889}
890
Pascal Brandc639ac82015-07-02 08:53:34 +0200891TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
892{
893 long stack;
894 long stack_addr = (long)&stack;
895
Etienne Carriere92c34422018-02-09 13:11:40 +0100896 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
897 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
898 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200899 return TEE_ERROR_GENERIC;
900
901 switch (params[0].value.a) {
902 case 1:
903 *((uint32_t *) 0) = 0;
904 break;
905 case 2:
906 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
907 break;
908 case 3:
909 ((void (*)(void))0) ();
910 break;
911 case 4:
912 ((void (*)(void))(stack_addr + 0x40000000)) ();
913 break;
914 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +0200915 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200916 break;
917 default:
918 break;
919 }
920
921 return TEE_SUCCESS;
922}
Jerome Forissiere916b102017-06-07 17:55:52 +0200923
924static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
925{
926 size_t i;
927
928 for (i = 0; i < bufsize; i++) {
929 a[i]++; b[i]++; c[i]++;
930 }
931}
932
933TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
934{
935 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
936 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
937 TEE_Param l_params[4] = { { {0} } };
938 size_t bufsize = 2 * 1024;
939 uint8_t in[bufsize];
940 uint8_t inout[bufsize];
941 uint8_t out[bufsize];
942 TEE_Result res;
943 uint32_t ret_orig;
944 uint32_t l_pts;
945 size_t i;
946 (void)params;
947
948 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
949 return TEE_ERROR_GENERIC;
950
951 res = TEE_OpenTASession(&test_uuid, 0, 0, NULL, &sess, &ret_orig);
952 if (res != TEE_SUCCESS) {
953 EMSG("TEE_OpenTASession failed");
954 goto cleanup_return;
955 }
956
957 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
958 TEE_PARAM_TYPE_MEMREF_INOUT,
959 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
960 l_params[0].memref.buffer = in;
961 l_params[0].memref.size = bufsize;
962 l_params[1].memref.buffer = inout;
963 l_params[1].memref.size = bufsize;
964 l_params[2].memref.buffer = out;
965 l_params[2].memref.size = bufsize;
966
967 /* Initialize buffers */
968 for (i = 0; i < bufsize; i++) {
969 in[i] = 5;
970 inout[i] = 10;
971 out[i] = 0;
972 }
973
974 /*
975 * TA will compute: out = ++inout + in
976 * Expected values after this step: in: 5, inout: 11, out: 16
977 */
978 res = TEE_InvokeTACommand(sess, 0, TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
979 l_pts, l_params, &ret_orig);
980 if (res != TEE_SUCCESS) {
981 EMSG("TEE_InvokeTACommand failed");
982 goto cleanup_return;
983 }
984
985 /*
986 * Increment all values by one.
987 * Expected values after this step: in: 6, inout: 12, out: 17
988 */
989 incr_values(bufsize, in, inout, out);
990
991 /*
992 * TA will compute: out = ++inout + in
993 * Expected values after this step: in: 6, inout: 13, out: 19
994 */
995 res = TEE_InvokeTACommand(sess, 0, TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
996 l_pts, l_params, &ret_orig);
997 if (res != TEE_SUCCESS) {
998 EMSG("TEE_InvokeTACommand failed");
999 goto cleanup_return;
1000 }
1001
1002 /* Check the actual values */
1003 for (i = 0; i < bufsize; i++) {
1004 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1005 EMSG("Unexpected value in buffer(s)");
1006 DHEXDUMP(in, bufsize);
1007 DHEXDUMP(inout, bufsize);
1008 DHEXDUMP(out, bufsize);
1009 return TEE_ERROR_GENERIC;
1010 }
1011 }
1012
1013cleanup_return:
1014 TEE_CloseTASession(sess);
1015 return res;
1016}
1017
1018TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1019{
1020 uint8_t *in;
1021 uint8_t *inout;
1022 uint8_t *out;
1023 size_t bufsize;
1024 size_t i;
1025
1026 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1027 TEE_PARAM_TYPE_MEMREF_INOUT,
1028 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1029 return TEE_ERROR_GENERIC;
1030
1031 bufsize = params[0].memref.size;
1032 if (params[1].memref.size != bufsize ||
1033 params[2].memref.size != bufsize)
1034 return TEE_ERROR_GENERIC;
1035
1036 in = params[0].memref.buffer;
1037 inout = params[1].memref.buffer;
1038 out = params[2].memref.buffer;
1039
1040 for (i = 0; i < bufsize; i++)
1041 out[i] = ++inout[i] + in[i];
1042
1043 return TEE_SUCCESS;
1044}
Jens Wiklander87e81702018-03-20 12:00:00 +08001045
1046TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1047{
1048 size_t n;
1049
1050 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1051 TEE_PARAM_TYPE_MEMREF_INPUT,
1052 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1053 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1054 return TEE_ERROR_BAD_PARAMETERS;
1055
1056 for (n = 0; n < TEE_NUM_PARAMS; n++)
1057 if (!params[n].memref.buffer || !params[n].memref.size)
1058 return TEE_ERROR_BAD_PARAMETERS;
1059
1060 return TEE_SUCCESS;
1061}
Jerome Forissier53bde722018-05-31 09:14:54 +02001062
1063TEE_Result ta_entry_call_lib(uint32_t param_types,
1064 TEE_Param params[4] __unused)
1065{
1066 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1067 TEE_PARAM_TYPE_NONE,
1068 TEE_PARAM_TYPE_NONE,
1069 TEE_PARAM_TYPE_NONE))
1070 return TEE_ERROR_BAD_PARAMETERS;
1071
1072 if (os_test_shlib_add(1, 2) != 3)
1073 return TEE_ERROR_GENERIC;
1074
1075 return TEE_SUCCESS;
1076}
1077
1078TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1079 TEE_Param params[4] __unused)
1080{
1081 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1082 TEE_PARAM_TYPE_NONE,
1083 TEE_PARAM_TYPE_NONE,
1084 TEE_PARAM_TYPE_NONE))
1085 return TEE_ERROR_BAD_PARAMETERS;
1086
1087 os_test_shlib_panic();
1088
1089 return TEE_ERROR_GENERIC;
1090}