blob: e8904241a6d3f936ceeb85f7e3ce6129ea69475f [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 */
27#include <stdint.h>
28
29#include <compiler.h>
30#include <ta_crypt.h>
31#include <ta_os_test.h>
32#include <tee_internal_api_extensions.h>
33
34#include "os_test.h"
35#include "testframework.h"
Jens Wiklander246184a2015-12-11 08:28:59 +010036#include "test_float_subj.h"
Pascal Brandc639ac82015-07-02 08:53:34 +020037
38enum p_type {
39 P_TYPE_BOOL,
40 P_TYPE_INT,
41 P_TYPE_UUID,
42 P_TYPE_IDENTITY,
43 P_TYPE_STRING,
44 P_TYPE_BINARY_BLOCK,
45};
46
47struct p_attr {
48 const char *str;
49 enum p_type type;
50 bool retrieved;
51};
52
53static TEE_Result print_properties(TEE_PropSetHandle h,
54 TEE_PropSetHandle prop_set,
55 struct p_attr *p_attrs, size_t num_p_attrs)
56{
57TEE_Result res;
58size_t n;
59
60TEE_StartPropertyEnumerator(h, prop_set);
61
62while (true) {
63 char nbuf[80];
64 char vbuf[80];
65 char vbuf2[80];
Jens Wiklanderc5231592015-11-11 09:27:27 +010066 uint32_t nblen = sizeof(nbuf);
67 uint32_t vblen = sizeof(vbuf);
68 uint32_t vblen2 = sizeof(vbuf2);
Pascal Brandc639ac82015-07-02 08:53:34 +020069
70 res = TEE_GetPropertyName(h, nbuf, &nblen);
71 if (res != TEE_SUCCESS) {
72 EMSG("TEE_GetPropertyName returned 0x%x\n",
73 (unsigned int)res);
74 return res;
75 }
76
77 res = TEE_GetPropertyAsString(h, NULL, vbuf, &vblen);
78 if (res != TEE_SUCCESS) {
79 EMSG("1TEE_GetPropertyAsString(\"%s\") returned 0x%x\n",
80 nbuf, (unsigned int)res);
81 return res;
82 }
83 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
84 if (res != TEE_SUCCESS) {
85 EMSG("2TEE_GetPropertyAsString(\"%s\") returned 0x%x\n",
86 nbuf, (unsigned int)res);
87 return res;
88 }
89 if (my_strcmp(vbuf, vbuf2) != 0) {
90 EMSG("String of \"%s\" differs\n", nbuf);
91 return TEE_ERROR_GENERIC;
92 }
93
94 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
95
96 for (n = 0; n < num_p_attrs; n++) {
97 if (my_strcmp(nbuf, p_attrs[n].str) != 0)
98 continue;
99
100 if (p_attrs[n].retrieved) {
101 EMSG("Value \"%s\" already retrieved\n",
102 p_attrs[n].str);
103 return TEE_ERROR_GENERIC;
104 }
105 p_attrs[n].retrieved = true;
106
107 switch (p_attrs[n].type) {
108 case P_TYPE_BOOL:
109 {
110 bool v;
111
112 res =
113 TEE_GetPropertyAsBool(h, NULL, &v);
114 if (res != TEE_SUCCESS) {
115 EMSG(
116 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
117 nbuf, (unsigned int)res);
118 return res;
119 }
120 }
121 break;
122
123 case P_TYPE_INT:
124 {
125 uint32_t v;
126
127 res = TEE_GetPropertyAsU32(h, NULL, &v);
128 if (res != TEE_SUCCESS) {
129 EMSG(
130 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
131 nbuf, (unsigned int)res);
132 return res;
133 }
134 }
135 break;
136
137 case P_TYPE_UUID:
138 {
139 TEE_UUID v;
140
141 res =
142 TEE_GetPropertyAsUUID(h, NULL, &v);
143 if (res != TEE_SUCCESS) {
144 EMSG(
145 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
146 nbuf, (unsigned int)res);
147 return res;
148 }
149 }
150 break;
151
152 case P_TYPE_IDENTITY:
153 {
154 TEE_Identity v;
155
156 res =
157 TEE_GetPropertyAsIdentity(h, NULL,
158 &v);
159 if (res != TEE_SUCCESS) {
160 EMSG(
161 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
162 nbuf, (unsigned int)res);
163 return res;
164 }
165 }
166 break;
167
168 case P_TYPE_STRING:
169 /* Already read as string */
170 break;
171
172 case P_TYPE_BINARY_BLOCK:
173 {
174 char bbuf[80];
Jens Wiklanderc5231592015-11-11 09:27:27 +0100175 uint32_t bblen = sizeof(bbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200176
177 res =
178 TEE_GetPropertyAsBinaryBlock(h,
179 NULL,
180 bbuf,
181 &bblen);
182 if (res != TEE_SUCCESS) {
183 EMSG(
184 "TEE_GetPropertyAsBinaryBlock(\"%s\") returned 0x%x\n",
185 nbuf, (unsigned int)res);
186 return res;
187 }
188 if (my_strcmp
189 ("myprop.binaryblock", nbuf) == 0) {
190 const char exp_bin_value[] =
191 "Hello world!";
192
193 if (bblen !=
194 my_strlen(exp_bin_value)
195 ||
196 TEE_MemCompare
197 (exp_bin_value, bbuf,
198 bblen) != 0) {
199 EMSG(
200 "Binary buffer of \"%s\" differs from \"%s\"\n",
201 nbuf, exp_bin_value);
202 EMSG(
203 "Got \"%s\"\n",
204 bbuf);
205 return
206 TEE_ERROR_GENERIC;
207 }
208 }
209
210 }
211 break;
212
213 default:
214 EMSG("Unknown type (%d) for \"%s\"\n",
215 p_attrs[n].type, p_attrs[n].str);
216 return TEE_ERROR_GENERIC;
217 }
218 }
219
220 res = TEE_GetNextProperty(h);
221 if (res != TEE_SUCCESS) {
222 if (res == TEE_ERROR_ITEM_NOT_FOUND)
223 return TEE_SUCCESS;
224 return res;
225 }
226}
227}
228
229static TEE_Result test_malloc(void)
230{
231 void *p = TEE_Malloc(4, 0);
232
233 if (p == NULL) {
234 EMSG("TEE_Malloc failed\n");
235 return TEE_ERROR_OUT_OF_MEMORY;
236 }
237 TEE_Free(p);
238 TEE_Free(NULL);
239
240 return TEE_SUCCESS;
241}
242
243static TEE_Result test_properties(void)
244{
245 TEE_Result res = TEE_ERROR_GENERIC;
246 TEE_PropSetHandle h;
247 struct p_attr p_attrs[] = {
248 {"gpd.ta.appID", P_TYPE_UUID},
249 {"gpd.ta.singleInstance", P_TYPE_BOOL},
250 {"gpd.ta.multiSession", P_TYPE_BOOL},
251 {"gpd.ta.instanceKeepAlive", P_TYPE_BOOL},
252 {"gpd.ta.dataSize", P_TYPE_INT},
253 {"gpd.ta.stackSize", P_TYPE_INT},
254 {"gpd.ta.version", P_TYPE_STRING},
255 {"gpd.ta.description", P_TYPE_STRING},
256 {"gpd.client.identity", P_TYPE_IDENTITY},
257 {"gpd.tee.apiversion", P_TYPE_STRING},
258 {"gpd.tee.description", P_TYPE_STRING},
259 {"gpd.tee.deviceID", P_TYPE_UUID},
260 {"gpd.tee.systemTime.protectionLevel", P_TYPE_INT},
261 {"gpd.tee.TAPersistentTime.protectionLevel", P_TYPE_INT},
262 {"gpd.tee.arith.maxBigIntSize", P_TYPE_INT},
263 {"gpd.tee.cryptography.ecc", P_TYPE_BOOL},
264 {"gpd.tee.trustedStorage.antiRollback.protectionLevel", P_TYPE_INT},
265 {"gpd.tee.trustedos.implementation.version", P_TYPE_STRING},
266 {"gpd.tee.trustedos.implementation.binaryversion", P_TYPE_INT},
267 {"gpd.tee.trustedos.manufacturer", P_TYPE_STRING},
268 {"gpd.tee.firmware.implementation.version", P_TYPE_STRING},
269 {"gpd.tee.firmware.implementation.binaryversion", P_TYPE_INT},
270 {"gpd.tee.firmware.manufacturer", P_TYPE_STRING},
271 {"myprop.true", P_TYPE_BOOL},
272 {"myprop.42", P_TYPE_INT},
273 {"myprop.123", P_TYPE_UUID},
274 {"myprop.1234", P_TYPE_IDENTITY},
275 {"myprop.hello", P_TYPE_STRING},
276 {"myprop.binaryblock", P_TYPE_BINARY_BLOCK},
277 };
278 const size_t num_p_attrs = sizeof(p_attrs) / sizeof(p_attrs[0]);
279 size_t n;
280
281 res = TEE_AllocatePropertyEnumerator(&h);
282 if (res != TEE_SUCCESS) {
283 EMSG("TEE_AllocatePropertyEnumerator: returned 0x%x\n",
284 (unsigned int)res);
285 return TEE_ERROR_GENERIC;
286 }
287
288 printf("Getting properties for current TA\n");
289 res = print_properties(h, TEE_PROPSET_CURRENT_TA, p_attrs, num_p_attrs);
290 if (res != TEE_SUCCESS)
291 goto cleanup_return;
292
293 printf("Getting properties for current client\n");
294 res = print_properties(h, TEE_PROPSET_CURRENT_CLIENT, p_attrs,
295 num_p_attrs);
296 if (res != TEE_SUCCESS)
297 goto cleanup_return;
298
299 printf("Getting properties for implementation\n");
300 res = print_properties(h, TEE_PROPSET_TEE_IMPLEMENTATION, p_attrs,
301 num_p_attrs);
302 if (res != TEE_SUCCESS)
303 goto cleanup_return;
304
305 for (n = 0; n < num_p_attrs; n++) {
306 if (!p_attrs[n].retrieved) {
307 EMSG("\"%s\" not retrieved\n", p_attrs[n].str);
308 res = TEE_ERROR_GENERIC;
309 goto cleanup_return;
310 }
311 }
312
313cleanup_return:
314 TEE_FreePropertyEnumerator(h);
315 return res;
316}
317
318static TEE_Result test_mem_access_right(uint32_t param_types,
319 TEE_Param params[4])
320{
321 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
322 TEE_Result res;
323 uint32_t ret_orig;
324 uint32_t l_pts;
325 TEE_Param l_params[4] = { { {0} } };
326 uint8_t buf[32];
327 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
328
329 if (param_types !=
330 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
331 return TEE_ERROR_GENERIC;
332 res =
333 TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
334 TEE_MEMORY_ACCESS_ANY_OWNER,
335 params[0].memref.buffer,
336 params[0].memref.size);
337 if (res != TEE_SUCCESS)
338 return res;
339 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
340 params[0].memref.buffer,
341 params[0].memref.size);
342 if (res != TEE_ERROR_ACCESS_DENIED)
343 return TEE_ERROR_GENERIC;
344
345 res = TEE_OpenTASession(&test_uuid, 0, 0, NULL, &sess, &ret_orig);
346 if (res != TEE_SUCCESS) {
347 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
348 goto cleanup_return;
349 }
350
351 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0);
352 l_params[0].memref.buffer = buf;
353 l_params[0].memref.size = sizeof(buf);
354 res = TEE_InvokeTACommand(sess, 0, TA_OS_TEST_CMD_PRIVATE_PARAMS,
355 l_pts, l_params, &ret_orig);
356 if (res != TEE_SUCCESS) {
357 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
358 goto cleanup_return;
359 }
360
361cleanup_return:
362 TEE_CloseTASession(sess);
363 return res;
364}
365
366static TEE_Result test_time(void)
367{
368 TEE_Result res;
369 TEE_Time t;
370 TEE_Time sys_t;
371
372 static const TEE_Time null_time = { 0, 0 };
373 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
374
375 TEE_GetSystemTime(&sys_t);
376 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
377 (unsigned int)sys_t.millis);
378
379 TEE_GetREETime(&t);
380 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
381 (unsigned int)t.millis);
382
383 res = TEE_GetTAPersistentTime(&t);
384 switch (res) {
385 case TEE_SUCCESS:
386 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
387 (unsigned int)t.millis);
388 break;
389 case TEE_ERROR_OVERFLOW:
390 EMSG("Stored TA time overflowed %u.%03u\n",
391 (unsigned int)t.seconds, (unsigned int)t.millis);
392 break;
393 case TEE_ERROR_TIME_NOT_SET:
394 EMSG("TA time not stored\n");
395 break;
396 case TEE_ERROR_TIME_NEEDS_RESET:
397 EMSG("TA time needs reset\n");
398 break;
399 default:
400 return res;
401 }
402
403 res = TEE_SetTAPersistentTime(&null_time);
404 if (res != TEE_SUCCESS) {
405 EMSG("TEE_SetTAPersistentTime: failed\n");
406 return res;
407 }
408
409 res = TEE_GetTAPersistentTime(&t);
410 if (res != TEE_SUCCESS) {
411 EMSG("TEE_GetTAPersistentTime null: failed\n");
412 return res;
413 }
414 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
415 (unsigned int)t.millis);
416 /*
417 * The time between TEE_SetTAPersistentTime() and
418 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
419 * it's not even a millisecond.
420 */
421 if (t.seconds > 1 || t.millis >= 1000) {
422 EMSG("Unexpected stored TA time %u.%03u\n",
423 (unsigned int)t.seconds, (unsigned int)t.millis);
424 return TEE_ERROR_BAD_STATE;
425 }
426
427 res = TEE_SetTAPersistentTime(&wrap_time);
428 if (res != TEE_SUCCESS) {
429 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
430 return res;
431 }
432
433 res = TEE_Wait(1000);
434 if (res != TEE_SUCCESS)
435 EMSG("TEE_Wait wrap: failed\n");
436
437 res = TEE_GetTAPersistentTime(&t);
438 if (res != TEE_ERROR_OVERFLOW) {
439 EMSG("TEE_GetTAPersistentTime: failed\n");
440 return TEE_ERROR_BAD_STATE;
441 }
442 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
443 (unsigned int)t.millis);
444
445 if (t.seconds > sys_t.seconds) {
446 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
447 (unsigned int)t.seconds, (unsigned int)t.millis,
448 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
449 return TEE_ERROR_BAD_STATE;
450 }
451
452 return TEE_SUCCESS;
453}
454
Jens Wiklander246184a2015-12-11 08:28:59 +0100455#ifdef CFG_TA_FLOAT_SUPPORT
456static bool my_dcmpeq(double v1, double v2, double prec)
457{
458 return v1 > (v2 - prec) && v1 < (v2 + prec);
459}
460
461static bool my_fcmpeq(float v1, float v2, float prec)
462{
463 return v1 > (v2 - prec) && v1 < (v2 + prec);
464}
465
466
467static TEE_Result test_float(void)
468{
469#define VAL1 2.6
470#define VAL1_INT 2
471#define VAL2 5.3
472#define DPREC 0.000000000000001
473#define FPREC 0.000001
474#define EXPECT(expr) do { \
475 if (!(expr)) { \
476 EMSG("Expression %s failed", #expr); \
477 return TEE_ERROR_GENERIC; \
478 } \
479 } while (0)
480
481 IMSG("Testing floating point operations");
482
483 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
484 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
485 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
486 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
487 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
488
489 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
490 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
491 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
492 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
493 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
494
495 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
496 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
497 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
498 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
499 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
500
501 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
502 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
503 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
504 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
505 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
506
507 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
508 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
509 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
510 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
511
512 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
513 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
514 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
515 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
516
517 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
518 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
519
520 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
521 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
522 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
523 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
524
525 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
526 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
527 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
528 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
529 return TEE_SUCCESS;
530}
531#else /*CFG_TA_FLOAT_SUPPORT*/
532static TEE_Result test_float(void)
533{
534 IMSG("Floating point disabled");
535 return TEE_SUCCESS;
536}
537#endif /*CFG_TA_FLOAT_SUPPORT*/
538
Pascal Brandc639ac82015-07-02 08:53:34 +0200539TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
540{
541 TEE_Result res = TEE_ERROR_GENERIC;
542
543 printf("ta_entry_basic: enter\n");
544
545 res = test_malloc();
546 if (res != TEE_SUCCESS)
547 return res;
548
549 res = test_properties();
550 if (res != TEE_SUCCESS)
551 return res;
552
553 res = test_mem_access_right(param_types, params);
554 if (res != TEE_SUCCESS)
555 return res;
556
557 res = test_time();
558 if (res != TEE_SUCCESS)
559 return res;
560
Jens Wiklander246184a2015-12-11 08:28:59 +0100561 res = test_float();
562 if (res != TEE_SUCCESS)
563 return res;
564
Pascal Brandc639ac82015-07-02 08:53:34 +0200565 /* mpa lib test bench, panics TA on failure */
566 tb_main();
567
568 return TEE_SUCCESS;
569}
570
571TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
572{
573 volatile bool mytrue = true;
574 (void)param_types;
575 (void)params;
576
577 printf("ta_entry_panic: enter\n");
578 /*
579 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
580 * the __noreturn attribute.
581 */
582 if (mytrue)
583 TEE_Panic(0xbeef);
584
585 /*
586 * Should not be reached, but if it is the testsuite can detect that
587 * TEE_Panic() returned instead of panicking the TA.
588 */
589 return TEE_SUCCESS;
590}
591
592TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
593 TEE_Param params[4])
594{
595 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
596 TEE_Result res;
597 TEE_TASessionHandle sess;
598 uint32_t ret_orig;
599
600 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
601 TEE_PARAM_TYPE_NONE,
602 TEE_PARAM_TYPE_NONE,
603 TEE_PARAM_TYPE_NONE)) {
604 EMSG("ta_entry_client_with_timeout: bad parameters\n");
605 return TEE_ERROR_BAD_PARAMETERS;
606 }
607
608 res = TEE_OpenTASession(&os_test_uuid, 0, 0, NULL, &sess, &ret_orig);
609 if (res != TEE_SUCCESS) {
610 EMSG(
611 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
612 return res;
613 }
614
615 res =
616 TEE_InvokeTACommand(sess, params[0].value.a / 2,
617 TA_OS_TEST_CMD_WAIT, param_types, params,
618 &ret_orig);
619
620 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
621 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
622 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
623 (unsigned int)ret_orig);
624 res = TEE_ERROR_GENERIC;
625 } else
626 res = TEE_SUCCESS;
627
628 TEE_CloseTASession(sess);
629 return res;
630
631}
632
633TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
634{
635 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
636 TEE_Result res;
637 uint32_t l_pts;
638 TEE_Param l_params[4] = { { {0} } };
639 TEE_TASessionHandle sess;
640 uint32_t ret_orig;
641 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
642 static const uint8_t sha256_out[] = {
643 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
644 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
645 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
646 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
647 };
648 uint8_t out[32] = { 0 };
649 void *in = NULL;
650
651 (void)param_types;
652 (void)params;
653
654 printf("ta_entry_client: enter\n");
655
656 in = TEE_Malloc(sizeof(sha256_in), 0);
657 if (in == NULL)
658 return TEE_ERROR_OUT_OF_MEMORY;
659 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
660
661 res = TEE_OpenTASession(&crypt_uuid, 0, 0, NULL, &sess, &ret_orig);
662 if (res != TEE_SUCCESS) {
663 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
664 goto cleanup_return;
665 }
666
667 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
668 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
669 l_params[0].memref.buffer = in;
670 l_params[0].memref.size = sizeof(sha256_in);
671 l_params[1].memref.buffer = out;
672 l_params[1].memref.size = sizeof(out);
673
674 res = TEE_InvokeTACommand(sess, 0, TA_CRYPT_CMD_SHA256, l_pts, l_params,
675 &ret_orig);
676 if (res != TEE_SUCCESS) {
677 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
678 goto cleanup_return;
679 }
680
681 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
682 EMSG("ta_entry_client: out parameter failed\n");
683 res = TEE_ERROR_GENERIC;
684 goto cleanup_return;
685 }
686
687cleanup_return:
688 TEE_Free(in);
689 TEE_CloseTASession(sess);
690 return res;
691}
692
693TEE_Result ta_entry_private_params(uint32_t param_types, TEE_Param params[4])
694{
695 TEE_Result res;
696
697 if (param_types !=
698 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
699 return TEE_ERROR_GENERIC;
700 res =
701 TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
702 TEE_MEMORY_ACCESS_ANY_OWNER,
703 params[0].memref.buffer,
704 params[0].memref.size);
705 if (res != TEE_SUCCESS)
706 return res;
707
708 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
709 params[0].memref.buffer,
710 params[0].memref.size);
711
712 return res;
713}
714
715TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
716{
717 TEE_Result res = TEE_SUCCESS;
718 (void)param_types;
719
720 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
721 /* Wait */
722 res = TEE_Wait(params[0].value.a);
723
724 return res;
725}
726
727TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
728{
729 long stack;
730 long stack_addr = (long)&stack;
731
732 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0))
733 return TEE_ERROR_GENERIC;
734
735 switch (params[0].value.a) {
736 case 1:
737 *((uint32_t *) 0) = 0;
738 break;
739 case 2:
740 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
741 break;
742 case 3:
743 ((void (*)(void))0) ();
744 break;
745 case 4:
746 ((void (*)(void))(stack_addr + 0x40000000)) ();
747 break;
748 case 5:
749 {
750 static const uint32_t my_undef = 0xffffffff;
751 ((void (*)(void))(uintptr_t) &my_undef) ();
752 }
753 break;
754 default:
755 break;
756 }
757
758 return TEE_SUCCESS;
759}