blob: feca6b4196b85d0102a8874b983a78991b3d3be6 [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>
Jens Wiklander8324ff22018-11-21 14:16:04 +010028#include <setjmp.h>
29#include <stdint.h>
30#include <string.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020031#include <ta_crypt.h>
32#include <ta_os_test.h>
33#include <tee_internal_api_extensions.h>
34
35#include "os_test.h"
Jens Wiklander246184a2015-12-11 08:28:59 +010036#include "test_float_subj.h"
Jerome Forissier53bde722018-05-31 09:14:54 +020037#include "os_test_lib.h"
Pascal Brandc639ac82015-07-02 08:53:34 +020038
39enum p_type {
40 P_TYPE_BOOL,
41 P_TYPE_INT,
42 P_TYPE_UUID,
43 P_TYPE_IDENTITY,
44 P_TYPE_STRING,
45 P_TYPE_BINARY_BLOCK,
46};
47
48struct p_attr {
49 const char *str;
50 enum p_type type;
51 bool retrieved;
52};
53
Pascal Brand624b6a32016-02-16 12:51:34 +010054static TEE_Result check_returned_prop(
Pascal Brandaf77fdd2016-03-08 13:59:01 +010055 int line __maybe_unused, char *prop_name __maybe_unused,
Pascal Brand624b6a32016-02-16 12:51:34 +010056 TEE_Result return_res, TEE_Result expected_res,
57 uint32_t return_len, uint32_t expected_len)
58{
59 if (return_res != expected_res) {
60 EMSG("From line %d (property name=%s): return_res=0x%x vs expected_res=0x%x",
61 line, (prop_name ? prop_name : "unknown"),
62 (unsigned int)return_res, (unsigned int)expected_res);
63 return TEE_ERROR_GENERIC;
64 }
65 if (return_len != expected_len) {
Pascal Brand07bb09f2016-02-19 16:04:10 +010066 EMSG("From line %d (property name=%s): return_len=%u vs expected_res=%u",
67 line, (prop_name ? prop_name : "unknown"),
68 return_len, expected_len);
Pascal Brand624b6a32016-02-16 12:51:34 +010069 return TEE_ERROR_GENERIC;
70 }
71 return TEE_SUCCESS;
72}
73
Pascal Brandc639ac82015-07-02 08:53:34 +020074static TEE_Result print_properties(TEE_PropSetHandle h,
75 TEE_PropSetHandle prop_set,
76 struct p_attr *p_attrs, size_t num_p_attrs)
77{
Etienne Carriere102092e2019-03-28 15:24:22 +010078TEE_Result res = TEE_ERROR_GENERIC;
79size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +020080
81TEE_StartPropertyEnumerator(h, prop_set);
82
83while (true) {
Etienne Carriere102092e2019-03-28 15:24:22 +010084 char nbuf[256] = { };
85 char nbuf_small[256] = { };
86 char vbuf[256] = { };
87 char vbuf2[256] = { };
Jens Wiklanderc5231592015-11-11 09:27:27 +010088 uint32_t nblen = sizeof(nbuf);
Etienne Carriere102092e2019-03-28 15:24:22 +010089 uint32_t nblen_small = 0;
Jens Wiklanderc5231592015-11-11 09:27:27 +010090 uint32_t vblen = sizeof(vbuf);
91 uint32_t vblen2 = sizeof(vbuf2);
Pascal Brandc639ac82015-07-02 08:53:34 +020092
93 res = TEE_GetPropertyName(h, nbuf, &nblen);
94 if (res != TEE_SUCCESS) {
95 EMSG("TEE_GetPropertyName returned 0x%x\n",
96 (unsigned int)res);
97 return res;
98 }
Pascal Brand624b6a32016-02-16 12:51:34 +010099 if (nblen != strlen(nbuf) + 1) {
Pascal Brand5b68cd62016-02-22 10:31:01 +0100100 EMSG("Name has wrong size: %u vs %zu", nblen, strlen(nbuf) + 1);
Pascal Brand624b6a32016-02-16 12:51:34 +0100101 return TEE_ERROR_GENERIC;
102 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200103
Pascal Brand624b6a32016-02-16 12:51:34 +0100104
105 /* Get the property name with a very small buffer */
106 nblen_small = 2;
107 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
108 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
109 nblen_small, nblen);
110 if (res != TEE_SUCCESS)
111 return res;
112
113 /* Get the property name with almost the correct buffer */
114 nblen_small = nblen - 1;
115 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
116 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
117 nblen_small, nblen);
118 if (res != TEE_SUCCESS)
119 return res;
120
121 /* Get the property name with the exact buffer length */
122 nblen_small = nblen;
123 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
124 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
125 nblen_small, nblen);
126 if (res != TEE_SUCCESS)
127 return res;
128
129 /* Get the property value */
Pascal Brandc639ac82015-07-02 08:53:34 +0200130 res = TEE_GetPropertyAsString(h, NULL, vbuf, &vblen);
Pascal Brand624b6a32016-02-16 12:51:34 +0100131 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
132 vblen, strlen(vbuf) + 1);
133 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200134 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100135
Pascal Brandc639ac82015-07-02 08:53:34 +0200136 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
Pascal Brand624b6a32016-02-16 12:51:34 +0100137 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
138 vblen2, strlen(vbuf2) + 1);
139 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200140 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100141
Jens Wiklander8324ff22018-11-21 14:16:04 +0100142 if (strcmp(vbuf, vbuf2) != 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200143 EMSG("String of \"%s\" differs\n", nbuf);
144 return TEE_ERROR_GENERIC;
145 }
146
Pascal Brand624b6a32016-02-16 12:51:34 +0100147 /* Get the property with a very small buffer */
148 vblen2 = 1;
149 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
150 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
151 vblen2, vblen);
152 if (res != TEE_SUCCESS)
153 return res;
154
155 /* Get the property with almost the correct buffer */
156 vblen2 = vblen - 1;
157 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
158 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
159 vblen2, vblen);
160 if (res != TEE_SUCCESS)
161 return res;
162
163 /* Get the property name with the exact buffer length */
164 vblen2 = vblen;
165 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
166 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS, vblen2, vblen);
167 if (res != TEE_SUCCESS)
168 return res;
169
170 /* check specific myprop.hello property, which is larger than 80 */
171 if (!strcmp("myprop.hello", nbuf) &&
172 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")) {
173 EMSG("TEE_GetPropertyAsString(\"%s\") is truncated - returned \"%s\"\n",
174 nbuf, vbuf);
175 return TEE_ERROR_GENERIC;
176 }
177
Pascal Brandc639ac82015-07-02 08:53:34 +0200178 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
179
180 for (n = 0; n < num_p_attrs; n++) {
Jens Wiklander8324ff22018-11-21 14:16:04 +0100181 if (strcmp(nbuf, p_attrs[n].str) != 0)
Pascal Brandc639ac82015-07-02 08:53:34 +0200182 continue;
183
184 if (p_attrs[n].retrieved) {
185 EMSG("Value \"%s\" already retrieved\n",
186 p_attrs[n].str);
187 return TEE_ERROR_GENERIC;
188 }
189 p_attrs[n].retrieved = true;
190
191 switch (p_attrs[n].type) {
192 case P_TYPE_BOOL:
193 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100194 bool v = false;
Pascal Brandc639ac82015-07-02 08:53:34 +0200195
196 res =
197 TEE_GetPropertyAsBool(h, NULL, &v);
198 if (res != TEE_SUCCESS) {
199 EMSG(
200 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
201 nbuf, (unsigned int)res);
202 return res;
203 }
204 }
205 break;
206
207 case P_TYPE_INT:
208 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100209 uint32_t v = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200210
211 res = TEE_GetPropertyAsU32(h, NULL, &v);
212 if (res != TEE_SUCCESS) {
213 EMSG(
214 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
215 nbuf, (unsigned int)res);
216 return res;
217 }
218 }
219 break;
220
221 case P_TYPE_UUID:
222 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100223 TEE_UUID v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200224
225 res =
226 TEE_GetPropertyAsUUID(h, NULL, &v);
227 if (res != TEE_SUCCESS) {
228 EMSG(
229 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
230 nbuf, (unsigned int)res);
231 return res;
232 }
233 }
234 break;
235
236 case P_TYPE_IDENTITY:
237 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100238 TEE_Identity v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200239
240 res =
241 TEE_GetPropertyAsIdentity(h, NULL,
242 &v);
243 if (res != TEE_SUCCESS) {
244 EMSG(
245 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
246 nbuf, (unsigned int)res);
247 return res;
248 }
249 }
250 break;
251
252 case P_TYPE_STRING:
253 /* Already read as string */
254 break;
255
256 case P_TYPE_BINARY_BLOCK:
257 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100258 char bbuf[80] = { };
Jens Wiklanderc5231592015-11-11 09:27:27 +0100259 uint32_t bblen = sizeof(bbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200260
261 res =
262 TEE_GetPropertyAsBinaryBlock(h,
263 NULL,
264 bbuf,
265 &bblen);
266 if (res != TEE_SUCCESS) {
267 EMSG(
268 "TEE_GetPropertyAsBinaryBlock(\"%s\") returned 0x%x\n",
269 nbuf, (unsigned int)res);
270 return res;
271 }
Jens Wiklander8324ff22018-11-21 14:16:04 +0100272 if (strcmp("myprop.binaryblock", nbuf) == 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200273 const char exp_bin_value[] =
274 "Hello world!";
275
Etienne Carriere102092e2019-03-28 15:24:22 +0100276 if (bblen != strlen(exp_bin_value) ||
277 TEE_MemCompare(exp_bin_value, bbuf,
278 bblen) != 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200279 EMSG(
280 "Binary buffer of \"%s\" differs from \"%s\"\n",
281 nbuf, exp_bin_value);
282 EMSG(
283 "Got \"%s\"\n",
284 bbuf);
285 return
286 TEE_ERROR_GENERIC;
287 }
288 }
289
290 }
291 break;
292
293 default:
294 EMSG("Unknown type (%d) for \"%s\"\n",
295 p_attrs[n].type, p_attrs[n].str);
296 return TEE_ERROR_GENERIC;
297 }
298 }
299
300 res = TEE_GetNextProperty(h);
301 if (res != TEE_SUCCESS) {
302 if (res == TEE_ERROR_ITEM_NOT_FOUND)
303 return TEE_SUCCESS;
304 return res;
305 }
306}
307}
308
309static TEE_Result test_malloc(void)
310{
311 void *p = TEE_Malloc(4, 0);
312
313 if (p == NULL) {
314 EMSG("TEE_Malloc failed\n");
315 return TEE_ERROR_OUT_OF_MEMORY;
316 }
317 TEE_Free(p);
318 TEE_Free(NULL);
319
320 return TEE_SUCCESS;
321}
322
323static TEE_Result test_properties(void)
324{
325 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriere102092e2019-03-28 15:24:22 +0100326 TEE_PropSetHandle h = TEE_HANDLE_NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200327 struct p_attr p_attrs[] = {
328 {"gpd.ta.appID", P_TYPE_UUID},
329 {"gpd.ta.singleInstance", P_TYPE_BOOL},
330 {"gpd.ta.multiSession", P_TYPE_BOOL},
331 {"gpd.ta.instanceKeepAlive", P_TYPE_BOOL},
332 {"gpd.ta.dataSize", P_TYPE_INT},
333 {"gpd.ta.stackSize", P_TYPE_INT},
334 {"gpd.ta.version", P_TYPE_STRING},
335 {"gpd.ta.description", P_TYPE_STRING},
336 {"gpd.client.identity", P_TYPE_IDENTITY},
337 {"gpd.tee.apiversion", P_TYPE_STRING},
338 {"gpd.tee.description", P_TYPE_STRING},
339 {"gpd.tee.deviceID", P_TYPE_UUID},
340 {"gpd.tee.systemTime.protectionLevel", P_TYPE_INT},
341 {"gpd.tee.TAPersistentTime.protectionLevel", P_TYPE_INT},
342 {"gpd.tee.arith.maxBigIntSize", P_TYPE_INT},
343 {"gpd.tee.cryptography.ecc", P_TYPE_BOOL},
344 {"gpd.tee.trustedStorage.antiRollback.protectionLevel", P_TYPE_INT},
345 {"gpd.tee.trustedos.implementation.version", P_TYPE_STRING},
346 {"gpd.tee.trustedos.implementation.binaryversion", P_TYPE_INT},
347 {"gpd.tee.trustedos.manufacturer", P_TYPE_STRING},
348 {"gpd.tee.firmware.implementation.version", P_TYPE_STRING},
349 {"gpd.tee.firmware.implementation.binaryversion", P_TYPE_INT},
350 {"gpd.tee.firmware.manufacturer", P_TYPE_STRING},
351 {"myprop.true", P_TYPE_BOOL},
352 {"myprop.42", P_TYPE_INT},
353 {"myprop.123", P_TYPE_UUID},
354 {"myprop.1234", P_TYPE_IDENTITY},
355 {"myprop.hello", P_TYPE_STRING},
356 {"myprop.binaryblock", P_TYPE_BINARY_BLOCK},
357 };
358 const size_t num_p_attrs = sizeof(p_attrs) / sizeof(p_attrs[0]);
Etienne Carriere102092e2019-03-28 15:24:22 +0100359 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200360
361 res = TEE_AllocatePropertyEnumerator(&h);
362 if (res != TEE_SUCCESS) {
363 EMSG("TEE_AllocatePropertyEnumerator: returned 0x%x\n",
364 (unsigned int)res);
365 return TEE_ERROR_GENERIC;
366 }
367
368 printf("Getting properties for current TA\n");
369 res = print_properties(h, TEE_PROPSET_CURRENT_TA, p_attrs, num_p_attrs);
370 if (res != TEE_SUCCESS)
371 goto cleanup_return;
372
373 printf("Getting properties for current client\n");
374 res = print_properties(h, TEE_PROPSET_CURRENT_CLIENT, p_attrs,
375 num_p_attrs);
376 if (res != TEE_SUCCESS)
377 goto cleanup_return;
378
379 printf("Getting properties for implementation\n");
380 res = print_properties(h, TEE_PROPSET_TEE_IMPLEMENTATION, p_attrs,
381 num_p_attrs);
382 if (res != TEE_SUCCESS)
383 goto cleanup_return;
384
385 for (n = 0; n < num_p_attrs; n++) {
386 if (!p_attrs[n].retrieved) {
387 EMSG("\"%s\" not retrieved\n", p_attrs[n].str);
388 res = TEE_ERROR_GENERIC;
389 goto cleanup_return;
390 }
391 }
392
393cleanup_return:
394 TEE_FreePropertyEnumerator(h);
395 return res;
396}
397
398static TEE_Result test_mem_access_right(uint32_t param_types,
399 TEE_Param params[4])
400{
401 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100402 TEE_Result res = TEE_ERROR_GENERIC;
403 uint32_t ret_orig = 0;
404 uint32_t l_pts = 0;
405 TEE_Param l_params[4] = { };
406 uint8_t buf[32] = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200407 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100408 TEE_UUID *uuid = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200409
410 if (param_types !=
411 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
412 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200413
414 /* test access rights on memref parameter */
415 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
416 TEE_MEMORY_ACCESS_ANY_OWNER,
417 params[0].memref.buffer,
418 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200419 if (res != TEE_SUCCESS)
420 return res;
Etienne Carriere281065d2016-10-28 15:41:33 +0200421
Pascal Brandc639ac82015-07-02 08:53:34 +0200422 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
423 params[0].memref.buffer,
424 params[0].memref.size);
425 if (res != TEE_ERROR_ACCESS_DENIED)
426 return TEE_ERROR_GENERIC;
427
Etienne Carriere281065d2016-10-28 15:41:33 +0200428 /* test access rights on private read-only and read-write memory */
429 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
430 (void *)&test_uuid, sizeof(test_uuid));
431 if (res != TEE_SUCCESS)
432 return res;
433
434 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_WRITE,
435 (void *)&test_uuid, sizeof(test_uuid));
436 if (res == TEE_SUCCESS)
437 return TEE_ERROR_GENERIC;
438
439 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
440 TEE_MEMORY_ACCESS_WRITE,
441 &ret_orig, sizeof(ret_orig));
442 if (res != TEE_SUCCESS)
443 return res;
444
445 uuid = TEE_Malloc(sizeof(*uuid), 0);
446 if (!uuid)
447 return TEE_ERROR_OUT_OF_MEMORY;
448
449 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
450 TEE_MEMORY_ACCESS_WRITE,
451 uuid, sizeof(*uuid));
452 TEE_Free(uuid);
453 if (res != TEE_SUCCESS)
454 return res;
455
456 /* test access rights on invalid memory (at least lower 256kB) */
457 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
458 NULL, 1);
459 if (res == TEE_SUCCESS)
460 return TEE_ERROR_GENERIC;
461
462 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
463 (void*)(256 * 1024), 1);
464 if (res == TEE_SUCCESS)
465 return TEE_ERROR_GENERIC;
466
Pascal Brandc639ac82015-07-02 08:53:34 +0200467 res = TEE_OpenTASession(&test_uuid, 0, 0, NULL, &sess, &ret_orig);
468 if (res != TEE_SUCCESS) {
469 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
470 goto cleanup_return;
471 }
472
Jerome Forissier04511d82018-01-30 14:33:49 +0100473 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
474 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200475 l_params[0].memref.buffer = buf;
476 l_params[0].memref.size = sizeof(buf);
Jerome Forissier04511d82018-01-30 14:33:49 +0100477 l_params[1].memref.buffer = NULL;
478 l_params[1].memref.size = 0;
Etienne Carriere281065d2016-10-28 15:41:33 +0200479 res = TEE_InvokeTACommand(sess, 0, TA_OS_TEST_CMD_PARAMS_ACCESS,
Pascal Brandc639ac82015-07-02 08:53:34 +0200480 l_pts, l_params, &ret_orig);
481 if (res != TEE_SUCCESS) {
482 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
483 goto cleanup_return;
484 }
485
486cleanup_return:
487 TEE_CloseTASession(sess);
488 return res;
489}
490
491static TEE_Result test_time(void)
492{
Etienne Carriere102092e2019-03-28 15:24:22 +0100493 TEE_Result res = TEE_ERROR_GENERIC;
494 TEE_Time t = { };
495 TEE_Time sys_t = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200496 static const TEE_Time null_time = { 0, 0 };
497 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
498
499 TEE_GetSystemTime(&sys_t);
500 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
501 (unsigned int)sys_t.millis);
502
503 TEE_GetREETime(&t);
504 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
505 (unsigned int)t.millis);
506
507 res = TEE_GetTAPersistentTime(&t);
508 switch (res) {
509 case TEE_SUCCESS:
510 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
511 (unsigned int)t.millis);
512 break;
513 case TEE_ERROR_OVERFLOW:
514 EMSG("Stored TA time overflowed %u.%03u\n",
515 (unsigned int)t.seconds, (unsigned int)t.millis);
516 break;
517 case TEE_ERROR_TIME_NOT_SET:
518 EMSG("TA time not stored\n");
519 break;
520 case TEE_ERROR_TIME_NEEDS_RESET:
521 EMSG("TA time needs reset\n");
522 break;
523 default:
524 return res;
525 }
526
527 res = TEE_SetTAPersistentTime(&null_time);
528 if (res != TEE_SUCCESS) {
529 EMSG("TEE_SetTAPersistentTime: failed\n");
530 return res;
531 }
532
533 res = TEE_GetTAPersistentTime(&t);
534 if (res != TEE_SUCCESS) {
535 EMSG("TEE_GetTAPersistentTime null: failed\n");
536 return res;
537 }
538 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
539 (unsigned int)t.millis);
540 /*
541 * The time between TEE_SetTAPersistentTime() and
542 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
543 * it's not even a millisecond.
544 */
545 if (t.seconds > 1 || t.millis >= 1000) {
546 EMSG("Unexpected stored TA time %u.%03u\n",
547 (unsigned int)t.seconds, (unsigned int)t.millis);
548 return TEE_ERROR_BAD_STATE;
549 }
550
551 res = TEE_SetTAPersistentTime(&wrap_time);
552 if (res != TEE_SUCCESS) {
553 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
554 return res;
555 }
556
557 res = TEE_Wait(1000);
558 if (res != TEE_SUCCESS)
559 EMSG("TEE_Wait wrap: failed\n");
560
561 res = TEE_GetTAPersistentTime(&t);
562 if (res != TEE_ERROR_OVERFLOW) {
563 EMSG("TEE_GetTAPersistentTime: failed\n");
564 return TEE_ERROR_BAD_STATE;
565 }
566 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
567 (unsigned int)t.millis);
568
569 if (t.seconds > sys_t.seconds) {
570 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
571 (unsigned int)t.seconds, (unsigned int)t.millis,
572 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
573 return TEE_ERROR_BAD_STATE;
574 }
575
576 return TEE_SUCCESS;
577}
578
Jens Wiklander246184a2015-12-11 08:28:59 +0100579#ifdef CFG_TA_FLOAT_SUPPORT
580static bool my_dcmpeq(double v1, double v2, double prec)
581{
582 return v1 > (v2 - prec) && v1 < (v2 + prec);
583}
584
585static bool my_fcmpeq(float v1, float v2, float prec)
586{
587 return v1 > (v2 - prec) && v1 < (v2 + prec);
588}
589
590
591static TEE_Result test_float(void)
592{
593#define VAL1 2.6
594#define VAL1_INT 2
595#define VAL2 5.3
596#define DPREC 0.000000000000001
597#define FPREC 0.000001
598#define EXPECT(expr) do { \
599 if (!(expr)) { \
600 EMSG("Expression %s failed", #expr); \
601 return TEE_ERROR_GENERIC; \
602 } \
603 } while (0)
604
605 IMSG("Testing floating point operations");
606
607 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
608 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
609 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
610 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
611 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
612
613 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
614 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
615 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
616 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
617 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
618
619 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
620 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
621 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
622 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
623 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
624
625 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
626 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
627 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
628 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
629 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
630
631 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
632 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
633 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
634 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
635
636 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
637 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
638 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
639 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
640
641 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
642 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
643
644 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
645 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
646 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
647 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
648
649 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
650 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
651 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
652 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
653 return TEE_SUCCESS;
654}
655#else /*CFG_TA_FLOAT_SUPPORT*/
656static TEE_Result test_float(void)
657{
658 IMSG("Floating point disabled");
659 return TEE_SUCCESS;
660}
661#endif /*CFG_TA_FLOAT_SUPPORT*/
662
Jens Wiklander9f682c62016-03-27 20:23:06 +0200663static __noinline void call_longjmp(jmp_buf env)
664{
665 DMSG("Calling longjmp");
666 longjmp(env, 1);
667 EMSG("error: longjmp returned to calling function");
668}
669
670static TEE_Result test_setjmp(void)
671{
Etienne Carriere102092e2019-03-28 15:24:22 +0100672 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200673
674 if (setjmp(env)) {
675 IMSG("Returned via longjmp");
676 return TEE_SUCCESS;
677 } else {
678 call_longjmp(env);
679 return TEE_ERROR_GENERIC;
680 }
681}
682
Pascal Brandc639ac82015-07-02 08:53:34 +0200683TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
684{
685 TEE_Result res = TEE_ERROR_GENERIC;
686
687 printf("ta_entry_basic: enter\n");
688
689 res = test_malloc();
690 if (res != TEE_SUCCESS)
691 return res;
692
693 res = test_properties();
694 if (res != TEE_SUCCESS)
695 return res;
696
697 res = test_mem_access_right(param_types, params);
698 if (res != TEE_SUCCESS)
699 return res;
700
701 res = test_time();
702 if (res != TEE_SUCCESS)
703 return res;
704
Jens Wiklander246184a2015-12-11 08:28:59 +0100705 res = test_float();
706 if (res != TEE_SUCCESS)
707 return res;
708
Jens Wiklander9f682c62016-03-27 20:23:06 +0200709 res = test_setjmp();
710 if (res != TEE_SUCCESS)
711 return res;
712
Pascal Brandc639ac82015-07-02 08:53:34 +0200713 return TEE_SUCCESS;
714}
715
716TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
717{
718 volatile bool mytrue = true;
719 (void)param_types;
720 (void)params;
721
722 printf("ta_entry_panic: enter\n");
723 /*
724 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
725 * the __noreturn attribute.
726 */
727 if (mytrue)
728 TEE_Panic(0xbeef);
729
730 /*
731 * Should not be reached, but if it is the testsuite can detect that
732 * TEE_Panic() returned instead of panicking the TA.
733 */
734 return TEE_SUCCESS;
735}
736
737TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
738 TEE_Param params[4])
739{
740 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100741 TEE_Result res = TEE_ERROR_GENERIC;
742 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
743 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200744
745 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
746 TEE_PARAM_TYPE_NONE,
747 TEE_PARAM_TYPE_NONE,
748 TEE_PARAM_TYPE_NONE)) {
749 EMSG("ta_entry_client_with_timeout: bad parameters\n");
750 return TEE_ERROR_BAD_PARAMETERS;
751 }
752
753 res = TEE_OpenTASession(&os_test_uuid, 0, 0, NULL, &sess, &ret_orig);
754 if (res != TEE_SUCCESS) {
755 EMSG(
756 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
757 return res;
758 }
759
760 res =
761 TEE_InvokeTACommand(sess, params[0].value.a / 2,
762 TA_OS_TEST_CMD_WAIT, param_types, params,
763 &ret_orig);
764
765 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
766 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
767 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
768 (unsigned int)ret_orig);
769 res = TEE_ERROR_GENERIC;
770 } else
771 res = TEE_SUCCESS;
772
773 TEE_CloseTASession(sess);
774 return res;
775
776}
777
778TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
779{
780 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100781 TEE_Result res = TEE_ERROR_GENERIC;
782 uint32_t l_pts = 0;
783 TEE_Param l_params[4] = { };
784 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
785 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200786 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
787 static const uint8_t sha256_out[] = {
788 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
789 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
790 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
791 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
792 };
793 uint8_t out[32] = { 0 };
794 void *in = NULL;
795
796 (void)param_types;
797 (void)params;
798
799 printf("ta_entry_client: enter\n");
800
801 in = TEE_Malloc(sizeof(sha256_in), 0);
802 if (in == NULL)
803 return TEE_ERROR_OUT_OF_MEMORY;
804 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
805
806 res = TEE_OpenTASession(&crypt_uuid, 0, 0, NULL, &sess, &ret_orig);
807 if (res != TEE_SUCCESS) {
808 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
809 goto cleanup_return;
810 }
811
812 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
813 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
814 l_params[0].memref.buffer = in;
815 l_params[0].memref.size = sizeof(sha256_in);
816 l_params[1].memref.buffer = out;
817 l_params[1].memref.size = sizeof(out);
818
819 res = TEE_InvokeTACommand(sess, 0, TA_CRYPT_CMD_SHA256, l_pts, l_params,
820 &ret_orig);
821 if (res != TEE_SUCCESS) {
822 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
823 goto cleanup_return;
824 }
825
826 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
827 EMSG("ta_entry_client: out parameter failed\n");
828 res = TEE_ERROR_GENERIC;
829 goto cleanup_return;
830 }
831
832cleanup_return:
833 TEE_Free(in);
834 TEE_CloseTASession(sess);
835 return res;
836}
837
Etienne Carriere281065d2016-10-28 15:41:33 +0200838TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200839{
Etienne Carriere102092e2019-03-28 15:24:22 +0100840 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200841
842 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100843 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
844 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200845 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200846
847 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
848 TEE_MEMORY_ACCESS_ANY_OWNER,
849 params[0].memref.buffer,
850 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200851 if (res != TEE_SUCCESS)
852 return res;
853
854 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
855 params[0].memref.buffer,
856 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200857 if (res != TEE_ERROR_ACCESS_DENIED)
858 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +0100859 if (params[1].memref.buffer || params[1].memref.size)
860 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200861
Etienne Carriere281065d2016-10-28 15:41:33 +0200862 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200863}
864
865TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
866{
867 TEE_Result res = TEE_SUCCESS;
868 (void)param_types;
869
870 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
871 /* Wait */
872 res = TEE_Wait(params[0].value.a);
873
874 return res;
875}
876
Jens Wiklander1425f952016-07-21 09:02:30 +0200877static void undef_instr(void)
878{
879#if defined(ARM64)
880 __asm__(".word 0x0");
881#elif defined(ARM32)
882 __asm__(".word 0xe7ffffff");
883#else
884#error "Unsupported architecture"
885#endif
886}
887
Pascal Brandc639ac82015-07-02 08:53:34 +0200888TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
889{
Etienne Carriere102092e2019-03-28 15:24:22 +0100890 long int stack = 0;
891 long int stack_addr = (long int)&stack;
Pascal Brandc639ac82015-07-02 08:53:34 +0200892
Etienne Carriere92c34422018-02-09 13:11:40 +0100893 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
894 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
895 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200896 return TEE_ERROR_GENERIC;
897
898 switch (params[0].value.a) {
899 case 1:
900 *((uint32_t *) 0) = 0;
901 break;
902 case 2:
903 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
904 break;
905 case 3:
906 ((void (*)(void))0) ();
907 break;
908 case 4:
909 ((void (*)(void))(stack_addr + 0x40000000)) ();
910 break;
911 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +0200912 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200913 break;
914 default:
915 break;
916 }
917
918 return TEE_SUCCESS;
919}
Jerome Forissiere916b102017-06-07 17:55:52 +0200920
921static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
922{
Etienne Carriere102092e2019-03-28 15:24:22 +0100923 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +0200924
925 for (i = 0; i < bufsize; i++) {
926 a[i]++; b[i]++; c[i]++;
927 }
928}
929
Etienne Carriere102092e2019-03-28 15:24:22 +0100930#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +0200931TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
932{
933 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
934 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100935 TEE_Param l_params[4] = { };
936 uint8_t in[TA2TA_BUF_SIZE] = { };
937 uint8_t inout[TA2TA_BUF_SIZE] = { };
938 uint8_t out[TA2TA_BUF_SIZE] = { };
939 TEE_Result res = TEE_ERROR_GENERIC;
940 uint32_t ret_orig = 0;
941 uint32_t l_pts = 0;
942 size_t i = 0;
943
Jerome Forissiere916b102017-06-07 17:55:52 +0200944 (void)params;
945
946 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
947 return TEE_ERROR_GENERIC;
948
949 res = TEE_OpenTASession(&test_uuid, 0, 0, NULL, &sess, &ret_orig);
950 if (res != TEE_SUCCESS) {
951 EMSG("TEE_OpenTASession failed");
952 goto cleanup_return;
953 }
954
955 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
956 TEE_PARAM_TYPE_MEMREF_INOUT,
957 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
958 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +0100959 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200960 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +0100961 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200962 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +0100963 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +0200964
965 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +0100966 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +0200967 in[i] = 5;
968 inout[i] = 10;
969 out[i] = 0;
970 }
971
972 /*
973 * TA will compute: out = ++inout + in
974 * Expected values after this step: in: 5, inout: 11, out: 16
975 */
976 res = TEE_InvokeTACommand(sess, 0, TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
977 l_pts, l_params, &ret_orig);
978 if (res != TEE_SUCCESS) {
979 EMSG("TEE_InvokeTACommand failed");
980 goto cleanup_return;
981 }
Etienne Carriere102092e2019-03-28 15:24:22 +0100982
Jerome Forissiere916b102017-06-07 17:55:52 +0200983 /*
984 * Increment all values by one.
985 * Expected values after this step: in: 6, inout: 12, out: 17
986 */
Etienne Carriere102092e2019-03-28 15:24:22 +0100987 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +0200988
989 /*
990 * TA will compute: out = ++inout + in
991 * Expected values after this step: in: 6, inout: 13, out: 19
992 */
993 res = TEE_InvokeTACommand(sess, 0, TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
994 l_pts, l_params, &ret_orig);
995 if (res != TEE_SUCCESS) {
996 EMSG("TEE_InvokeTACommand failed");
997 goto cleanup_return;
998 }
999
1000 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001001 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001002 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1003 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001004 DHEXDUMP(in, TA2TA_BUF_SIZE);
1005 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1006 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001007 return TEE_ERROR_GENERIC;
1008 }
1009 }
1010
1011cleanup_return:
1012 TEE_CloseTASession(sess);
1013 return res;
1014}
1015
1016TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1017{
Etienne Carriere102092e2019-03-28 15:24:22 +01001018 uint8_t *in = NULL;
1019 uint8_t *inout = NULL;
1020 uint8_t *out = NULL;
1021 size_t bufsize = 0;
1022 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001023
1024 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1025 TEE_PARAM_TYPE_MEMREF_INOUT,
1026 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1027 return TEE_ERROR_GENERIC;
1028
1029 bufsize = params[0].memref.size;
1030 if (params[1].memref.size != bufsize ||
1031 params[2].memref.size != bufsize)
1032 return TEE_ERROR_GENERIC;
1033
1034 in = params[0].memref.buffer;
1035 inout = params[1].memref.buffer;
1036 out = params[2].memref.buffer;
1037
1038 for (i = 0; i < bufsize; i++)
1039 out[i] = ++inout[i] + in[i];
1040
1041 return TEE_SUCCESS;
1042}
Jens Wiklander87e81702018-03-20 12:00:00 +08001043
1044TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1045{
Etienne Carriere102092e2019-03-28 15:24:22 +01001046 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001047
1048 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1049 TEE_PARAM_TYPE_MEMREF_INPUT,
1050 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1051 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1052 return TEE_ERROR_BAD_PARAMETERS;
1053
1054 for (n = 0; n < TEE_NUM_PARAMS; n++)
1055 if (!params[n].memref.buffer || !params[n].memref.size)
1056 return TEE_ERROR_BAD_PARAMETERS;
1057
1058 return TEE_SUCCESS;
1059}
Jerome Forissier53bde722018-05-31 09:14:54 +02001060
1061TEE_Result ta_entry_call_lib(uint32_t param_types,
1062 TEE_Param params[4] __unused)
1063{
1064 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1065 TEE_PARAM_TYPE_NONE,
1066 TEE_PARAM_TYPE_NONE,
1067 TEE_PARAM_TYPE_NONE))
1068 return TEE_ERROR_BAD_PARAMETERS;
1069
1070 if (os_test_shlib_add(1, 2) != 3)
1071 return TEE_ERROR_GENERIC;
1072
1073 return TEE_SUCCESS;
1074}
1075
1076TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1077 TEE_Param params[4] __unused)
1078{
1079 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1080 TEE_PARAM_TYPE_NONE,
1081 TEE_PARAM_TYPE_NONE,
1082 TEE_PARAM_TYPE_NONE))
1083 return TEE_ERROR_BAD_PARAMETERS;
1084
1085 os_test_shlib_panic();
1086
1087 return TEE_ERROR_GENERIC;
1088}