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