blob: 84c850b2338a891d25d63c432ce7e1c642815a5c [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>
Jerome Forissiera9ab5d02019-03-17 21:14:06 +010028#include <dlfcn.h>
Jens Wiklander8324ff22018-11-21 14:16:04 +010029#include <setjmp.h>
30#include <stdint.h>
31#include <string.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020032#include <ta_crypt.h>
33#include <ta_os_test.h>
34#include <tee_internal_api_extensions.h>
35
36#include "os_test.h"
Jens Wiklander246184a2015-12-11 08:28:59 +010037#include "test_float_subj.h"
Jerome Forissier53bde722018-05-31 09:14:54 +020038#include "os_test_lib.h"
Pascal Brandc639ac82015-07-02 08:53:34 +020039
40enum p_type {
41 P_TYPE_BOOL,
42 P_TYPE_INT,
43 P_TYPE_UUID,
44 P_TYPE_IDENTITY,
45 P_TYPE_STRING,
46 P_TYPE_BINARY_BLOCK,
47};
48
49struct p_attr {
50 const char *str;
51 enum p_type type;
52 bool retrieved;
53};
54
Pascal Brand624b6a32016-02-16 12:51:34 +010055static TEE_Result check_returned_prop(
Pascal Brandaf77fdd2016-03-08 13:59:01 +010056 int line __maybe_unused, char *prop_name __maybe_unused,
Pascal Brand624b6a32016-02-16 12:51:34 +010057 TEE_Result return_res, TEE_Result expected_res,
58 uint32_t return_len, uint32_t expected_len)
59{
60 if (return_res != expected_res) {
61 EMSG("From line %d (property name=%s): return_res=0x%x vs expected_res=0x%x",
62 line, (prop_name ? prop_name : "unknown"),
63 (unsigned int)return_res, (unsigned int)expected_res);
64 return TEE_ERROR_GENERIC;
65 }
66 if (return_len != expected_len) {
Pascal Brand07bb09f2016-02-19 16:04:10 +010067 EMSG("From line %d (property name=%s): return_len=%u vs expected_res=%u",
68 line, (prop_name ? prop_name : "unknown"),
69 return_len, expected_len);
Pascal Brand624b6a32016-02-16 12:51:34 +010070 return TEE_ERROR_GENERIC;
71 }
72 return TEE_SUCCESS;
73}
74
Pascal Brandc639ac82015-07-02 08:53:34 +020075static TEE_Result print_properties(TEE_PropSetHandle h,
76 TEE_PropSetHandle prop_set,
77 struct p_attr *p_attrs, size_t num_p_attrs)
78{
Etienne Carriere102092e2019-03-28 15:24:22 +010079TEE_Result res = TEE_ERROR_GENERIC;
80size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +020081
82TEE_StartPropertyEnumerator(h, prop_set);
83
84while (true) {
Etienne Carriere102092e2019-03-28 15:24:22 +010085 char nbuf[256] = { };
86 char nbuf_small[256] = { };
87 char vbuf[256] = { };
88 char vbuf2[256] = { };
Jens Wiklanderc5231592015-11-11 09:27:27 +010089 uint32_t nblen = sizeof(nbuf);
Etienne Carriere102092e2019-03-28 15:24:22 +010090 uint32_t nblen_small = 0;
Jens Wiklanderc5231592015-11-11 09:27:27 +010091 uint32_t vblen = sizeof(vbuf);
92 uint32_t vblen2 = sizeof(vbuf2);
Pascal Brandc639ac82015-07-02 08:53:34 +020093
94 res = TEE_GetPropertyName(h, nbuf, &nblen);
95 if (res != TEE_SUCCESS) {
96 EMSG("TEE_GetPropertyName returned 0x%x\n",
97 (unsigned int)res);
98 return res;
99 }
Pascal Brand624b6a32016-02-16 12:51:34 +0100100 if (nblen != strlen(nbuf) + 1) {
Pascal Brand5b68cd62016-02-22 10:31:01 +0100101 EMSG("Name has wrong size: %u vs %zu", nblen, strlen(nbuf) + 1);
Pascal Brand624b6a32016-02-16 12:51:34 +0100102 return TEE_ERROR_GENERIC;
103 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200104
Pascal Brand624b6a32016-02-16 12:51:34 +0100105
106 /* Get the property name with a very small buffer */
107 nblen_small = 2;
108 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
109 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
110 nblen_small, nblen);
111 if (res != TEE_SUCCESS)
112 return res;
113
114 /* Get the property name with almost the correct buffer */
115 nblen_small = nblen - 1;
116 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
117 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
118 nblen_small, nblen);
119 if (res != TEE_SUCCESS)
120 return res;
121
122 /* Get the property name with the exact buffer length */
123 nblen_small = nblen;
124 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
125 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
126 nblen_small, nblen);
127 if (res != TEE_SUCCESS)
128 return res;
129
130 /* Get the property value */
Pascal Brandc639ac82015-07-02 08:53:34 +0200131 res = TEE_GetPropertyAsString(h, NULL, vbuf, &vblen);
Pascal Brand624b6a32016-02-16 12:51:34 +0100132 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
133 vblen, strlen(vbuf) + 1);
134 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200135 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100136
Pascal Brandc639ac82015-07-02 08:53:34 +0200137 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
Pascal Brand624b6a32016-02-16 12:51:34 +0100138 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
139 vblen2, strlen(vbuf2) + 1);
140 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200141 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100142
Jens Wiklander8324ff22018-11-21 14:16:04 +0100143 if (strcmp(vbuf, vbuf2) != 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200144 EMSG("String of \"%s\" differs\n", nbuf);
145 return TEE_ERROR_GENERIC;
146 }
147
Pascal Brand624b6a32016-02-16 12:51:34 +0100148 /* Get the property with a very small buffer */
149 vblen2 = 1;
150 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
151 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
152 vblen2, vblen);
153 if (res != TEE_SUCCESS)
154 return res;
155
156 /* Get the property with almost the correct buffer */
157 vblen2 = vblen - 1;
158 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
159 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
160 vblen2, vblen);
161 if (res != TEE_SUCCESS)
162 return res;
163
164 /* Get the property name with the exact buffer length */
165 vblen2 = vblen;
166 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
167 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS, vblen2, vblen);
168 if (res != TEE_SUCCESS)
169 return res;
170
171 /* check specific myprop.hello property, which is larger than 80 */
172 if (!strcmp("myprop.hello", nbuf) &&
173 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")) {
174 EMSG("TEE_GetPropertyAsString(\"%s\") is truncated - returned \"%s\"\n",
175 nbuf, vbuf);
176 return TEE_ERROR_GENERIC;
177 }
178
Pascal Brandc639ac82015-07-02 08:53:34 +0200179 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
180
181 for (n = 0; n < num_p_attrs; n++) {
Jens Wiklander8324ff22018-11-21 14:16:04 +0100182 if (strcmp(nbuf, p_attrs[n].str) != 0)
Pascal Brandc639ac82015-07-02 08:53:34 +0200183 continue;
184
185 if (p_attrs[n].retrieved) {
186 EMSG("Value \"%s\" already retrieved\n",
187 p_attrs[n].str);
188 return TEE_ERROR_GENERIC;
189 }
190 p_attrs[n].retrieved = true;
191
192 switch (p_attrs[n].type) {
193 case P_TYPE_BOOL:
194 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100195 bool v = false;
Pascal Brandc639ac82015-07-02 08:53:34 +0200196
197 res =
198 TEE_GetPropertyAsBool(h, NULL, &v);
199 if (res != TEE_SUCCESS) {
200 EMSG(
201 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
202 nbuf, (unsigned int)res);
203 return res;
204 }
205 }
206 break;
207
208 case P_TYPE_INT:
209 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100210 uint32_t v = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200211
212 res = TEE_GetPropertyAsU32(h, NULL, &v);
213 if (res != TEE_SUCCESS) {
214 EMSG(
215 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
216 nbuf, (unsigned int)res);
217 return res;
218 }
219 }
220 break;
221
222 case P_TYPE_UUID:
223 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100224 TEE_UUID v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200225
226 res =
227 TEE_GetPropertyAsUUID(h, NULL, &v);
228 if (res != TEE_SUCCESS) {
229 EMSG(
230 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
231 nbuf, (unsigned int)res);
232 return res;
233 }
234 }
235 break;
236
237 case P_TYPE_IDENTITY:
238 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100239 TEE_Identity v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200240
241 res =
242 TEE_GetPropertyAsIdentity(h, NULL,
243 &v);
244 if (res != TEE_SUCCESS) {
245 EMSG(
246 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
247 nbuf, (unsigned int)res);
248 return res;
249 }
250 }
251 break;
252
253 case P_TYPE_STRING:
254 /* Already read as string */
255 break;
256
257 case P_TYPE_BINARY_BLOCK:
258 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100259 char bbuf[80] = { };
Jens Wiklanderc5231592015-11-11 09:27:27 +0100260 uint32_t bblen = sizeof(bbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200261
262 res =
263 TEE_GetPropertyAsBinaryBlock(h,
264 NULL,
265 bbuf,
266 &bblen);
267 if (res != TEE_SUCCESS) {
268 EMSG(
269 "TEE_GetPropertyAsBinaryBlock(\"%s\") returned 0x%x\n",
270 nbuf, (unsigned int)res);
271 return res;
272 }
Jens Wiklander8324ff22018-11-21 14:16:04 +0100273 if (strcmp("myprop.binaryblock", nbuf) == 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200274 const char exp_bin_value[] =
275 "Hello world!";
276
Etienne Carriere102092e2019-03-28 15:24:22 +0100277 if (bblen != strlen(exp_bin_value) ||
278 TEE_MemCompare(exp_bin_value, bbuf,
279 bblen) != 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200280 EMSG(
281 "Binary buffer of \"%s\" differs from \"%s\"\n",
282 nbuf, exp_bin_value);
283 EMSG(
284 "Got \"%s\"\n",
285 bbuf);
286 return
287 TEE_ERROR_GENERIC;
288 }
289 }
290
291 }
292 break;
293
294 default:
295 EMSG("Unknown type (%d) for \"%s\"\n",
296 p_attrs[n].type, p_attrs[n].str);
297 return TEE_ERROR_GENERIC;
298 }
299 }
300
301 res = TEE_GetNextProperty(h);
302 if (res != TEE_SUCCESS) {
303 if (res == TEE_ERROR_ITEM_NOT_FOUND)
304 return TEE_SUCCESS;
305 return res;
306 }
307}
308}
309
310static TEE_Result test_malloc(void)
311{
312 void *p = TEE_Malloc(4, 0);
313
314 if (p == NULL) {
315 EMSG("TEE_Malloc failed\n");
316 return TEE_ERROR_OUT_OF_MEMORY;
317 }
318 TEE_Free(p);
319 TEE_Free(NULL);
320
321 return TEE_SUCCESS;
322}
323
324static TEE_Result test_properties(void)
325{
326 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriere102092e2019-03-28 15:24:22 +0100327 TEE_PropSetHandle h = TEE_HANDLE_NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200328 struct p_attr p_attrs[] = {
329 {"gpd.ta.appID", P_TYPE_UUID},
330 {"gpd.ta.singleInstance", P_TYPE_BOOL},
331 {"gpd.ta.multiSession", P_TYPE_BOOL},
332 {"gpd.ta.instanceKeepAlive", P_TYPE_BOOL},
333 {"gpd.ta.dataSize", P_TYPE_INT},
334 {"gpd.ta.stackSize", P_TYPE_INT},
335 {"gpd.ta.version", P_TYPE_STRING},
336 {"gpd.ta.description", P_TYPE_STRING},
337 {"gpd.client.identity", P_TYPE_IDENTITY},
338 {"gpd.tee.apiversion", P_TYPE_STRING},
339 {"gpd.tee.description", P_TYPE_STRING},
340 {"gpd.tee.deviceID", P_TYPE_UUID},
341 {"gpd.tee.systemTime.protectionLevel", P_TYPE_INT},
342 {"gpd.tee.TAPersistentTime.protectionLevel", P_TYPE_INT},
343 {"gpd.tee.arith.maxBigIntSize", P_TYPE_INT},
344 {"gpd.tee.cryptography.ecc", P_TYPE_BOOL},
345 {"gpd.tee.trustedStorage.antiRollback.protectionLevel", P_TYPE_INT},
346 {"gpd.tee.trustedos.implementation.version", P_TYPE_STRING},
347 {"gpd.tee.trustedos.implementation.binaryversion", P_TYPE_INT},
348 {"gpd.tee.trustedos.manufacturer", P_TYPE_STRING},
349 {"gpd.tee.firmware.implementation.version", P_TYPE_STRING},
350 {"gpd.tee.firmware.implementation.binaryversion", P_TYPE_INT},
351 {"gpd.tee.firmware.manufacturer", P_TYPE_STRING},
352 {"myprop.true", P_TYPE_BOOL},
353 {"myprop.42", P_TYPE_INT},
354 {"myprop.123", P_TYPE_UUID},
355 {"myprop.1234", P_TYPE_IDENTITY},
356 {"myprop.hello", P_TYPE_STRING},
357 {"myprop.binaryblock", P_TYPE_BINARY_BLOCK},
358 };
359 const size_t num_p_attrs = sizeof(p_attrs) / sizeof(p_attrs[0]);
Etienne Carriere102092e2019-03-28 15:24:22 +0100360 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200361
362 res = TEE_AllocatePropertyEnumerator(&h);
363 if (res != TEE_SUCCESS) {
364 EMSG("TEE_AllocatePropertyEnumerator: returned 0x%x\n",
365 (unsigned int)res);
366 return TEE_ERROR_GENERIC;
367 }
368
369 printf("Getting properties for current TA\n");
370 res = print_properties(h, TEE_PROPSET_CURRENT_TA, p_attrs, num_p_attrs);
371 if (res != TEE_SUCCESS)
372 goto cleanup_return;
373
374 printf("Getting properties for current client\n");
375 res = print_properties(h, TEE_PROPSET_CURRENT_CLIENT, p_attrs,
376 num_p_attrs);
377 if (res != TEE_SUCCESS)
378 goto cleanup_return;
379
380 printf("Getting properties for implementation\n");
381 res = print_properties(h, TEE_PROPSET_TEE_IMPLEMENTATION, p_attrs,
382 num_p_attrs);
383 if (res != TEE_SUCCESS)
384 goto cleanup_return;
385
386 for (n = 0; n < num_p_attrs; n++) {
387 if (!p_attrs[n].retrieved) {
388 EMSG("\"%s\" not retrieved\n", p_attrs[n].str);
389 res = TEE_ERROR_GENERIC;
390 goto cleanup_return;
391 }
392 }
393
394cleanup_return:
395 TEE_FreePropertyEnumerator(h);
396 return res;
397}
398
399static TEE_Result test_mem_access_right(uint32_t param_types,
400 TEE_Param params[4])
401{
402 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100403 TEE_Result res = TEE_ERROR_GENERIC;
404 uint32_t ret_orig = 0;
405 uint32_t l_pts = 0;
406 TEE_Param l_params[4] = { };
407 uint8_t buf[32] = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200408 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100409 TEE_UUID *uuid = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200410
411 if (param_types !=
412 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
413 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200414
415 /* test access rights on memref parameter */
416 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
417 TEE_MEMORY_ACCESS_ANY_OWNER,
418 params[0].memref.buffer,
419 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200420 if (res != TEE_SUCCESS)
421 return res;
Etienne Carriere281065d2016-10-28 15:41:33 +0200422
Pascal Brandc639ac82015-07-02 08:53:34 +0200423 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
424 params[0].memref.buffer,
425 params[0].memref.size);
426 if (res != TEE_ERROR_ACCESS_DENIED)
427 return TEE_ERROR_GENERIC;
428
Etienne Carriere281065d2016-10-28 15:41:33 +0200429 /* test access rights on private read-only and read-write memory */
430 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
431 (void *)&test_uuid, sizeof(test_uuid));
432 if (res != TEE_SUCCESS)
433 return res;
434
435 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_WRITE,
436 (void *)&test_uuid, sizeof(test_uuid));
437 if (res == TEE_SUCCESS)
438 return TEE_ERROR_GENERIC;
439
440 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
441 TEE_MEMORY_ACCESS_WRITE,
442 &ret_orig, sizeof(ret_orig));
443 if (res != TEE_SUCCESS)
444 return res;
445
446 uuid = TEE_Malloc(sizeof(*uuid), 0);
447 if (!uuid)
448 return TEE_ERROR_OUT_OF_MEMORY;
449
450 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
451 TEE_MEMORY_ACCESS_WRITE,
452 uuid, sizeof(*uuid));
453 TEE_Free(uuid);
454 if (res != TEE_SUCCESS)
455 return res;
456
457 /* test access rights on invalid memory (at least lower 256kB) */
458 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
459 NULL, 1);
460 if (res == TEE_SUCCESS)
461 return TEE_ERROR_GENERIC;
462
463 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
464 (void*)(256 * 1024), 1);
465 if (res == TEE_SUCCESS)
466 return TEE_ERROR_GENERIC;
467
Pascal Brandc639ac82015-07-02 08:53:34 +0200468 res = TEE_OpenTASession(&test_uuid, 0, 0, NULL, &sess, &ret_orig);
469 if (res != TEE_SUCCESS) {
470 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
471 goto cleanup_return;
472 }
473
Jerome Forissier04511d82018-01-30 14:33:49 +0100474 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
475 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200476 l_params[0].memref.buffer = buf;
477 l_params[0].memref.size = sizeof(buf);
Jerome Forissier04511d82018-01-30 14:33:49 +0100478 l_params[1].memref.buffer = NULL;
479 l_params[1].memref.size = 0;
Etienne Carriere281065d2016-10-28 15:41:33 +0200480 res = TEE_InvokeTACommand(sess, 0, TA_OS_TEST_CMD_PARAMS_ACCESS,
Pascal Brandc639ac82015-07-02 08:53:34 +0200481 l_pts, l_params, &ret_orig);
482 if (res != TEE_SUCCESS) {
483 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
484 goto cleanup_return;
485 }
486
487cleanup_return:
488 TEE_CloseTASession(sess);
489 return res;
490}
491
492static TEE_Result test_time(void)
493{
Etienne Carriere102092e2019-03-28 15:24:22 +0100494 TEE_Result res = TEE_ERROR_GENERIC;
495 TEE_Time t = { };
496 TEE_Time sys_t = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200497 static const TEE_Time null_time = { 0, 0 };
498 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
499
500 TEE_GetSystemTime(&sys_t);
501 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
502 (unsigned int)sys_t.millis);
503
504 TEE_GetREETime(&t);
505 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
506 (unsigned int)t.millis);
507
508 res = TEE_GetTAPersistentTime(&t);
509 switch (res) {
510 case TEE_SUCCESS:
511 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
512 (unsigned int)t.millis);
513 break;
514 case TEE_ERROR_OVERFLOW:
515 EMSG("Stored TA time overflowed %u.%03u\n",
516 (unsigned int)t.seconds, (unsigned int)t.millis);
517 break;
518 case TEE_ERROR_TIME_NOT_SET:
519 EMSG("TA time not stored\n");
520 break;
521 case TEE_ERROR_TIME_NEEDS_RESET:
522 EMSG("TA time needs reset\n");
523 break;
524 default:
525 return res;
526 }
527
528 res = TEE_SetTAPersistentTime(&null_time);
529 if (res != TEE_SUCCESS) {
530 EMSG("TEE_SetTAPersistentTime: failed\n");
531 return res;
532 }
533
534 res = TEE_GetTAPersistentTime(&t);
535 if (res != TEE_SUCCESS) {
536 EMSG("TEE_GetTAPersistentTime null: failed\n");
537 return res;
538 }
539 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
540 (unsigned int)t.millis);
541 /*
542 * The time between TEE_SetTAPersistentTime() and
543 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
544 * it's not even a millisecond.
545 */
546 if (t.seconds > 1 || t.millis >= 1000) {
547 EMSG("Unexpected stored TA time %u.%03u\n",
548 (unsigned int)t.seconds, (unsigned int)t.millis);
549 return TEE_ERROR_BAD_STATE;
550 }
551
552 res = TEE_SetTAPersistentTime(&wrap_time);
553 if (res != TEE_SUCCESS) {
554 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
555 return res;
556 }
557
558 res = TEE_Wait(1000);
559 if (res != TEE_SUCCESS)
560 EMSG("TEE_Wait wrap: failed\n");
561
562 res = TEE_GetTAPersistentTime(&t);
563 if (res != TEE_ERROR_OVERFLOW) {
564 EMSG("TEE_GetTAPersistentTime: failed\n");
565 return TEE_ERROR_BAD_STATE;
566 }
567 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
568 (unsigned int)t.millis);
569
570 if (t.seconds > sys_t.seconds) {
571 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
572 (unsigned int)t.seconds, (unsigned int)t.millis,
573 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
574 return TEE_ERROR_BAD_STATE;
575 }
576
577 return TEE_SUCCESS;
578}
579
Jens Wiklander246184a2015-12-11 08:28:59 +0100580#ifdef CFG_TA_FLOAT_SUPPORT
581static bool my_dcmpeq(double v1, double v2, double prec)
582{
583 return v1 > (v2 - prec) && v1 < (v2 + prec);
584}
585
586static bool my_fcmpeq(float v1, float v2, float prec)
587{
588 return v1 > (v2 - prec) && v1 < (v2 + prec);
589}
590
591
592static TEE_Result test_float(void)
593{
594#define VAL1 2.6
595#define VAL1_INT 2
596#define VAL2 5.3
597#define DPREC 0.000000000000001
598#define FPREC 0.000001
599#define EXPECT(expr) do { \
600 if (!(expr)) { \
601 EMSG("Expression %s failed", #expr); \
602 return TEE_ERROR_GENERIC; \
603 } \
604 } while (0)
605
606 IMSG("Testing floating point operations");
607
608 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
609 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
610 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
611 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
612 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
613
614 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
615 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
616 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
617 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
618 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
619
620 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
621 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
622 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
623 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
624 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
625
626 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
627 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
628 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
629 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
630 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
631
632 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
633 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
634 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
635 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
636
637 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
638 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
639 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
640 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
641
642 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
643 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
644
645 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
646 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
647 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
648 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
649
650 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
651 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
652 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
653 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
654 return TEE_SUCCESS;
655}
656#else /*CFG_TA_FLOAT_SUPPORT*/
657static TEE_Result test_float(void)
658{
659 IMSG("Floating point disabled");
660 return TEE_SUCCESS;
661}
662#endif /*CFG_TA_FLOAT_SUPPORT*/
663
Jens Wiklander9f682c62016-03-27 20:23:06 +0200664static __noinline void call_longjmp(jmp_buf env)
665{
666 DMSG("Calling longjmp");
667 longjmp(env, 1);
668 EMSG("error: longjmp returned to calling function");
669}
670
671static TEE_Result test_setjmp(void)
672{
Etienne Carriere102092e2019-03-28 15:24:22 +0100673 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200674
675 if (setjmp(env)) {
676 IMSG("Returned via longjmp");
677 return TEE_SUCCESS;
678 } else {
679 call_longjmp(env);
680 return TEE_ERROR_GENERIC;
681 }
682}
683
Pascal Brandc639ac82015-07-02 08:53:34 +0200684TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
685{
686 TEE_Result res = TEE_ERROR_GENERIC;
687
688 printf("ta_entry_basic: enter\n");
689
690 res = test_malloc();
691 if (res != TEE_SUCCESS)
692 return res;
693
694 res = test_properties();
695 if (res != TEE_SUCCESS)
696 return res;
697
698 res = test_mem_access_right(param_types, params);
699 if (res != TEE_SUCCESS)
700 return res;
701
702 res = test_time();
703 if (res != TEE_SUCCESS)
704 return res;
705
Jens Wiklander246184a2015-12-11 08:28:59 +0100706 res = test_float();
707 if (res != TEE_SUCCESS)
708 return res;
709
Jens Wiklander9f682c62016-03-27 20:23:06 +0200710 res = test_setjmp();
711 if (res != TEE_SUCCESS)
712 return res;
713
Pascal Brandc639ac82015-07-02 08:53:34 +0200714 return TEE_SUCCESS;
715}
716
717TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
718{
719 volatile bool mytrue = true;
720 (void)param_types;
721 (void)params;
722
723 printf("ta_entry_panic: enter\n");
724 /*
725 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
726 * the __noreturn attribute.
727 */
728 if (mytrue)
729 TEE_Panic(0xbeef);
730
731 /*
732 * Should not be reached, but if it is the testsuite can detect that
733 * TEE_Panic() returned instead of panicking the TA.
734 */
735 return TEE_SUCCESS;
736}
737
738TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
739 TEE_Param params[4])
740{
741 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100742 TEE_Result res = TEE_ERROR_GENERIC;
743 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
744 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200745
746 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
747 TEE_PARAM_TYPE_NONE,
748 TEE_PARAM_TYPE_NONE,
749 TEE_PARAM_TYPE_NONE)) {
750 EMSG("ta_entry_client_with_timeout: bad parameters\n");
751 return TEE_ERROR_BAD_PARAMETERS;
752 }
753
754 res = TEE_OpenTASession(&os_test_uuid, 0, 0, NULL, &sess, &ret_orig);
755 if (res != TEE_SUCCESS) {
756 EMSG(
757 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
758 return res;
759 }
760
761 res =
762 TEE_InvokeTACommand(sess, params[0].value.a / 2,
763 TA_OS_TEST_CMD_WAIT, param_types, params,
764 &ret_orig);
765
766 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
767 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
768 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
769 (unsigned int)ret_orig);
770 res = TEE_ERROR_GENERIC;
771 } else
772 res = TEE_SUCCESS;
773
774 TEE_CloseTASession(sess);
775 return res;
776
777}
778
779TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
780{
781 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100782 TEE_Result res = TEE_ERROR_GENERIC;
783 uint32_t l_pts = 0;
784 TEE_Param l_params[4] = { };
785 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
786 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200787 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
788 static const uint8_t sha256_out[] = {
789 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
790 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
791 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
792 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
793 };
794 uint8_t out[32] = { 0 };
795 void *in = NULL;
796
797 (void)param_types;
798 (void)params;
799
800 printf("ta_entry_client: enter\n");
801
802 in = TEE_Malloc(sizeof(sha256_in), 0);
803 if (in == NULL)
804 return TEE_ERROR_OUT_OF_MEMORY;
805 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
806
807 res = TEE_OpenTASession(&crypt_uuid, 0, 0, NULL, &sess, &ret_orig);
808 if (res != TEE_SUCCESS) {
809 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
810 goto cleanup_return;
811 }
812
813 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
814 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
815 l_params[0].memref.buffer = in;
816 l_params[0].memref.size = sizeof(sha256_in);
817 l_params[1].memref.buffer = out;
818 l_params[1].memref.size = sizeof(out);
819
820 res = TEE_InvokeTACommand(sess, 0, TA_CRYPT_CMD_SHA256, l_pts, l_params,
821 &ret_orig);
822 if (res != TEE_SUCCESS) {
823 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
824 goto cleanup_return;
825 }
826
827 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
828 EMSG("ta_entry_client: out parameter failed\n");
829 res = TEE_ERROR_GENERIC;
830 goto cleanup_return;
831 }
832
833cleanup_return:
834 TEE_Free(in);
835 TEE_CloseTASession(sess);
836 return res;
837}
838
Etienne Carriere281065d2016-10-28 15:41:33 +0200839TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200840{
Etienne Carriere102092e2019-03-28 15:24:22 +0100841 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200842
843 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100844 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
845 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200846 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200847
848 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
849 TEE_MEMORY_ACCESS_ANY_OWNER,
850 params[0].memref.buffer,
851 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200852 if (res != TEE_SUCCESS)
853 return res;
854
855 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
856 params[0].memref.buffer,
857 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200858 if (res != TEE_ERROR_ACCESS_DENIED)
859 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +0100860 if (params[1].memref.buffer || params[1].memref.size)
861 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200862
Etienne Carriere281065d2016-10-28 15:41:33 +0200863 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200864}
865
866TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
867{
868 TEE_Result res = TEE_SUCCESS;
869 (void)param_types;
870
871 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
872 /* Wait */
873 res = TEE_Wait(params[0].value.a);
874
875 return res;
876}
877
Jens Wiklander1425f952016-07-21 09:02:30 +0200878static void undef_instr(void)
879{
880#if defined(ARM64)
881 __asm__(".word 0x0");
882#elif defined(ARM32)
883 __asm__(".word 0xe7ffffff");
884#else
885#error "Unsupported architecture"
886#endif
887}
888
Pascal Brandc639ac82015-07-02 08:53:34 +0200889TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
890{
Etienne Carriere102092e2019-03-28 15:24:22 +0100891 long int stack = 0;
892 long int stack_addr = (long int)&stack;
Pascal Brandc639ac82015-07-02 08:53:34 +0200893
Etienne Carriere92c34422018-02-09 13:11:40 +0100894 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
895 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
896 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200897 return TEE_ERROR_GENERIC;
898
899 switch (params[0].value.a) {
900 case 1:
901 *((uint32_t *) 0) = 0;
902 break;
903 case 2:
904 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
905 break;
906 case 3:
907 ((void (*)(void))0) ();
908 break;
909 case 4:
910 ((void (*)(void))(stack_addr + 0x40000000)) ();
911 break;
912 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +0200913 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200914 break;
915 default:
916 break;
917 }
918
919 return TEE_SUCCESS;
920}
Jerome Forissiere916b102017-06-07 17:55:52 +0200921
922static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
923{
Etienne Carriere102092e2019-03-28 15:24:22 +0100924 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +0200925
926 for (i = 0; i < bufsize; i++) {
927 a[i]++; b[i]++; c[i]++;
928 }
929}
930
Etienne Carriere102092e2019-03-28 15:24:22 +0100931#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +0200932TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
933{
934 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
935 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100936 TEE_Param l_params[4] = { };
937 uint8_t in[TA2TA_BUF_SIZE] = { };
938 uint8_t inout[TA2TA_BUF_SIZE] = { };
939 uint8_t out[TA2TA_BUF_SIZE] = { };
940 TEE_Result res = TEE_ERROR_GENERIC;
941 uint32_t ret_orig = 0;
942 uint32_t l_pts = 0;
943 size_t i = 0;
944
Jerome Forissiere916b102017-06-07 17:55:52 +0200945 (void)params;
946
947 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
948 return TEE_ERROR_GENERIC;
949
950 res = TEE_OpenTASession(&test_uuid, 0, 0, NULL, &sess, &ret_orig);
951 if (res != TEE_SUCCESS) {
952 EMSG("TEE_OpenTASession failed");
953 goto cleanup_return;
954 }
955
956 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
957 TEE_PARAM_TYPE_MEMREF_INOUT,
958 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
959 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +0100960 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200961 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +0100962 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200963 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +0100964 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200965
966 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +0100967 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +0200968 in[i] = 5;
969 inout[i] = 10;
970 out[i] = 0;
971 }
972
973 /*
974 * TA will compute: out = ++inout + in
975 * Expected values after this step: in: 5, inout: 11, out: 16
976 */
977 res = TEE_InvokeTACommand(sess, 0, TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
978 l_pts, l_params, &ret_orig);
979 if (res != TEE_SUCCESS) {
980 EMSG("TEE_InvokeTACommand failed");
981 goto cleanup_return;
982 }
Etienne Carriere102092e2019-03-28 15:24:22 +0100983
Jerome Forissiere916b102017-06-07 17:55:52 +0200984 /*
985 * Increment all values by one.
986 * Expected values after this step: in: 6, inout: 12, out: 17
987 */
Etienne Carriere102092e2019-03-28 15:24:22 +0100988 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +0200989
990 /*
991 * TA will compute: out = ++inout + in
992 * Expected values after this step: in: 6, inout: 13, out: 19
993 */
994 res = TEE_InvokeTACommand(sess, 0, TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
995 l_pts, l_params, &ret_orig);
996 if (res != TEE_SUCCESS) {
997 EMSG("TEE_InvokeTACommand failed");
998 goto cleanup_return;
999 }
1000
1001 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001002 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001003 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1004 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001005 DHEXDUMP(in, TA2TA_BUF_SIZE);
1006 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1007 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001008 return TEE_ERROR_GENERIC;
1009 }
1010 }
1011
1012cleanup_return:
1013 TEE_CloseTASession(sess);
1014 return res;
1015}
1016
1017TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1018{
Etienne Carriere102092e2019-03-28 15:24:22 +01001019 uint8_t *in = NULL;
1020 uint8_t *inout = NULL;
1021 uint8_t *out = NULL;
1022 size_t bufsize = 0;
1023 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001024
1025 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1026 TEE_PARAM_TYPE_MEMREF_INOUT,
1027 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1028 return TEE_ERROR_GENERIC;
1029
1030 bufsize = params[0].memref.size;
1031 if (params[1].memref.size != bufsize ||
1032 params[2].memref.size != bufsize)
1033 return TEE_ERROR_GENERIC;
1034
1035 in = params[0].memref.buffer;
1036 inout = params[1].memref.buffer;
1037 out = params[2].memref.buffer;
1038
1039 for (i = 0; i < bufsize; i++)
1040 out[i] = ++inout[i] + in[i];
1041
1042 return TEE_SUCCESS;
1043}
Jens Wiklander87e81702018-03-20 12:00:00 +08001044
1045TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1046{
Etienne Carriere102092e2019-03-28 15:24:22 +01001047 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001048
1049 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1050 TEE_PARAM_TYPE_MEMREF_INPUT,
1051 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1052 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1053 return TEE_ERROR_BAD_PARAMETERS;
1054
1055 for (n = 0; n < TEE_NUM_PARAMS; n++)
1056 if (!params[n].memref.buffer || !params[n].memref.size)
1057 return TEE_ERROR_BAD_PARAMETERS;
1058
1059 return TEE_SUCCESS;
1060}
Jerome Forissier53bde722018-05-31 09:14:54 +02001061
1062TEE_Result ta_entry_call_lib(uint32_t param_types,
1063 TEE_Param params[4] __unused)
1064{
1065 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1066 TEE_PARAM_TYPE_NONE,
1067 TEE_PARAM_TYPE_NONE,
1068 TEE_PARAM_TYPE_NONE))
1069 return TEE_ERROR_BAD_PARAMETERS;
1070
1071 if (os_test_shlib_add(1, 2) != 3)
1072 return TEE_ERROR_GENERIC;
1073
1074 return TEE_SUCCESS;
1075}
1076
1077TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1078 TEE_Param params[4] __unused)
1079{
1080 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1081 TEE_PARAM_TYPE_NONE,
1082 TEE_PARAM_TYPE_NONE,
1083 TEE_PARAM_TYPE_NONE))
1084 return TEE_ERROR_BAD_PARAMETERS;
1085
1086 os_test_shlib_panic();
1087
1088 return TEE_ERROR_GENERIC;
1089}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001090
1091TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1092 TEE_Param params[4] __unused)
1093{
1094 int (*add_func)(int a, int b) = NULL;
1095 TEE_Result res = TEE_ERROR_GENERIC;
1096 void *handle = NULL;
1097 void *hnull = NULL;
1098
1099 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1100 TEE_PARAM_TYPE_NONE,
1101 TEE_PARAM_TYPE_NONE,
1102 TEE_PARAM_TYPE_NONE))
1103 return TEE_ERROR_BAD_PARAMETERS;
1104
1105 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1106 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1107 if (!handle)
1108 return TEE_ERROR_OUT_OF_MEMORY;
1109
1110 add_func = dlsym(handle, "os_test_shlib_dl_add");
1111 if (!add_func)
1112 goto err;
1113 if (add_func(3, 4) != 7)
1114 goto err;
1115
1116 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1117 if (!hnull) {
1118 res = TEE_ERROR_OUT_OF_MEMORY;
1119 goto err;
1120 }
1121
1122 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1123 if (!add_func)
1124 goto err;
1125 if (add_func(5, 6) != 11)
1126 goto err;
1127
1128 res = TEE_SUCCESS;
1129 dlclose(hnull);
1130err:
1131 dlclose(handle);
1132 return res;
1133}
1134
1135TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1136 TEE_Param params[4] __unused)
1137{
1138 int (*panic_func)(void) = NULL;
1139 void *handle = NULL;
1140 TEE_Result res = TEE_ERROR_GENERIC;
1141
1142 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1143 TEE_PARAM_TYPE_NONE,
1144 TEE_PARAM_TYPE_NONE,
1145 TEE_PARAM_TYPE_NONE))
1146 return TEE_ERROR_BAD_PARAMETERS;
1147
1148 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1149 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1150 if (!handle)
1151 return res;
1152
1153 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1154 if (!panic_func)
1155 goto err;
1156 panic_func();
1157 return TEE_ERROR_GENERIC;
1158err:
1159 dlclose(handle);
1160 return res;
1161}