blob: e8b5494588e8b0296bd3e1bdee94cda49d8bab64 [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");
Vincent Mailhol9748d2a2023-11-16 20:30:00 +0900538 return res;
Pascal Brandc639ac82015-07-02 08:53:34 +0200539 }
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);
Vincent Mailhol9748d2a2023-11-16 20:30:00 +0900550 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
Pascal Brandc639ac82015-07-02 08:53:34 +0200553 TEE_CloseTASession(sess);
554 return res;
555}
556
557static TEE_Result test_time(void)
558{
Etienne Carriere102092e2019-03-28 15:24:22 +0100559 TEE_Result res = TEE_ERROR_GENERIC;
560 TEE_Time t = { };
561 TEE_Time sys_t = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200562 static const TEE_Time null_time = { 0, 0 };
563 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
564
565 TEE_GetSystemTime(&sys_t);
566 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
567 (unsigned int)sys_t.millis);
568
569 TEE_GetREETime(&t);
570 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
571 (unsigned int)t.millis);
572
573 res = TEE_GetTAPersistentTime(&t);
574 switch (res) {
575 case TEE_SUCCESS:
576 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
577 (unsigned int)t.millis);
578 break;
579 case TEE_ERROR_OVERFLOW:
580 EMSG("Stored TA time overflowed %u.%03u\n",
581 (unsigned int)t.seconds, (unsigned int)t.millis);
582 break;
583 case TEE_ERROR_TIME_NOT_SET:
584 EMSG("TA time not stored\n");
585 break;
586 case TEE_ERROR_TIME_NEEDS_RESET:
587 EMSG("TA time needs reset\n");
588 break;
589 default:
590 return res;
591 }
592
593 res = TEE_SetTAPersistentTime(&null_time);
594 if (res != TEE_SUCCESS) {
595 EMSG("TEE_SetTAPersistentTime: failed\n");
596 return res;
597 }
598
599 res = TEE_GetTAPersistentTime(&t);
600 if (res != TEE_SUCCESS) {
601 EMSG("TEE_GetTAPersistentTime null: failed\n");
602 return res;
603 }
604 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
605 (unsigned int)t.millis);
606 /*
607 * The time between TEE_SetTAPersistentTime() and
608 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
609 * it's not even a millisecond.
610 */
611 if (t.seconds > 1 || t.millis >= 1000) {
612 EMSG("Unexpected stored TA time %u.%03u\n",
613 (unsigned int)t.seconds, (unsigned int)t.millis);
614 return TEE_ERROR_BAD_STATE;
615 }
616
617 res = TEE_SetTAPersistentTime(&wrap_time);
618 if (res != TEE_SUCCESS) {
619 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
620 return res;
621 }
622
623 res = TEE_Wait(1000);
624 if (res != TEE_SUCCESS)
625 EMSG("TEE_Wait wrap: failed\n");
626
627 res = TEE_GetTAPersistentTime(&t);
628 if (res != TEE_ERROR_OVERFLOW) {
629 EMSG("TEE_GetTAPersistentTime: failed\n");
630 return TEE_ERROR_BAD_STATE;
631 }
632 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
633 (unsigned int)t.millis);
634
Clement Faurea2c1ce32023-11-06 09:42:53 +0100635 if (t.seconds > 1) {
636 EMSG("Unexpected wrapped time %u.%03u\n",
637 (unsigned int)t.seconds, (unsigned int)t.millis);
Pascal Brandc639ac82015-07-02 08:53:34 +0200638 return TEE_ERROR_BAD_STATE;
639 }
640
641 return TEE_SUCCESS;
642}
643
Jens Wiklander246184a2015-12-11 08:28:59 +0100644#ifdef CFG_TA_FLOAT_SUPPORT
645static bool my_dcmpeq(double v1, double v2, double prec)
646{
647 return v1 > (v2 - prec) && v1 < (v2 + prec);
648}
649
650static bool my_fcmpeq(float v1, float v2, float prec)
651{
652 return v1 > (v2 - prec) && v1 < (v2 + prec);
653}
654
655
656static TEE_Result test_float(void)
657{
658#define VAL1 2.6
659#define VAL1_INT 2
660#define VAL2 5.3
661#define DPREC 0.000000000000001
662#define FPREC 0.000001
663#define EXPECT(expr) do { \
664 if (!(expr)) { \
665 EMSG("Expression %s failed", #expr); \
666 return TEE_ERROR_GENERIC; \
667 } \
668 } while (0)
669
670 IMSG("Testing floating point operations");
671
672 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
673 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
674 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
675 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
676 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
677
678 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
679 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
680 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
681 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
682 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
683
684 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
685 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
686 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
687 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
688 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
689
690 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
691 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
692 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
693 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
694 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
695
696 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
697 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
698 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
699 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
700
701 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
702 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
703 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
704 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
705
706 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
707 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
708
709 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
710 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
711 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
712 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
713
714 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
715 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
716 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
717 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
718 return TEE_SUCCESS;
719}
720#else /*CFG_TA_FLOAT_SUPPORT*/
721static TEE_Result test_float(void)
722{
723 IMSG("Floating point disabled");
724 return TEE_SUCCESS;
725}
726#endif /*CFG_TA_FLOAT_SUPPORT*/
727
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100728#if defined(CFG_TA_BGET_TEST)
729/* From libutils */
730int bget_main_test(void *(*malloc_func)(size_t), void (*free_func)(void *));
731
732static void *malloc_wrapper(size_t size)
733{
734 return tee_map_zi(size, 0);
735}
736
737static void free_wrapper(void *ptr __unused)
738{
739}
740
Etienne Carriere24fcf0e2023-03-07 17:44:00 +0100741static bool optee_pager_with_small_pool(void)
742{
743 uint32_t ptypes = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
744 TEE_PARAM_TYPE_VALUE_OUTPUT,
745 TEE_PARAM_TYPE_VALUE_OUTPUT,
746 TEE_PARAM_TYPE_NONE);
747 static const TEE_UUID uuid = STATS_UUID;
748 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
749 TEE_Result res = TEE_ERROR_GENERIC;
750 TEE_Param params[4] = { };
751 uint32_t eo = 0;
752 bool rc = false;
753
754 res = TEE_OpenTASession(&uuid, TEE_TIMEOUT_INFINITE, 0, NULL, &sess,
755 &eo);
756 if (res)
757 return false;
758
759 res = TEE_InvokeTACommand(sess, 0, STATS_CMD_PAGER_STATS,
760 ptypes, params, &eo);
761 if (res == TEE_SUCCESS &&
762 params[0].value.b && params[0].value.b <= PAGER_PAGE_COUNT_THRESHOLD)
763 rc = true;
764
765 TEE_CloseTASession(sess);
766
767 return rc;
768}
769
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100770static TEE_Result test_bget(void)
771{
Etienne Carriere24fcf0e2023-03-07 17:44:00 +0100772 if (optee_pager_with_small_pool()) {
773 IMSG("Skip testing bget due to pager pool constraints");
774 return TEE_SUCCESS;
775 }
776
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100777 DMSG("Testing bget");
778 if (bget_main_test(malloc_wrapper, free_wrapper)) {
779 EMSG("bget_main_test failed");
780 return TEE_ERROR_GENERIC;
781 }
782 DMSG("Bget OK");
783 return TEE_SUCCESS;
784}
785#else
786static TEE_Result test_bget(void)
787{
788 IMSG("Bget test disabled");
789 return TEE_SUCCESS;
790}
791#endif
792
793
Jerome Forissier892ae4d2020-03-09 09:58:09 +0100794static __noinline __noreturn void call_longjmp(jmp_buf env)
Jens Wiklander9f682c62016-03-27 20:23:06 +0200795{
796 DMSG("Calling longjmp");
797 longjmp(env, 1);
798 EMSG("error: longjmp returned to calling function");
799}
800
801static TEE_Result test_setjmp(void)
802{
Etienne Carriere102092e2019-03-28 15:24:22 +0100803 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200804
805 if (setjmp(env)) {
806 IMSG("Returned via longjmp");
807 return TEE_SUCCESS;
808 } else {
809 call_longjmp(env);
810 return TEE_ERROR_GENERIC;
811 }
812}
813
Pascal Brandc639ac82015-07-02 08:53:34 +0200814TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
815{
816 TEE_Result res = TEE_ERROR_GENERIC;
817
818 printf("ta_entry_basic: enter\n");
819
820 res = test_malloc();
821 if (res != TEE_SUCCESS)
822 return res;
823
824 res = test_properties();
825 if (res != TEE_SUCCESS)
826 return res;
827
828 res = test_mem_access_right(param_types, params);
829 if (res != TEE_SUCCESS)
830 return res;
831
832 res = test_time();
833 if (res != TEE_SUCCESS)
834 return res;
835
Jens Wiklander246184a2015-12-11 08:28:59 +0100836 res = test_float();
837 if (res != TEE_SUCCESS)
838 return res;
839
Jens Wiklander9f682c62016-03-27 20:23:06 +0200840 res = test_setjmp();
841 if (res != TEE_SUCCESS)
842 return res;
843
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100844 res = test_bget();
845 if (res != TEE_SUCCESS)
846 return res;
847
Pascal Brandc639ac82015-07-02 08:53:34 +0200848 return TEE_SUCCESS;
849}
850
851TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
852{
853 volatile bool mytrue = true;
854 (void)param_types;
855 (void)params;
856
857 printf("ta_entry_panic: enter\n");
858 /*
859 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
860 * the __noreturn attribute.
861 */
862 if (mytrue)
863 TEE_Panic(0xbeef);
864
865 /*
866 * Should not be reached, but if it is the testsuite can detect that
867 * TEE_Panic() returned instead of panicking the TA.
868 */
869 return TEE_SUCCESS;
870}
871
872TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
873 TEE_Param params[4])
874{
875 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100876 TEE_Result res = TEE_ERROR_GENERIC;
877 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
878 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200879
880 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
881 TEE_PARAM_TYPE_NONE,
882 TEE_PARAM_TYPE_NONE,
883 TEE_PARAM_TYPE_NONE)) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900884 EMSG("bad parameters\n");
Pascal Brandc639ac82015-07-02 08:53:34 +0200885 return TEE_ERROR_BAD_PARAMETERS;
886 }
887
Cedric Augere668b3f2019-09-11 13:41:21 +0200888 res = TEE_OpenTASession(&os_test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
889 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200890 if (res != TEE_SUCCESS) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900891 EMSG("TEE_OpenTASession failed\n");
Pascal Brandc639ac82015-07-02 08:53:34 +0200892 return res;
893 }
894
895 res =
896 TEE_InvokeTACommand(sess, params[0].value.a / 2,
897 TA_OS_TEST_CMD_WAIT, param_types, params,
898 &ret_orig);
899
900 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900901 EMSG("TEE_InvokeTACommand: res 0x%x ret_orig 0x%x\n",
902 (unsigned int)res, (unsigned int)ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200903 res = TEE_ERROR_GENERIC;
904 } else
905 res = TEE_SUCCESS;
906
907 TEE_CloseTASession(sess);
908 return res;
909
910}
911
912TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
913{
914 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100915 TEE_Result res = TEE_ERROR_GENERIC;
916 uint32_t l_pts = 0;
917 TEE_Param l_params[4] = { };
918 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
919 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200920 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
921 static const uint8_t sha256_out[] = {
922 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
923 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
924 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
925 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
926 };
927 uint8_t out[32] = { 0 };
928 void *in = NULL;
929
930 (void)param_types;
931 (void)params;
932
933 printf("ta_entry_client: enter\n");
934
935 in = TEE_Malloc(sizeof(sha256_in), 0);
936 if (in == NULL)
937 return TEE_ERROR_OUT_OF_MEMORY;
938 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
939
Cedric Augere668b3f2019-09-11 13:41:21 +0200940 res = TEE_OpenTASession(&crypt_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
941 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200942 if (res != TEE_SUCCESS) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900943 EMSG("TEE_OpenTASession failed\n");
Vincent Mailhol9748d2a2023-11-16 20:30:00 +0900944 goto cleanup_free;
Pascal Brandc639ac82015-07-02 08:53:34 +0200945 }
946
947 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
948 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
949 l_params[0].memref.buffer = in;
950 l_params[0].memref.size = sizeof(sha256_in);
951 l_params[1].memref.buffer = out;
952 l_params[1].memref.size = sizeof(out);
953
Cedric Augere668b3f2019-09-11 13:41:21 +0200954 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
955 TA_CRYPT_CMD_SHA256, l_pts, l_params,
Pascal Brandc639ac82015-07-02 08:53:34 +0200956 &ret_orig);
957 if (res != TEE_SUCCESS) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900958 EMSG("TEE_InvokeTACommand failed\n");
Vincent Mailhol9748d2a2023-11-16 20:30:00 +0900959 goto cleanup_close_session;
Pascal Brandc639ac82015-07-02 08:53:34 +0200960 }
961
962 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
Vincent Mailhol4e5d6c02023-11-19 13:20:47 +0900963 EMSG("out parameter failed\n");
Pascal Brandc639ac82015-07-02 08:53:34 +0200964 res = TEE_ERROR_GENERIC;
Vincent Mailhol9748d2a2023-11-16 20:30:00 +0900965 goto cleanup_close_session;
Pascal Brandc639ac82015-07-02 08:53:34 +0200966 }
967
Vincent Mailhol9748d2a2023-11-16 20:30:00 +0900968cleanup_close_session:
Pascal Brandc639ac82015-07-02 08:53:34 +0200969 TEE_CloseTASession(sess);
Vincent Mailhol9748d2a2023-11-16 20:30:00 +0900970cleanup_free:
971 TEE_Free(in);
Pascal Brandc639ac82015-07-02 08:53:34 +0200972 return res;
973}
974
Etienne Carriere281065d2016-10-28 15:41:33 +0200975TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200976{
Etienne Carriere102092e2019-03-28 15:24:22 +0100977 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200978
979 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100980 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
981 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Vincent Mailholc7391612023-11-19 13:11:12 +0900982 return TEE_ERROR_BAD_PARAMETERS;
Etienne Carriere281065d2016-10-28 15:41:33 +0200983
984 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
985 TEE_MEMORY_ACCESS_ANY_OWNER,
986 params[0].memref.buffer,
987 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200988 if (res != TEE_SUCCESS)
989 return res;
990
991 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
992 params[0].memref.buffer,
993 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200994 if (res != TEE_ERROR_ACCESS_DENIED)
995 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +0100996 if (params[1].memref.buffer || params[1].memref.size)
997 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200998
Etienne Carriere281065d2016-10-28 15:41:33 +0200999 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +02001000}
1001
1002TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
1003{
1004 TEE_Result res = TEE_SUCCESS;
1005 (void)param_types;
1006
1007 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
1008 /* Wait */
1009 res = TEE_Wait(params[0].value.a);
1010
1011 return res;
1012}
1013
Jens Wiklander1425f952016-07-21 09:02:30 +02001014static void undef_instr(void)
1015{
1016#if defined(ARM64)
1017 __asm__(".word 0x0");
1018#elif defined(ARM32)
1019 __asm__(".word 0xe7ffffff");
Marouene Boubakri38fd7892023-01-06 10:45:15 +01001020#elif defined(RV64) || defined(RV32)
1021 __asm__(".word 0x0");
Jens Wiklander1425f952016-07-21 09:02:30 +02001022#else
1023#error "Unsupported architecture"
1024#endif
1025}
1026
Pascal Brandc639ac82015-07-02 08:53:34 +02001027TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
1028{
Etienne Carriere102092e2019-03-28 15:24:22 +01001029 long int stack = 0;
1030 long int stack_addr = (long int)&stack;
Jerome Forissiere2a58c62019-09-19 16:01:54 +02001031 void (*volatile null_fn_ptr)(void) = NULL;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001032 char *zero_size_malloc = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +02001033
Etienne Carriere92c34422018-02-09 13:11:40 +01001034 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
1035 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
1036 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Vincent Mailholc7391612023-11-19 13:11:12 +09001037 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +02001038
1039 switch (params[0].value.a) {
1040 case 1:
Jerome Forissier71da60f2019-09-19 15:59:56 +02001041 *((volatile uint32_t *)0) = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +02001042 break;
1043 case 2:
1044 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
1045 break;
1046 case 3:
Jerome Forissiere2a58c62019-09-19 16:01:54 +02001047 null_fn_ptr();
Pascal Brandc639ac82015-07-02 08:53:34 +02001048 break;
1049 case 4:
1050 ((void (*)(void))(stack_addr + 0x40000000)) ();
1051 break;
1052 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +02001053 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +02001054 break;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001055 case 6:
1056 zero_size_malloc = TEE_Malloc(0, 0);
1057 if (!zero_size_malloc)
1058 return TEE_ERROR_GENERIC;
Etienne Carriere713db5a2021-09-29 20:32:32 +02001059 if (*zero_size_malloc)
1060 return TEE_ERROR_GENERIC;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001061 break;
1062 case 7:
1063 zero_size_malloc = TEE_Malloc(0, 0);
1064 if (!zero_size_malloc)
1065 return TEE_ERROR_GENERIC;
1066 *zero_size_malloc = 0;
1067 break;
Pascal Brandc639ac82015-07-02 08:53:34 +02001068 default:
1069 break;
1070 }
1071
1072 return TEE_SUCCESS;
1073}
Jerome Forissiere916b102017-06-07 17:55:52 +02001074
1075static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
1076{
Etienne Carriere102092e2019-03-28 15:24:22 +01001077 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001078
1079 for (i = 0; i < bufsize; i++) {
1080 a[i]++; b[i]++; c[i]++;
1081 }
1082}
1083
Etienne Carriere102092e2019-03-28 15:24:22 +01001084#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +02001085TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
1086{
1087 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
1088 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +01001089 TEE_Param l_params[4] = { };
1090 uint8_t in[TA2TA_BUF_SIZE] = { };
1091 uint8_t inout[TA2TA_BUF_SIZE] = { };
1092 uint8_t out[TA2TA_BUF_SIZE] = { };
1093 TEE_Result res = TEE_ERROR_GENERIC;
1094 uint32_t ret_orig = 0;
1095 uint32_t l_pts = 0;
1096 size_t i = 0;
1097
Jerome Forissiere916b102017-06-07 17:55:52 +02001098 (void)params;
1099
1100 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
Vincent Mailholc7391612023-11-19 13:11:12 +09001101 return TEE_ERROR_BAD_PARAMETERS;
Jerome Forissiere916b102017-06-07 17:55:52 +02001102
Cedric Augere668b3f2019-09-11 13:41:21 +02001103 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
1104 &sess, &ret_orig);
Jerome Forissiere916b102017-06-07 17:55:52 +02001105 if (res != TEE_SUCCESS) {
1106 EMSG("TEE_OpenTASession failed");
Vincent Mailhol9748d2a2023-11-16 20:30:00 +09001107 return res;
Jerome Forissiere916b102017-06-07 17:55:52 +02001108 }
1109
1110 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1111 TEE_PARAM_TYPE_MEMREF_INOUT,
1112 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
1113 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +01001114 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001115 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +01001116 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001117 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +01001118 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001119
1120 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +01001121 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001122 in[i] = 5;
1123 inout[i] = 10;
1124 out[i] = 0;
1125 }
1126
1127 /*
1128 * TA will compute: out = ++inout + in
1129 * Expected values after this step: in: 5, inout: 11, out: 16
1130 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001131 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1132 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001133 l_pts, l_params, &ret_orig);
1134 if (res != TEE_SUCCESS) {
1135 EMSG("TEE_InvokeTACommand failed");
1136 goto cleanup_return;
1137 }
Etienne Carriere102092e2019-03-28 15:24:22 +01001138
Jerome Forissiere916b102017-06-07 17:55:52 +02001139 /*
1140 * Increment all values by one.
1141 * Expected values after this step: in: 6, inout: 12, out: 17
1142 */
Etienne Carriere102092e2019-03-28 15:24:22 +01001143 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +02001144
1145 /*
1146 * TA will compute: out = ++inout + in
1147 * Expected values after this step: in: 6, inout: 13, out: 19
1148 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001149 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1150 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001151 l_pts, l_params, &ret_orig);
1152 if (res != TEE_SUCCESS) {
1153 EMSG("TEE_InvokeTACommand failed");
1154 goto cleanup_return;
1155 }
1156
1157 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001158 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001159 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1160 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001161 DHEXDUMP(in, TA2TA_BUF_SIZE);
1162 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1163 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001164 return TEE_ERROR_GENERIC;
1165 }
1166 }
1167
1168cleanup_return:
1169 TEE_CloseTASession(sess);
1170 return res;
1171}
Vincent Mailholbbbb4852023-11-16 16:19:06 +09001172#undef TA2TA_BUF_SIZE
Jerome Forissiere916b102017-06-07 17:55:52 +02001173
Vincent Mailholda741cd2023-11-16 20:20:54 +09001174TEE_Result ta_entry_ta2ta_memref_size0(uint32_t param_types, TEE_Param params[4])
1175{
1176 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
1177 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
1178 uint32_t ret_orig = 0;
1179 TEE_Result res = TEE_ERROR_GENERIC;
1180
1181 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1182 TEE_PARAM_TYPE_MEMREF_INOUT,
1183 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1184 TEE_PARAM_TYPE_NONE))
1185 return TEE_ERROR_BAD_PARAMETERS;
1186
1187 /*
1188 * This test expects all memory references to be non-NULL but
1189 * all sizes to be zero.
1190 */
1191 if (!params[0].memref.buffer || params[0].memref.size ||
1192 !params[1].memref.buffer || params[1].memref.size ||
1193 !params[2].memref.buffer || params[2].memref.size)
1194 return TEE_ERROR_BAD_PARAMETERS;
1195
1196 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
1197 &sess, &ret_orig);
1198 if (res != TEE_SUCCESS) {
1199 EMSG("TEE_OpenTASession failed");
1200 return res;
1201 }
1202
1203 /*
1204 * TA basically does nothing. The actual test just consists
1205 * into validating that passing non-NULL memref of size zero
1206 * does not panic.
1207 */
1208 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1209 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
1210 param_types, params, &ret_orig);
1211
1212 TEE_CloseTASession(sess);
1213 return res;
1214}
1215
Jerome Forissiere916b102017-06-07 17:55:52 +02001216TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1217{
Etienne Carriere102092e2019-03-28 15:24:22 +01001218 uint8_t *in = NULL;
1219 uint8_t *inout = NULL;
1220 uint8_t *out = NULL;
1221 size_t bufsize = 0;
1222 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001223
1224 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1225 TEE_PARAM_TYPE_MEMREF_INOUT,
1226 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
Vincent Mailholc7391612023-11-19 13:11:12 +09001227 return TEE_ERROR_BAD_PARAMETERS;
Jerome Forissiere916b102017-06-07 17:55:52 +02001228
1229 bufsize = params[0].memref.size;
1230 if (params[1].memref.size != bufsize ||
1231 params[2].memref.size != bufsize)
Vincent Mailholc7391612023-11-19 13:11:12 +09001232 return TEE_ERROR_BAD_PARAMETERS;
Jerome Forissiere916b102017-06-07 17:55:52 +02001233
1234 in = params[0].memref.buffer;
1235 inout = params[1].memref.buffer;
1236 out = params[2].memref.buffer;
1237
1238 for (i = 0; i < bufsize; i++)
1239 out[i] = ++inout[i] + in[i];
1240
1241 return TEE_SUCCESS;
1242}
Jens Wiklander87e81702018-03-20 12:00:00 +08001243
1244TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1245{
Etienne Carriere102092e2019-03-28 15:24:22 +01001246 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001247
1248 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1249 TEE_PARAM_TYPE_MEMREF_INPUT,
1250 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1251 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1252 return TEE_ERROR_BAD_PARAMETERS;
1253
1254 for (n = 0; n < TEE_NUM_PARAMS; n++)
1255 if (!params[n].memref.buffer || !params[n].memref.size)
1256 return TEE_ERROR_BAD_PARAMETERS;
1257
1258 return TEE_SUCCESS;
1259}
Jerome Forissier53bde722018-05-31 09:14:54 +02001260
Cedric Neveux9f483bb2019-03-04 08:58:06 +01001261TEE_Result ta_entry_null_memref(uint32_t param_types, TEE_Param params[4])
1262{
1263 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1264 TEE_PARAM_TYPE_MEMREF_INPUT,
1265 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1266 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1267 return TEE_ERROR_BAD_PARAMETERS;
1268
1269 /*
1270 * Tests how client can provide null or non-null memref parameters
1271 * param[0] expected as a 0 byte input mapped memeref.
1272 * param[1] expected as a 0 byte input not-mapped memeref.
1273 * param[2] expected as a 0 byte output mapped memeref.
1274 * param[3] expected as a 0 byte output not-mapped memeref.
1275 */
1276 if (!params[0].memref.buffer || params[0].memref.size ||
1277 params[1].memref.buffer || params[1].memref.size ||
1278 !params[2].memref.buffer || params[2].memref.size ||
1279 params[3].memref.buffer || params[3].memref.size)
1280 return TEE_ERROR_BAD_PARAMETERS;
1281
1282 return TEE_SUCCESS;
1283}
1284
Jerome Forissier53bde722018-05-31 09:14:54 +02001285TEE_Result ta_entry_call_lib(uint32_t param_types,
1286 TEE_Param params[4] __unused)
1287{
1288 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1289 TEE_PARAM_TYPE_NONE,
1290 TEE_PARAM_TYPE_NONE,
1291 TEE_PARAM_TYPE_NONE))
1292 return TEE_ERROR_BAD_PARAMETERS;
1293
1294 if (os_test_shlib_add(1, 2) != 3)
1295 return TEE_ERROR_GENERIC;
1296
1297 return TEE_SUCCESS;
1298}
1299
1300TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1301 TEE_Param params[4] __unused)
1302{
1303 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1304 TEE_PARAM_TYPE_NONE,
1305 TEE_PARAM_TYPE_NONE,
1306 TEE_PARAM_TYPE_NONE))
1307 return TEE_ERROR_BAD_PARAMETERS;
1308
1309 os_test_shlib_panic();
1310
1311 return TEE_ERROR_GENERIC;
1312}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001313
1314TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1315 TEE_Param params[4] __unused)
1316{
1317 int (*add_func)(int a, int b) = NULL;
1318 TEE_Result res = TEE_ERROR_GENERIC;
1319 void *handle = NULL;
1320 void *hnull = NULL;
1321
1322 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1323 TEE_PARAM_TYPE_NONE,
1324 TEE_PARAM_TYPE_NONE,
1325 TEE_PARAM_TYPE_NONE))
1326 return TEE_ERROR_BAD_PARAMETERS;
1327
1328 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1329 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1330 if (!handle)
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001331 return TEE_ERROR_GENERIC;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001332
1333 add_func = dlsym(handle, "os_test_shlib_dl_add");
1334 if (!add_func)
1335 goto err;
1336 if (add_func(3, 4) != 7)
1337 goto err;
1338
1339 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001340 if (!hnull)
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001341 goto err;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001342
1343 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1344 if (!add_func)
1345 goto err;
1346 if (add_func(5, 6) != 11)
1347 goto err;
1348
1349 res = TEE_SUCCESS;
1350 dlclose(hnull);
1351err:
1352 dlclose(handle);
1353 return res;
1354}
1355
1356TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1357 TEE_Param params[4] __unused)
1358{
1359 int (*panic_func)(void) = NULL;
1360 void *handle = NULL;
1361 TEE_Result res = TEE_ERROR_GENERIC;
1362
1363 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1364 TEE_PARAM_TYPE_NONE,
1365 TEE_PARAM_TYPE_NONE,
1366 TEE_PARAM_TYPE_NONE))
1367 return TEE_ERROR_BAD_PARAMETERS;
1368
1369 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1370 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1371 if (!handle)
1372 return res;
1373
1374 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1375 if (!panic_func)
1376 goto err;
1377 panic_func();
1378 return TEE_ERROR_GENERIC;
1379err:
1380 dlclose(handle);
1381 return res;
1382}
Jerome Forissiere9571e82020-02-18 15:26:20 +01001383
1384/* ELF initialization/finalization test */
1385
Jerome Forissier391168e2020-06-15 09:52:25 +02001386volatile int os_test_global;
Jerome Forissiere9571e82020-02-18 15:26:20 +01001387
1388static void __attribute__((constructor)) os_test_init(void)
1389{
1390 os_test_global *= 10;
1391 os_test_global += 1;
1392 DMSG("os_test_global=%d", os_test_global);
1393}
1394
1395TEE_Result ta_entry_get_global_var(uint32_t param_types, TEE_Param params[4])
1396{
1397 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1398 TEE_PARAM_TYPE_NONE,
1399 TEE_PARAM_TYPE_NONE,
1400 TEE_PARAM_TYPE_NONE))
1401 return TEE_ERROR_BAD_PARAMETERS;
1402
1403 params[0].value.a = os_test_global;
1404
1405 return TEE_SUCCESS;
1406}
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001407
1408TEE_Result ta_entry_client_identity(uint32_t param_types, TEE_Param params[4])
1409{
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001410 TEE_Result res = TEE_ERROR_GENERIC;
1411 TEE_Identity identity = { };
1412
1413 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1414 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1415 TEE_PARAM_TYPE_NONE,
1416 TEE_PARAM_TYPE_NONE))
1417 return TEE_ERROR_BAD_PARAMETERS;
1418
1419 if (params[1].memref.size < sizeof(TEE_UUID)) {
1420 params[1].memref.size = sizeof(TEE_UUID);
1421 return TEE_ERROR_SHORT_BUFFER;
1422 }
1423
1424 res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
1425 "gpd.client.identity", &identity);
1426 if (res != TEE_SUCCESS) {
1427 EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32, res);
1428 return res;
1429 }
1430
1431 params[0].value.a = identity.login;
1432 memcpy(params[1].memref.buffer, &identity.uuid, sizeof(TEE_UUID));
1433 params[1].memref.size = sizeof(TEE_UUID);
1434
1435 return res;
1436}
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001437
Jerome Forissier6d66ca92020-11-10 15:56:06 +01001438#if defined(WITH_TLS_TESTS)
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001439__thread int os_test_tls_a;
1440__thread int os_test_tls_b = 42;
1441
1442TEE_Result ta_entry_tls_test_main(void)
1443{
1444 if (os_test_tls_a != 0) {
1445 EMSG("os_test_tls_a=%d, expected 0", os_test_tls_a);
1446 return TEE_ERROR_GENERIC;
1447 }
1448 if (os_test_tls_b != 42) {
1449 EMSG("os_test_tls_b=%d, expected 42", os_test_tls_b);
1450 return TEE_ERROR_GENERIC;
1451 }
1452
1453 return TEE_SUCCESS;
1454}
1455
1456TEE_Result ta_entry_tls_test_shlib(void)
1457{
1458 if (os_test_shlib_tls_a != 0) {
1459 EMSG("os_test_shlib_tls_a=%d, expected 0", os_test_shlib_tls_a);
1460 return TEE_ERROR_GENERIC;
1461 }
1462 if (os_test_shlib_tls_b != 123) {
1463 EMSG("os_test_shlib_tls_b=%d, expected 123",
1464 os_test_shlib_tls_b);
1465 return TEE_ERROR_GENERIC;
1466 }
1467
1468 return TEE_SUCCESS;
1469}
Jerome Forissier6d66ca92020-11-10 15:56:06 +01001470#else
1471TEE_Result ta_entry_tls_test_main(void)
1472{
1473 return TEE_ERROR_NOT_SUPPORTED;
1474}
1475
1476TEE_Result ta_entry_tls_test_shlib(void)
1477{
1478 return TEE_ERROR_NOT_SUPPORTED;
1479}
1480#endif
Jerome Forissier4565c452020-06-17 17:55:00 +02001481
1482static int iterate_hdr_cb(struct dl_phdr_info *info __maybe_unused,
1483 size_t size __unused, void *data)
1484{
1485 int *count = data;
1486
1487 (*count)++;
1488 IMSG("ELF module index: %d", *count);
1489 IMSG(" dlpi_addr=%p", (void *)info->dlpi_addr);
1490 IMSG(" dlpi_name='%s'", info->dlpi_name);
1491 IMSG(" dlpi_phdr=%p", (void *)info->dlpi_phdr);
1492 IMSG(" dlpi_phnum=%hu", info->dlpi_phnum);
1493 IMSG(" dlpi_adds=%llu", info->dlpi_adds);
1494 IMSG(" dlpi_subs=%llu", info->dlpi_subs);
1495 IMSG(" dlpi_tls_modid=%zu", info->dlpi_tls_modid);
1496 IMSG(" dlpi_tls_data=%p", info->dlpi_tls_data);
1497
1498 return 123;
1499}
1500
1501static TEE_Result expect_dl_count_ge(size_t exp_count)
1502{
1503 int st = 0;
1504 size_t count = 0;
1505
1506 st = dl_iterate_phdr(iterate_hdr_cb, (void *)&count);
1507 if (st != 123) {
1508 /*
1509 * dl_iterate_phdr() should return the last value returned by
1510 * the callback
1511 */
1512 EMSG("Expected return value 123, got %d", st);
1513 return TEE_ERROR_GENERIC;
1514 }
1515 if (count < exp_count) {
1516 /*
1517 * Expect >= and not == since there could be more shared
1518 * libraries (for instance, CFG_ULIBS_SHARED=y)
1519 */
1520 EMSG("Expected count > %zu, got: %zu", exp_count, count);
1521 return TEE_ERROR_GENERIC;
1522 }
1523
1524 return TEE_SUCCESS;
1525}
1526
1527TEE_Result ta_entry_dl_phdr(void)
1528{
1529 return expect_dl_count_ge(2);
1530}
1531
1532TEE_Result ta_entry_dl_phdr_dl(void)
1533{
1534 TEE_Result res = TEE_ERROR_GENERIC;
1535 void *handle = NULL;
1536
1537 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1538 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1539 if (!handle)
1540 return TEE_ERROR_GENERIC;
1541
1542 res = expect_dl_count_ge(3);
1543 dlclose(handle);
1544
1545 return res;
1546}
Jens Wiklander50339ef2022-04-12 20:47:27 +02001547
1548TEE_Result ta_entry_memtag_use_after_free(void)
1549{
1550 uint32_t *p = NULL;
1551
1552 if (!memtag_is_enabled())
1553 return TEE_ERROR_NOT_SUPPORTED;
1554
1555 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1556 *p = 43;
1557 TEE_Free(p);
1558 (*p) += 2;
1559 return TEE_ERROR_GENERIC;
1560}
1561
1562TEE_Result ta_entry_memtag_invalid_tag(void)
1563{
1564 uint32_t *p = NULL;
1565 uint32_t *p2 = NULL;
1566
1567 if (!memtag_is_enabled())
1568 return TEE_ERROR_NOT_SUPPORTED;
1569
1570 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1571
1572 if (!memtag_get_tag(p)) {
1573 EMSG("missing tag in %p", (void *)p);
1574 goto err;
1575 }
1576 *p = 32;
1577
1578 p2 = memtag_insert_tag(p, (memtag_get_tag(p) + 1) & 0xf);
1579 *p2 = 42;
1580 EMSG("Expected to crash when writing to %p which was allocated as %p",
1581 (void *)p2, (void *)p);
1582err:
1583 TEE_Free(p);
1584 return TEE_ERROR_GENERIC;
1585}
1586
1587TEE_Result ta_entry_memtag_double_free(void)
1588{
1589 uint32_t *p = NULL;
1590
1591 if (!memtag_is_enabled())
1592 return TEE_ERROR_NOT_SUPPORTED;
1593
1594 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1595 *p = 43;
1596 TEE_Free(p);
1597 TEE_Free(p);
1598 return TEE_ERROR_GENERIC;
1599}
1600
1601TEE_Result ta_entry_memtag_buffer_overrun(void)
1602{
1603 uint64_t *p = NULL;
1604
1605 if (!memtag_is_enabled())
1606 return TEE_ERROR_NOT_SUPPORTED;
1607
1608 p = TEE_Malloc(sizeof(*p) * 2, TEE_MALLOC_FILL_ZERO);
1609 p[2] += 44;
1610 TEE_Free(p);
1611 return TEE_ERROR_GENERIC;
1612}