blob: 4329ed4c0bd0eb4da6fd2dd5d3f8d1a4b964f58b [file] [log] [blame]
Etienne Carriere75141172020-05-16 11:58:23 +02001// SPDX-License-Identifier: BSD-2-Clause
Pascal Brandc639ac82015-07-02 08:53:34 +02002/*
3 * Copyright (c) 2014, STMicroelectronics International N.V.
4 * All rights reserved.
Pascal Brandc639ac82015-07-02 08:53:34 +02005 */
Pascal Brandc639ac82015-07-02 08:53:34 +02006#include <compiler.h>
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01007#include <dlfcn.h>
Jerome Forissier4565c452020-06-17 17:55:00 +02008#include <link.h>
Jens Wiklander8324ff22018-11-21 14:16:04 +01009#include <setjmp.h>
10#include <stdint.h>
11#include <string.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020012#include <ta_crypt.h>
13#include <ta_os_test.h>
14#include <tee_internal_api_extensions.h>
15
16#include "os_test.h"
Jens Wiklander246184a2015-12-11 08:28:59 +010017#include "test_float_subj.h"
Jerome Forissier53bde722018-05-31 09:14:54 +020018#include "os_test_lib.h"
Pascal Brandc639ac82015-07-02 08:53:34 +020019
20enum p_type {
21 P_TYPE_BOOL,
22 P_TYPE_INT,
23 P_TYPE_UUID,
24 P_TYPE_IDENTITY,
25 P_TYPE_STRING,
26 P_TYPE_BINARY_BLOCK,
27};
28
29struct p_attr {
30 const char *str;
31 enum p_type type;
32 bool retrieved;
33};
34
Pascal Brand624b6a32016-02-16 12:51:34 +010035static TEE_Result check_returned_prop(
Pascal Brandaf77fdd2016-03-08 13:59:01 +010036 int line __maybe_unused, char *prop_name __maybe_unused,
Pascal Brand624b6a32016-02-16 12:51:34 +010037 TEE_Result return_res, TEE_Result expected_res,
38 uint32_t return_len, uint32_t expected_len)
39{
40 if (return_res != expected_res) {
41 EMSG("From line %d (property name=%s): return_res=0x%x vs expected_res=0x%x",
42 line, (prop_name ? prop_name : "unknown"),
43 (unsigned int)return_res, (unsigned int)expected_res);
44 return TEE_ERROR_GENERIC;
45 }
46 if (return_len != expected_len) {
Pascal Brand07bb09f2016-02-19 16:04:10 +010047 EMSG("From line %d (property name=%s): return_len=%u vs expected_res=%u",
48 line, (prop_name ? prop_name : "unknown"),
49 return_len, expected_len);
Pascal Brand624b6a32016-02-16 12:51:34 +010050 return TEE_ERROR_GENERIC;
51 }
52 return TEE_SUCCESS;
53}
54
Etienne Carriere58e3a832020-07-08 16:56:01 +020055static TEE_Result check_binprop_ones(size_t size, char *bbuf, size_t bblen)
Etienne Carriereb34caff2020-05-26 09:25:35 +020056{
Etienne Carriere58e3a832020-07-08 16:56:01 +020057 char ones[4] = { 0xff, 0xff, 0xff, 0xff };
Etienne Carriereb34caff2020-05-26 09:25:35 +020058
59 if (size > 4 || bblen != size) {
60 EMSG("Size error (size=%zu, bblen=%zu)", size, bblen);
61 return TEE_ERROR_GENERIC;
62 }
63 if (strncmp(bbuf, ones, bblen)) {
64 EMSG("Unexpected content");
65 DHEXDUMP(bbuf, bblen);
66 return TEE_ERROR_GENERIC;
67 }
68 return TEE_SUCCESS;
69}
70
71static TEE_Result get_binblock_property(TEE_PropSetHandle h,
Etienne Carriere58e3a832020-07-08 16:56:01 +020072 char *nbuf, char **bbuf, size_t *bblen)
Etienne Carriereb34caff2020-05-26 09:25:35 +020073{
74 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriere58e3a832020-07-08 16:56:01 +020075 uint32_t block_len = 0;
Etienne Carriereb34caff2020-05-26 09:25:35 +020076
77 *bbuf = NULL;
78 *bblen = 0;
Etienne Carriere58e3a832020-07-08 16:56:01 +020079 res = TEE_GetPropertyAsBinaryBlock(h, NULL, *bbuf, &block_len);
Etienne Carriereb34caff2020-05-26 09:25:35 +020080
Etienne Carriere58e3a832020-07-08 16:56:01 +020081 if (res == TEE_SUCCESS && !block_len)
Etienne Carriereb34caff2020-05-26 09:25:35 +020082 return TEE_SUCCESS;
83
84 if (res != TEE_ERROR_SHORT_BUFFER) {
85 EMSG("TEE_GetPropertyAsBinaryBlock() size query returned 0x%x",
86 (unsigned int)res);
87 return res ? res : TEE_ERROR_GENERIC;
88 }
89
Etienne Carriere58e3a832020-07-08 16:56:01 +020090 *bbuf = TEE_Malloc(block_len, TEE_MALLOC_FILL_ZERO);
Etienne Carriereb34caff2020-05-26 09:25:35 +020091 if (!bbuf)
92 return TEE_ERROR_OUT_OF_MEMORY;
93
Etienne Carriere58e3a832020-07-08 16:56:01 +020094 res = TEE_GetPropertyAsBinaryBlock(h, NULL, *bbuf, &block_len);
Etienne Carriereb34caff2020-05-26 09:25:35 +020095 if (res != TEE_SUCCESS)
96 EMSG("TEE_GetPropertyAsBinaryBlock(\"%s\") returned 0x%x",
97 nbuf, (unsigned int)res);
Etienne Carriere58e3a832020-07-08 16:56:01 +020098 else
99 *bblen = block_len;
Etienne Carriereb34caff2020-05-26 09:25:35 +0200100
101 return res;
102}
103
Pascal Brandc639ac82015-07-02 08:53:34 +0200104static TEE_Result print_properties(TEE_PropSetHandle h,
105 TEE_PropSetHandle prop_set,
106 struct p_attr *p_attrs, size_t num_p_attrs)
107{
Etienne Carriere102092e2019-03-28 15:24:22 +0100108TEE_Result res = TEE_ERROR_GENERIC;
109size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200110
111TEE_StartPropertyEnumerator(h, prop_set);
112
113while (true) {
Etienne Carriere102092e2019-03-28 15:24:22 +0100114 char nbuf[256] = { };
115 char nbuf_small[256] = { };
116 char vbuf[256] = { };
117 char vbuf2[256] = { };
Jens Wiklanderc5231592015-11-11 09:27:27 +0100118 uint32_t nblen = sizeof(nbuf);
Etienne Carriere102092e2019-03-28 15:24:22 +0100119 uint32_t nblen_small = 0;
Jens Wiklanderc5231592015-11-11 09:27:27 +0100120 uint32_t vblen = sizeof(vbuf);
121 uint32_t vblen2 = sizeof(vbuf2);
Etienne Carriere58e3a832020-07-08 16:56:01 +0200122 char *bbuf = NULL;
Etienne Carriereb34caff2020-05-26 09:25:35 +0200123 size_t bblen = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200124
125 res = TEE_GetPropertyName(h, nbuf, &nblen);
126 if (res != TEE_SUCCESS) {
127 EMSG("TEE_GetPropertyName returned 0x%x\n",
128 (unsigned int)res);
129 return res;
130 }
Pascal Brand624b6a32016-02-16 12:51:34 +0100131 if (nblen != strlen(nbuf) + 1) {
Pascal Brand5b68cd62016-02-22 10:31:01 +0100132 EMSG("Name has wrong size: %u vs %zu", nblen, strlen(nbuf) + 1);
Pascal Brand624b6a32016-02-16 12:51:34 +0100133 return TEE_ERROR_GENERIC;
134 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200135
Pascal Brand624b6a32016-02-16 12:51:34 +0100136
137 /* Get the property name with a very small buffer */
138 nblen_small = 2;
139 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
140 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
141 nblen_small, nblen);
142 if (res != TEE_SUCCESS)
143 return res;
144
145 /* Get the property name with almost the correct buffer */
146 nblen_small = nblen - 1;
147 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
148 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
149 nblen_small, nblen);
150 if (res != TEE_SUCCESS)
151 return res;
152
153 /* Get the property name with the exact buffer length */
154 nblen_small = nblen;
155 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
156 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
157 nblen_small, nblen);
158 if (res != TEE_SUCCESS)
159 return res;
160
161 /* Get the property value */
Pascal Brandc639ac82015-07-02 08:53:34 +0200162 res = TEE_GetPropertyAsString(h, NULL, vbuf, &vblen);
Pascal Brand624b6a32016-02-16 12:51:34 +0100163 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
164 vblen, strlen(vbuf) + 1);
165 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200166 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100167
Pascal Brandc639ac82015-07-02 08:53:34 +0200168 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
Pascal Brand624b6a32016-02-16 12:51:34 +0100169 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
170 vblen2, strlen(vbuf2) + 1);
171 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200172 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100173
Jens Wiklander8324ff22018-11-21 14:16:04 +0100174 if (strcmp(vbuf, vbuf2) != 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200175 EMSG("String of \"%s\" differs\n", nbuf);
176 return TEE_ERROR_GENERIC;
177 }
178
Pascal Brand624b6a32016-02-16 12:51:34 +0100179 /* Get the property with a very small buffer */
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200180 if (vblen > 1) {
181 vblen2 = 1;
182 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
183 res = check_returned_prop(__LINE__, nbuf, res,
184 TEE_ERROR_SHORT_BUFFER,
185 vblen2, vblen);
186 if (res != TEE_SUCCESS)
187 return res;
188 }
Pascal Brand624b6a32016-02-16 12:51:34 +0100189
190 /* Get the property with almost the correct buffer */
191 vblen2 = vblen - 1;
192 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
193 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
194 vblen2, vblen);
195 if (res != TEE_SUCCESS)
196 return res;
197
198 /* Get the property name with the exact buffer length */
199 vblen2 = vblen;
200 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
201 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS, vblen2, vblen);
202 if (res != TEE_SUCCESS)
203 return res;
204
205 /* check specific myprop.hello property, which is larger than 80 */
206 if (!strcmp("myprop.hello", nbuf) &&
207 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")) {
208 EMSG("TEE_GetPropertyAsString(\"%s\") is truncated - returned \"%s\"\n",
209 nbuf, vbuf);
210 return TEE_ERROR_GENERIC;
211 }
212
Pascal Brandc639ac82015-07-02 08:53:34 +0200213 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
214
215 for (n = 0; n < num_p_attrs; n++) {
Jens Wiklander8324ff22018-11-21 14:16:04 +0100216 if (strcmp(nbuf, p_attrs[n].str) != 0)
Pascal Brandc639ac82015-07-02 08:53:34 +0200217 continue;
218
219 if (p_attrs[n].retrieved) {
220 EMSG("Value \"%s\" already retrieved\n",
221 p_attrs[n].str);
222 return TEE_ERROR_GENERIC;
223 }
224 p_attrs[n].retrieved = true;
225
226 switch (p_attrs[n].type) {
227 case P_TYPE_BOOL:
228 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100229 bool v = false;
Pascal Brandc639ac82015-07-02 08:53:34 +0200230
231 res =
232 TEE_GetPropertyAsBool(h, NULL, &v);
233 if (res != TEE_SUCCESS) {
234 EMSG(
235 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
236 nbuf, (unsigned int)res);
237 return res;
238 }
239 }
240 break;
241
242 case P_TYPE_INT:
243 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100244 uint32_t v = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200245
246 res = TEE_GetPropertyAsU32(h, NULL, &v);
247 if (res != TEE_SUCCESS) {
248 EMSG(
249 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
250 nbuf, (unsigned int)res);
251 return res;
252 }
253 }
254 break;
255
256 case P_TYPE_UUID:
257 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100258 TEE_UUID v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200259
260 res =
261 TEE_GetPropertyAsUUID(h, NULL, &v);
262 if (res != TEE_SUCCESS) {
263 EMSG(
264 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
265 nbuf, (unsigned int)res);
266 return res;
267 }
268 }
269 break;
270
271 case P_TYPE_IDENTITY:
272 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100273 TEE_Identity v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200274
275 res =
276 TEE_GetPropertyAsIdentity(h, NULL,
277 &v);
278 if (res != TEE_SUCCESS) {
279 EMSG(
280 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
281 nbuf, (unsigned int)res);
282 return res;
283 }
284 }
285 break;
286
287 case P_TYPE_STRING:
288 /* Already read as string */
289 break;
290
291 case P_TYPE_BINARY_BLOCK:
Etienne Carriereb34caff2020-05-26 09:25:35 +0200292 res = get_binblock_property(h, nbuf, &bbuf, &bblen);
293 if (res)
294 return res;
Pascal Brandc639ac82015-07-02 08:53:34 +0200295
Etienne Carriereb34caff2020-05-26 09:25:35 +0200296 if (!strcmp("myprop.binaryblock", nbuf)) {
297 const char exp_bin_value[] = "Hello world!";
298
299 if (bblen != strlen(exp_bin_value) ||
300 TEE_MemCompare(exp_bin_value, bbuf,
301 bblen)) {
302 EMSG("Binary buffer of \"%s\" differs from \"%s\"",
303 nbuf, exp_bin_value);
304 EMSG("Got \"%s\"", bbuf);
305 return TEE_ERROR_GENERIC;
306 }
307 } else if (!strcmp("myprop.binaryblock.1byte-ones",
308 nbuf)) {
309 res = check_binprop_ones(1, bbuf, bblen);
310 if (res)
Pascal Brandc639ac82015-07-02 08:53:34 +0200311 return res;
Etienne Carriereb34caff2020-05-26 09:25:35 +0200312 } else if (!strcmp("myprop.binaryblock.2byte-ones",
313 nbuf)) {
314 res = check_binprop_ones(2, bbuf, bblen);
315 if (res)
316 return res;
317 } else if (!strcmp("myprop.binaryblock.3byte-ones",
318 nbuf)) {
319 res = check_binprop_ones(3, bbuf, bblen);
320 if (res)
321 return res;
322 } else if (!strcmp("myprop.binaryblock.4byte-ones",
323 nbuf)) {
324 res = check_binprop_ones(4, bbuf, bblen);
325 if (res)
326 return res;
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200327 } else if (!strcmp("myprop.binaryblock.empty1", nbuf) ||
328 !strcmp("myprop.binaryblock.empty2", nbuf) ||
329 !strcmp("myprop.binaryblock.empty3", nbuf)) {
330 if (bblen) {
331 EMSG("Property \"%s\": %zu byte(s)",
332 nbuf, bblen);
333 return TEE_ERROR_GENERIC;
334 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200335 } else {
336 EMSG("Unexpected property \"%s\"", nbuf);
337 TEE_Panic(0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200338 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200339
340 TEE_Free(bbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200341 break;
342
343 default:
344 EMSG("Unknown type (%d) for \"%s\"\n",
345 p_attrs[n].type, p_attrs[n].str);
346 return TEE_ERROR_GENERIC;
347 }
348 }
349
350 res = TEE_GetNextProperty(h);
351 if (res != TEE_SUCCESS) {
352 if (res == TEE_ERROR_ITEM_NOT_FOUND)
353 return TEE_SUCCESS;
354 return res;
355 }
356}
357}
358
359static TEE_Result test_malloc(void)
360{
361 void *p = TEE_Malloc(4, 0);
362
363 if (p == NULL) {
364 EMSG("TEE_Malloc failed\n");
365 return TEE_ERROR_OUT_OF_MEMORY;
366 }
367 TEE_Free(p);
368 TEE_Free(NULL);
369
370 return TEE_SUCCESS;
371}
372
373static TEE_Result test_properties(void)
374{
375 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriere102092e2019-03-28 15:24:22 +0100376 TEE_PropSetHandle h = TEE_HANDLE_NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200377 struct p_attr p_attrs[] = {
378 {"gpd.ta.appID", P_TYPE_UUID},
379 {"gpd.ta.singleInstance", P_TYPE_BOOL},
380 {"gpd.ta.multiSession", P_TYPE_BOOL},
381 {"gpd.ta.instanceKeepAlive", P_TYPE_BOOL},
382 {"gpd.ta.dataSize", P_TYPE_INT},
383 {"gpd.ta.stackSize", P_TYPE_INT},
384 {"gpd.ta.version", P_TYPE_STRING},
385 {"gpd.ta.description", P_TYPE_STRING},
386 {"gpd.client.identity", P_TYPE_IDENTITY},
387 {"gpd.tee.apiversion", P_TYPE_STRING},
388 {"gpd.tee.description", P_TYPE_STRING},
389 {"gpd.tee.deviceID", P_TYPE_UUID},
390 {"gpd.tee.systemTime.protectionLevel", P_TYPE_INT},
391 {"gpd.tee.TAPersistentTime.protectionLevel", P_TYPE_INT},
392 {"gpd.tee.arith.maxBigIntSize", P_TYPE_INT},
393 {"gpd.tee.cryptography.ecc", P_TYPE_BOOL},
394 {"gpd.tee.trustedStorage.antiRollback.protectionLevel", P_TYPE_INT},
395 {"gpd.tee.trustedos.implementation.version", P_TYPE_STRING},
396 {"gpd.tee.trustedos.implementation.binaryversion", P_TYPE_INT},
397 {"gpd.tee.trustedos.manufacturer", P_TYPE_STRING},
398 {"gpd.tee.firmware.implementation.version", P_TYPE_STRING},
399 {"gpd.tee.firmware.implementation.binaryversion", P_TYPE_INT},
400 {"gpd.tee.firmware.manufacturer", P_TYPE_STRING},
401 {"myprop.true", P_TYPE_BOOL},
402 {"myprop.42", P_TYPE_INT},
403 {"myprop.123", P_TYPE_UUID},
404 {"myprop.1234", P_TYPE_IDENTITY},
405 {"myprop.hello", P_TYPE_STRING},
406 {"myprop.binaryblock", P_TYPE_BINARY_BLOCK},
Etienne Carriereb34caff2020-05-26 09:25:35 +0200407 {"myprop.binaryblock.1byte-ones", P_TYPE_BINARY_BLOCK},
408 {"myprop.binaryblock.2byte-ones", P_TYPE_BINARY_BLOCK},
409 {"myprop.binaryblock.3byte-ones", P_TYPE_BINARY_BLOCK},
410 {"myprop.binaryblock.4byte-ones", P_TYPE_BINARY_BLOCK},
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200411 {"myprop.binaryblock.empty1", P_TYPE_BINARY_BLOCK},
412 {"myprop.binaryblock.empty2", P_TYPE_BINARY_BLOCK},
413 {"myprop.binaryblock.empty3", P_TYPE_BINARY_BLOCK},
Pascal Brandc639ac82015-07-02 08:53:34 +0200414 };
415 const size_t num_p_attrs = sizeof(p_attrs) / sizeof(p_attrs[0]);
Etienne Carriere102092e2019-03-28 15:24:22 +0100416 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200417
418 res = TEE_AllocatePropertyEnumerator(&h);
419 if (res != TEE_SUCCESS) {
420 EMSG("TEE_AllocatePropertyEnumerator: returned 0x%x\n",
421 (unsigned int)res);
422 return TEE_ERROR_GENERIC;
423 }
424
425 printf("Getting properties for current TA\n");
426 res = print_properties(h, TEE_PROPSET_CURRENT_TA, p_attrs, num_p_attrs);
427 if (res != TEE_SUCCESS)
428 goto cleanup_return;
429
430 printf("Getting properties for current client\n");
431 res = print_properties(h, TEE_PROPSET_CURRENT_CLIENT, p_attrs,
432 num_p_attrs);
433 if (res != TEE_SUCCESS)
434 goto cleanup_return;
435
436 printf("Getting properties for implementation\n");
437 res = print_properties(h, TEE_PROPSET_TEE_IMPLEMENTATION, p_attrs,
438 num_p_attrs);
439 if (res != TEE_SUCCESS)
440 goto cleanup_return;
441
442 for (n = 0; n < num_p_attrs; n++) {
443 if (!p_attrs[n].retrieved) {
444 EMSG("\"%s\" not retrieved\n", p_attrs[n].str);
445 res = TEE_ERROR_GENERIC;
446 goto cleanup_return;
447 }
448 }
449
450cleanup_return:
451 TEE_FreePropertyEnumerator(h);
452 return res;
453}
454
455static TEE_Result test_mem_access_right(uint32_t param_types,
456 TEE_Param params[4])
457{
458 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100459 TEE_Result res = TEE_ERROR_GENERIC;
460 uint32_t ret_orig = 0;
461 uint32_t l_pts = 0;
462 TEE_Param l_params[4] = { };
463 uint8_t buf[32] = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200464 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100465 TEE_UUID *uuid = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200466
467 if (param_types !=
468 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
469 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200470
471 /* test access rights on memref parameter */
472 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
473 TEE_MEMORY_ACCESS_ANY_OWNER,
474 params[0].memref.buffer,
475 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200476 if (res != TEE_SUCCESS)
477 return res;
Etienne Carriere281065d2016-10-28 15:41:33 +0200478
Pascal Brandc639ac82015-07-02 08:53:34 +0200479 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
480 params[0].memref.buffer,
481 params[0].memref.size);
482 if (res != TEE_ERROR_ACCESS_DENIED)
483 return TEE_ERROR_GENERIC;
484
Etienne Carriere281065d2016-10-28 15:41:33 +0200485 /* test access rights on private read-only and read-write memory */
486 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
487 (void *)&test_uuid, sizeof(test_uuid));
488 if (res != TEE_SUCCESS)
489 return res;
490
491 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_WRITE,
492 (void *)&test_uuid, sizeof(test_uuid));
493 if (res == TEE_SUCCESS)
494 return TEE_ERROR_GENERIC;
495
496 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
497 TEE_MEMORY_ACCESS_WRITE,
498 &ret_orig, sizeof(ret_orig));
499 if (res != TEE_SUCCESS)
500 return res;
501
502 uuid = TEE_Malloc(sizeof(*uuid), 0);
503 if (!uuid)
504 return TEE_ERROR_OUT_OF_MEMORY;
505
506 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
507 TEE_MEMORY_ACCESS_WRITE,
508 uuid, sizeof(*uuid));
509 TEE_Free(uuid);
510 if (res != TEE_SUCCESS)
511 return res;
512
513 /* test access rights on invalid memory (at least lower 256kB) */
514 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
515 NULL, 1);
516 if (res == TEE_SUCCESS)
517 return TEE_ERROR_GENERIC;
518
519 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
520 (void*)(256 * 1024), 1);
521 if (res == TEE_SUCCESS)
522 return TEE_ERROR_GENERIC;
523
Cedric Augere668b3f2019-09-11 13:41:21 +0200524 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
525 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200526 if (res != TEE_SUCCESS) {
527 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
528 goto cleanup_return;
529 }
530
Jerome Forissier04511d82018-01-30 14:33:49 +0100531 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
532 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200533 l_params[0].memref.buffer = buf;
534 l_params[0].memref.size = sizeof(buf);
Jerome Forissier04511d82018-01-30 14:33:49 +0100535 l_params[1].memref.buffer = NULL;
536 l_params[1].memref.size = 0;
Cedric Augere668b3f2019-09-11 13:41:21 +0200537 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
538 TA_OS_TEST_CMD_PARAMS_ACCESS,
Pascal Brandc639ac82015-07-02 08:53:34 +0200539 l_pts, l_params, &ret_orig);
540 if (res != TEE_SUCCESS) {
541 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
542 goto cleanup_return;
543 }
544
545cleanup_return:
546 TEE_CloseTASession(sess);
547 return res;
548}
549
550static TEE_Result test_time(void)
551{
Etienne Carriere102092e2019-03-28 15:24:22 +0100552 TEE_Result res = TEE_ERROR_GENERIC;
553 TEE_Time t = { };
554 TEE_Time sys_t = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200555 static const TEE_Time null_time = { 0, 0 };
556 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
557
558 TEE_GetSystemTime(&sys_t);
559 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
560 (unsigned int)sys_t.millis);
561
562 TEE_GetREETime(&t);
563 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
564 (unsigned int)t.millis);
565
566 res = TEE_GetTAPersistentTime(&t);
567 switch (res) {
568 case TEE_SUCCESS:
569 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
570 (unsigned int)t.millis);
571 break;
572 case TEE_ERROR_OVERFLOW:
573 EMSG("Stored TA time overflowed %u.%03u\n",
574 (unsigned int)t.seconds, (unsigned int)t.millis);
575 break;
576 case TEE_ERROR_TIME_NOT_SET:
577 EMSG("TA time not stored\n");
578 break;
579 case TEE_ERROR_TIME_NEEDS_RESET:
580 EMSG("TA time needs reset\n");
581 break;
582 default:
583 return res;
584 }
585
586 res = TEE_SetTAPersistentTime(&null_time);
587 if (res != TEE_SUCCESS) {
588 EMSG("TEE_SetTAPersistentTime: failed\n");
589 return res;
590 }
591
592 res = TEE_GetTAPersistentTime(&t);
593 if (res != TEE_SUCCESS) {
594 EMSG("TEE_GetTAPersistentTime null: failed\n");
595 return res;
596 }
597 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
598 (unsigned int)t.millis);
599 /*
600 * The time between TEE_SetTAPersistentTime() and
601 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
602 * it's not even a millisecond.
603 */
604 if (t.seconds > 1 || t.millis >= 1000) {
605 EMSG("Unexpected stored TA time %u.%03u\n",
606 (unsigned int)t.seconds, (unsigned int)t.millis);
607 return TEE_ERROR_BAD_STATE;
608 }
609
610 res = TEE_SetTAPersistentTime(&wrap_time);
611 if (res != TEE_SUCCESS) {
612 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
613 return res;
614 }
615
616 res = TEE_Wait(1000);
617 if (res != TEE_SUCCESS)
618 EMSG("TEE_Wait wrap: failed\n");
619
620 res = TEE_GetTAPersistentTime(&t);
621 if (res != TEE_ERROR_OVERFLOW) {
622 EMSG("TEE_GetTAPersistentTime: failed\n");
623 return TEE_ERROR_BAD_STATE;
624 }
625 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
626 (unsigned int)t.millis);
627
628 if (t.seconds > sys_t.seconds) {
629 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
630 (unsigned int)t.seconds, (unsigned int)t.millis,
631 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
632 return TEE_ERROR_BAD_STATE;
633 }
634
635 return TEE_SUCCESS;
636}
637
Jens Wiklander246184a2015-12-11 08:28:59 +0100638#ifdef CFG_TA_FLOAT_SUPPORT
639static bool my_dcmpeq(double v1, double v2, double prec)
640{
641 return v1 > (v2 - prec) && v1 < (v2 + prec);
642}
643
644static bool my_fcmpeq(float v1, float v2, float prec)
645{
646 return v1 > (v2 - prec) && v1 < (v2 + prec);
647}
648
649
650static TEE_Result test_float(void)
651{
652#define VAL1 2.6
653#define VAL1_INT 2
654#define VAL2 5.3
655#define DPREC 0.000000000000001
656#define FPREC 0.000001
657#define EXPECT(expr) do { \
658 if (!(expr)) { \
659 EMSG("Expression %s failed", #expr); \
660 return TEE_ERROR_GENERIC; \
661 } \
662 } while (0)
663
664 IMSG("Testing floating point operations");
665
666 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
667 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
668 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
669 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
670 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
671
672 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
673 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
674 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
675 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
676 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
677
678 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
679 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
680 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
681 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
682 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
683
684 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
685 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
686 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
687 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
688 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
689
690 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
691 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
692 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
693 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
694
695 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
696 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
697 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
698 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
699
700 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
701 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
702
703 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
704 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
705 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
706 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
707
708 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
709 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
710 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
711 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
712 return TEE_SUCCESS;
713}
714#else /*CFG_TA_FLOAT_SUPPORT*/
715static TEE_Result test_float(void)
716{
717 IMSG("Floating point disabled");
718 return TEE_SUCCESS;
719}
720#endif /*CFG_TA_FLOAT_SUPPORT*/
721
Jerome Forissier892ae4d2020-03-09 09:58:09 +0100722static __noinline __noreturn void call_longjmp(jmp_buf env)
Jens Wiklander9f682c62016-03-27 20:23:06 +0200723{
724 DMSG("Calling longjmp");
725 longjmp(env, 1);
726 EMSG("error: longjmp returned to calling function");
727}
728
729static TEE_Result test_setjmp(void)
730{
Etienne Carriere102092e2019-03-28 15:24:22 +0100731 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200732
733 if (setjmp(env)) {
734 IMSG("Returned via longjmp");
735 return TEE_SUCCESS;
736 } else {
737 call_longjmp(env);
738 return TEE_ERROR_GENERIC;
739 }
740}
741
Pascal Brandc639ac82015-07-02 08:53:34 +0200742TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
743{
744 TEE_Result res = TEE_ERROR_GENERIC;
745
746 printf("ta_entry_basic: enter\n");
747
748 res = test_malloc();
749 if (res != TEE_SUCCESS)
750 return res;
751
752 res = test_properties();
753 if (res != TEE_SUCCESS)
754 return res;
755
756 res = test_mem_access_right(param_types, params);
757 if (res != TEE_SUCCESS)
758 return res;
759
760 res = test_time();
761 if (res != TEE_SUCCESS)
762 return res;
763
Jens Wiklander246184a2015-12-11 08:28:59 +0100764 res = test_float();
765 if (res != TEE_SUCCESS)
766 return res;
767
Jens Wiklander9f682c62016-03-27 20:23:06 +0200768 res = test_setjmp();
769 if (res != TEE_SUCCESS)
770 return res;
771
Pascal Brandc639ac82015-07-02 08:53:34 +0200772 return TEE_SUCCESS;
773}
774
775TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
776{
777 volatile bool mytrue = true;
778 (void)param_types;
779 (void)params;
780
781 printf("ta_entry_panic: enter\n");
782 /*
783 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
784 * the __noreturn attribute.
785 */
786 if (mytrue)
787 TEE_Panic(0xbeef);
788
789 /*
790 * Should not be reached, but if it is the testsuite can detect that
791 * TEE_Panic() returned instead of panicking the TA.
792 */
793 return TEE_SUCCESS;
794}
795
796TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
797 TEE_Param params[4])
798{
799 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100800 TEE_Result res = TEE_ERROR_GENERIC;
801 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
802 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200803
804 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
805 TEE_PARAM_TYPE_NONE,
806 TEE_PARAM_TYPE_NONE,
807 TEE_PARAM_TYPE_NONE)) {
808 EMSG("ta_entry_client_with_timeout: bad parameters\n");
809 return TEE_ERROR_BAD_PARAMETERS;
810 }
811
Cedric Augere668b3f2019-09-11 13:41:21 +0200812 res = TEE_OpenTASession(&os_test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
813 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200814 if (res != TEE_SUCCESS) {
815 EMSG(
816 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
817 return res;
818 }
819
820 res =
821 TEE_InvokeTACommand(sess, params[0].value.a / 2,
822 TA_OS_TEST_CMD_WAIT, param_types, params,
823 &ret_orig);
824
825 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
826 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
827 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
828 (unsigned int)ret_orig);
829 res = TEE_ERROR_GENERIC;
830 } else
831 res = TEE_SUCCESS;
832
833 TEE_CloseTASession(sess);
834 return res;
835
836}
837
838TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
839{
840 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100841 TEE_Result res = TEE_ERROR_GENERIC;
842 uint32_t l_pts = 0;
843 TEE_Param l_params[4] = { };
844 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
845 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200846 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
847 static const uint8_t sha256_out[] = {
848 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
849 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
850 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
851 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
852 };
853 uint8_t out[32] = { 0 };
854 void *in = NULL;
855
856 (void)param_types;
857 (void)params;
858
859 printf("ta_entry_client: enter\n");
860
861 in = TEE_Malloc(sizeof(sha256_in), 0);
862 if (in == NULL)
863 return TEE_ERROR_OUT_OF_MEMORY;
864 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
865
Cedric Augere668b3f2019-09-11 13:41:21 +0200866 res = TEE_OpenTASession(&crypt_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
867 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200868 if (res != TEE_SUCCESS) {
869 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
870 goto cleanup_return;
871 }
872
873 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
874 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
875 l_params[0].memref.buffer = in;
876 l_params[0].memref.size = sizeof(sha256_in);
877 l_params[1].memref.buffer = out;
878 l_params[1].memref.size = sizeof(out);
879
Cedric Augere668b3f2019-09-11 13:41:21 +0200880 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
881 TA_CRYPT_CMD_SHA256, l_pts, l_params,
Pascal Brandc639ac82015-07-02 08:53:34 +0200882 &ret_orig);
883 if (res != TEE_SUCCESS) {
884 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
885 goto cleanup_return;
886 }
887
888 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
889 EMSG("ta_entry_client: out parameter failed\n");
890 res = TEE_ERROR_GENERIC;
891 goto cleanup_return;
892 }
893
894cleanup_return:
895 TEE_Free(in);
896 TEE_CloseTASession(sess);
897 return res;
898}
899
Etienne Carriere281065d2016-10-28 15:41:33 +0200900TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200901{
Etienne Carriere102092e2019-03-28 15:24:22 +0100902 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200903
904 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100905 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
906 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200907 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200908
909 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
910 TEE_MEMORY_ACCESS_ANY_OWNER,
911 params[0].memref.buffer,
912 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200913 if (res != TEE_SUCCESS)
914 return res;
915
916 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
917 params[0].memref.buffer,
918 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200919 if (res != TEE_ERROR_ACCESS_DENIED)
920 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +0100921 if (params[1].memref.buffer || params[1].memref.size)
922 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200923
Etienne Carriere281065d2016-10-28 15:41:33 +0200924 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200925}
926
927TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
928{
929 TEE_Result res = TEE_SUCCESS;
930 (void)param_types;
931
932 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
933 /* Wait */
934 res = TEE_Wait(params[0].value.a);
935
936 return res;
937}
938
Jens Wiklander1425f952016-07-21 09:02:30 +0200939static void undef_instr(void)
940{
941#if defined(ARM64)
942 __asm__(".word 0x0");
943#elif defined(ARM32)
944 __asm__(".word 0xe7ffffff");
945#else
946#error "Unsupported architecture"
947#endif
948}
949
Pascal Brandc639ac82015-07-02 08:53:34 +0200950TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
951{
Etienne Carriere102092e2019-03-28 15:24:22 +0100952 long int stack = 0;
953 long int stack_addr = (long int)&stack;
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200954 void (*volatile null_fn_ptr)(void) = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200955
Etienne Carriere92c34422018-02-09 13:11:40 +0100956 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
957 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
958 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200959 return TEE_ERROR_GENERIC;
960
961 switch (params[0].value.a) {
962 case 1:
Jerome Forissier71da60f2019-09-19 15:59:56 +0200963 *((volatile uint32_t *)0) = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200964 break;
965 case 2:
966 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
967 break;
968 case 3:
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200969 null_fn_ptr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200970 break;
971 case 4:
972 ((void (*)(void))(stack_addr + 0x40000000)) ();
973 break;
974 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +0200975 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +0200976 break;
977 default:
978 break;
979 }
980
981 return TEE_SUCCESS;
982}
Jerome Forissiere916b102017-06-07 17:55:52 +0200983
984static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
985{
Etienne Carriere102092e2019-03-28 15:24:22 +0100986 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +0200987
988 for (i = 0; i < bufsize; i++) {
989 a[i]++; b[i]++; c[i]++;
990 }
991}
992
Etienne Carriere102092e2019-03-28 15:24:22 +0100993#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +0200994TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
995{
996 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
997 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100998 TEE_Param l_params[4] = { };
999 uint8_t in[TA2TA_BUF_SIZE] = { };
1000 uint8_t inout[TA2TA_BUF_SIZE] = { };
1001 uint8_t out[TA2TA_BUF_SIZE] = { };
1002 TEE_Result res = TEE_ERROR_GENERIC;
1003 uint32_t ret_orig = 0;
1004 uint32_t l_pts = 0;
1005 size_t i = 0;
1006
Jerome Forissiere916b102017-06-07 17:55:52 +02001007 (void)params;
1008
1009 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
1010 return TEE_ERROR_GENERIC;
1011
Cedric Augere668b3f2019-09-11 13:41:21 +02001012 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
1013 &sess, &ret_orig);
Jerome Forissiere916b102017-06-07 17:55:52 +02001014 if (res != TEE_SUCCESS) {
1015 EMSG("TEE_OpenTASession failed");
1016 goto cleanup_return;
1017 }
1018
1019 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1020 TEE_PARAM_TYPE_MEMREF_INOUT,
1021 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
1022 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +01001023 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001024 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +01001025 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001026 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +01001027 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001028
1029 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +01001030 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001031 in[i] = 5;
1032 inout[i] = 10;
1033 out[i] = 0;
1034 }
1035
1036 /*
1037 * TA will compute: out = ++inout + in
1038 * Expected values after this step: in: 5, inout: 11, out: 16
1039 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001040 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1041 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001042 l_pts, l_params, &ret_orig);
1043 if (res != TEE_SUCCESS) {
1044 EMSG("TEE_InvokeTACommand failed");
1045 goto cleanup_return;
1046 }
Etienne Carriere102092e2019-03-28 15:24:22 +01001047
Jerome Forissiere916b102017-06-07 17:55:52 +02001048 /*
1049 * Increment all values by one.
1050 * Expected values after this step: in: 6, inout: 12, out: 17
1051 */
Etienne Carriere102092e2019-03-28 15:24:22 +01001052 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +02001053
1054 /*
1055 * TA will compute: out = ++inout + in
1056 * Expected values after this step: in: 6, inout: 13, out: 19
1057 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001058 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1059 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001060 l_pts, l_params, &ret_orig);
1061 if (res != TEE_SUCCESS) {
1062 EMSG("TEE_InvokeTACommand failed");
1063 goto cleanup_return;
1064 }
1065
1066 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001067 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001068 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1069 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001070 DHEXDUMP(in, TA2TA_BUF_SIZE);
1071 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1072 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001073 return TEE_ERROR_GENERIC;
1074 }
1075 }
1076
1077cleanup_return:
1078 TEE_CloseTASession(sess);
1079 return res;
1080}
1081
1082TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1083{
Etienne Carriere102092e2019-03-28 15:24:22 +01001084 uint8_t *in = NULL;
1085 uint8_t *inout = NULL;
1086 uint8_t *out = NULL;
1087 size_t bufsize = 0;
1088 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001089
1090 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1091 TEE_PARAM_TYPE_MEMREF_INOUT,
1092 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1093 return TEE_ERROR_GENERIC;
1094
1095 bufsize = params[0].memref.size;
1096 if (params[1].memref.size != bufsize ||
1097 params[2].memref.size != bufsize)
1098 return TEE_ERROR_GENERIC;
1099
1100 in = params[0].memref.buffer;
1101 inout = params[1].memref.buffer;
1102 out = params[2].memref.buffer;
1103
1104 for (i = 0; i < bufsize; i++)
1105 out[i] = ++inout[i] + in[i];
1106
1107 return TEE_SUCCESS;
1108}
Jens Wiklander87e81702018-03-20 12:00:00 +08001109
1110TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1111{
Etienne Carriere102092e2019-03-28 15:24:22 +01001112 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001113
1114 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1115 TEE_PARAM_TYPE_MEMREF_INPUT,
1116 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1117 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1118 return TEE_ERROR_BAD_PARAMETERS;
1119
1120 for (n = 0; n < TEE_NUM_PARAMS; n++)
1121 if (!params[n].memref.buffer || !params[n].memref.size)
1122 return TEE_ERROR_BAD_PARAMETERS;
1123
1124 return TEE_SUCCESS;
1125}
Jerome Forissier53bde722018-05-31 09:14:54 +02001126
Cedric Neveux9f483bb2019-03-04 08:58:06 +01001127TEE_Result ta_entry_null_memref(uint32_t param_types, TEE_Param params[4])
1128{
1129 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1130 TEE_PARAM_TYPE_MEMREF_INPUT,
1131 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1132 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1133 return TEE_ERROR_BAD_PARAMETERS;
1134
1135 /*
1136 * Tests how client can provide null or non-null memref parameters
1137 * param[0] expected as a 0 byte input mapped memeref.
1138 * param[1] expected as a 0 byte input not-mapped memeref.
1139 * param[2] expected as a 0 byte output mapped memeref.
1140 * param[3] expected as a 0 byte output not-mapped memeref.
1141 */
1142 if (!params[0].memref.buffer || params[0].memref.size ||
1143 params[1].memref.buffer || params[1].memref.size ||
1144 !params[2].memref.buffer || params[2].memref.size ||
1145 params[3].memref.buffer || params[3].memref.size)
1146 return TEE_ERROR_BAD_PARAMETERS;
1147
1148 return TEE_SUCCESS;
1149}
1150
Jerome Forissier53bde722018-05-31 09:14:54 +02001151TEE_Result ta_entry_call_lib(uint32_t param_types,
1152 TEE_Param params[4] __unused)
1153{
1154 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1155 TEE_PARAM_TYPE_NONE,
1156 TEE_PARAM_TYPE_NONE,
1157 TEE_PARAM_TYPE_NONE))
1158 return TEE_ERROR_BAD_PARAMETERS;
1159
1160 if (os_test_shlib_add(1, 2) != 3)
1161 return TEE_ERROR_GENERIC;
1162
1163 return TEE_SUCCESS;
1164}
1165
1166TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1167 TEE_Param params[4] __unused)
1168{
1169 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1170 TEE_PARAM_TYPE_NONE,
1171 TEE_PARAM_TYPE_NONE,
1172 TEE_PARAM_TYPE_NONE))
1173 return TEE_ERROR_BAD_PARAMETERS;
1174
1175 os_test_shlib_panic();
1176
1177 return TEE_ERROR_GENERIC;
1178}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001179
1180TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1181 TEE_Param params[4] __unused)
1182{
1183 int (*add_func)(int a, int b) = NULL;
1184 TEE_Result res = TEE_ERROR_GENERIC;
1185 void *handle = NULL;
1186 void *hnull = NULL;
1187
1188 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1189 TEE_PARAM_TYPE_NONE,
1190 TEE_PARAM_TYPE_NONE,
1191 TEE_PARAM_TYPE_NONE))
1192 return TEE_ERROR_BAD_PARAMETERS;
1193
1194 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1195 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1196 if (!handle)
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001197 return TEE_ERROR_GENERIC;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001198
1199 add_func = dlsym(handle, "os_test_shlib_dl_add");
1200 if (!add_func)
1201 goto err;
1202 if (add_func(3, 4) != 7)
1203 goto err;
1204
1205 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001206 if (!hnull)
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001207 goto err;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001208
1209 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1210 if (!add_func)
1211 goto err;
1212 if (add_func(5, 6) != 11)
1213 goto err;
1214
1215 res = TEE_SUCCESS;
1216 dlclose(hnull);
1217err:
1218 dlclose(handle);
1219 return res;
1220}
1221
1222TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1223 TEE_Param params[4] __unused)
1224{
1225 int (*panic_func)(void) = NULL;
1226 void *handle = NULL;
1227 TEE_Result res = TEE_ERROR_GENERIC;
1228
1229 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1230 TEE_PARAM_TYPE_NONE,
1231 TEE_PARAM_TYPE_NONE,
1232 TEE_PARAM_TYPE_NONE))
1233 return TEE_ERROR_BAD_PARAMETERS;
1234
1235 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1236 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1237 if (!handle)
1238 return res;
1239
1240 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1241 if (!panic_func)
1242 goto err;
1243 panic_func();
1244 return TEE_ERROR_GENERIC;
1245err:
1246 dlclose(handle);
1247 return res;
1248}
Jerome Forissiere9571e82020-02-18 15:26:20 +01001249
1250/* ELF initialization/finalization test */
1251
Jerome Forissier391168e2020-06-15 09:52:25 +02001252volatile int os_test_global;
Jerome Forissiere9571e82020-02-18 15:26:20 +01001253
1254static void __attribute__((constructor)) os_test_init(void)
1255{
1256 os_test_global *= 10;
1257 os_test_global += 1;
1258 DMSG("os_test_global=%d", os_test_global);
1259}
1260
1261TEE_Result ta_entry_get_global_var(uint32_t param_types, TEE_Param params[4])
1262{
1263 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1264 TEE_PARAM_TYPE_NONE,
1265 TEE_PARAM_TYPE_NONE,
1266 TEE_PARAM_TYPE_NONE))
1267 return TEE_ERROR_BAD_PARAMETERS;
1268
1269 params[0].value.a = os_test_global;
1270
1271 return TEE_SUCCESS;
1272}
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001273
1274TEE_Result ta_entry_client_identity(uint32_t param_types, TEE_Param params[4])
1275{
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001276 TEE_Result res = TEE_ERROR_GENERIC;
1277 TEE_Identity identity = { };
1278
1279 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1280 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1281 TEE_PARAM_TYPE_NONE,
1282 TEE_PARAM_TYPE_NONE))
1283 return TEE_ERROR_BAD_PARAMETERS;
1284
1285 if (params[1].memref.size < sizeof(TEE_UUID)) {
1286 params[1].memref.size = sizeof(TEE_UUID);
1287 return TEE_ERROR_SHORT_BUFFER;
1288 }
1289
1290 res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
1291 "gpd.client.identity", &identity);
1292 if (res != TEE_SUCCESS) {
1293 EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32, res);
1294 return res;
1295 }
1296
1297 params[0].value.a = identity.login;
1298 memcpy(params[1].memref.buffer, &identity.uuid, sizeof(TEE_UUID));
1299 params[1].memref.size = sizeof(TEE_UUID);
1300
1301 return res;
1302}
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001303
1304__thread int os_test_tls_a;
1305__thread int os_test_tls_b = 42;
1306
1307TEE_Result ta_entry_tls_test_main(void)
1308{
1309 if (os_test_tls_a != 0) {
1310 EMSG("os_test_tls_a=%d, expected 0", os_test_tls_a);
1311 return TEE_ERROR_GENERIC;
1312 }
1313 if (os_test_tls_b != 42) {
1314 EMSG("os_test_tls_b=%d, expected 42", os_test_tls_b);
1315 return TEE_ERROR_GENERIC;
1316 }
1317
1318 return TEE_SUCCESS;
1319}
1320
1321TEE_Result ta_entry_tls_test_shlib(void)
1322{
1323 if (os_test_shlib_tls_a != 0) {
1324 EMSG("os_test_shlib_tls_a=%d, expected 0", os_test_shlib_tls_a);
1325 return TEE_ERROR_GENERIC;
1326 }
1327 if (os_test_shlib_tls_b != 123) {
1328 EMSG("os_test_shlib_tls_b=%d, expected 123",
1329 os_test_shlib_tls_b);
1330 return TEE_ERROR_GENERIC;
1331 }
1332
1333 return TEE_SUCCESS;
1334}
Jerome Forissier4565c452020-06-17 17:55:00 +02001335
1336static int iterate_hdr_cb(struct dl_phdr_info *info __maybe_unused,
1337 size_t size __unused, void *data)
1338{
1339 int *count = data;
1340
1341 (*count)++;
1342 IMSG("ELF module index: %d", *count);
1343 IMSG(" dlpi_addr=%p", (void *)info->dlpi_addr);
1344 IMSG(" dlpi_name='%s'", info->dlpi_name);
1345 IMSG(" dlpi_phdr=%p", (void *)info->dlpi_phdr);
1346 IMSG(" dlpi_phnum=%hu", info->dlpi_phnum);
1347 IMSG(" dlpi_adds=%llu", info->dlpi_adds);
1348 IMSG(" dlpi_subs=%llu", info->dlpi_subs);
1349 IMSG(" dlpi_tls_modid=%zu", info->dlpi_tls_modid);
1350 IMSG(" dlpi_tls_data=%p", info->dlpi_tls_data);
1351
1352 return 123;
1353}
1354
1355static TEE_Result expect_dl_count_ge(size_t exp_count)
1356{
1357 int st = 0;
1358 size_t count = 0;
1359
1360 st = dl_iterate_phdr(iterate_hdr_cb, (void *)&count);
1361 if (st != 123) {
1362 /*
1363 * dl_iterate_phdr() should return the last value returned by
1364 * the callback
1365 */
1366 EMSG("Expected return value 123, got %d", st);
1367 return TEE_ERROR_GENERIC;
1368 }
1369 if (count < exp_count) {
1370 /*
1371 * Expect >= and not == since there could be more shared
1372 * libraries (for instance, CFG_ULIBS_SHARED=y)
1373 */
1374 EMSG("Expected count > %zu, got: %zu", exp_count, count);
1375 return TEE_ERROR_GENERIC;
1376 }
1377
1378 return TEE_SUCCESS;
1379}
1380
1381TEE_Result ta_entry_dl_phdr(void)
1382{
1383 return expect_dl_count_ge(2);
1384}
1385
1386TEE_Result ta_entry_dl_phdr_dl(void)
1387{
1388 TEE_Result res = TEE_ERROR_GENERIC;
1389 void *handle = NULL;
1390
1391 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1392 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1393 if (!handle)
1394 return TEE_ERROR_GENERIC;
1395
1396 res = expect_dl_count_ge(3);
1397 dlclose(handle);
1398
1399 return res;
1400}