blob: 4b733ba562a8e0f2559e646a54ba373d2310afbc [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) {
65 EMSG("From line %d: return_len=%u vs expected_res=%u",
66 line, return_len, expected_len);
67 return TEE_ERROR_GENERIC;
68 }
69 return TEE_SUCCESS;
70}
71
Pascal Brandc639ac82015-07-02 08:53:34 +020072static TEE_Result print_properties(TEE_PropSetHandle h,
73 TEE_PropSetHandle prop_set,
74 struct p_attr *p_attrs, size_t num_p_attrs)
75{
76TEE_Result res;
77size_t n;
78
79TEE_StartPropertyEnumerator(h, prop_set);
80
81while (true) {
Pascal Brand624b6a32016-02-16 12:51:34 +010082 char nbuf[256];
83 char nbuf_small[256];
84 char vbuf[256];
85 char vbuf2[256];
Jens Wiklanderc5231592015-11-11 09:27:27 +010086 uint32_t nblen = sizeof(nbuf);
Pascal Brand624b6a32016-02-16 12:51:34 +010087 uint32_t nblen_small;
Jens Wiklanderc5231592015-11-11 09:27:27 +010088 uint32_t vblen = sizeof(vbuf);
89 uint32_t vblen2 = sizeof(vbuf2);
Pascal Brandc639ac82015-07-02 08:53:34 +020090
91 res = TEE_GetPropertyName(h, nbuf, &nblen);
92 if (res != TEE_SUCCESS) {
93 EMSG("TEE_GetPropertyName returned 0x%x\n",
94 (unsigned int)res);
95 return res;
96 }
Pascal Brand624b6a32016-02-16 12:51:34 +010097 if (nblen != strlen(nbuf) + 1) {
98 EMSG("Name has wrong size: %u vs %u", nblen, strlen(nbuf) + 1);
99 return TEE_ERROR_GENERIC;
100 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200101
Pascal Brand624b6a32016-02-16 12:51:34 +0100102
103 /* Get the property name with a very small buffer */
104 nblen_small = 2;
105 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
106 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
107 nblen_small, nblen);
108 if (res != TEE_SUCCESS)
109 return res;
110
111 /* Get the property name with almost the correct buffer */
112 nblen_small = nblen - 1;
113 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
114 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
115 nblen_small, nblen);
116 if (res != TEE_SUCCESS)
117 return res;
118
119 /* Get the property name with the exact buffer length */
120 nblen_small = nblen;
121 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
122 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
123 nblen_small, nblen);
124 if (res != TEE_SUCCESS)
125 return res;
126
127 /* Get the property value */
Pascal Brandc639ac82015-07-02 08:53:34 +0200128 res = TEE_GetPropertyAsString(h, NULL, vbuf, &vblen);
Pascal Brand624b6a32016-02-16 12:51:34 +0100129 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
130 vblen, strlen(vbuf) + 1);
131 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200132 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100133
Pascal Brandc639ac82015-07-02 08:53:34 +0200134 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
Pascal Brand624b6a32016-02-16 12:51:34 +0100135 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
136 vblen2, strlen(vbuf2) + 1);
137 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200138 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100139
Pascal Brandc639ac82015-07-02 08:53:34 +0200140 if (my_strcmp(vbuf, vbuf2) != 0) {
141 EMSG("String of \"%s\" differs\n", nbuf);
142 return TEE_ERROR_GENERIC;
143 }
144
Pascal Brand624b6a32016-02-16 12:51:34 +0100145 /* Get the property with a very small buffer */
146 vblen2 = 1;
147 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
148 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
149 vblen2, vblen);
150 if (res != TEE_SUCCESS)
151 return res;
152
153 /* Get the property with almost the correct buffer */
154 vblen2 = vblen - 1;
155 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
156 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
157 vblen2, vblen);
158 if (res != TEE_SUCCESS)
159 return res;
160
161 /* Get the property name with the exact buffer length */
162 vblen2 = vblen;
163 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
164 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS, vblen2, vblen);
165 if (res != TEE_SUCCESS)
166 return res;
167
168 /* check specific myprop.hello property, which is larger than 80 */
169 if (!strcmp("myprop.hello", nbuf) &&
170 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")) {
171 EMSG("TEE_GetPropertyAsString(\"%s\") is truncated - returned \"%s\"\n",
172 nbuf, vbuf);
173 return TEE_ERROR_GENERIC;
174 }
175
Pascal Brandc639ac82015-07-02 08:53:34 +0200176 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
177
178 for (n = 0; n < num_p_attrs; n++) {
179 if (my_strcmp(nbuf, p_attrs[n].str) != 0)
180 continue;
181
182 if (p_attrs[n].retrieved) {
183 EMSG("Value \"%s\" already retrieved\n",
184 p_attrs[n].str);
185 return TEE_ERROR_GENERIC;
186 }
187 p_attrs[n].retrieved = true;
188
189 switch (p_attrs[n].type) {
190 case P_TYPE_BOOL:
191 {
192 bool v;
193
194 res =
195 TEE_GetPropertyAsBool(h, NULL, &v);
196 if (res != TEE_SUCCESS) {
197 EMSG(
198 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
199 nbuf, (unsigned int)res);
200 return res;
201 }
202 }
203 break;
204
205 case P_TYPE_INT:
206 {
207 uint32_t v;
208
209 res = TEE_GetPropertyAsU32(h, NULL, &v);
210 if (res != TEE_SUCCESS) {
211 EMSG(
212 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
213 nbuf, (unsigned int)res);
214 return res;
215 }
216 }
217 break;
218
219 case P_TYPE_UUID:
220 {
221 TEE_UUID v;
222
223 res =
224 TEE_GetPropertyAsUUID(h, NULL, &v);
225 if (res != TEE_SUCCESS) {
226 EMSG(
227 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
228 nbuf, (unsigned int)res);
229 return res;
230 }
231 }
232 break;
233
234 case P_TYPE_IDENTITY:
235 {
236 TEE_Identity v;
237
238 res =
239 TEE_GetPropertyAsIdentity(h, NULL,
240 &v);
241 if (res != TEE_SUCCESS) {
242 EMSG(
243 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
244 nbuf, (unsigned int)res);
245 return res;
246 }
247 }
248 break;
249
250 case P_TYPE_STRING:
251 /* Already read as string */
252 break;
253
254 case P_TYPE_BINARY_BLOCK:
255 {
256 char bbuf[80];
Jens Wiklanderc5231592015-11-11 09:27:27 +0100257 uint32_t bblen = sizeof(bbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200258
259 res =
260 TEE_GetPropertyAsBinaryBlock(h,
261 NULL,
262 bbuf,
263 &bblen);
264 if (res != TEE_SUCCESS) {
265 EMSG(
266 "TEE_GetPropertyAsBinaryBlock(\"%s\") returned 0x%x\n",
267 nbuf, (unsigned int)res);
268 return res;
269 }
270 if (my_strcmp
271 ("myprop.binaryblock", nbuf) == 0) {
272 const char exp_bin_value[] =
273 "Hello world!";
274
275 if (bblen !=
276 my_strlen(exp_bin_value)
277 ||
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;
410
411 if (param_types !=
412 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
413 return TEE_ERROR_GENERIC;
414 res =
415 TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
416 TEE_MEMORY_ACCESS_ANY_OWNER,
417 params[0].memref.buffer,
418 params[0].memref.size);
419 if (res != TEE_SUCCESS)
420 return res;
421 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
422 params[0].memref.buffer,
423 params[0].memref.size);
424 if (res != TEE_ERROR_ACCESS_DENIED)
425 return TEE_ERROR_GENERIC;
426
427 res = TEE_OpenTASession(&test_uuid, 0, 0, NULL, &sess, &ret_orig);
428 if (res != TEE_SUCCESS) {
429 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
430 goto cleanup_return;
431 }
432
433 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0);
434 l_params[0].memref.buffer = buf;
435 l_params[0].memref.size = sizeof(buf);
436 res = TEE_InvokeTACommand(sess, 0, TA_OS_TEST_CMD_PRIVATE_PARAMS,
437 l_pts, l_params, &ret_orig);
438 if (res != TEE_SUCCESS) {
439 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
440 goto cleanup_return;
441 }
442
443cleanup_return:
444 TEE_CloseTASession(sess);
445 return res;
446}
447
448static TEE_Result test_time(void)
449{
450 TEE_Result res;
451 TEE_Time t;
452 TEE_Time sys_t;
453
454 static const TEE_Time null_time = { 0, 0 };
455 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
456
457 TEE_GetSystemTime(&sys_t);
458 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
459 (unsigned int)sys_t.millis);
460
461 TEE_GetREETime(&t);
462 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
463 (unsigned int)t.millis);
464
465 res = TEE_GetTAPersistentTime(&t);
466 switch (res) {
467 case TEE_SUCCESS:
468 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
469 (unsigned int)t.millis);
470 break;
471 case TEE_ERROR_OVERFLOW:
472 EMSG("Stored TA time overflowed %u.%03u\n",
473 (unsigned int)t.seconds, (unsigned int)t.millis);
474 break;
475 case TEE_ERROR_TIME_NOT_SET:
476 EMSG("TA time not stored\n");
477 break;
478 case TEE_ERROR_TIME_NEEDS_RESET:
479 EMSG("TA time needs reset\n");
480 break;
481 default:
482 return res;
483 }
484
485 res = TEE_SetTAPersistentTime(&null_time);
486 if (res != TEE_SUCCESS) {
487 EMSG("TEE_SetTAPersistentTime: failed\n");
488 return res;
489 }
490
491 res = TEE_GetTAPersistentTime(&t);
492 if (res != TEE_SUCCESS) {
493 EMSG("TEE_GetTAPersistentTime null: failed\n");
494 return res;
495 }
496 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
497 (unsigned int)t.millis);
498 /*
499 * The time between TEE_SetTAPersistentTime() and
500 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
501 * it's not even a millisecond.
502 */
503 if (t.seconds > 1 || t.millis >= 1000) {
504 EMSG("Unexpected stored TA time %u.%03u\n",
505 (unsigned int)t.seconds, (unsigned int)t.millis);
506 return TEE_ERROR_BAD_STATE;
507 }
508
509 res = TEE_SetTAPersistentTime(&wrap_time);
510 if (res != TEE_SUCCESS) {
511 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
512 return res;
513 }
514
515 res = TEE_Wait(1000);
516 if (res != TEE_SUCCESS)
517 EMSG("TEE_Wait wrap: failed\n");
518
519 res = TEE_GetTAPersistentTime(&t);
520 if (res != TEE_ERROR_OVERFLOW) {
521 EMSG("TEE_GetTAPersistentTime: failed\n");
522 return TEE_ERROR_BAD_STATE;
523 }
524 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
525 (unsigned int)t.millis);
526
527 if (t.seconds > sys_t.seconds) {
528 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
529 (unsigned int)t.seconds, (unsigned int)t.millis,
530 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
531 return TEE_ERROR_BAD_STATE;
532 }
533
534 return TEE_SUCCESS;
535}
536
Jens Wiklander246184a2015-12-11 08:28:59 +0100537#ifdef CFG_TA_FLOAT_SUPPORT
538static bool my_dcmpeq(double v1, double v2, double prec)
539{
540 return v1 > (v2 - prec) && v1 < (v2 + prec);
541}
542
543static bool my_fcmpeq(float v1, float v2, float prec)
544{
545 return v1 > (v2 - prec) && v1 < (v2 + prec);
546}
547
548
549static TEE_Result test_float(void)
550{
551#define VAL1 2.6
552#define VAL1_INT 2
553#define VAL2 5.3
554#define DPREC 0.000000000000001
555#define FPREC 0.000001
556#define EXPECT(expr) do { \
557 if (!(expr)) { \
558 EMSG("Expression %s failed", #expr); \
559 return TEE_ERROR_GENERIC; \
560 } \
561 } while (0)
562
563 IMSG("Testing floating point operations");
564
565 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
566 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
567 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
568 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
569 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
570
571 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
572 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
573 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
574 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
575 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
576
577 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
578 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
579 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
580 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
581 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
582
583 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
584 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
585 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
586 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
587 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
588
589 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
590 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
591 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
592 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
593
594 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
595 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
596 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
597 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
598
599 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
600 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
601
602 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
603 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
604 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
605 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
606
607 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
608 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
609 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
610 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
611 return TEE_SUCCESS;
612}
613#else /*CFG_TA_FLOAT_SUPPORT*/
614static TEE_Result test_float(void)
615{
616 IMSG("Floating point disabled");
617 return TEE_SUCCESS;
618}
619#endif /*CFG_TA_FLOAT_SUPPORT*/
620
Pascal Brandc639ac82015-07-02 08:53:34 +0200621TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
622{
623 TEE_Result res = TEE_ERROR_GENERIC;
624
625 printf("ta_entry_basic: enter\n");
626
627 res = test_malloc();
628 if (res != TEE_SUCCESS)
629 return res;
630
631 res = test_properties();
632 if (res != TEE_SUCCESS)
633 return res;
634
635 res = test_mem_access_right(param_types, params);
636 if (res != TEE_SUCCESS)
637 return res;
638
639 res = test_time();
640 if (res != TEE_SUCCESS)
641 return res;
642
Jens Wiklander246184a2015-12-11 08:28:59 +0100643 res = test_float();
644 if (res != TEE_SUCCESS)
645 return res;
646
Pascal Brandc639ac82015-07-02 08:53:34 +0200647 /* mpa lib test bench, panics TA on failure */
648 tb_main();
649
650 return TEE_SUCCESS;
651}
652
653TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
654{
655 volatile bool mytrue = true;
656 (void)param_types;
657 (void)params;
658
659 printf("ta_entry_panic: enter\n");
660 /*
661 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
662 * the __noreturn attribute.
663 */
664 if (mytrue)
665 TEE_Panic(0xbeef);
666
667 /*
668 * Should not be reached, but if it is the testsuite can detect that
669 * TEE_Panic() returned instead of panicking the TA.
670 */
671 return TEE_SUCCESS;
672}
673
674TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
675 TEE_Param params[4])
676{
677 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
678 TEE_Result res;
679 TEE_TASessionHandle sess;
680 uint32_t ret_orig;
681
682 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
683 TEE_PARAM_TYPE_NONE,
684 TEE_PARAM_TYPE_NONE,
685 TEE_PARAM_TYPE_NONE)) {
686 EMSG("ta_entry_client_with_timeout: bad parameters\n");
687 return TEE_ERROR_BAD_PARAMETERS;
688 }
689
690 res = TEE_OpenTASession(&os_test_uuid, 0, 0, NULL, &sess, &ret_orig);
691 if (res != TEE_SUCCESS) {
692 EMSG(
693 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
694 return res;
695 }
696
697 res =
698 TEE_InvokeTACommand(sess, params[0].value.a / 2,
699 TA_OS_TEST_CMD_WAIT, param_types, params,
700 &ret_orig);
701
702 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
703 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
704 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
705 (unsigned int)ret_orig);
706 res = TEE_ERROR_GENERIC;
707 } else
708 res = TEE_SUCCESS;
709
710 TEE_CloseTASession(sess);
711 return res;
712
713}
714
715TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
716{
717 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
718 TEE_Result res;
719 uint32_t l_pts;
720 TEE_Param l_params[4] = { { {0} } };
721 TEE_TASessionHandle sess;
722 uint32_t ret_orig;
723 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
724 static const uint8_t sha256_out[] = {
725 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
726 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
727 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
728 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
729 };
730 uint8_t out[32] = { 0 };
731 void *in = NULL;
732
733 (void)param_types;
734 (void)params;
735
736 printf("ta_entry_client: enter\n");
737
738 in = TEE_Malloc(sizeof(sha256_in), 0);
739 if (in == NULL)
740 return TEE_ERROR_OUT_OF_MEMORY;
741 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
742
743 res = TEE_OpenTASession(&crypt_uuid, 0, 0, NULL, &sess, &ret_orig);
744 if (res != TEE_SUCCESS) {
745 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
746 goto cleanup_return;
747 }
748
749 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
750 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
751 l_params[0].memref.buffer = in;
752 l_params[0].memref.size = sizeof(sha256_in);
753 l_params[1].memref.buffer = out;
754 l_params[1].memref.size = sizeof(out);
755
756 res = TEE_InvokeTACommand(sess, 0, TA_CRYPT_CMD_SHA256, l_pts, l_params,
757 &ret_orig);
758 if (res != TEE_SUCCESS) {
759 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
760 goto cleanup_return;
761 }
762
763 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
764 EMSG("ta_entry_client: out parameter failed\n");
765 res = TEE_ERROR_GENERIC;
766 goto cleanup_return;
767 }
768
769cleanup_return:
770 TEE_Free(in);
771 TEE_CloseTASession(sess);
772 return res;
773}
774
775TEE_Result ta_entry_private_params(uint32_t param_types, TEE_Param params[4])
776{
777 TEE_Result res;
778
779 if (param_types !=
780 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
781 return TEE_ERROR_GENERIC;
782 res =
783 TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
784 TEE_MEMORY_ACCESS_ANY_OWNER,
785 params[0].memref.buffer,
786 params[0].memref.size);
787 if (res != TEE_SUCCESS)
788 return res;
789
790 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
791 params[0].memref.buffer,
792 params[0].memref.size);
793
794 return res;
795}
796
797TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
798{
799 TEE_Result res = TEE_SUCCESS;
800 (void)param_types;
801
802 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
803 /* Wait */
804 res = TEE_Wait(params[0].value.a);
805
806 return res;
807}
808
809TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
810{
811 long stack;
812 long stack_addr = (long)&stack;
813
814 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0))
815 return TEE_ERROR_GENERIC;
816
817 switch (params[0].value.a) {
818 case 1:
819 *((uint32_t *) 0) = 0;
820 break;
821 case 2:
822 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
823 break;
824 case 3:
825 ((void (*)(void))0) ();
826 break;
827 case 4:
828 ((void (*)(void))(stack_addr + 0x40000000)) ();
829 break;
830 case 5:
831 {
832 static const uint32_t my_undef = 0xffffffff;
833 ((void (*)(void))(uintptr_t) &my_undef) ();
834 }
835 break;
836 default:
837 break;
838 }
839
840 return TEE_SUCCESS;
841}