blob: d6edb3df9e2ecb5e8c2ae82db28948231f66c25e [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))
479 return TEE_ERROR_GENERIC;
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) {
537 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
538 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) {
551 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
552 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
638 if (t.seconds > sys_t.seconds) {
639 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
640 (unsigned int)t.seconds, (unsigned int)t.millis,
641 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
642 return TEE_ERROR_BAD_STATE;
643 }
644
645 return TEE_SUCCESS;
646}
647
Jens Wiklander246184a2015-12-11 08:28:59 +0100648#ifdef CFG_TA_FLOAT_SUPPORT
649static bool my_dcmpeq(double v1, double v2, double prec)
650{
651 return v1 > (v2 - prec) && v1 < (v2 + prec);
652}
653
654static bool my_fcmpeq(float v1, float v2, float prec)
655{
656 return v1 > (v2 - prec) && v1 < (v2 + prec);
657}
658
659
660static TEE_Result test_float(void)
661{
662#define VAL1 2.6
663#define VAL1_INT 2
664#define VAL2 5.3
665#define DPREC 0.000000000000001
666#define FPREC 0.000001
667#define EXPECT(expr) do { \
668 if (!(expr)) { \
669 EMSG("Expression %s failed", #expr); \
670 return TEE_ERROR_GENERIC; \
671 } \
672 } while (0)
673
674 IMSG("Testing floating point operations");
675
676 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
677 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
678 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
679 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
680 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
681
682 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
683 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
684 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
685 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
686 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
687
688 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
689 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
690 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
691 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
692 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
693
694 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
695 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
696 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
697 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
698 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
699
700 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
701 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
702 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
703 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
704
705 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
706 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
707 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
708 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
709
710 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
711 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
712
713 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
714 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
715 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
716 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
717
718 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
719 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
720 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
721 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
722 return TEE_SUCCESS;
723}
724#else /*CFG_TA_FLOAT_SUPPORT*/
725static TEE_Result test_float(void)
726{
727 IMSG("Floating point disabled");
728 return TEE_SUCCESS;
729}
730#endif /*CFG_TA_FLOAT_SUPPORT*/
731
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100732#if defined(CFG_TA_BGET_TEST)
733/* From libutils */
734int bget_main_test(void *(*malloc_func)(size_t), void (*free_func)(void *));
735
736static void *malloc_wrapper(size_t size)
737{
738 return tee_map_zi(size, 0);
739}
740
741static void free_wrapper(void *ptr __unused)
742{
743}
744
Etienne Carriere24fcf0e2023-03-07 17:44:00 +0100745static bool optee_pager_with_small_pool(void)
746{
747 uint32_t ptypes = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
748 TEE_PARAM_TYPE_VALUE_OUTPUT,
749 TEE_PARAM_TYPE_VALUE_OUTPUT,
750 TEE_PARAM_TYPE_NONE);
751 static const TEE_UUID uuid = STATS_UUID;
752 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
753 TEE_Result res = TEE_ERROR_GENERIC;
754 TEE_Param params[4] = { };
755 uint32_t eo = 0;
756 bool rc = false;
757
758 res = TEE_OpenTASession(&uuid, TEE_TIMEOUT_INFINITE, 0, NULL, &sess,
759 &eo);
760 if (res)
761 return false;
762
763 res = TEE_InvokeTACommand(sess, 0, STATS_CMD_PAGER_STATS,
764 ptypes, params, &eo);
765 if (res == TEE_SUCCESS &&
766 params[0].value.b && params[0].value.b <= PAGER_PAGE_COUNT_THRESHOLD)
767 rc = true;
768
769 TEE_CloseTASession(sess);
770
771 return rc;
772}
773
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100774static TEE_Result test_bget(void)
775{
Etienne Carriere24fcf0e2023-03-07 17:44:00 +0100776 if (optee_pager_with_small_pool()) {
777 IMSG("Skip testing bget due to pager pool constraints");
778 return TEE_SUCCESS;
779 }
780
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100781 DMSG("Testing bget");
782 if (bget_main_test(malloc_wrapper, free_wrapper)) {
783 EMSG("bget_main_test failed");
784 return TEE_ERROR_GENERIC;
785 }
786 DMSG("Bget OK");
787 return TEE_SUCCESS;
788}
789#else
790static TEE_Result test_bget(void)
791{
792 IMSG("Bget test disabled");
793 return TEE_SUCCESS;
794}
795#endif
796
797
Jerome Forissier892ae4d2020-03-09 09:58:09 +0100798static __noinline __noreturn void call_longjmp(jmp_buf env)
Jens Wiklander9f682c62016-03-27 20:23:06 +0200799{
800 DMSG("Calling longjmp");
801 longjmp(env, 1);
802 EMSG("error: longjmp returned to calling function");
803}
804
805static TEE_Result test_setjmp(void)
806{
Etienne Carriere102092e2019-03-28 15:24:22 +0100807 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200808
809 if (setjmp(env)) {
810 IMSG("Returned via longjmp");
811 return TEE_SUCCESS;
812 } else {
813 call_longjmp(env);
814 return TEE_ERROR_GENERIC;
815 }
816}
817
Pascal Brandc639ac82015-07-02 08:53:34 +0200818TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
819{
820 TEE_Result res = TEE_ERROR_GENERIC;
821
822 printf("ta_entry_basic: enter\n");
823
824 res = test_malloc();
825 if (res != TEE_SUCCESS)
826 return res;
827
828 res = test_properties();
829 if (res != TEE_SUCCESS)
830 return res;
831
832 res = test_mem_access_right(param_types, params);
833 if (res != TEE_SUCCESS)
834 return res;
835
836 res = test_time();
837 if (res != TEE_SUCCESS)
838 return res;
839
Jens Wiklander246184a2015-12-11 08:28:59 +0100840 res = test_float();
841 if (res != TEE_SUCCESS)
842 return res;
843
Jens Wiklander9f682c62016-03-27 20:23:06 +0200844 res = test_setjmp();
845 if (res != TEE_SUCCESS)
846 return res;
847
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100848 res = test_bget();
849 if (res != TEE_SUCCESS)
850 return res;
851
Pascal Brandc639ac82015-07-02 08:53:34 +0200852 return TEE_SUCCESS;
853}
854
855TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
856{
857 volatile bool mytrue = true;
858 (void)param_types;
859 (void)params;
860
861 printf("ta_entry_panic: enter\n");
862 /*
863 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
864 * the __noreturn attribute.
865 */
866 if (mytrue)
867 TEE_Panic(0xbeef);
868
869 /*
870 * Should not be reached, but if it is the testsuite can detect that
871 * TEE_Panic() returned instead of panicking the TA.
872 */
873 return TEE_SUCCESS;
874}
875
876TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
877 TEE_Param params[4])
878{
879 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100880 TEE_Result res = TEE_ERROR_GENERIC;
881 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
882 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200883
884 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
885 TEE_PARAM_TYPE_NONE,
886 TEE_PARAM_TYPE_NONE,
887 TEE_PARAM_TYPE_NONE)) {
888 EMSG("ta_entry_client_with_timeout: bad parameters\n");
889 return TEE_ERROR_BAD_PARAMETERS;
890 }
891
Cedric Augere668b3f2019-09-11 13:41:21 +0200892 res = TEE_OpenTASession(&os_test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
893 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200894 if (res != TEE_SUCCESS) {
895 EMSG(
896 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
897 return res;
898 }
899
900 res =
901 TEE_InvokeTACommand(sess, params[0].value.a / 2,
902 TA_OS_TEST_CMD_WAIT, param_types, params,
903 &ret_orig);
904
905 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
906 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
907 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
908 (unsigned int)ret_orig);
909 res = TEE_ERROR_GENERIC;
910 } else
911 res = TEE_SUCCESS;
912
913 TEE_CloseTASession(sess);
914 return res;
915
916}
917
918TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
919{
920 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100921 TEE_Result res = TEE_ERROR_GENERIC;
922 uint32_t l_pts = 0;
923 TEE_Param l_params[4] = { };
924 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
925 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200926 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
927 static const uint8_t sha256_out[] = {
928 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
929 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
930 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
931 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
932 };
933 uint8_t out[32] = { 0 };
934 void *in = NULL;
935
936 (void)param_types;
937 (void)params;
938
939 printf("ta_entry_client: enter\n");
940
941 in = TEE_Malloc(sizeof(sha256_in), 0);
942 if (in == NULL)
943 return TEE_ERROR_OUT_OF_MEMORY;
944 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
945
Cedric Augere668b3f2019-09-11 13:41:21 +0200946 res = TEE_OpenTASession(&crypt_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
947 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200948 if (res != TEE_SUCCESS) {
949 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
950 goto cleanup_return;
951 }
952
953 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
954 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
955 l_params[0].memref.buffer = in;
956 l_params[0].memref.size = sizeof(sha256_in);
957 l_params[1].memref.buffer = out;
958 l_params[1].memref.size = sizeof(out);
959
Cedric Augere668b3f2019-09-11 13:41:21 +0200960 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
961 TA_CRYPT_CMD_SHA256, l_pts, l_params,
Pascal Brandc639ac82015-07-02 08:53:34 +0200962 &ret_orig);
963 if (res != TEE_SUCCESS) {
964 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
965 goto cleanup_return;
966 }
967
968 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
969 EMSG("ta_entry_client: out parameter failed\n");
970 res = TEE_ERROR_GENERIC;
971 goto cleanup_return;
972 }
973
974cleanup_return:
975 TEE_Free(in);
976 TEE_CloseTASession(sess);
977 return res;
978}
979
Etienne Carriere281065d2016-10-28 15:41:33 +0200980TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200981{
Etienne Carriere102092e2019-03-28 15:24:22 +0100982 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200983
984 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100985 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
986 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200987 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200988
989 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
990 TEE_MEMORY_ACCESS_ANY_OWNER,
991 params[0].memref.buffer,
992 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200993 if (res != TEE_SUCCESS)
994 return res;
995
996 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
997 params[0].memref.buffer,
998 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200999 if (res != TEE_ERROR_ACCESS_DENIED)
1000 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +01001001 if (params[1].memref.buffer || params[1].memref.size)
1002 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +02001003
Etienne Carriere281065d2016-10-28 15:41:33 +02001004 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +02001005}
1006
1007TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
1008{
1009 TEE_Result res = TEE_SUCCESS;
1010 (void)param_types;
1011
1012 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
1013 /* Wait */
1014 res = TEE_Wait(params[0].value.a);
1015
1016 return res;
1017}
1018
Jens Wiklander1425f952016-07-21 09:02:30 +02001019static void undef_instr(void)
1020{
1021#if defined(ARM64)
1022 __asm__(".word 0x0");
1023#elif defined(ARM32)
1024 __asm__(".word 0xe7ffffff");
Marouene Boubakri38fd7892023-01-06 10:45:15 +01001025#elif defined(RV64) || defined(RV32)
1026 __asm__(".word 0x0");
Jens Wiklander1425f952016-07-21 09:02:30 +02001027#else
1028#error "Unsupported architecture"
1029#endif
1030}
1031
Pascal Brandc639ac82015-07-02 08:53:34 +02001032TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
1033{
Etienne Carriere102092e2019-03-28 15:24:22 +01001034 long int stack = 0;
1035 long int stack_addr = (long int)&stack;
Jerome Forissiere2a58c62019-09-19 16:01:54 +02001036 void (*volatile null_fn_ptr)(void) = NULL;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001037 char *zero_size_malloc = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +02001038
Etienne Carriere92c34422018-02-09 13:11:40 +01001039 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
1040 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
1041 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +02001042 return TEE_ERROR_GENERIC;
1043
1044 switch (params[0].value.a) {
1045 case 1:
Jerome Forissier71da60f2019-09-19 15:59:56 +02001046 *((volatile uint32_t *)0) = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +02001047 break;
1048 case 2:
1049 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
1050 break;
1051 case 3:
Jerome Forissiere2a58c62019-09-19 16:01:54 +02001052 null_fn_ptr();
Pascal Brandc639ac82015-07-02 08:53:34 +02001053 break;
1054 case 4:
1055 ((void (*)(void))(stack_addr + 0x40000000)) ();
1056 break;
1057 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +02001058 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +02001059 break;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001060 case 6:
1061 zero_size_malloc = TEE_Malloc(0, 0);
1062 if (!zero_size_malloc)
1063 return TEE_ERROR_GENERIC;
Etienne Carriere713db5a2021-09-29 20:32:32 +02001064 if (*zero_size_malloc)
1065 return TEE_ERROR_GENERIC;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001066 break;
1067 case 7:
1068 zero_size_malloc = TEE_Malloc(0, 0);
1069 if (!zero_size_malloc)
1070 return TEE_ERROR_GENERIC;
1071 *zero_size_malloc = 0;
1072 break;
Pascal Brandc639ac82015-07-02 08:53:34 +02001073 default:
1074 break;
1075 }
1076
1077 return TEE_SUCCESS;
1078}
Jerome Forissiere916b102017-06-07 17:55:52 +02001079
1080static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
1081{
Etienne Carriere102092e2019-03-28 15:24:22 +01001082 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001083
1084 for (i = 0; i < bufsize; i++) {
1085 a[i]++; b[i]++; c[i]++;
1086 }
1087}
1088
Etienne Carriere102092e2019-03-28 15:24:22 +01001089#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +02001090TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
1091{
1092 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
1093 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +01001094 TEE_Param l_params[4] = { };
1095 uint8_t in[TA2TA_BUF_SIZE] = { };
1096 uint8_t inout[TA2TA_BUF_SIZE] = { };
1097 uint8_t out[TA2TA_BUF_SIZE] = { };
1098 TEE_Result res = TEE_ERROR_GENERIC;
1099 uint32_t ret_orig = 0;
1100 uint32_t l_pts = 0;
1101 size_t i = 0;
1102
Jerome Forissiere916b102017-06-07 17:55:52 +02001103 (void)params;
1104
1105 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
1106 return TEE_ERROR_GENERIC;
1107
Cedric Augere668b3f2019-09-11 13:41:21 +02001108 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
1109 &sess, &ret_orig);
Jerome Forissiere916b102017-06-07 17:55:52 +02001110 if (res != TEE_SUCCESS) {
1111 EMSG("TEE_OpenTASession failed");
1112 goto cleanup_return;
1113 }
1114
1115 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1116 TEE_PARAM_TYPE_MEMREF_INOUT,
1117 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
1118 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +01001119 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001120 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +01001121 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001122 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +01001123 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001124
1125 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +01001126 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001127 in[i] = 5;
1128 inout[i] = 10;
1129 out[i] = 0;
1130 }
1131
1132 /*
1133 * TA will compute: out = ++inout + in
1134 * Expected values after this step: in: 5, inout: 11, out: 16
1135 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001136 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1137 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001138 l_pts, l_params, &ret_orig);
1139 if (res != TEE_SUCCESS) {
1140 EMSG("TEE_InvokeTACommand failed");
1141 goto cleanup_return;
1142 }
Etienne Carriere102092e2019-03-28 15:24:22 +01001143
Jerome Forissiere916b102017-06-07 17:55:52 +02001144 /*
1145 * Increment all values by one.
1146 * Expected values after this step: in: 6, inout: 12, out: 17
1147 */
Etienne Carriere102092e2019-03-28 15:24:22 +01001148 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +02001149
1150 /*
1151 * TA will compute: out = ++inout + in
1152 * Expected values after this step: in: 6, inout: 13, out: 19
1153 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001154 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1155 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001156 l_pts, l_params, &ret_orig);
1157 if (res != TEE_SUCCESS) {
1158 EMSG("TEE_InvokeTACommand failed");
1159 goto cleanup_return;
1160 }
1161
1162 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001163 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001164 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1165 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001166 DHEXDUMP(in, TA2TA_BUF_SIZE);
1167 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1168 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001169 return TEE_ERROR_GENERIC;
1170 }
1171 }
1172
1173cleanup_return:
1174 TEE_CloseTASession(sess);
1175 return res;
1176}
1177
1178TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1179{
Etienne Carriere102092e2019-03-28 15:24:22 +01001180 uint8_t *in = NULL;
1181 uint8_t *inout = NULL;
1182 uint8_t *out = NULL;
1183 size_t bufsize = 0;
1184 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001185
1186 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1187 TEE_PARAM_TYPE_MEMREF_INOUT,
1188 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1189 return TEE_ERROR_GENERIC;
1190
1191 bufsize = params[0].memref.size;
1192 if (params[1].memref.size != bufsize ||
1193 params[2].memref.size != bufsize)
1194 return TEE_ERROR_GENERIC;
1195
1196 in = params[0].memref.buffer;
1197 inout = params[1].memref.buffer;
1198 out = params[2].memref.buffer;
1199
1200 for (i = 0; i < bufsize; i++)
1201 out[i] = ++inout[i] + in[i];
1202
1203 return TEE_SUCCESS;
1204}
Jens Wiklander87e81702018-03-20 12:00:00 +08001205
1206TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1207{
Etienne Carriere102092e2019-03-28 15:24:22 +01001208 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001209
1210 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1211 TEE_PARAM_TYPE_MEMREF_INPUT,
1212 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1213 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1214 return TEE_ERROR_BAD_PARAMETERS;
1215
1216 for (n = 0; n < TEE_NUM_PARAMS; n++)
1217 if (!params[n].memref.buffer || !params[n].memref.size)
1218 return TEE_ERROR_BAD_PARAMETERS;
1219
1220 return TEE_SUCCESS;
1221}
Jerome Forissier53bde722018-05-31 09:14:54 +02001222
Cedric Neveux9f483bb2019-03-04 08:58:06 +01001223TEE_Result ta_entry_null_memref(uint32_t param_types, TEE_Param params[4])
1224{
1225 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1226 TEE_PARAM_TYPE_MEMREF_INPUT,
1227 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1228 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1229 return TEE_ERROR_BAD_PARAMETERS;
1230
1231 /*
1232 * Tests how client can provide null or non-null memref parameters
1233 * param[0] expected as a 0 byte input mapped memeref.
1234 * param[1] expected as a 0 byte input not-mapped memeref.
1235 * param[2] expected as a 0 byte output mapped memeref.
1236 * param[3] expected as a 0 byte output not-mapped memeref.
1237 */
1238 if (!params[0].memref.buffer || params[0].memref.size ||
1239 params[1].memref.buffer || params[1].memref.size ||
1240 !params[2].memref.buffer || params[2].memref.size ||
1241 params[3].memref.buffer || params[3].memref.size)
1242 return TEE_ERROR_BAD_PARAMETERS;
1243
1244 return TEE_SUCCESS;
1245}
1246
Jerome Forissier53bde722018-05-31 09:14:54 +02001247TEE_Result ta_entry_call_lib(uint32_t param_types,
1248 TEE_Param params[4] __unused)
1249{
1250 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1251 TEE_PARAM_TYPE_NONE,
1252 TEE_PARAM_TYPE_NONE,
1253 TEE_PARAM_TYPE_NONE))
1254 return TEE_ERROR_BAD_PARAMETERS;
1255
1256 if (os_test_shlib_add(1, 2) != 3)
1257 return TEE_ERROR_GENERIC;
1258
1259 return TEE_SUCCESS;
1260}
1261
1262TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1263 TEE_Param params[4] __unused)
1264{
1265 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1266 TEE_PARAM_TYPE_NONE,
1267 TEE_PARAM_TYPE_NONE,
1268 TEE_PARAM_TYPE_NONE))
1269 return TEE_ERROR_BAD_PARAMETERS;
1270
1271 os_test_shlib_panic();
1272
1273 return TEE_ERROR_GENERIC;
1274}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001275
1276TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1277 TEE_Param params[4] __unused)
1278{
1279 int (*add_func)(int a, int b) = NULL;
1280 TEE_Result res = TEE_ERROR_GENERIC;
1281 void *handle = NULL;
1282 void *hnull = NULL;
1283
1284 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1285 TEE_PARAM_TYPE_NONE,
1286 TEE_PARAM_TYPE_NONE,
1287 TEE_PARAM_TYPE_NONE))
1288 return TEE_ERROR_BAD_PARAMETERS;
1289
1290 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1291 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1292 if (!handle)
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001293 return TEE_ERROR_GENERIC;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001294
1295 add_func = dlsym(handle, "os_test_shlib_dl_add");
1296 if (!add_func)
1297 goto err;
1298 if (add_func(3, 4) != 7)
1299 goto err;
1300
1301 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001302 if (!hnull)
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001303 goto err;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001304
1305 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1306 if (!add_func)
1307 goto err;
1308 if (add_func(5, 6) != 11)
1309 goto err;
1310
1311 res = TEE_SUCCESS;
1312 dlclose(hnull);
1313err:
1314 dlclose(handle);
1315 return res;
1316}
1317
1318TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1319 TEE_Param params[4] __unused)
1320{
1321 int (*panic_func)(void) = NULL;
1322 void *handle = NULL;
1323 TEE_Result res = TEE_ERROR_GENERIC;
1324
1325 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1326 TEE_PARAM_TYPE_NONE,
1327 TEE_PARAM_TYPE_NONE,
1328 TEE_PARAM_TYPE_NONE))
1329 return TEE_ERROR_BAD_PARAMETERS;
1330
1331 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1332 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1333 if (!handle)
1334 return res;
1335
1336 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1337 if (!panic_func)
1338 goto err;
1339 panic_func();
1340 return TEE_ERROR_GENERIC;
1341err:
1342 dlclose(handle);
1343 return res;
1344}
Jerome Forissiere9571e82020-02-18 15:26:20 +01001345
1346/* ELF initialization/finalization test */
1347
Jerome Forissier391168e2020-06-15 09:52:25 +02001348volatile int os_test_global;
Jerome Forissiere9571e82020-02-18 15:26:20 +01001349
1350static void __attribute__((constructor)) os_test_init(void)
1351{
1352 os_test_global *= 10;
1353 os_test_global += 1;
1354 DMSG("os_test_global=%d", os_test_global);
1355}
1356
1357TEE_Result ta_entry_get_global_var(uint32_t param_types, TEE_Param params[4])
1358{
1359 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1360 TEE_PARAM_TYPE_NONE,
1361 TEE_PARAM_TYPE_NONE,
1362 TEE_PARAM_TYPE_NONE))
1363 return TEE_ERROR_BAD_PARAMETERS;
1364
1365 params[0].value.a = os_test_global;
1366
1367 return TEE_SUCCESS;
1368}
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001369
1370TEE_Result ta_entry_client_identity(uint32_t param_types, TEE_Param params[4])
1371{
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001372 TEE_Result res = TEE_ERROR_GENERIC;
1373 TEE_Identity identity = { };
1374
1375 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1376 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1377 TEE_PARAM_TYPE_NONE,
1378 TEE_PARAM_TYPE_NONE))
1379 return TEE_ERROR_BAD_PARAMETERS;
1380
1381 if (params[1].memref.size < sizeof(TEE_UUID)) {
1382 params[1].memref.size = sizeof(TEE_UUID);
1383 return TEE_ERROR_SHORT_BUFFER;
1384 }
1385
1386 res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
1387 "gpd.client.identity", &identity);
1388 if (res != TEE_SUCCESS) {
1389 EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32, res);
1390 return res;
1391 }
1392
1393 params[0].value.a = identity.login;
1394 memcpy(params[1].memref.buffer, &identity.uuid, sizeof(TEE_UUID));
1395 params[1].memref.size = sizeof(TEE_UUID);
1396
1397 return res;
1398}
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001399
Jerome Forissier6d66ca92020-11-10 15:56:06 +01001400#if defined(WITH_TLS_TESTS)
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001401__thread int os_test_tls_a;
1402__thread int os_test_tls_b = 42;
1403
1404TEE_Result ta_entry_tls_test_main(void)
1405{
1406 if (os_test_tls_a != 0) {
1407 EMSG("os_test_tls_a=%d, expected 0", os_test_tls_a);
1408 return TEE_ERROR_GENERIC;
1409 }
1410 if (os_test_tls_b != 42) {
1411 EMSG("os_test_tls_b=%d, expected 42", os_test_tls_b);
1412 return TEE_ERROR_GENERIC;
1413 }
1414
1415 return TEE_SUCCESS;
1416}
1417
1418TEE_Result ta_entry_tls_test_shlib(void)
1419{
1420 if (os_test_shlib_tls_a != 0) {
1421 EMSG("os_test_shlib_tls_a=%d, expected 0", os_test_shlib_tls_a);
1422 return TEE_ERROR_GENERIC;
1423 }
1424 if (os_test_shlib_tls_b != 123) {
1425 EMSG("os_test_shlib_tls_b=%d, expected 123",
1426 os_test_shlib_tls_b);
1427 return TEE_ERROR_GENERIC;
1428 }
1429
1430 return TEE_SUCCESS;
1431}
Jerome Forissier6d66ca92020-11-10 15:56:06 +01001432#else
1433TEE_Result ta_entry_tls_test_main(void)
1434{
1435 return TEE_ERROR_NOT_SUPPORTED;
1436}
1437
1438TEE_Result ta_entry_tls_test_shlib(void)
1439{
1440 return TEE_ERROR_NOT_SUPPORTED;
1441}
1442#endif
Jerome Forissier4565c452020-06-17 17:55:00 +02001443
1444static int iterate_hdr_cb(struct dl_phdr_info *info __maybe_unused,
1445 size_t size __unused, void *data)
1446{
1447 int *count = data;
1448
1449 (*count)++;
1450 IMSG("ELF module index: %d", *count);
1451 IMSG(" dlpi_addr=%p", (void *)info->dlpi_addr);
1452 IMSG(" dlpi_name='%s'", info->dlpi_name);
1453 IMSG(" dlpi_phdr=%p", (void *)info->dlpi_phdr);
1454 IMSG(" dlpi_phnum=%hu", info->dlpi_phnum);
1455 IMSG(" dlpi_adds=%llu", info->dlpi_adds);
1456 IMSG(" dlpi_subs=%llu", info->dlpi_subs);
1457 IMSG(" dlpi_tls_modid=%zu", info->dlpi_tls_modid);
1458 IMSG(" dlpi_tls_data=%p", info->dlpi_tls_data);
1459
1460 return 123;
1461}
1462
1463static TEE_Result expect_dl_count_ge(size_t exp_count)
1464{
1465 int st = 0;
1466 size_t count = 0;
1467
1468 st = dl_iterate_phdr(iterate_hdr_cb, (void *)&count);
1469 if (st != 123) {
1470 /*
1471 * dl_iterate_phdr() should return the last value returned by
1472 * the callback
1473 */
1474 EMSG("Expected return value 123, got %d", st);
1475 return TEE_ERROR_GENERIC;
1476 }
1477 if (count < exp_count) {
1478 /*
1479 * Expect >= and not == since there could be more shared
1480 * libraries (for instance, CFG_ULIBS_SHARED=y)
1481 */
1482 EMSG("Expected count > %zu, got: %zu", exp_count, count);
1483 return TEE_ERROR_GENERIC;
1484 }
1485
1486 return TEE_SUCCESS;
1487}
1488
1489TEE_Result ta_entry_dl_phdr(void)
1490{
1491 return expect_dl_count_ge(2);
1492}
1493
1494TEE_Result ta_entry_dl_phdr_dl(void)
1495{
1496 TEE_Result res = TEE_ERROR_GENERIC;
1497 void *handle = NULL;
1498
1499 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1500 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1501 if (!handle)
1502 return TEE_ERROR_GENERIC;
1503
1504 res = expect_dl_count_ge(3);
1505 dlclose(handle);
1506
1507 return res;
1508}
Jens Wiklander50339ef2022-04-12 20:47:27 +02001509
1510TEE_Result ta_entry_memtag_use_after_free(void)
1511{
1512 uint32_t *p = NULL;
1513
1514 if (!memtag_is_enabled())
1515 return TEE_ERROR_NOT_SUPPORTED;
1516
1517 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1518 *p = 43;
1519 TEE_Free(p);
1520 (*p) += 2;
1521 return TEE_ERROR_GENERIC;
1522}
1523
1524TEE_Result ta_entry_memtag_invalid_tag(void)
1525{
1526 uint32_t *p = NULL;
1527 uint32_t *p2 = NULL;
1528
1529 if (!memtag_is_enabled())
1530 return TEE_ERROR_NOT_SUPPORTED;
1531
1532 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1533
1534 if (!memtag_get_tag(p)) {
1535 EMSG("missing tag in %p", (void *)p);
1536 goto err;
1537 }
1538 *p = 32;
1539
1540 p2 = memtag_insert_tag(p, (memtag_get_tag(p) + 1) & 0xf);
1541 *p2 = 42;
1542 EMSG("Expected to crash when writing to %p which was allocated as %p",
1543 (void *)p2, (void *)p);
1544err:
1545 TEE_Free(p);
1546 return TEE_ERROR_GENERIC;
1547}
1548
1549TEE_Result ta_entry_memtag_double_free(void)
1550{
1551 uint32_t *p = NULL;
1552
1553 if (!memtag_is_enabled())
1554 return TEE_ERROR_NOT_SUPPORTED;
1555
1556 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1557 *p = 43;
1558 TEE_Free(p);
1559 TEE_Free(p);
1560 return TEE_ERROR_GENERIC;
1561}
1562
1563TEE_Result ta_entry_memtag_buffer_overrun(void)
1564{
1565 uint64_t *p = NULL;
1566
1567 if (!memtag_is_enabled())
1568 return TEE_ERROR_NOT_SUPPORTED;
1569
1570 p = TEE_Malloc(sizeof(*p) * 2, TEE_MALLOC_FILL_ZERO);
1571 p[2] += 44;
1572 TEE_Free(p);
1573 return TEE_ERROR_GENERIC;
1574}