blob: 14094701e583cca34be3089f2aaec0b235bf95e8 [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
Cedric Augere668b3f2019-09-11 13:41:21 +0200468 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
469 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200470 if (res != TEE_SUCCESS) {
471 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
472 goto cleanup_return;
473 }
474
Jerome Forissier04511d82018-01-30 14:33:49 +0100475 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
476 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200477 l_params[0].memref.buffer = buf;
478 l_params[0].memref.size = sizeof(buf);
Jerome Forissier04511d82018-01-30 14:33:49 +0100479 l_params[1].memref.buffer = NULL;
480 l_params[1].memref.size = 0;
Cedric Augere668b3f2019-09-11 13:41:21 +0200481 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
482 TA_OS_TEST_CMD_PARAMS_ACCESS,
Pascal Brandc639ac82015-07-02 08:53:34 +0200483 l_pts, l_params, &ret_orig);
484 if (res != TEE_SUCCESS) {
485 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
486 goto cleanup_return;
487 }
488
489cleanup_return:
490 TEE_CloseTASession(sess);
491 return res;
492}
493
494static TEE_Result test_time(void)
495{
Etienne Carriere102092e2019-03-28 15:24:22 +0100496 TEE_Result res = TEE_ERROR_GENERIC;
497 TEE_Time t = { };
498 TEE_Time sys_t = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200499 static const TEE_Time null_time = { 0, 0 };
500 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
501
502 TEE_GetSystemTime(&sys_t);
503 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
504 (unsigned int)sys_t.millis);
505
506 TEE_GetREETime(&t);
507 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
508 (unsigned int)t.millis);
509
510 res = TEE_GetTAPersistentTime(&t);
511 switch (res) {
512 case TEE_SUCCESS:
513 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
514 (unsigned int)t.millis);
515 break;
516 case TEE_ERROR_OVERFLOW:
517 EMSG("Stored TA time overflowed %u.%03u\n",
518 (unsigned int)t.seconds, (unsigned int)t.millis);
519 break;
520 case TEE_ERROR_TIME_NOT_SET:
521 EMSG("TA time not stored\n");
522 break;
523 case TEE_ERROR_TIME_NEEDS_RESET:
524 EMSG("TA time needs reset\n");
525 break;
526 default:
527 return res;
528 }
529
530 res = TEE_SetTAPersistentTime(&null_time);
531 if (res != TEE_SUCCESS) {
532 EMSG("TEE_SetTAPersistentTime: failed\n");
533 return res;
534 }
535
536 res = TEE_GetTAPersistentTime(&t);
537 if (res != TEE_SUCCESS) {
538 EMSG("TEE_GetTAPersistentTime null: failed\n");
539 return res;
540 }
541 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
542 (unsigned int)t.millis);
543 /*
544 * The time between TEE_SetTAPersistentTime() and
545 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
546 * it's not even a millisecond.
547 */
548 if (t.seconds > 1 || t.millis >= 1000) {
549 EMSG("Unexpected stored TA time %u.%03u\n",
550 (unsigned int)t.seconds, (unsigned int)t.millis);
551 return TEE_ERROR_BAD_STATE;
552 }
553
554 res = TEE_SetTAPersistentTime(&wrap_time);
555 if (res != TEE_SUCCESS) {
556 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
557 return res;
558 }
559
560 res = TEE_Wait(1000);
561 if (res != TEE_SUCCESS)
562 EMSG("TEE_Wait wrap: failed\n");
563
564 res = TEE_GetTAPersistentTime(&t);
565 if (res != TEE_ERROR_OVERFLOW) {
566 EMSG("TEE_GetTAPersistentTime: failed\n");
567 return TEE_ERROR_BAD_STATE;
568 }
569 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
570 (unsigned int)t.millis);
571
572 if (t.seconds > sys_t.seconds) {
573 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
574 (unsigned int)t.seconds, (unsigned int)t.millis,
575 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
576 return TEE_ERROR_BAD_STATE;
577 }
578
579 return TEE_SUCCESS;
580}
581
Jens Wiklander246184a2015-12-11 08:28:59 +0100582#ifdef CFG_TA_FLOAT_SUPPORT
583static bool my_dcmpeq(double v1, double v2, double prec)
584{
585 return v1 > (v2 - prec) && v1 < (v2 + prec);
586}
587
588static bool my_fcmpeq(float v1, float v2, float prec)
589{
590 return v1 > (v2 - prec) && v1 < (v2 + prec);
591}
592
593
594static TEE_Result test_float(void)
595{
596#define VAL1 2.6
597#define VAL1_INT 2
598#define VAL2 5.3
599#define DPREC 0.000000000000001
600#define FPREC 0.000001
601#define EXPECT(expr) do { \
602 if (!(expr)) { \
603 EMSG("Expression %s failed", #expr); \
604 return TEE_ERROR_GENERIC; \
605 } \
606 } while (0)
607
608 IMSG("Testing floating point operations");
609
610 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
611 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
612 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
613 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
614 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
615
616 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
617 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
618 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
619 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
620 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
621
622 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
623 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
624 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
625 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
626 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
627
628 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
629 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
630 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
631 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
632 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
633
634 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
635 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
636 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
637 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
638
639 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
640 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
641 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
642 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
643
644 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
645 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
646
647 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
648 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
649 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
650 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
651
652 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
653 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
654 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
655 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
656 return TEE_SUCCESS;
657}
658#else /*CFG_TA_FLOAT_SUPPORT*/
659static TEE_Result test_float(void)
660{
661 IMSG("Floating point disabled");
662 return TEE_SUCCESS;
663}
664#endif /*CFG_TA_FLOAT_SUPPORT*/
665
Jens Wiklander9f682c62016-03-27 20:23:06 +0200666static __noinline void call_longjmp(jmp_buf env)
667{
668 DMSG("Calling longjmp");
669 longjmp(env, 1);
670 EMSG("error: longjmp returned to calling function");
671}
672
673static TEE_Result test_setjmp(void)
674{
Etienne Carriere102092e2019-03-28 15:24:22 +0100675 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200676
677 if (setjmp(env)) {
678 IMSG("Returned via longjmp");
679 return TEE_SUCCESS;
680 } else {
681 call_longjmp(env);
682 return TEE_ERROR_GENERIC;
683 }
684}
685
Pascal Brandc639ac82015-07-02 08:53:34 +0200686TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
687{
688 TEE_Result res = TEE_ERROR_GENERIC;
689
690 printf("ta_entry_basic: enter\n");
691
692 res = test_malloc();
693 if (res != TEE_SUCCESS)
694 return res;
695
696 res = test_properties();
697 if (res != TEE_SUCCESS)
698 return res;
699
700 res = test_mem_access_right(param_types, params);
701 if (res != TEE_SUCCESS)
702 return res;
703
704 res = test_time();
705 if (res != TEE_SUCCESS)
706 return res;
707
Jens Wiklander246184a2015-12-11 08:28:59 +0100708 res = test_float();
709 if (res != TEE_SUCCESS)
710 return res;
711
Jens Wiklander9f682c62016-03-27 20:23:06 +0200712 res = test_setjmp();
713 if (res != TEE_SUCCESS)
714 return res;
715
Pascal Brandc639ac82015-07-02 08:53:34 +0200716 return TEE_SUCCESS;
717}
718
719TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
720{
721 volatile bool mytrue = true;
722 (void)param_types;
723 (void)params;
724
725 printf("ta_entry_panic: enter\n");
726 /*
727 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
728 * the __noreturn attribute.
729 */
730 if (mytrue)
731 TEE_Panic(0xbeef);
732
733 /*
734 * Should not be reached, but if it is the testsuite can detect that
735 * TEE_Panic() returned instead of panicking the TA.
736 */
737 return TEE_SUCCESS;
738}
739
740TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
741 TEE_Param params[4])
742{
743 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100744 TEE_Result res = TEE_ERROR_GENERIC;
745 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
746 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200747
748 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
749 TEE_PARAM_TYPE_NONE,
750 TEE_PARAM_TYPE_NONE,
751 TEE_PARAM_TYPE_NONE)) {
752 EMSG("ta_entry_client_with_timeout: bad parameters\n");
753 return TEE_ERROR_BAD_PARAMETERS;
754 }
755
Cedric Augere668b3f2019-09-11 13:41:21 +0200756 res = TEE_OpenTASession(&os_test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
757 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200758 if (res != TEE_SUCCESS) {
759 EMSG(
760 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
761 return res;
762 }
763
764 res =
765 TEE_InvokeTACommand(sess, params[0].value.a / 2,
766 TA_OS_TEST_CMD_WAIT, param_types, params,
767 &ret_orig);
768
769 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
770 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
771 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
772 (unsigned int)ret_orig);
773 res = TEE_ERROR_GENERIC;
774 } else
775 res = TEE_SUCCESS;
776
777 TEE_CloseTASession(sess);
778 return res;
779
780}
781
782TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
783{
784 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100785 TEE_Result res = TEE_ERROR_GENERIC;
786 uint32_t l_pts = 0;
787 TEE_Param l_params[4] = { };
788 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
789 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200790 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
791 static const uint8_t sha256_out[] = {
792 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
793 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
794 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
795 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
796 };
797 uint8_t out[32] = { 0 };
798 void *in = NULL;
799
800 (void)param_types;
801 (void)params;
802
803 printf("ta_entry_client: enter\n");
804
805 in = TEE_Malloc(sizeof(sha256_in), 0);
806 if (in == NULL)
807 return TEE_ERROR_OUT_OF_MEMORY;
808 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
809
Cedric Augere668b3f2019-09-11 13:41:21 +0200810 res = TEE_OpenTASession(&crypt_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
811 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200812 if (res != TEE_SUCCESS) {
813 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
814 goto cleanup_return;
815 }
816
817 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
818 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
819 l_params[0].memref.buffer = in;
820 l_params[0].memref.size = sizeof(sha256_in);
821 l_params[1].memref.buffer = out;
822 l_params[1].memref.size = sizeof(out);
823
Cedric Augere668b3f2019-09-11 13:41:21 +0200824 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
825 TA_CRYPT_CMD_SHA256, l_pts, l_params,
Pascal Brandc639ac82015-07-02 08:53:34 +0200826 &ret_orig);
827 if (res != TEE_SUCCESS) {
828 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
829 goto cleanup_return;
830 }
831
832 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
833 EMSG("ta_entry_client: out parameter failed\n");
834 res = TEE_ERROR_GENERIC;
835 goto cleanup_return;
836 }
837
838cleanup_return:
839 TEE_Free(in);
840 TEE_CloseTASession(sess);
841 return res;
842}
843
Etienne Carriere281065d2016-10-28 15:41:33 +0200844TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200845{
Etienne Carriere102092e2019-03-28 15:24:22 +0100846 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200847
848 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100849 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
850 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200851 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200852
853 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
854 TEE_MEMORY_ACCESS_ANY_OWNER,
855 params[0].memref.buffer,
856 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200857 if (res != TEE_SUCCESS)
858 return res;
859
860 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
861 params[0].memref.buffer,
862 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200863 if (res != TEE_ERROR_ACCESS_DENIED)
864 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +0100865 if (params[1].memref.buffer || params[1].memref.size)
866 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200867
Etienne Carriere281065d2016-10-28 15:41:33 +0200868 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200869}
870
871TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
872{
873 TEE_Result res = TEE_SUCCESS;
874 (void)param_types;
875
876 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
877 /* Wait */
878 res = TEE_Wait(params[0].value.a);
879
880 return res;
881}
882
Jens Wiklander1425f952016-07-21 09:02:30 +0200883static void undef_instr(void)
884{
885#if defined(ARM64)
886 __asm__(".word 0x0");
887#elif defined(ARM32)
888 __asm__(".word 0xe7ffffff");
889#else
890#error "Unsupported architecture"
891#endif
892}
893
Pascal Brandc639ac82015-07-02 08:53:34 +0200894TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
895{
Etienne Carriere102092e2019-03-28 15:24:22 +0100896 long int stack = 0;
897 long int stack_addr = (long int)&stack;
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200898 void (*volatile null_fn_ptr)(void) = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200899
Etienne Carriere92c34422018-02-09 13:11:40 +0100900 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
901 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
902 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200903 return TEE_ERROR_GENERIC;
904
905 switch (params[0].value.a) {
906 case 1:
Jerome Forissier71da60f2019-09-19 15:59:56 +0200907 *((volatile uint32_t *)0) = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200908 break;
909 case 2:
910 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
911 break;
912 case 3:
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200913 null_fn_ptr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200914 break;
915 case 4:
916 ((void (*)(void))(stack_addr + 0x40000000)) ();
917 break;
918 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +0200919 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200920 break;
921 default:
922 break;
923 }
924
925 return TEE_SUCCESS;
926}
Jerome Forissiere916b102017-06-07 17:55:52 +0200927
928static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
929{
Etienne Carriere102092e2019-03-28 15:24:22 +0100930 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +0200931
932 for (i = 0; i < bufsize; i++) {
933 a[i]++; b[i]++; c[i]++;
934 }
935}
936
Etienne Carriere102092e2019-03-28 15:24:22 +0100937#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +0200938TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
939{
940 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
941 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100942 TEE_Param l_params[4] = { };
943 uint8_t in[TA2TA_BUF_SIZE] = { };
944 uint8_t inout[TA2TA_BUF_SIZE] = { };
945 uint8_t out[TA2TA_BUF_SIZE] = { };
946 TEE_Result res = TEE_ERROR_GENERIC;
947 uint32_t ret_orig = 0;
948 uint32_t l_pts = 0;
949 size_t i = 0;
950
Jerome Forissiere916b102017-06-07 17:55:52 +0200951 (void)params;
952
953 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
954 return TEE_ERROR_GENERIC;
955
Cedric Augere668b3f2019-09-11 13:41:21 +0200956 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
957 &sess, &ret_orig);
Jerome Forissiere916b102017-06-07 17:55:52 +0200958 if (res != TEE_SUCCESS) {
959 EMSG("TEE_OpenTASession failed");
960 goto cleanup_return;
961 }
962
963 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
964 TEE_PARAM_TYPE_MEMREF_INOUT,
965 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
966 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +0100967 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200968 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +0100969 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200970 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +0100971 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200972
973 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +0100974 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +0200975 in[i] = 5;
976 inout[i] = 10;
977 out[i] = 0;
978 }
979
980 /*
981 * TA will compute: out = ++inout + in
982 * Expected values after this step: in: 5, inout: 11, out: 16
983 */
Cedric Augere668b3f2019-09-11 13:41:21 +0200984 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
985 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +0200986 l_pts, l_params, &ret_orig);
987 if (res != TEE_SUCCESS) {
988 EMSG("TEE_InvokeTACommand failed");
989 goto cleanup_return;
990 }
Etienne Carriere102092e2019-03-28 15:24:22 +0100991
Jerome Forissiere916b102017-06-07 17:55:52 +0200992 /*
993 * Increment all values by one.
994 * Expected values after this step: in: 6, inout: 12, out: 17
995 */
Etienne Carriere102092e2019-03-28 15:24:22 +0100996 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +0200997
998 /*
999 * TA will compute: out = ++inout + in
1000 * Expected values after this step: in: 6, inout: 13, out: 19
1001 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001002 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1003 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001004 l_pts, l_params, &ret_orig);
1005 if (res != TEE_SUCCESS) {
1006 EMSG("TEE_InvokeTACommand failed");
1007 goto cleanup_return;
1008 }
1009
1010 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001011 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001012 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1013 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001014 DHEXDUMP(in, TA2TA_BUF_SIZE);
1015 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1016 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001017 return TEE_ERROR_GENERIC;
1018 }
1019 }
1020
1021cleanup_return:
1022 TEE_CloseTASession(sess);
1023 return res;
1024}
1025
1026TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1027{
Etienne Carriere102092e2019-03-28 15:24:22 +01001028 uint8_t *in = NULL;
1029 uint8_t *inout = NULL;
1030 uint8_t *out = NULL;
1031 size_t bufsize = 0;
1032 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001033
1034 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1035 TEE_PARAM_TYPE_MEMREF_INOUT,
1036 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1037 return TEE_ERROR_GENERIC;
1038
1039 bufsize = params[0].memref.size;
1040 if (params[1].memref.size != bufsize ||
1041 params[2].memref.size != bufsize)
1042 return TEE_ERROR_GENERIC;
1043
1044 in = params[0].memref.buffer;
1045 inout = params[1].memref.buffer;
1046 out = params[2].memref.buffer;
1047
1048 for (i = 0; i < bufsize; i++)
1049 out[i] = ++inout[i] + in[i];
1050
1051 return TEE_SUCCESS;
1052}
Jens Wiklander87e81702018-03-20 12:00:00 +08001053
1054TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1055{
Etienne Carriere102092e2019-03-28 15:24:22 +01001056 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001057
1058 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1059 TEE_PARAM_TYPE_MEMREF_INPUT,
1060 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1061 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1062 return TEE_ERROR_BAD_PARAMETERS;
1063
1064 for (n = 0; n < TEE_NUM_PARAMS; n++)
1065 if (!params[n].memref.buffer || !params[n].memref.size)
1066 return TEE_ERROR_BAD_PARAMETERS;
1067
1068 return TEE_SUCCESS;
1069}
Jerome Forissier53bde722018-05-31 09:14:54 +02001070
1071TEE_Result ta_entry_call_lib(uint32_t param_types,
1072 TEE_Param params[4] __unused)
1073{
1074 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1075 TEE_PARAM_TYPE_NONE,
1076 TEE_PARAM_TYPE_NONE,
1077 TEE_PARAM_TYPE_NONE))
1078 return TEE_ERROR_BAD_PARAMETERS;
1079
1080 if (os_test_shlib_add(1, 2) != 3)
1081 return TEE_ERROR_GENERIC;
1082
1083 return TEE_SUCCESS;
1084}
1085
1086TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1087 TEE_Param params[4] __unused)
1088{
1089 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1090 TEE_PARAM_TYPE_NONE,
1091 TEE_PARAM_TYPE_NONE,
1092 TEE_PARAM_TYPE_NONE))
1093 return TEE_ERROR_BAD_PARAMETERS;
1094
1095 os_test_shlib_panic();
1096
1097 return TEE_ERROR_GENERIC;
1098}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001099
1100TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1101 TEE_Param params[4] __unused)
1102{
1103 int (*add_func)(int a, int b) = NULL;
1104 TEE_Result res = TEE_ERROR_GENERIC;
1105 void *handle = NULL;
1106 void *hnull = NULL;
1107
1108 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1109 TEE_PARAM_TYPE_NONE,
1110 TEE_PARAM_TYPE_NONE,
1111 TEE_PARAM_TYPE_NONE))
1112 return TEE_ERROR_BAD_PARAMETERS;
1113
1114 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1115 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1116 if (!handle)
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001117 return TEE_ERROR_GENERIC;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001118
1119 add_func = dlsym(handle, "os_test_shlib_dl_add");
1120 if (!add_func)
1121 goto err;
1122 if (add_func(3, 4) != 7)
1123 goto err;
1124
1125 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001126 if (!hnull)
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001127 goto err;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001128
1129 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1130 if (!add_func)
1131 goto err;
1132 if (add_func(5, 6) != 11)
1133 goto err;
1134
1135 res = TEE_SUCCESS;
1136 dlclose(hnull);
1137err:
1138 dlclose(handle);
1139 return res;
1140}
1141
1142TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1143 TEE_Param params[4] __unused)
1144{
1145 int (*panic_func)(void) = NULL;
1146 void *handle = NULL;
1147 TEE_Result res = TEE_ERROR_GENERIC;
1148
1149 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1150 TEE_PARAM_TYPE_NONE,
1151 TEE_PARAM_TYPE_NONE,
1152 TEE_PARAM_TYPE_NONE))
1153 return TEE_ERROR_BAD_PARAMETERS;
1154
1155 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1156 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1157 if (!handle)
1158 return res;
1159
1160 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1161 if (!panic_func)
1162 goto err;
1163 panic_func();
1164 return TEE_ERROR_GENERIC;
1165err:
1166 dlclose(handle);
1167 return res;
1168}