blob: 52d7b494dea9fa084a51e40d5d3d919adaac9d7a [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;
Pascal Brandc639ac82015-07-02 08:53:34 +0200898
Etienne Carriere92c34422018-02-09 13:11:40 +0100899 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
900 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
901 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200902 return TEE_ERROR_GENERIC;
903
904 switch (params[0].value.a) {
905 case 1:
906 *((uint32_t *) 0) = 0;
907 break;
908 case 2:
909 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
910 break;
911 case 3:
912 ((void (*)(void))0) ();
913 break;
914 case 4:
915 ((void (*)(void))(stack_addr + 0x40000000)) ();
916 break;
917 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +0200918 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200919 break;
920 default:
921 break;
922 }
923
924 return TEE_SUCCESS;
925}
Jerome Forissiere916b102017-06-07 17:55:52 +0200926
927static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
928{
Etienne Carriere102092e2019-03-28 15:24:22 +0100929 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +0200930
931 for (i = 0; i < bufsize; i++) {
932 a[i]++; b[i]++; c[i]++;
933 }
934}
935
Etienne Carriere102092e2019-03-28 15:24:22 +0100936#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +0200937TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
938{
939 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
940 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100941 TEE_Param l_params[4] = { };
942 uint8_t in[TA2TA_BUF_SIZE] = { };
943 uint8_t inout[TA2TA_BUF_SIZE] = { };
944 uint8_t out[TA2TA_BUF_SIZE] = { };
945 TEE_Result res = TEE_ERROR_GENERIC;
946 uint32_t ret_orig = 0;
947 uint32_t l_pts = 0;
948 size_t i = 0;
949
Jerome Forissiere916b102017-06-07 17:55:52 +0200950 (void)params;
951
952 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
953 return TEE_ERROR_GENERIC;
954
Cedric Augere668b3f2019-09-11 13:41:21 +0200955 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
956 &sess, &ret_orig);
Jerome Forissiere916b102017-06-07 17:55:52 +0200957 if (res != TEE_SUCCESS) {
958 EMSG("TEE_OpenTASession failed");
959 goto cleanup_return;
960 }
961
962 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
963 TEE_PARAM_TYPE_MEMREF_INOUT,
964 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
965 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +0100966 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200967 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +0100968 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200969 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +0100970 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200971
972 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +0100973 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +0200974 in[i] = 5;
975 inout[i] = 10;
976 out[i] = 0;
977 }
978
979 /*
980 * TA will compute: out = ++inout + in
981 * Expected values after this step: in: 5, inout: 11, out: 16
982 */
Cedric Augere668b3f2019-09-11 13:41:21 +0200983 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
984 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +0200985 l_pts, l_params, &ret_orig);
986 if (res != TEE_SUCCESS) {
987 EMSG("TEE_InvokeTACommand failed");
988 goto cleanup_return;
989 }
Etienne Carriere102092e2019-03-28 15:24:22 +0100990
Jerome Forissiere916b102017-06-07 17:55:52 +0200991 /*
992 * Increment all values by one.
993 * Expected values after this step: in: 6, inout: 12, out: 17
994 */
Etienne Carriere102092e2019-03-28 15:24:22 +0100995 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +0200996
997 /*
998 * TA will compute: out = ++inout + in
999 * Expected values after this step: in: 6, inout: 13, out: 19
1000 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001001 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1002 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001003 l_pts, l_params, &ret_orig);
1004 if (res != TEE_SUCCESS) {
1005 EMSG("TEE_InvokeTACommand failed");
1006 goto cleanup_return;
1007 }
1008
1009 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001010 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001011 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1012 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001013 DHEXDUMP(in, TA2TA_BUF_SIZE);
1014 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1015 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001016 return TEE_ERROR_GENERIC;
1017 }
1018 }
1019
1020cleanup_return:
1021 TEE_CloseTASession(sess);
1022 return res;
1023}
1024
1025TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1026{
Etienne Carriere102092e2019-03-28 15:24:22 +01001027 uint8_t *in = NULL;
1028 uint8_t *inout = NULL;
1029 uint8_t *out = NULL;
1030 size_t bufsize = 0;
1031 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001032
1033 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1034 TEE_PARAM_TYPE_MEMREF_INOUT,
1035 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1036 return TEE_ERROR_GENERIC;
1037
1038 bufsize = params[0].memref.size;
1039 if (params[1].memref.size != bufsize ||
1040 params[2].memref.size != bufsize)
1041 return TEE_ERROR_GENERIC;
1042
1043 in = params[0].memref.buffer;
1044 inout = params[1].memref.buffer;
1045 out = params[2].memref.buffer;
1046
1047 for (i = 0; i < bufsize; i++)
1048 out[i] = ++inout[i] + in[i];
1049
1050 return TEE_SUCCESS;
1051}
Jens Wiklander87e81702018-03-20 12:00:00 +08001052
1053TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1054{
Etienne Carriere102092e2019-03-28 15:24:22 +01001055 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001056
1057 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1058 TEE_PARAM_TYPE_MEMREF_INPUT,
1059 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1060 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1061 return TEE_ERROR_BAD_PARAMETERS;
1062
1063 for (n = 0; n < TEE_NUM_PARAMS; n++)
1064 if (!params[n].memref.buffer || !params[n].memref.size)
1065 return TEE_ERROR_BAD_PARAMETERS;
1066
1067 return TEE_SUCCESS;
1068}
Jerome Forissier53bde722018-05-31 09:14:54 +02001069
1070TEE_Result ta_entry_call_lib(uint32_t param_types,
1071 TEE_Param params[4] __unused)
1072{
1073 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1074 TEE_PARAM_TYPE_NONE,
1075 TEE_PARAM_TYPE_NONE,
1076 TEE_PARAM_TYPE_NONE))
1077 return TEE_ERROR_BAD_PARAMETERS;
1078
1079 if (os_test_shlib_add(1, 2) != 3)
1080 return TEE_ERROR_GENERIC;
1081
1082 return TEE_SUCCESS;
1083}
1084
1085TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1086 TEE_Param params[4] __unused)
1087{
1088 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1089 TEE_PARAM_TYPE_NONE,
1090 TEE_PARAM_TYPE_NONE,
1091 TEE_PARAM_TYPE_NONE))
1092 return TEE_ERROR_BAD_PARAMETERS;
1093
1094 os_test_shlib_panic();
1095
1096 return TEE_ERROR_GENERIC;
1097}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001098
1099TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1100 TEE_Param params[4] __unused)
1101{
1102 int (*add_func)(int a, int b) = NULL;
1103 TEE_Result res = TEE_ERROR_GENERIC;
1104 void *handle = NULL;
1105 void *hnull = NULL;
1106
1107 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1108 TEE_PARAM_TYPE_NONE,
1109 TEE_PARAM_TYPE_NONE,
1110 TEE_PARAM_TYPE_NONE))
1111 return TEE_ERROR_BAD_PARAMETERS;
1112
1113 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1114 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1115 if (!handle)
1116 return TEE_ERROR_OUT_OF_MEMORY;
1117
1118 add_func = dlsym(handle, "os_test_shlib_dl_add");
1119 if (!add_func)
1120 goto err;
1121 if (add_func(3, 4) != 7)
1122 goto err;
1123
1124 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1125 if (!hnull) {
1126 res = TEE_ERROR_OUT_OF_MEMORY;
1127 goto err;
1128 }
1129
1130 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1131 if (!add_func)
1132 goto err;
1133 if (add_func(5, 6) != 11)
1134 goto err;
1135
1136 res = TEE_SUCCESS;
1137 dlclose(hnull);
1138err:
1139 dlclose(handle);
1140 return res;
1141}
1142
1143TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1144 TEE_Param params[4] __unused)
1145{
1146 int (*panic_func)(void) = NULL;
1147 void *handle = NULL;
1148 TEE_Result res = TEE_ERROR_GENERIC;
1149
1150 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1151 TEE_PARAM_TYPE_NONE,
1152 TEE_PARAM_TYPE_NONE,
1153 TEE_PARAM_TYPE_NONE))
1154 return TEE_ERROR_BAD_PARAMETERS;
1155
1156 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1157 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1158 if (!handle)
1159 return res;
1160
1161 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1162 if (!panic_func)
1163 goto err;
1164 panic_func();
1165 return TEE_ERROR_GENERIC;
1166err:
1167 dlclose(handle);
1168 return res;
1169}