blob: 0f7aeb04a68e66ff3dd243dc986d6a0dfbec9abf [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.
Jens Wiklander50339ef2022-04-12 20:47:27 +02005 * Copyright (c) 2022, Linaro Limited.
Pascal Brandc639ac82015-07-02 08:53:34 +02006 */
Pascal Brandc639ac82015-07-02 08:53:34 +02007#include <compiler.h>
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01008#include <dlfcn.h>
Jerome Forissier4565c452020-06-17 17:55:00 +02009#include <link.h>
Jens Wiklander50339ef2022-04-12 20:47:27 +020010#include <memtag.h>
Jens Wiklander8324ff22018-11-21 14:16:04 +010011#include <setjmp.h>
12#include <stdint.h>
13#include <string.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020014#include <ta_crypt.h>
15#include <ta_os_test.h>
16#include <tee_internal_api_extensions.h>
17
18#include "os_test.h"
Jens Wiklander246184a2015-12-11 08:28:59 +010019#include "test_float_subj.h"
Jerome Forissier53bde722018-05-31 09:14:54 +020020#include "os_test_lib.h"
Pascal Brandc639ac82015-07-02 08:53:34 +020021
Etienne Carriere24fcf0e2023-03-07 17:44:00 +010022#define STATS_UUID \
23 { 0xd96a5b40, 0xe2c7, 0xb1af, \
24 { 0x87, 0x94, 0x10, 0x02, 0xa5, 0xd5, 0xc6, 0x1b } }
25
26#define STATS_CMD_PAGER_STATS 0
27
28#define PAGER_PAGE_COUNT_THRESHOLD ((128 * 1024) / 4096)
29
Pascal Brandc639ac82015-07-02 08:53:34 +020030enum p_type {
31 P_TYPE_BOOL,
32 P_TYPE_INT,
33 P_TYPE_UUID,
34 P_TYPE_IDENTITY,
35 P_TYPE_STRING,
36 P_TYPE_BINARY_BLOCK,
37};
38
39struct p_attr {
40 const char *str;
41 enum p_type type;
42 bool retrieved;
43};
44
Pascal Brand624b6a32016-02-16 12:51:34 +010045static TEE_Result check_returned_prop(
Pascal Brandaf77fdd2016-03-08 13:59:01 +010046 int line __maybe_unused, char *prop_name __maybe_unused,
Pascal Brand624b6a32016-02-16 12:51:34 +010047 TEE_Result return_res, TEE_Result expected_res,
48 uint32_t return_len, uint32_t expected_len)
49{
50 if (return_res != expected_res) {
51 EMSG("From line %d (property name=%s): return_res=0x%x vs expected_res=0x%x",
52 line, (prop_name ? prop_name : "unknown"),
53 (unsigned int)return_res, (unsigned int)expected_res);
54 return TEE_ERROR_GENERIC;
55 }
56 if (return_len != expected_len) {
Pascal Brand07bb09f2016-02-19 16:04:10 +010057 EMSG("From line %d (property name=%s): return_len=%u vs expected_res=%u",
58 line, (prop_name ? prop_name : "unknown"),
59 return_len, expected_len);
Pascal Brand624b6a32016-02-16 12:51:34 +010060 return TEE_ERROR_GENERIC;
61 }
62 return TEE_SUCCESS;
63}
64
Etienne Carriere58e3a832020-07-08 16:56:01 +020065static TEE_Result check_binprop_ones(size_t size, char *bbuf, size_t bblen)
Etienne Carriereb34caff2020-05-26 09:25:35 +020066{
Etienne Carriere58e3a832020-07-08 16:56:01 +020067 char ones[4] = { 0xff, 0xff, 0xff, 0xff };
Etienne Carriereb34caff2020-05-26 09:25:35 +020068
69 if (size > 4 || bblen != size) {
70 EMSG("Size error (size=%zu, bblen=%zu)", size, bblen);
71 return TEE_ERROR_GENERIC;
72 }
73 if (strncmp(bbuf, ones, bblen)) {
74 EMSG("Unexpected content");
75 DHEXDUMP(bbuf, bblen);
76 return TEE_ERROR_GENERIC;
77 }
78 return TEE_SUCCESS;
79}
80
81static TEE_Result get_binblock_property(TEE_PropSetHandle h,
Vesa Jääskeläinena9ab8f82021-02-06 21:16:20 +020082 char *nbuf __unused, char **bbuf, size_t *bblen)
Etienne Carriereb34caff2020-05-26 09:25:35 +020083{
84 TEE_Result res = TEE_ERROR_GENERIC;
Jens Wiklandere1634fa2022-12-12 12:59:28 +010085 size_t block_len = 0;
Etienne Carriereb34caff2020-05-26 09:25:35 +020086
87 *bbuf = NULL;
88 *bblen = 0;
Etienne Carriere58e3a832020-07-08 16:56:01 +020089 res = TEE_GetPropertyAsBinaryBlock(h, NULL, *bbuf, &block_len);
Etienne Carriereb34caff2020-05-26 09:25:35 +020090
Etienne Carriere58e3a832020-07-08 16:56:01 +020091 if (res == TEE_SUCCESS && !block_len)
Etienne Carriereb34caff2020-05-26 09:25:35 +020092 return TEE_SUCCESS;
93
94 if (res != TEE_ERROR_SHORT_BUFFER) {
95 EMSG("TEE_GetPropertyAsBinaryBlock() size query returned 0x%x",
96 (unsigned int)res);
97 return res ? res : TEE_ERROR_GENERIC;
98 }
99
Etienne Carriere58e3a832020-07-08 16:56:01 +0200100 *bbuf = TEE_Malloc(block_len, TEE_MALLOC_FILL_ZERO);
Etienne Carriereb34caff2020-05-26 09:25:35 +0200101 if (!bbuf)
102 return TEE_ERROR_OUT_OF_MEMORY;
103
Etienne Carriere58e3a832020-07-08 16:56:01 +0200104 res = TEE_GetPropertyAsBinaryBlock(h, NULL, *bbuf, &block_len);
Etienne Carriereb34caff2020-05-26 09:25:35 +0200105 if (res != TEE_SUCCESS)
106 EMSG("TEE_GetPropertyAsBinaryBlock(\"%s\") returned 0x%x",
107 nbuf, (unsigned int)res);
Etienne Carriere58e3a832020-07-08 16:56:01 +0200108 else
109 *bblen = block_len;
Etienne Carriereb34caff2020-05-26 09:25:35 +0200110
111 return res;
112}
113
Pascal Brandc639ac82015-07-02 08:53:34 +0200114static TEE_Result print_properties(TEE_PropSetHandle h,
115 TEE_PropSetHandle prop_set,
116 struct p_attr *p_attrs, size_t num_p_attrs)
117{
queeniefa2fb9b2023-06-15 10:59:44 +0800118 TEE_Result res = TEE_ERROR_GENERIC;
119 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200120
queeniefa2fb9b2023-06-15 10:59:44 +0800121 TEE_StartPropertyEnumerator(h, prop_set);
Pascal Brandc639ac82015-07-02 08:53:34 +0200122
queeniefa2fb9b2023-06-15 10:59:44 +0800123 while (true) {
124 char nbuf[256] = { };
125 char nbuf_small[256] = { };
126 char vbuf[256] = { };
127 char vbuf2[256] = { };
128 size_t nblen = sizeof(nbuf);
129 size_t nblen_small = 0;
130 size_t vblen = sizeof(vbuf);
131 size_t vblen2 = sizeof(vbuf2);
132 char *bbuf = NULL;
133 size_t bblen = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200134
queeniefa2fb9b2023-06-15 10:59:44 +0800135 res = TEE_GetPropertyName(h, nbuf, &nblen);
136 if (res != TEE_SUCCESS) {
137 EMSG("TEE_GetPropertyName returned 0x%x\n",
138 (unsigned int)res);
139 return res;
140 }
141 if (nblen != strlen(nbuf) + 1) {
142 EMSG("Name has wrong size: %zu vs %zu",
143 nblen, strlen(nbuf) + 1);
144 return TEE_ERROR_GENERIC;
145 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200146
queeniefa2fb9b2023-06-15 10:59:44 +0800147 /* Get the property name with a very small buffer */
148 nblen_small = 2;
149 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
150 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
151 nblen_small, nblen);
152 if (res != TEE_SUCCESS)
153 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100154
queeniefa2fb9b2023-06-15 10:59:44 +0800155 /* Get the property name with almost the correct buffer */
156 nblen_small = nblen - 1;
157 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
158 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
159 nblen_small, nblen);
160 if (res != TEE_SUCCESS)
161 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100162
queeniefa2fb9b2023-06-15 10:59:44 +0800163 /* Get the property name with the exact buffer length */
164 nblen_small = nblen;
165 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
166 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
167 nblen_small, nblen);
168 if (res != TEE_SUCCESS)
169 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100170
queeniefa2fb9b2023-06-15 10:59:44 +0800171 /* Get the property value */
172 res = TEE_GetPropertyAsString(h, NULL, vbuf, &vblen);
173 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
174 vblen, strlen(vbuf) + 1);
175 if (res != TEE_SUCCESS)
176 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100177
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200178 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
queeniefa2fb9b2023-06-15 10:59:44 +0800179 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
180 vblen2, strlen(vbuf2) + 1);
181 if (res != TEE_SUCCESS)
182 return res;
183
184 if (strcmp(vbuf, vbuf2) != 0) {
185 EMSG("String of \"%s\" differs\n", nbuf);
186 return TEE_ERROR_GENERIC;
187 }
188
189 /* Get the property with a very small buffer */
190 if (vblen > 1) {
191 vblen2 = 1;
192 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
193 res = check_returned_prop(__LINE__, nbuf, res,
194 TEE_ERROR_SHORT_BUFFER,
195 vblen2, vblen);
196 if (res != TEE_SUCCESS)
197 return res;
198 }
199
200 /* Get the property with almost the correct buffer */
201 vblen2 = vblen - 1;
202 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
203 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200204 vblen2, vblen);
205 if (res != TEE_SUCCESS)
206 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100207
queeniefa2fb9b2023-06-15 10:59:44 +0800208 /* Get the property name with the exact buffer length */
209 vblen2 = vblen;
210 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
211 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS, vblen2, vblen);
212 if (res != TEE_SUCCESS)
213 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100214
queeniefa2fb9b2023-06-15 10:59:44 +0800215 /* check specific myprop.hello property, which is larger than 80 */
216 if (!strcmp("myprop.hello", nbuf) &&
217 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")) {
218 EMSG("TEE_GetPropertyAsString(\"%s\") is truncated - returned \"%s\"\n",
219 nbuf, vbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200220 return TEE_ERROR_GENERIC;
221 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200222
queeniefa2fb9b2023-06-15 10:59:44 +0800223 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200224
queeniefa2fb9b2023-06-15 10:59:44 +0800225 for (n = 0; n < num_p_attrs; n++) {
226 if (strcmp(nbuf, p_attrs[n].str) != 0)
227 continue;
228
229 if (p_attrs[n].retrieved) {
230 EMSG("Value \"%s\" already retrieved\n",
231 p_attrs[n].str);
232 return TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200233 }
queeniefa2fb9b2023-06-15 10:59:44 +0800234 p_attrs[n].retrieved = true;
Pascal Brandc639ac82015-07-02 08:53:34 +0200235
queeniefa2fb9b2023-06-15 10:59:44 +0800236 switch (p_attrs[n].type) {
237 case P_TYPE_BOOL:
238 {
239 bool v = false;
Pascal Brandc639ac82015-07-02 08:53:34 +0200240
queeniefa2fb9b2023-06-15 10:59:44 +0800241 res =
242 TEE_GetPropertyAsBool(h, NULL, &v);
243 if (res != TEE_SUCCESS) {
244 EMSG(
245 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
246 nbuf, (unsigned int)res);
247 return res;
248 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200249 }
queeniefa2fb9b2023-06-15 10:59:44 +0800250 break;
Pascal Brandc639ac82015-07-02 08:53:34 +0200251
queeniefa2fb9b2023-06-15 10:59:44 +0800252 case P_TYPE_INT:
253 {
254 uint32_t v = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200255
queeniefa2fb9b2023-06-15 10:59:44 +0800256 res = TEE_GetPropertyAsU32(h, NULL, &v);
257 if (res != TEE_SUCCESS) {
258 EMSG(
259 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
260 nbuf, (unsigned int)res);
261 return res;
262 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200263 }
queeniefa2fb9b2023-06-15 10:59:44 +0800264 break;
Pascal Brandc639ac82015-07-02 08:53:34 +0200265
queeniefa2fb9b2023-06-15 10:59:44 +0800266 case P_TYPE_UUID:
267 {
268 TEE_UUID v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200269
queeniefa2fb9b2023-06-15 10:59:44 +0800270 res =
271 TEE_GetPropertyAsUUID(h, NULL, &v);
272 if (res != TEE_SUCCESS) {
273 EMSG(
274 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
275 nbuf, (unsigned int)res);
276 return res;
277 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200278 }
queeniefa2fb9b2023-06-15 10:59:44 +0800279 break;
Pascal Brandc639ac82015-07-02 08:53:34 +0200280
queeniefa2fb9b2023-06-15 10:59:44 +0800281 case P_TYPE_IDENTITY:
282 {
283 TEE_Identity v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200284
queeniefa2fb9b2023-06-15 10:59:44 +0800285 res =
286 TEE_GetPropertyAsIdentity(h, NULL,
287 &v);
288 if (res != TEE_SUCCESS) {
289 EMSG(
290 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
291 nbuf, (unsigned int)res);
292 return res;
293 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200294 }
queeniefa2fb9b2023-06-15 10:59:44 +0800295 break;
296
297 case P_TYPE_STRING:
298 /* Already read as string */
299 break;
300
301 case P_TYPE_BINARY_BLOCK:
302 res = get_binblock_property(h, nbuf, &bbuf, &bblen);
Etienne Carriereb34caff2020-05-26 09:25:35 +0200303 if (res)
Pascal Brandc639ac82015-07-02 08:53:34 +0200304 return res;
queeniefa2fb9b2023-06-15 10:59:44 +0800305
306 if (!strcmp("myprop.binaryblock", nbuf)) {
307 const char exp_bin_value[] = "Hello world!";
308
309 if (bblen != strlen(exp_bin_value) ||
310 TEE_MemCompare(exp_bin_value, bbuf,
311 bblen)) {
312 EMSG("Binary buffer of \"%s\" differs from \"%s\"",
313 nbuf, exp_bin_value);
314 EMSG("Got \"%s\"", bbuf);
315 return TEE_ERROR_GENERIC;
316 }
317 } else if (!strcmp("myprop.binaryblock.1byte-ones",
318 nbuf)) {
319 res = check_binprop_ones(1, bbuf, bblen);
320 if (res)
321 return res;
322 } else if (!strcmp("myprop.binaryblock.2byte-ones",
323 nbuf)) {
324 res = check_binprop_ones(2, bbuf, bblen);
325 if (res)
326 return res;
327 } else if (!strcmp("myprop.binaryblock.3byte-ones",
328 nbuf)) {
329 res = check_binprop_ones(3, bbuf, bblen);
330 if (res)
331 return res;
332 } else if (!strcmp("myprop.binaryblock.4byte-ones",
333 nbuf)) {
334 res = check_binprop_ones(4, bbuf, bblen);
335 if (res)
336 return res;
337 } else if (!strcmp("myprop.binaryblock.empty1", nbuf) ||
338 !strcmp("myprop.binaryblock.empty2", nbuf) ||
339 !strcmp("myprop.binaryblock.empty3", nbuf)) {
340 if (bblen) {
341 EMSG("Property \"%s\": %zu byte(s)",
342 nbuf, bblen);
343 return TEE_ERROR_GENERIC;
344 }
345 } else {
346 EMSG("Unexpected property \"%s\"", nbuf);
347 TEE_Panic(0);
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200348 }
queeniefa2fb9b2023-06-15 10:59:44 +0800349
350 TEE_Free(bbuf);
351 break;
352
353 default:
354 EMSG("Unknown type (%d) for \"%s\"\n",
355 p_attrs[n].type, p_attrs[n].str);
356 return TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200357 }
queeniefa2fb9b2023-06-15 10:59:44 +0800358 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200359
queeniefa2fb9b2023-06-15 10:59:44 +0800360 res = TEE_GetNextProperty(h);
361 if (res != TEE_SUCCESS) {
362 if (res == TEE_ERROR_ITEM_NOT_FOUND)
363 return TEE_SUCCESS;
364 return res;
Pascal Brandc639ac82015-07-02 08:53:34 +0200365 }
366 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200367}
368
369static TEE_Result test_malloc(void)
370{
371 void *p = TEE_Malloc(4, 0);
372
373 if (p == NULL) {
374 EMSG("TEE_Malloc failed\n");
375 return TEE_ERROR_OUT_OF_MEMORY;
376 }
377 TEE_Free(p);
378 TEE_Free(NULL);
379
380 return TEE_SUCCESS;
381}
382
383static TEE_Result test_properties(void)
384{
385 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriere102092e2019-03-28 15:24:22 +0100386 TEE_PropSetHandle h = TEE_HANDLE_NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200387 struct p_attr p_attrs[] = {
388 {"gpd.ta.appID", P_TYPE_UUID},
389 {"gpd.ta.singleInstance", P_TYPE_BOOL},
390 {"gpd.ta.multiSession", P_TYPE_BOOL},
391 {"gpd.ta.instanceKeepAlive", P_TYPE_BOOL},
392 {"gpd.ta.dataSize", P_TYPE_INT},
393 {"gpd.ta.stackSize", P_TYPE_INT},
394 {"gpd.ta.version", P_TYPE_STRING},
395 {"gpd.ta.description", P_TYPE_STRING},
396 {"gpd.client.identity", P_TYPE_IDENTITY},
397 {"gpd.tee.apiversion", P_TYPE_STRING},
398 {"gpd.tee.description", P_TYPE_STRING},
399 {"gpd.tee.deviceID", P_TYPE_UUID},
400 {"gpd.tee.systemTime.protectionLevel", P_TYPE_INT},
401 {"gpd.tee.TAPersistentTime.protectionLevel", P_TYPE_INT},
402 {"gpd.tee.arith.maxBigIntSize", P_TYPE_INT},
403 {"gpd.tee.cryptography.ecc", P_TYPE_BOOL},
404 {"gpd.tee.trustedStorage.antiRollback.protectionLevel", P_TYPE_INT},
405 {"gpd.tee.trustedos.implementation.version", P_TYPE_STRING},
406 {"gpd.tee.trustedos.implementation.binaryversion", P_TYPE_INT},
407 {"gpd.tee.trustedos.manufacturer", P_TYPE_STRING},
408 {"gpd.tee.firmware.implementation.version", P_TYPE_STRING},
409 {"gpd.tee.firmware.implementation.binaryversion", P_TYPE_INT},
410 {"gpd.tee.firmware.manufacturer", P_TYPE_STRING},
411 {"myprop.true", P_TYPE_BOOL},
412 {"myprop.42", P_TYPE_INT},
413 {"myprop.123", P_TYPE_UUID},
414 {"myprop.1234", P_TYPE_IDENTITY},
415 {"myprop.hello", P_TYPE_STRING},
416 {"myprop.binaryblock", P_TYPE_BINARY_BLOCK},
Etienne Carriereb34caff2020-05-26 09:25:35 +0200417 {"myprop.binaryblock.1byte-ones", P_TYPE_BINARY_BLOCK},
418 {"myprop.binaryblock.2byte-ones", P_TYPE_BINARY_BLOCK},
419 {"myprop.binaryblock.3byte-ones", P_TYPE_BINARY_BLOCK},
420 {"myprop.binaryblock.4byte-ones", P_TYPE_BINARY_BLOCK},
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200421 {"myprop.binaryblock.empty1", P_TYPE_BINARY_BLOCK},
422 {"myprop.binaryblock.empty2", P_TYPE_BINARY_BLOCK},
423 {"myprop.binaryblock.empty3", P_TYPE_BINARY_BLOCK},
Pascal Brandc639ac82015-07-02 08:53:34 +0200424 };
425 const size_t num_p_attrs = sizeof(p_attrs) / sizeof(p_attrs[0]);
Etienne Carriere102092e2019-03-28 15:24:22 +0100426 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200427
428 res = TEE_AllocatePropertyEnumerator(&h);
429 if (res != TEE_SUCCESS) {
430 EMSG("TEE_AllocatePropertyEnumerator: returned 0x%x\n",
431 (unsigned int)res);
432 return TEE_ERROR_GENERIC;
433 }
434
435 printf("Getting properties for current TA\n");
436 res = print_properties(h, TEE_PROPSET_CURRENT_TA, p_attrs, num_p_attrs);
437 if (res != TEE_SUCCESS)
438 goto cleanup_return;
439
440 printf("Getting properties for current client\n");
441 res = print_properties(h, TEE_PROPSET_CURRENT_CLIENT, p_attrs,
442 num_p_attrs);
443 if (res != TEE_SUCCESS)
444 goto cleanup_return;
445
446 printf("Getting properties for implementation\n");
447 res = print_properties(h, TEE_PROPSET_TEE_IMPLEMENTATION, p_attrs,
448 num_p_attrs);
449 if (res != TEE_SUCCESS)
450 goto cleanup_return;
451
452 for (n = 0; n < num_p_attrs; n++) {
453 if (!p_attrs[n].retrieved) {
454 EMSG("\"%s\" not retrieved\n", p_attrs[n].str);
455 res = TEE_ERROR_GENERIC;
456 goto cleanup_return;
457 }
458 }
459
460cleanup_return:
461 TEE_FreePropertyEnumerator(h);
462 return res;
463}
464
465static TEE_Result test_mem_access_right(uint32_t param_types,
466 TEE_Param params[4])
467{
468 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100469 TEE_Result res = TEE_ERROR_GENERIC;
470 uint32_t ret_orig = 0;
471 uint32_t l_pts = 0;
472 TEE_Param l_params[4] = { };
473 uint8_t buf[32] = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200474 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100475 TEE_UUID *uuid = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200476
477 if (param_types !=
478 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
Vincent Mailholc7391612023-11-19 13:11:12 +0900479 return TEE_ERROR_BAD_PARAMETERS;
Etienne Carriere281065d2016-10-28 15:41:33 +0200480
481 /* test access rights on memref parameter */
482 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
483 TEE_MEMORY_ACCESS_ANY_OWNER,
484 params[0].memref.buffer,
485 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200486 if (res != TEE_SUCCESS)
487 return res;
Etienne Carriere281065d2016-10-28 15:41:33 +0200488
Pascal Brandc639ac82015-07-02 08:53:34 +0200489 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
490 params[0].memref.buffer,
491 params[0].memref.size);
492 if (res != TEE_ERROR_ACCESS_DENIED)
493 return TEE_ERROR_GENERIC;
494
Etienne Carriere281065d2016-10-28 15:41:33 +0200495 /* test access rights on private read-only and read-write memory */
496 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
497 (void *)&test_uuid, sizeof(test_uuid));
498 if (res != TEE_SUCCESS)
499 return res;
500
501 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_WRITE,
502 (void *)&test_uuid, sizeof(test_uuid));
503 if (res == TEE_SUCCESS)
504 return TEE_ERROR_GENERIC;
505
506 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
507 TEE_MEMORY_ACCESS_WRITE,
508 &ret_orig, sizeof(ret_orig));
509 if (res != TEE_SUCCESS)
510 return res;
511
512 uuid = TEE_Malloc(sizeof(*uuid), 0);
513 if (!uuid)
514 return TEE_ERROR_OUT_OF_MEMORY;
515
516 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
517 TEE_MEMORY_ACCESS_WRITE,
518 uuid, sizeof(*uuid));
519 TEE_Free(uuid);
520 if (res != TEE_SUCCESS)
521 return res;
522
523 /* test access rights on invalid memory (at least lower 256kB) */
524 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
525 NULL, 1);
526 if (res == TEE_SUCCESS)
527 return TEE_ERROR_GENERIC;
528
529 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
530 (void*)(256 * 1024), 1);
531 if (res == TEE_SUCCESS)
532 return TEE_ERROR_GENERIC;
533
Cedric Augere668b3f2019-09-11 13:41:21 +0200534 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
535 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200536 if (res != TEE_SUCCESS) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900537 EMSG("TEE_OpenTASession failed\n");
Pascal Brandc639ac82015-07-02 08:53:34 +0200538 goto cleanup_return;
539 }
540
Jerome Forissier04511d82018-01-30 14:33:49 +0100541 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
542 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200543 l_params[0].memref.buffer = buf;
544 l_params[0].memref.size = sizeof(buf);
Jerome Forissier04511d82018-01-30 14:33:49 +0100545 l_params[1].memref.buffer = NULL;
546 l_params[1].memref.size = 0;
Cedric Augere668b3f2019-09-11 13:41:21 +0200547 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
548 TA_OS_TEST_CMD_PARAMS_ACCESS,
Pascal Brandc639ac82015-07-02 08:53:34 +0200549 l_pts, l_params, &ret_orig);
550 if (res != TEE_SUCCESS) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900551 EMSG("TEE_InvokeTACommand failed\n");
Pascal Brandc639ac82015-07-02 08:53:34 +0200552 goto cleanup_return;
553 }
554
555cleanup_return:
556 TEE_CloseTASession(sess);
557 return res;
558}
559
560static TEE_Result test_time(void)
561{
Etienne Carriere102092e2019-03-28 15:24:22 +0100562 TEE_Result res = TEE_ERROR_GENERIC;
563 TEE_Time t = { };
564 TEE_Time sys_t = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200565 static const TEE_Time null_time = { 0, 0 };
566 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
567
568 TEE_GetSystemTime(&sys_t);
569 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
570 (unsigned int)sys_t.millis);
571
572 TEE_GetREETime(&t);
573 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
574 (unsigned int)t.millis);
575
576 res = TEE_GetTAPersistentTime(&t);
577 switch (res) {
578 case TEE_SUCCESS:
579 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
580 (unsigned int)t.millis);
581 break;
582 case TEE_ERROR_OVERFLOW:
583 EMSG("Stored TA time overflowed %u.%03u\n",
584 (unsigned int)t.seconds, (unsigned int)t.millis);
585 break;
586 case TEE_ERROR_TIME_NOT_SET:
587 EMSG("TA time not stored\n");
588 break;
589 case TEE_ERROR_TIME_NEEDS_RESET:
590 EMSG("TA time needs reset\n");
591 break;
592 default:
593 return res;
594 }
595
596 res = TEE_SetTAPersistentTime(&null_time);
597 if (res != TEE_SUCCESS) {
598 EMSG("TEE_SetTAPersistentTime: failed\n");
599 return res;
600 }
601
602 res = TEE_GetTAPersistentTime(&t);
603 if (res != TEE_SUCCESS) {
604 EMSG("TEE_GetTAPersistentTime null: failed\n");
605 return res;
606 }
607 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
608 (unsigned int)t.millis);
609 /*
610 * The time between TEE_SetTAPersistentTime() and
611 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
612 * it's not even a millisecond.
613 */
614 if (t.seconds > 1 || t.millis >= 1000) {
615 EMSG("Unexpected stored TA time %u.%03u\n",
616 (unsigned int)t.seconds, (unsigned int)t.millis);
617 return TEE_ERROR_BAD_STATE;
618 }
619
620 res = TEE_SetTAPersistentTime(&wrap_time);
621 if (res != TEE_SUCCESS) {
622 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
623 return res;
624 }
625
626 res = TEE_Wait(1000);
627 if (res != TEE_SUCCESS)
628 EMSG("TEE_Wait wrap: failed\n");
629
630 res = TEE_GetTAPersistentTime(&t);
631 if (res != TEE_ERROR_OVERFLOW) {
632 EMSG("TEE_GetTAPersistentTime: failed\n");
633 return TEE_ERROR_BAD_STATE;
634 }
635 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
636 (unsigned int)t.millis);
637
Clement Faurea2c1ce32023-11-06 09:42:53 +0100638 if (t.seconds > 1) {
639 EMSG("Unexpected wrapped time %u.%03u\n",
640 (unsigned int)t.seconds, (unsigned int)t.millis);
Pascal Brandc639ac82015-07-02 08:53:34 +0200641 return TEE_ERROR_BAD_STATE;
642 }
643
644 return TEE_SUCCESS;
645}
646
Jens Wiklander246184a2015-12-11 08:28:59 +0100647#ifdef CFG_TA_FLOAT_SUPPORT
648static bool my_dcmpeq(double v1, double v2, double prec)
649{
650 return v1 > (v2 - prec) && v1 < (v2 + prec);
651}
652
653static bool my_fcmpeq(float v1, float v2, float prec)
654{
655 return v1 > (v2 - prec) && v1 < (v2 + prec);
656}
657
658
659static TEE_Result test_float(void)
660{
661#define VAL1 2.6
662#define VAL1_INT 2
663#define VAL2 5.3
664#define DPREC 0.000000000000001
665#define FPREC 0.000001
666#define EXPECT(expr) do { \
667 if (!(expr)) { \
668 EMSG("Expression %s failed", #expr); \
669 return TEE_ERROR_GENERIC; \
670 } \
671 } while (0)
672
673 IMSG("Testing floating point operations");
674
675 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
676 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
677 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
678 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
679 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
680
681 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
682 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
683 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
684 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
685 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
686
687 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
688 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
689 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
690 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
691 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
692
693 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
694 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
695 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
696 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
697 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
698
699 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
700 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
701 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
702 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
703
704 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
705 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
706 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
707 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
708
709 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
710 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
711
712 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
713 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
714 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
715 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
716
717 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
718 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
719 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
720 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
721 return TEE_SUCCESS;
722}
723#else /*CFG_TA_FLOAT_SUPPORT*/
724static TEE_Result test_float(void)
725{
726 IMSG("Floating point disabled");
727 return TEE_SUCCESS;
728}
729#endif /*CFG_TA_FLOAT_SUPPORT*/
730
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100731#if defined(CFG_TA_BGET_TEST)
732/* From libutils */
733int bget_main_test(void *(*malloc_func)(size_t), void (*free_func)(void *));
734
735static void *malloc_wrapper(size_t size)
736{
737 return tee_map_zi(size, 0);
738}
739
740static void free_wrapper(void *ptr __unused)
741{
742}
743
Etienne Carriere24fcf0e2023-03-07 17:44:00 +0100744static bool optee_pager_with_small_pool(void)
745{
746 uint32_t ptypes = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
747 TEE_PARAM_TYPE_VALUE_OUTPUT,
748 TEE_PARAM_TYPE_VALUE_OUTPUT,
749 TEE_PARAM_TYPE_NONE);
750 static const TEE_UUID uuid = STATS_UUID;
751 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
752 TEE_Result res = TEE_ERROR_GENERIC;
753 TEE_Param params[4] = { };
754 uint32_t eo = 0;
755 bool rc = false;
756
757 res = TEE_OpenTASession(&uuid, TEE_TIMEOUT_INFINITE, 0, NULL, &sess,
758 &eo);
759 if (res)
760 return false;
761
762 res = TEE_InvokeTACommand(sess, 0, STATS_CMD_PAGER_STATS,
763 ptypes, params, &eo);
764 if (res == TEE_SUCCESS &&
765 params[0].value.b && params[0].value.b <= PAGER_PAGE_COUNT_THRESHOLD)
766 rc = true;
767
768 TEE_CloseTASession(sess);
769
770 return rc;
771}
772
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100773static TEE_Result test_bget(void)
774{
Etienne Carriere24fcf0e2023-03-07 17:44:00 +0100775 if (optee_pager_with_small_pool()) {
776 IMSG("Skip testing bget due to pager pool constraints");
777 return TEE_SUCCESS;
778 }
779
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100780 DMSG("Testing bget");
781 if (bget_main_test(malloc_wrapper, free_wrapper)) {
782 EMSG("bget_main_test failed");
783 return TEE_ERROR_GENERIC;
784 }
785 DMSG("Bget OK");
786 return TEE_SUCCESS;
787}
788#else
789static TEE_Result test_bget(void)
790{
791 IMSG("Bget test disabled");
792 return TEE_SUCCESS;
793}
794#endif
795
796
Jerome Forissier892ae4d2020-03-09 09:58:09 +0100797static __noinline __noreturn void call_longjmp(jmp_buf env)
Jens Wiklander9f682c62016-03-27 20:23:06 +0200798{
799 DMSG("Calling longjmp");
800 longjmp(env, 1);
801 EMSG("error: longjmp returned to calling function");
802}
803
804static TEE_Result test_setjmp(void)
805{
Etienne Carriere102092e2019-03-28 15:24:22 +0100806 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200807
808 if (setjmp(env)) {
809 IMSG("Returned via longjmp");
810 return TEE_SUCCESS;
811 } else {
812 call_longjmp(env);
813 return TEE_ERROR_GENERIC;
814 }
815}
816
Pascal Brandc639ac82015-07-02 08:53:34 +0200817TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
818{
819 TEE_Result res = TEE_ERROR_GENERIC;
820
821 printf("ta_entry_basic: enter\n");
822
823 res = test_malloc();
824 if (res != TEE_SUCCESS)
825 return res;
826
827 res = test_properties();
828 if (res != TEE_SUCCESS)
829 return res;
830
831 res = test_mem_access_right(param_types, params);
832 if (res != TEE_SUCCESS)
833 return res;
834
835 res = test_time();
836 if (res != TEE_SUCCESS)
837 return res;
838
Jens Wiklander246184a2015-12-11 08:28:59 +0100839 res = test_float();
840 if (res != TEE_SUCCESS)
841 return res;
842
Jens Wiklander9f682c62016-03-27 20:23:06 +0200843 res = test_setjmp();
844 if (res != TEE_SUCCESS)
845 return res;
846
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100847 res = test_bget();
848 if (res != TEE_SUCCESS)
849 return res;
850
Pascal Brandc639ac82015-07-02 08:53:34 +0200851 return TEE_SUCCESS;
852}
853
854TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
855{
856 volatile bool mytrue = true;
857 (void)param_types;
858 (void)params;
859
860 printf("ta_entry_panic: enter\n");
861 /*
862 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
863 * the __noreturn attribute.
864 */
865 if (mytrue)
866 TEE_Panic(0xbeef);
867
868 /*
869 * Should not be reached, but if it is the testsuite can detect that
870 * TEE_Panic() returned instead of panicking the TA.
871 */
872 return TEE_SUCCESS;
873}
874
875TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
876 TEE_Param params[4])
877{
878 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100879 TEE_Result res = TEE_ERROR_GENERIC;
880 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
881 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200882
883 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
884 TEE_PARAM_TYPE_NONE,
885 TEE_PARAM_TYPE_NONE,
886 TEE_PARAM_TYPE_NONE)) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900887 EMSG("bad parameters\n");
Pascal Brandc639ac82015-07-02 08:53:34 +0200888 return TEE_ERROR_BAD_PARAMETERS;
889 }
890
Cedric Augere668b3f2019-09-11 13:41:21 +0200891 res = TEE_OpenTASession(&os_test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
892 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200893 if (res != TEE_SUCCESS) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900894 EMSG("TEE_OpenTASession failed\n");
Pascal Brandc639ac82015-07-02 08:53:34 +0200895 return res;
896 }
897
898 res =
899 TEE_InvokeTACommand(sess, params[0].value.a / 2,
900 TA_OS_TEST_CMD_WAIT, param_types, params,
901 &ret_orig);
902
903 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900904 EMSG("TEE_InvokeTACommand: res 0x%x ret_orig 0x%x\n",
905 (unsigned int)res, (unsigned int)ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200906 res = TEE_ERROR_GENERIC;
907 } else
908 res = TEE_SUCCESS;
909
910 TEE_CloseTASession(sess);
911 return res;
912
913}
914
915TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
916{
917 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100918 TEE_Result res = TEE_ERROR_GENERIC;
919 uint32_t l_pts = 0;
920 TEE_Param l_params[4] = { };
921 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
922 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200923 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
924 static const uint8_t sha256_out[] = {
925 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
926 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
927 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
928 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
929 };
930 uint8_t out[32] = { 0 };
931 void *in = NULL;
932
933 (void)param_types;
934 (void)params;
935
936 printf("ta_entry_client: enter\n");
937
938 in = TEE_Malloc(sizeof(sha256_in), 0);
939 if (in == NULL)
940 return TEE_ERROR_OUT_OF_MEMORY;
941 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
942
Cedric Augere668b3f2019-09-11 13:41:21 +0200943 res = TEE_OpenTASession(&crypt_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
944 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200945 if (res != TEE_SUCCESS) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900946 EMSG("TEE_OpenTASession failed\n");
Pascal Brandc639ac82015-07-02 08:53:34 +0200947 goto cleanup_return;
948 }
949
950 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
951 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
952 l_params[0].memref.buffer = in;
953 l_params[0].memref.size = sizeof(sha256_in);
954 l_params[1].memref.buffer = out;
955 l_params[1].memref.size = sizeof(out);
956
Cedric Augere668b3f2019-09-11 13:41:21 +0200957 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
958 TA_CRYPT_CMD_SHA256, l_pts, l_params,
Pascal Brandc639ac82015-07-02 08:53:34 +0200959 &ret_orig);
960 if (res != TEE_SUCCESS) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900961 EMSG("TEE_InvokeTACommand failed\n");
Pascal Brandc639ac82015-07-02 08:53:34 +0200962 goto cleanup_return;
963 }
964
965 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900966 EMSG("out parameter failed\n");
Pascal Brandc639ac82015-07-02 08:53:34 +0200967 res = TEE_ERROR_GENERIC;
968 goto cleanup_return;
969 }
970
971cleanup_return:
972 TEE_Free(in);
973 TEE_CloseTASession(sess);
974 return res;
975}
976
Etienne Carriere281065d2016-10-28 15:41:33 +0200977TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200978{
Etienne Carriere102092e2019-03-28 15:24:22 +0100979 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200980
981 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100982 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
983 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Vincent Mailholc7391612023-11-19 13:11:12 +0900984 return TEE_ERROR_BAD_PARAMETERS;
Etienne Carriere281065d2016-10-28 15:41:33 +0200985
986 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
987 TEE_MEMORY_ACCESS_ANY_OWNER,
988 params[0].memref.buffer,
989 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200990 if (res != TEE_SUCCESS)
991 return res;
992
993 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
994 params[0].memref.buffer,
995 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200996 if (res != TEE_ERROR_ACCESS_DENIED)
997 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +0100998 if (params[1].memref.buffer || params[1].memref.size)
999 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +02001000
Etienne Carriere281065d2016-10-28 15:41:33 +02001001 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +02001002}
1003
1004TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
1005{
1006 TEE_Result res = TEE_SUCCESS;
1007 (void)param_types;
1008
1009 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
1010 /* Wait */
1011 res = TEE_Wait(params[0].value.a);
1012
1013 return res;
1014}
1015
Jens Wiklander1425f952016-07-21 09:02:30 +02001016static void undef_instr(void)
1017{
1018#if defined(ARM64)
1019 __asm__(".word 0x0");
1020#elif defined(ARM32)
1021 __asm__(".word 0xe7ffffff");
Marouene Boubakri38fd7892023-01-06 10:45:15 +01001022#elif defined(RV64) || defined(RV32)
1023 __asm__(".word 0x0");
Jens Wiklander1425f952016-07-21 09:02:30 +02001024#else
1025#error "Unsupported architecture"
1026#endif
1027}
1028
Pascal Brandc639ac82015-07-02 08:53:34 +02001029TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
1030{
Etienne Carriere102092e2019-03-28 15:24:22 +01001031 long int stack = 0;
1032 long int stack_addr = (long int)&stack;
Jerome Forissiere2a58c62019-09-19 16:01:54 +02001033 void (*volatile null_fn_ptr)(void) = NULL;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001034 char *zero_size_malloc = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +02001035
Etienne Carriere92c34422018-02-09 13:11:40 +01001036 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
1037 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
1038 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Vincent Mailholc7391612023-11-19 13:11:12 +09001039 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +02001040
1041 switch (params[0].value.a) {
1042 case 1:
Jerome Forissier71da60f2019-09-19 15:59:56 +02001043 *((volatile uint32_t *)0) = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +02001044 break;
1045 case 2:
1046 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
1047 break;
1048 case 3:
Jerome Forissiere2a58c62019-09-19 16:01:54 +02001049 null_fn_ptr();
Pascal Brandc639ac82015-07-02 08:53:34 +02001050 break;
1051 case 4:
1052 ((void (*)(void))(stack_addr + 0x40000000)) ();
1053 break;
1054 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +02001055 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +02001056 break;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001057 case 6:
1058 zero_size_malloc = TEE_Malloc(0, 0);
1059 if (!zero_size_malloc)
1060 return TEE_ERROR_GENERIC;
Etienne Carriere713db5a2021-09-29 20:32:32 +02001061 if (*zero_size_malloc)
1062 return TEE_ERROR_GENERIC;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001063 break;
1064 case 7:
1065 zero_size_malloc = TEE_Malloc(0, 0);
1066 if (!zero_size_malloc)
1067 return TEE_ERROR_GENERIC;
1068 *zero_size_malloc = 0;
1069 break;
Pascal Brandc639ac82015-07-02 08:53:34 +02001070 default:
1071 break;
1072 }
1073
1074 return TEE_SUCCESS;
1075}
Jerome Forissiere916b102017-06-07 17:55:52 +02001076
1077static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
1078{
Etienne Carriere102092e2019-03-28 15:24:22 +01001079 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001080
1081 for (i = 0; i < bufsize; i++) {
1082 a[i]++; b[i]++; c[i]++;
1083 }
1084}
1085
Etienne Carriere102092e2019-03-28 15:24:22 +01001086#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +02001087TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
1088{
1089 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
1090 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +01001091 TEE_Param l_params[4] = { };
1092 uint8_t in[TA2TA_BUF_SIZE] = { };
1093 uint8_t inout[TA2TA_BUF_SIZE] = { };
1094 uint8_t out[TA2TA_BUF_SIZE] = { };
1095 TEE_Result res = TEE_ERROR_GENERIC;
1096 uint32_t ret_orig = 0;
1097 uint32_t l_pts = 0;
1098 size_t i = 0;
1099
Jerome Forissiere916b102017-06-07 17:55:52 +02001100 (void)params;
1101
1102 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
Vincent Mailholc7391612023-11-19 13:11:12 +09001103 return TEE_ERROR_BAD_PARAMETERS;
Jerome Forissiere916b102017-06-07 17:55:52 +02001104
Cedric Augere668b3f2019-09-11 13:41:21 +02001105 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
1106 &sess, &ret_orig);
Jerome Forissiere916b102017-06-07 17:55:52 +02001107 if (res != TEE_SUCCESS) {
1108 EMSG("TEE_OpenTASession failed");
1109 goto cleanup_return;
1110 }
1111
1112 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1113 TEE_PARAM_TYPE_MEMREF_INOUT,
1114 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
1115 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +01001116 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001117 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +01001118 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001119 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +01001120 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001121
1122 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +01001123 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001124 in[i] = 5;
1125 inout[i] = 10;
1126 out[i] = 0;
1127 }
1128
1129 /*
1130 * TA will compute: out = ++inout + in
1131 * Expected values after this step: in: 5, inout: 11, out: 16
1132 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001133 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1134 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001135 l_pts, l_params, &ret_orig);
1136 if (res != TEE_SUCCESS) {
1137 EMSG("TEE_InvokeTACommand failed");
1138 goto cleanup_return;
1139 }
Etienne Carriere102092e2019-03-28 15:24:22 +01001140
Jerome Forissiere916b102017-06-07 17:55:52 +02001141 /*
1142 * Increment all values by one.
1143 * Expected values after this step: in: 6, inout: 12, out: 17
1144 */
Etienne Carriere102092e2019-03-28 15:24:22 +01001145 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +02001146
1147 /*
1148 * TA will compute: out = ++inout + in
1149 * Expected values after this step: in: 6, inout: 13, out: 19
1150 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001151 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1152 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001153 l_pts, l_params, &ret_orig);
1154 if (res != TEE_SUCCESS) {
1155 EMSG("TEE_InvokeTACommand failed");
1156 goto cleanup_return;
1157 }
1158
1159 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001160 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001161 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1162 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001163 DHEXDUMP(in, TA2TA_BUF_SIZE);
1164 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1165 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001166 return TEE_ERROR_GENERIC;
1167 }
1168 }
1169
1170cleanup_return:
1171 TEE_CloseTASession(sess);
1172 return res;
1173}
Vincent Mailholbbbb4852023-11-16 16:19:06 +09001174#undef TA2TA_BUF_SIZE
Jerome Forissiere916b102017-06-07 17:55:52 +02001175
1176TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1177{
Etienne Carriere102092e2019-03-28 15:24:22 +01001178 uint8_t *in = NULL;
1179 uint8_t *inout = NULL;
1180 uint8_t *out = NULL;
1181 size_t bufsize = 0;
1182 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001183
1184 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1185 TEE_PARAM_TYPE_MEMREF_INOUT,
1186 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
Vincent Mailholc7391612023-11-19 13:11:12 +09001187 return TEE_ERROR_BAD_PARAMETERS;
Jerome Forissiere916b102017-06-07 17:55:52 +02001188
1189 bufsize = params[0].memref.size;
1190 if (params[1].memref.size != bufsize ||
1191 params[2].memref.size != bufsize)
Vincent Mailholc7391612023-11-19 13:11:12 +09001192 return TEE_ERROR_BAD_PARAMETERS;
Jerome Forissiere916b102017-06-07 17:55:52 +02001193
1194 in = params[0].memref.buffer;
1195 inout = params[1].memref.buffer;
1196 out = params[2].memref.buffer;
1197
1198 for (i = 0; i < bufsize; i++)
1199 out[i] = ++inout[i] + in[i];
1200
1201 return TEE_SUCCESS;
1202}
Jens Wiklander87e81702018-03-20 12:00:00 +08001203
1204TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1205{
Etienne Carriere102092e2019-03-28 15:24:22 +01001206 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001207
1208 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1209 TEE_PARAM_TYPE_MEMREF_INPUT,
1210 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1211 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1212 return TEE_ERROR_BAD_PARAMETERS;
1213
1214 for (n = 0; n < TEE_NUM_PARAMS; n++)
1215 if (!params[n].memref.buffer || !params[n].memref.size)
1216 return TEE_ERROR_BAD_PARAMETERS;
1217
1218 return TEE_SUCCESS;
1219}
Jerome Forissier53bde722018-05-31 09:14:54 +02001220
Cedric Neveux9f483bb2019-03-04 08:58:06 +01001221TEE_Result ta_entry_null_memref(uint32_t param_types, TEE_Param params[4])
1222{
1223 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1224 TEE_PARAM_TYPE_MEMREF_INPUT,
1225 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1226 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1227 return TEE_ERROR_BAD_PARAMETERS;
1228
1229 /*
1230 * Tests how client can provide null or non-null memref parameters
1231 * param[0] expected as a 0 byte input mapped memeref.
1232 * param[1] expected as a 0 byte input not-mapped memeref.
1233 * param[2] expected as a 0 byte output mapped memeref.
1234 * param[3] expected as a 0 byte output not-mapped memeref.
1235 */
1236 if (!params[0].memref.buffer || params[0].memref.size ||
1237 params[1].memref.buffer || params[1].memref.size ||
1238 !params[2].memref.buffer || params[2].memref.size ||
1239 params[3].memref.buffer || params[3].memref.size)
1240 return TEE_ERROR_BAD_PARAMETERS;
1241
1242 return TEE_SUCCESS;
1243}
1244
Jerome Forissier53bde722018-05-31 09:14:54 +02001245TEE_Result ta_entry_call_lib(uint32_t param_types,
1246 TEE_Param params[4] __unused)
1247{
1248 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1249 TEE_PARAM_TYPE_NONE,
1250 TEE_PARAM_TYPE_NONE,
1251 TEE_PARAM_TYPE_NONE))
1252 return TEE_ERROR_BAD_PARAMETERS;
1253
1254 if (os_test_shlib_add(1, 2) != 3)
1255 return TEE_ERROR_GENERIC;
1256
1257 return TEE_SUCCESS;
1258}
1259
1260TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1261 TEE_Param params[4] __unused)
1262{
1263 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1264 TEE_PARAM_TYPE_NONE,
1265 TEE_PARAM_TYPE_NONE,
1266 TEE_PARAM_TYPE_NONE))
1267 return TEE_ERROR_BAD_PARAMETERS;
1268
1269 os_test_shlib_panic();
1270
1271 return TEE_ERROR_GENERIC;
1272}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001273
1274TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1275 TEE_Param params[4] __unused)
1276{
1277 int (*add_func)(int a, int b) = NULL;
1278 TEE_Result res = TEE_ERROR_GENERIC;
1279 void *handle = NULL;
1280 void *hnull = NULL;
1281
1282 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1283 TEE_PARAM_TYPE_NONE,
1284 TEE_PARAM_TYPE_NONE,
1285 TEE_PARAM_TYPE_NONE))
1286 return TEE_ERROR_BAD_PARAMETERS;
1287
1288 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1289 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1290 if (!handle)
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001291 return TEE_ERROR_GENERIC;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001292
1293 add_func = dlsym(handle, "os_test_shlib_dl_add");
1294 if (!add_func)
1295 goto err;
1296 if (add_func(3, 4) != 7)
1297 goto err;
1298
1299 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001300 if (!hnull)
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001301 goto err;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001302
1303 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1304 if (!add_func)
1305 goto err;
1306 if (add_func(5, 6) != 11)
1307 goto err;
1308
1309 res = TEE_SUCCESS;
1310 dlclose(hnull);
1311err:
1312 dlclose(handle);
1313 return res;
1314}
1315
1316TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1317 TEE_Param params[4] __unused)
1318{
1319 int (*panic_func)(void) = NULL;
1320 void *handle = NULL;
1321 TEE_Result res = TEE_ERROR_GENERIC;
1322
1323 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1324 TEE_PARAM_TYPE_NONE,
1325 TEE_PARAM_TYPE_NONE,
1326 TEE_PARAM_TYPE_NONE))
1327 return TEE_ERROR_BAD_PARAMETERS;
1328
1329 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1330 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1331 if (!handle)
1332 return res;
1333
1334 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1335 if (!panic_func)
1336 goto err;
1337 panic_func();
1338 return TEE_ERROR_GENERIC;
1339err:
1340 dlclose(handle);
1341 return res;
1342}
Jerome Forissiere9571e82020-02-18 15:26:20 +01001343
1344/* ELF initialization/finalization test */
1345
Jerome Forissier391168e2020-06-15 09:52:25 +02001346volatile int os_test_global;
Jerome Forissiere9571e82020-02-18 15:26:20 +01001347
1348static void __attribute__((constructor)) os_test_init(void)
1349{
1350 os_test_global *= 10;
1351 os_test_global += 1;
1352 DMSG("os_test_global=%d", os_test_global);
1353}
1354
1355TEE_Result ta_entry_get_global_var(uint32_t param_types, TEE_Param params[4])
1356{
1357 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1358 TEE_PARAM_TYPE_NONE,
1359 TEE_PARAM_TYPE_NONE,
1360 TEE_PARAM_TYPE_NONE))
1361 return TEE_ERROR_BAD_PARAMETERS;
1362
1363 params[0].value.a = os_test_global;
1364
1365 return TEE_SUCCESS;
1366}
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001367
1368TEE_Result ta_entry_client_identity(uint32_t param_types, TEE_Param params[4])
1369{
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001370 TEE_Result res = TEE_ERROR_GENERIC;
1371 TEE_Identity identity = { };
1372
1373 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1374 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1375 TEE_PARAM_TYPE_NONE,
1376 TEE_PARAM_TYPE_NONE))
1377 return TEE_ERROR_BAD_PARAMETERS;
1378
1379 if (params[1].memref.size < sizeof(TEE_UUID)) {
1380 params[1].memref.size = sizeof(TEE_UUID);
1381 return TEE_ERROR_SHORT_BUFFER;
1382 }
1383
1384 res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
1385 "gpd.client.identity", &identity);
1386 if (res != TEE_SUCCESS) {
1387 EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32, res);
1388 return res;
1389 }
1390
1391 params[0].value.a = identity.login;
1392 memcpy(params[1].memref.buffer, &identity.uuid, sizeof(TEE_UUID));
1393 params[1].memref.size = sizeof(TEE_UUID);
1394
1395 return res;
1396}
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001397
Jerome Forissier6d66ca92020-11-10 15:56:06 +01001398#if defined(WITH_TLS_TESTS)
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001399__thread int os_test_tls_a;
1400__thread int os_test_tls_b = 42;
1401
1402TEE_Result ta_entry_tls_test_main(void)
1403{
1404 if (os_test_tls_a != 0) {
1405 EMSG("os_test_tls_a=%d, expected 0", os_test_tls_a);
1406 return TEE_ERROR_GENERIC;
1407 }
1408 if (os_test_tls_b != 42) {
1409 EMSG("os_test_tls_b=%d, expected 42", os_test_tls_b);
1410 return TEE_ERROR_GENERIC;
1411 }
1412
1413 return TEE_SUCCESS;
1414}
1415
1416TEE_Result ta_entry_tls_test_shlib(void)
1417{
1418 if (os_test_shlib_tls_a != 0) {
1419 EMSG("os_test_shlib_tls_a=%d, expected 0", os_test_shlib_tls_a);
1420 return TEE_ERROR_GENERIC;
1421 }
1422 if (os_test_shlib_tls_b != 123) {
1423 EMSG("os_test_shlib_tls_b=%d, expected 123",
1424 os_test_shlib_tls_b);
1425 return TEE_ERROR_GENERIC;
1426 }
1427
1428 return TEE_SUCCESS;
1429}
Jerome Forissier6d66ca92020-11-10 15:56:06 +01001430#else
1431TEE_Result ta_entry_tls_test_main(void)
1432{
1433 return TEE_ERROR_NOT_SUPPORTED;
1434}
1435
1436TEE_Result ta_entry_tls_test_shlib(void)
1437{
1438 return TEE_ERROR_NOT_SUPPORTED;
1439}
1440#endif
Jerome Forissier4565c452020-06-17 17:55:00 +02001441
1442static int iterate_hdr_cb(struct dl_phdr_info *info __maybe_unused,
1443 size_t size __unused, void *data)
1444{
1445 int *count = data;
1446
1447 (*count)++;
1448 IMSG("ELF module index: %d", *count);
1449 IMSG(" dlpi_addr=%p", (void *)info->dlpi_addr);
1450 IMSG(" dlpi_name='%s'", info->dlpi_name);
1451 IMSG(" dlpi_phdr=%p", (void *)info->dlpi_phdr);
1452 IMSG(" dlpi_phnum=%hu", info->dlpi_phnum);
1453 IMSG(" dlpi_adds=%llu", info->dlpi_adds);
1454 IMSG(" dlpi_subs=%llu", info->dlpi_subs);
1455 IMSG(" dlpi_tls_modid=%zu", info->dlpi_tls_modid);
1456 IMSG(" dlpi_tls_data=%p", info->dlpi_tls_data);
1457
1458 return 123;
1459}
1460
1461static TEE_Result expect_dl_count_ge(size_t exp_count)
1462{
1463 int st = 0;
1464 size_t count = 0;
1465
1466 st = dl_iterate_phdr(iterate_hdr_cb, (void *)&count);
1467 if (st != 123) {
1468 /*
1469 * dl_iterate_phdr() should return the last value returned by
1470 * the callback
1471 */
1472 EMSG("Expected return value 123, got %d", st);
1473 return TEE_ERROR_GENERIC;
1474 }
1475 if (count < exp_count) {
1476 /*
1477 * Expect >= and not == since there could be more shared
1478 * libraries (for instance, CFG_ULIBS_SHARED=y)
1479 */
1480 EMSG("Expected count > %zu, got: %zu", exp_count, count);
1481 return TEE_ERROR_GENERIC;
1482 }
1483
1484 return TEE_SUCCESS;
1485}
1486
1487TEE_Result ta_entry_dl_phdr(void)
1488{
1489 return expect_dl_count_ge(2);
1490}
1491
1492TEE_Result ta_entry_dl_phdr_dl(void)
1493{
1494 TEE_Result res = TEE_ERROR_GENERIC;
1495 void *handle = NULL;
1496
1497 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1498 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1499 if (!handle)
1500 return TEE_ERROR_GENERIC;
1501
1502 res = expect_dl_count_ge(3);
1503 dlclose(handle);
1504
1505 return res;
1506}
Jens Wiklander50339ef2022-04-12 20:47:27 +02001507
1508TEE_Result ta_entry_memtag_use_after_free(void)
1509{
1510 uint32_t *p = NULL;
1511
1512 if (!memtag_is_enabled())
1513 return TEE_ERROR_NOT_SUPPORTED;
1514
1515 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1516 *p = 43;
1517 TEE_Free(p);
1518 (*p) += 2;
1519 return TEE_ERROR_GENERIC;
1520}
1521
1522TEE_Result ta_entry_memtag_invalid_tag(void)
1523{
1524 uint32_t *p = NULL;
1525 uint32_t *p2 = NULL;
1526
1527 if (!memtag_is_enabled())
1528 return TEE_ERROR_NOT_SUPPORTED;
1529
1530 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1531
1532 if (!memtag_get_tag(p)) {
1533 EMSG("missing tag in %p", (void *)p);
1534 goto err;
1535 }
1536 *p = 32;
1537
1538 p2 = memtag_insert_tag(p, (memtag_get_tag(p) + 1) & 0xf);
1539 *p2 = 42;
1540 EMSG("Expected to crash when writing to %p which was allocated as %p",
1541 (void *)p2, (void *)p);
1542err:
1543 TEE_Free(p);
1544 return TEE_ERROR_GENERIC;
1545}
1546
1547TEE_Result ta_entry_memtag_double_free(void)
1548{
1549 uint32_t *p = NULL;
1550
1551 if (!memtag_is_enabled())
1552 return TEE_ERROR_NOT_SUPPORTED;
1553
1554 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1555 *p = 43;
1556 TEE_Free(p);
1557 TEE_Free(p);
1558 return TEE_ERROR_GENERIC;
1559}
1560
1561TEE_Result ta_entry_memtag_buffer_overrun(void)
1562{
1563 uint64_t *p = NULL;
1564
1565 if (!memtag_is_enabled())
1566 return TEE_ERROR_NOT_SUPPORTED;
1567
1568 p = TEE_Malloc(sizeof(*p) * 2, TEE_MALLOC_FILL_ZERO);
1569 p[2] += 44;
1570 TEE_Free(p);
1571 return TEE_ERROR_GENERIC;
1572}