blob: 134ad2298652c509300db18bc5958189838029e6 [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{
Etienne Carriere102092e2019-03-28 15:24:22 +0100118TEE_Result res = TEE_ERROR_GENERIC;
119size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200120
121TEE_StartPropertyEnumerator(h, prop_set);
122
123while (true) {
Etienne Carriere102092e2019-03-28 15:24:22 +0100124 char nbuf[256] = { };
125 char nbuf_small[256] = { };
126 char vbuf[256] = { };
127 char vbuf2[256] = { };
Jens Wiklandere1634fa2022-12-12 12:59:28 +0100128 size_t nblen = sizeof(nbuf);
129 size_t nblen_small = 0;
130 size_t vblen = sizeof(vbuf);
131 size_t vblen2 = sizeof(vbuf2);
Etienne Carriere58e3a832020-07-08 16:56:01 +0200132 char *bbuf = NULL;
Etienne Carriereb34caff2020-05-26 09:25:35 +0200133 size_t bblen = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200134
135 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 }
Pascal Brand624b6a32016-02-16 12:51:34 +0100141 if (nblen != strlen(nbuf) + 1) {
Jens Wiklandere1634fa2022-12-12 12:59:28 +0100142 EMSG("Name has wrong size: %zu vs %zu",
143 nblen, strlen(nbuf) + 1);
Pascal Brand624b6a32016-02-16 12:51:34 +0100144 return TEE_ERROR_GENERIC;
145 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200146
Pascal Brand624b6a32016-02-16 12:51:34 +0100147
148 /* Get the property name with a very small buffer */
149 nblen_small = 2;
150 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
151 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
152 nblen_small, nblen);
153 if (res != TEE_SUCCESS)
154 return res;
155
156 /* Get the property name with almost the correct buffer */
157 nblen_small = nblen - 1;
158 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
159 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
160 nblen_small, nblen);
161 if (res != TEE_SUCCESS)
162 return res;
163
164 /* Get the property name with the exact buffer length */
165 nblen_small = nblen;
166 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
167 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
168 nblen_small, nblen);
169 if (res != TEE_SUCCESS)
170 return res;
171
172 /* Get the property value */
Pascal Brandc639ac82015-07-02 08:53:34 +0200173 res = TEE_GetPropertyAsString(h, NULL, vbuf, &vblen);
Pascal Brand624b6a32016-02-16 12:51:34 +0100174 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
175 vblen, strlen(vbuf) + 1);
176 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200177 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100178
Pascal Brandc639ac82015-07-02 08:53:34 +0200179 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
Pascal Brand624b6a32016-02-16 12:51:34 +0100180 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
181 vblen2, strlen(vbuf2) + 1);
182 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200183 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100184
Jens Wiklander8324ff22018-11-21 14:16:04 +0100185 if (strcmp(vbuf, vbuf2) != 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200186 EMSG("String of \"%s\" differs\n", nbuf);
187 return TEE_ERROR_GENERIC;
188 }
189
Pascal Brand624b6a32016-02-16 12:51:34 +0100190 /* Get the property with a very small buffer */
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200191 if (vblen > 1) {
192 vblen2 = 1;
193 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
194 res = check_returned_prop(__LINE__, nbuf, res,
195 TEE_ERROR_SHORT_BUFFER,
196 vblen2, vblen);
197 if (res != TEE_SUCCESS)
198 return res;
199 }
Pascal Brand624b6a32016-02-16 12:51:34 +0100200
201 /* Get the property with almost the correct buffer */
202 vblen2 = vblen - 1;
203 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
204 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
205 vblen2, vblen);
206 if (res != TEE_SUCCESS)
207 return res;
208
209 /* Get the property name with the exact buffer length */
210 vblen2 = vblen;
211 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
212 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS, vblen2, vblen);
213 if (res != TEE_SUCCESS)
214 return res;
215
216 /* check specific myprop.hello property, which is larger than 80 */
217 if (!strcmp("myprop.hello", nbuf) &&
218 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")) {
219 EMSG("TEE_GetPropertyAsString(\"%s\") is truncated - returned \"%s\"\n",
220 nbuf, vbuf);
221 return TEE_ERROR_GENERIC;
222 }
223
Pascal Brandc639ac82015-07-02 08:53:34 +0200224 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
225
226 for (n = 0; n < num_p_attrs; n++) {
Jens Wiklander8324ff22018-11-21 14:16:04 +0100227 if (strcmp(nbuf, p_attrs[n].str) != 0)
Pascal Brandc639ac82015-07-02 08:53:34 +0200228 continue;
229
230 if (p_attrs[n].retrieved) {
231 EMSG("Value \"%s\" already retrieved\n",
232 p_attrs[n].str);
233 return TEE_ERROR_GENERIC;
234 }
235 p_attrs[n].retrieved = true;
236
237 switch (p_attrs[n].type) {
238 case P_TYPE_BOOL:
239 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100240 bool v = false;
Pascal Brandc639ac82015-07-02 08:53:34 +0200241
242 res =
243 TEE_GetPropertyAsBool(h, NULL, &v);
244 if (res != TEE_SUCCESS) {
245 EMSG(
246 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
247 nbuf, (unsigned int)res);
248 return res;
249 }
250 }
251 break;
252
253 case P_TYPE_INT:
254 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100255 uint32_t v = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200256
257 res = TEE_GetPropertyAsU32(h, NULL, &v);
258 if (res != TEE_SUCCESS) {
259 EMSG(
260 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
261 nbuf, (unsigned int)res);
262 return res;
263 }
264 }
265 break;
266
267 case P_TYPE_UUID:
268 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100269 TEE_UUID v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200270
271 res =
272 TEE_GetPropertyAsUUID(h, NULL, &v);
273 if (res != TEE_SUCCESS) {
274 EMSG(
275 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
276 nbuf, (unsigned int)res);
277 return res;
278 }
279 }
280 break;
281
282 case P_TYPE_IDENTITY:
283 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100284 TEE_Identity v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200285
286 res =
287 TEE_GetPropertyAsIdentity(h, NULL,
288 &v);
289 if (res != TEE_SUCCESS) {
290 EMSG(
291 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
292 nbuf, (unsigned int)res);
293 return res;
294 }
295 }
296 break;
297
298 case P_TYPE_STRING:
299 /* Already read as string */
300 break;
301
302 case P_TYPE_BINARY_BLOCK:
Etienne Carriereb34caff2020-05-26 09:25:35 +0200303 res = get_binblock_property(h, nbuf, &bbuf, &bblen);
304 if (res)
305 return res;
Pascal Brandc639ac82015-07-02 08:53:34 +0200306
Etienne Carriereb34caff2020-05-26 09:25:35 +0200307 if (!strcmp("myprop.binaryblock", nbuf)) {
308 const char exp_bin_value[] = "Hello world!";
309
310 if (bblen != strlen(exp_bin_value) ||
311 TEE_MemCompare(exp_bin_value, bbuf,
312 bblen)) {
313 EMSG("Binary buffer of \"%s\" differs from \"%s\"",
314 nbuf, exp_bin_value);
315 EMSG("Got \"%s\"", bbuf);
316 return TEE_ERROR_GENERIC;
317 }
318 } else if (!strcmp("myprop.binaryblock.1byte-ones",
319 nbuf)) {
320 res = check_binprop_ones(1, bbuf, bblen);
321 if (res)
Pascal Brandc639ac82015-07-02 08:53:34 +0200322 return res;
Etienne Carriereb34caff2020-05-26 09:25:35 +0200323 } else if (!strcmp("myprop.binaryblock.2byte-ones",
324 nbuf)) {
325 res = check_binprop_ones(2, bbuf, bblen);
326 if (res)
327 return res;
328 } else if (!strcmp("myprop.binaryblock.3byte-ones",
329 nbuf)) {
330 res = check_binprop_ones(3, bbuf, bblen);
331 if (res)
332 return res;
333 } else if (!strcmp("myprop.binaryblock.4byte-ones",
334 nbuf)) {
335 res = check_binprop_ones(4, bbuf, bblen);
336 if (res)
337 return res;
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200338 } else if (!strcmp("myprop.binaryblock.empty1", nbuf) ||
339 !strcmp("myprop.binaryblock.empty2", nbuf) ||
340 !strcmp("myprop.binaryblock.empty3", nbuf)) {
341 if (bblen) {
342 EMSG("Property \"%s\": %zu byte(s)",
343 nbuf, bblen);
344 return TEE_ERROR_GENERIC;
345 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200346 } else {
347 EMSG("Unexpected property \"%s\"", nbuf);
348 TEE_Panic(0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200349 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200350
351 TEE_Free(bbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200352 break;
353
354 default:
355 EMSG("Unknown type (%d) for \"%s\"\n",
356 p_attrs[n].type, p_attrs[n].str);
357 return TEE_ERROR_GENERIC;
358 }
359 }
360
361 res = TEE_GetNextProperty(h);
362 if (res != TEE_SUCCESS) {
363 if (res == TEE_ERROR_ITEM_NOT_FOUND)
364 return TEE_SUCCESS;
365 return res;
366 }
367}
368}
369
370static TEE_Result test_malloc(void)
371{
372 void *p = TEE_Malloc(4, 0);
373
374 if (p == NULL) {
375 EMSG("TEE_Malloc failed\n");
376 return TEE_ERROR_OUT_OF_MEMORY;
377 }
378 TEE_Free(p);
379 TEE_Free(NULL);
380
381 return TEE_SUCCESS;
382}
383
384static TEE_Result test_properties(void)
385{
386 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriere102092e2019-03-28 15:24:22 +0100387 TEE_PropSetHandle h = TEE_HANDLE_NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200388 struct p_attr p_attrs[] = {
389 {"gpd.ta.appID", P_TYPE_UUID},
390 {"gpd.ta.singleInstance", P_TYPE_BOOL},
391 {"gpd.ta.multiSession", P_TYPE_BOOL},
392 {"gpd.ta.instanceKeepAlive", P_TYPE_BOOL},
393 {"gpd.ta.dataSize", P_TYPE_INT},
394 {"gpd.ta.stackSize", P_TYPE_INT},
395 {"gpd.ta.version", P_TYPE_STRING},
396 {"gpd.ta.description", P_TYPE_STRING},
397 {"gpd.client.identity", P_TYPE_IDENTITY},
398 {"gpd.tee.apiversion", P_TYPE_STRING},
399 {"gpd.tee.description", P_TYPE_STRING},
400 {"gpd.tee.deviceID", P_TYPE_UUID},
401 {"gpd.tee.systemTime.protectionLevel", P_TYPE_INT},
402 {"gpd.tee.TAPersistentTime.protectionLevel", P_TYPE_INT},
403 {"gpd.tee.arith.maxBigIntSize", P_TYPE_INT},
404 {"gpd.tee.cryptography.ecc", P_TYPE_BOOL},
405 {"gpd.tee.trustedStorage.antiRollback.protectionLevel", P_TYPE_INT},
406 {"gpd.tee.trustedos.implementation.version", P_TYPE_STRING},
407 {"gpd.tee.trustedos.implementation.binaryversion", P_TYPE_INT},
408 {"gpd.tee.trustedos.manufacturer", P_TYPE_STRING},
409 {"gpd.tee.firmware.implementation.version", P_TYPE_STRING},
410 {"gpd.tee.firmware.implementation.binaryversion", P_TYPE_INT},
411 {"gpd.tee.firmware.manufacturer", P_TYPE_STRING},
412 {"myprop.true", P_TYPE_BOOL},
413 {"myprop.42", P_TYPE_INT},
414 {"myprop.123", P_TYPE_UUID},
415 {"myprop.1234", P_TYPE_IDENTITY},
416 {"myprop.hello", P_TYPE_STRING},
417 {"myprop.binaryblock", P_TYPE_BINARY_BLOCK},
Etienne Carriereb34caff2020-05-26 09:25:35 +0200418 {"myprop.binaryblock.1byte-ones", P_TYPE_BINARY_BLOCK},
419 {"myprop.binaryblock.2byte-ones", P_TYPE_BINARY_BLOCK},
420 {"myprop.binaryblock.3byte-ones", P_TYPE_BINARY_BLOCK},
421 {"myprop.binaryblock.4byte-ones", P_TYPE_BINARY_BLOCK},
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200422 {"myprop.binaryblock.empty1", P_TYPE_BINARY_BLOCK},
423 {"myprop.binaryblock.empty2", P_TYPE_BINARY_BLOCK},
424 {"myprop.binaryblock.empty3", P_TYPE_BINARY_BLOCK},
Pascal Brandc639ac82015-07-02 08:53:34 +0200425 };
426 const size_t num_p_attrs = sizeof(p_attrs) / sizeof(p_attrs[0]);
Etienne Carriere102092e2019-03-28 15:24:22 +0100427 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200428
429 res = TEE_AllocatePropertyEnumerator(&h);
430 if (res != TEE_SUCCESS) {
431 EMSG("TEE_AllocatePropertyEnumerator: returned 0x%x\n",
432 (unsigned int)res);
433 return TEE_ERROR_GENERIC;
434 }
435
436 printf("Getting properties for current TA\n");
437 res = print_properties(h, TEE_PROPSET_CURRENT_TA, p_attrs, num_p_attrs);
438 if (res != TEE_SUCCESS)
439 goto cleanup_return;
440
441 printf("Getting properties for current client\n");
442 res = print_properties(h, TEE_PROPSET_CURRENT_CLIENT, p_attrs,
443 num_p_attrs);
444 if (res != TEE_SUCCESS)
445 goto cleanup_return;
446
447 printf("Getting properties for implementation\n");
448 res = print_properties(h, TEE_PROPSET_TEE_IMPLEMENTATION, p_attrs,
449 num_p_attrs);
450 if (res != TEE_SUCCESS)
451 goto cleanup_return;
452
453 for (n = 0; n < num_p_attrs; n++) {
454 if (!p_attrs[n].retrieved) {
455 EMSG("\"%s\" not retrieved\n", p_attrs[n].str);
456 res = TEE_ERROR_GENERIC;
457 goto cleanup_return;
458 }
459 }
460
461cleanup_return:
462 TEE_FreePropertyEnumerator(h);
463 return res;
464}
465
466static TEE_Result test_mem_access_right(uint32_t param_types,
467 TEE_Param params[4])
468{
469 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100470 TEE_Result res = TEE_ERROR_GENERIC;
471 uint32_t ret_orig = 0;
472 uint32_t l_pts = 0;
473 TEE_Param l_params[4] = { };
474 uint8_t buf[32] = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200475 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100476 TEE_UUID *uuid = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200477
478 if (param_types !=
479 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
480 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200481
482 /* test access rights on memref parameter */
483 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
484 TEE_MEMORY_ACCESS_ANY_OWNER,
485 params[0].memref.buffer,
486 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200487 if (res != TEE_SUCCESS)
488 return res;
Etienne Carriere281065d2016-10-28 15:41:33 +0200489
Pascal Brandc639ac82015-07-02 08:53:34 +0200490 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
491 params[0].memref.buffer,
492 params[0].memref.size);
493 if (res != TEE_ERROR_ACCESS_DENIED)
494 return TEE_ERROR_GENERIC;
495
Etienne Carriere281065d2016-10-28 15:41:33 +0200496 /* test access rights on private read-only and read-write memory */
497 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
498 (void *)&test_uuid, sizeof(test_uuid));
499 if (res != TEE_SUCCESS)
500 return res;
501
502 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_WRITE,
503 (void *)&test_uuid, sizeof(test_uuid));
504 if (res == TEE_SUCCESS)
505 return TEE_ERROR_GENERIC;
506
507 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
508 TEE_MEMORY_ACCESS_WRITE,
509 &ret_orig, sizeof(ret_orig));
510 if (res != TEE_SUCCESS)
511 return res;
512
513 uuid = TEE_Malloc(sizeof(*uuid), 0);
514 if (!uuid)
515 return TEE_ERROR_OUT_OF_MEMORY;
516
517 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
518 TEE_MEMORY_ACCESS_WRITE,
519 uuid, sizeof(*uuid));
520 TEE_Free(uuid);
521 if (res != TEE_SUCCESS)
522 return res;
523
524 /* test access rights on invalid memory (at least lower 256kB) */
525 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
526 NULL, 1);
527 if (res == TEE_SUCCESS)
528 return TEE_ERROR_GENERIC;
529
530 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
531 (void*)(256 * 1024), 1);
532 if (res == TEE_SUCCESS)
533 return TEE_ERROR_GENERIC;
534
Cedric Augere668b3f2019-09-11 13:41:21 +0200535 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
536 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200537 if (res != TEE_SUCCESS) {
538 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
539 goto cleanup_return;
540 }
541
Jerome Forissier04511d82018-01-30 14:33:49 +0100542 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
543 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200544 l_params[0].memref.buffer = buf;
545 l_params[0].memref.size = sizeof(buf);
Jerome Forissier04511d82018-01-30 14:33:49 +0100546 l_params[1].memref.buffer = NULL;
547 l_params[1].memref.size = 0;
Cedric Augere668b3f2019-09-11 13:41:21 +0200548 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
549 TA_OS_TEST_CMD_PARAMS_ACCESS,
Pascal Brandc639ac82015-07-02 08:53:34 +0200550 l_pts, l_params, &ret_orig);
551 if (res != TEE_SUCCESS) {
552 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
553 goto cleanup_return;
554 }
555
556cleanup_return:
557 TEE_CloseTASession(sess);
558 return res;
559}
560
561static TEE_Result test_time(void)
562{
Etienne Carriere102092e2019-03-28 15:24:22 +0100563 TEE_Result res = TEE_ERROR_GENERIC;
564 TEE_Time t = { };
565 TEE_Time sys_t = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200566 static const TEE_Time null_time = { 0, 0 };
567 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
568
569 TEE_GetSystemTime(&sys_t);
570 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
571 (unsigned int)sys_t.millis);
572
573 TEE_GetREETime(&t);
574 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
575 (unsigned int)t.millis);
576
577 res = TEE_GetTAPersistentTime(&t);
578 switch (res) {
579 case TEE_SUCCESS:
580 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
581 (unsigned int)t.millis);
582 break;
583 case TEE_ERROR_OVERFLOW:
584 EMSG("Stored TA time overflowed %u.%03u\n",
585 (unsigned int)t.seconds, (unsigned int)t.millis);
586 break;
587 case TEE_ERROR_TIME_NOT_SET:
588 EMSG("TA time not stored\n");
589 break;
590 case TEE_ERROR_TIME_NEEDS_RESET:
591 EMSG("TA time needs reset\n");
592 break;
593 default:
594 return res;
595 }
596
597 res = TEE_SetTAPersistentTime(&null_time);
598 if (res != TEE_SUCCESS) {
599 EMSG("TEE_SetTAPersistentTime: failed\n");
600 return res;
601 }
602
603 res = TEE_GetTAPersistentTime(&t);
604 if (res != TEE_SUCCESS) {
605 EMSG("TEE_GetTAPersistentTime null: failed\n");
606 return res;
607 }
608 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
609 (unsigned int)t.millis);
610 /*
611 * The time between TEE_SetTAPersistentTime() and
612 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
613 * it's not even a millisecond.
614 */
615 if (t.seconds > 1 || t.millis >= 1000) {
616 EMSG("Unexpected stored TA time %u.%03u\n",
617 (unsigned int)t.seconds, (unsigned int)t.millis);
618 return TEE_ERROR_BAD_STATE;
619 }
620
621 res = TEE_SetTAPersistentTime(&wrap_time);
622 if (res != TEE_SUCCESS) {
623 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
624 return res;
625 }
626
627 res = TEE_Wait(1000);
628 if (res != TEE_SUCCESS)
629 EMSG("TEE_Wait wrap: failed\n");
630
631 res = TEE_GetTAPersistentTime(&t);
632 if (res != TEE_ERROR_OVERFLOW) {
633 EMSG("TEE_GetTAPersistentTime: failed\n");
634 return TEE_ERROR_BAD_STATE;
635 }
636 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
637 (unsigned int)t.millis);
638
639 if (t.seconds > sys_t.seconds) {
640 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
641 (unsigned int)t.seconds, (unsigned int)t.millis,
642 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
643 return TEE_ERROR_BAD_STATE;
644 }
645
646 return TEE_SUCCESS;
647}
648
Jens Wiklander246184a2015-12-11 08:28:59 +0100649#ifdef CFG_TA_FLOAT_SUPPORT
650static bool my_dcmpeq(double v1, double v2, double prec)
651{
652 return v1 > (v2 - prec) && v1 < (v2 + prec);
653}
654
655static bool my_fcmpeq(float v1, float v2, float prec)
656{
657 return v1 > (v2 - prec) && v1 < (v2 + prec);
658}
659
660
661static TEE_Result test_float(void)
662{
663#define VAL1 2.6
664#define VAL1_INT 2
665#define VAL2 5.3
666#define DPREC 0.000000000000001
667#define FPREC 0.000001
668#define EXPECT(expr) do { \
669 if (!(expr)) { \
670 EMSG("Expression %s failed", #expr); \
671 return TEE_ERROR_GENERIC; \
672 } \
673 } while (0)
674
675 IMSG("Testing floating point operations");
676
677 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
678 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
679 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
680 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
681 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
682
683 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
684 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
685 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
686 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
687 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
688
689 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
690 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
691 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
692 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
693 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
694
695 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
696 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
697 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
698 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
699 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
700
701 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
702 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
703 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
704 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
705
706 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
707 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
708 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
709 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
710
711 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
712 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
713
714 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
715 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
716 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
717 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
718
719 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
720 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
721 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
722 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
723 return TEE_SUCCESS;
724}
725#else /*CFG_TA_FLOAT_SUPPORT*/
726static TEE_Result test_float(void)
727{
728 IMSG("Floating point disabled");
729 return TEE_SUCCESS;
730}
731#endif /*CFG_TA_FLOAT_SUPPORT*/
732
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100733#if defined(CFG_TA_BGET_TEST)
734/* From libutils */
735int bget_main_test(void *(*malloc_func)(size_t), void (*free_func)(void *));
736
737static void *malloc_wrapper(size_t size)
738{
739 return tee_map_zi(size, 0);
740}
741
742static void free_wrapper(void *ptr __unused)
743{
744}
745
Etienne Carriere24fcf0e2023-03-07 17:44:00 +0100746static bool optee_pager_with_small_pool(void)
747{
748 uint32_t ptypes = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
749 TEE_PARAM_TYPE_VALUE_OUTPUT,
750 TEE_PARAM_TYPE_VALUE_OUTPUT,
751 TEE_PARAM_TYPE_NONE);
752 static const TEE_UUID uuid = STATS_UUID;
753 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
754 TEE_Result res = TEE_ERROR_GENERIC;
755 TEE_Param params[4] = { };
756 uint32_t eo = 0;
757 bool rc = false;
758
759 res = TEE_OpenTASession(&uuid, TEE_TIMEOUT_INFINITE, 0, NULL, &sess,
760 &eo);
761 if (res)
762 return false;
763
764 res = TEE_InvokeTACommand(sess, 0, STATS_CMD_PAGER_STATS,
765 ptypes, params, &eo);
766 if (res == TEE_SUCCESS &&
767 params[0].value.b && params[0].value.b <= PAGER_PAGE_COUNT_THRESHOLD)
768 rc = true;
769
770 TEE_CloseTASession(sess);
771
772 return rc;
773}
774
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100775static TEE_Result test_bget(void)
776{
Etienne Carriere24fcf0e2023-03-07 17:44:00 +0100777 if (optee_pager_with_small_pool()) {
778 IMSG("Skip testing bget due to pager pool constraints");
779 return TEE_SUCCESS;
780 }
781
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100782 DMSG("Testing bget");
783 if (bget_main_test(malloc_wrapper, free_wrapper)) {
784 EMSG("bget_main_test failed");
785 return TEE_ERROR_GENERIC;
786 }
787 DMSG("Bget OK");
788 return TEE_SUCCESS;
789}
790#else
791static TEE_Result test_bget(void)
792{
793 IMSG("Bget test disabled");
794 return TEE_SUCCESS;
795}
796#endif
797
798
Jerome Forissier892ae4d2020-03-09 09:58:09 +0100799static __noinline __noreturn void call_longjmp(jmp_buf env)
Jens Wiklander9f682c62016-03-27 20:23:06 +0200800{
801 DMSG("Calling longjmp");
802 longjmp(env, 1);
803 EMSG("error: longjmp returned to calling function");
804}
805
806static TEE_Result test_setjmp(void)
807{
Etienne Carriere102092e2019-03-28 15:24:22 +0100808 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200809
810 if (setjmp(env)) {
811 IMSG("Returned via longjmp");
812 return TEE_SUCCESS;
813 } else {
814 call_longjmp(env);
815 return TEE_ERROR_GENERIC;
816 }
817}
818
Pascal Brandc639ac82015-07-02 08:53:34 +0200819TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
820{
821 TEE_Result res = TEE_ERROR_GENERIC;
822
823 printf("ta_entry_basic: enter\n");
824
825 res = test_malloc();
826 if (res != TEE_SUCCESS)
827 return res;
828
829 res = test_properties();
830 if (res != TEE_SUCCESS)
831 return res;
832
833 res = test_mem_access_right(param_types, params);
834 if (res != TEE_SUCCESS)
835 return res;
836
837 res = test_time();
838 if (res != TEE_SUCCESS)
839 return res;
840
Jens Wiklander246184a2015-12-11 08:28:59 +0100841 res = test_float();
842 if (res != TEE_SUCCESS)
843 return res;
844
Jens Wiklander9f682c62016-03-27 20:23:06 +0200845 res = test_setjmp();
846 if (res != TEE_SUCCESS)
847 return res;
848
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100849 res = test_bget();
850 if (res != TEE_SUCCESS)
851 return res;
852
Pascal Brandc639ac82015-07-02 08:53:34 +0200853 return TEE_SUCCESS;
854}
855
856TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
857{
858 volatile bool mytrue = true;
859 (void)param_types;
860 (void)params;
861
862 printf("ta_entry_panic: enter\n");
863 /*
864 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
865 * the __noreturn attribute.
866 */
867 if (mytrue)
868 TEE_Panic(0xbeef);
869
870 /*
871 * Should not be reached, but if it is the testsuite can detect that
872 * TEE_Panic() returned instead of panicking the TA.
873 */
874 return TEE_SUCCESS;
875}
876
877TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
878 TEE_Param params[4])
879{
880 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100881 TEE_Result res = TEE_ERROR_GENERIC;
882 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
883 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200884
885 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
886 TEE_PARAM_TYPE_NONE,
887 TEE_PARAM_TYPE_NONE,
888 TEE_PARAM_TYPE_NONE)) {
889 EMSG("ta_entry_client_with_timeout: bad parameters\n");
890 return TEE_ERROR_BAD_PARAMETERS;
891 }
892
Cedric Augere668b3f2019-09-11 13:41:21 +0200893 res = TEE_OpenTASession(&os_test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
894 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200895 if (res != TEE_SUCCESS) {
896 EMSG(
897 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
898 return res;
899 }
900
901 res =
902 TEE_InvokeTACommand(sess, params[0].value.a / 2,
903 TA_OS_TEST_CMD_WAIT, param_types, params,
904 &ret_orig);
905
906 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
907 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
908 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
909 (unsigned int)ret_orig);
910 res = TEE_ERROR_GENERIC;
911 } else
912 res = TEE_SUCCESS;
913
914 TEE_CloseTASession(sess);
915 return res;
916
917}
918
919TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
920{
921 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100922 TEE_Result res = TEE_ERROR_GENERIC;
923 uint32_t l_pts = 0;
924 TEE_Param l_params[4] = { };
925 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
926 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200927 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
928 static const uint8_t sha256_out[] = {
929 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
930 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
931 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
932 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
933 };
934 uint8_t out[32] = { 0 };
935 void *in = NULL;
936
937 (void)param_types;
938 (void)params;
939
940 printf("ta_entry_client: enter\n");
941
942 in = TEE_Malloc(sizeof(sha256_in), 0);
943 if (in == NULL)
944 return TEE_ERROR_OUT_OF_MEMORY;
945 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
946
Cedric Augere668b3f2019-09-11 13:41:21 +0200947 res = TEE_OpenTASession(&crypt_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
948 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200949 if (res != TEE_SUCCESS) {
950 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
951 goto cleanup_return;
952 }
953
954 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
955 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
956 l_params[0].memref.buffer = in;
957 l_params[0].memref.size = sizeof(sha256_in);
958 l_params[1].memref.buffer = out;
959 l_params[1].memref.size = sizeof(out);
960
Cedric Augere668b3f2019-09-11 13:41:21 +0200961 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
962 TA_CRYPT_CMD_SHA256, l_pts, l_params,
Pascal Brandc639ac82015-07-02 08:53:34 +0200963 &ret_orig);
964 if (res != TEE_SUCCESS) {
965 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
966 goto cleanup_return;
967 }
968
969 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
970 EMSG("ta_entry_client: out parameter failed\n");
971 res = TEE_ERROR_GENERIC;
972 goto cleanup_return;
973 }
974
975cleanup_return:
976 TEE_Free(in);
977 TEE_CloseTASession(sess);
978 return res;
979}
980
Etienne Carriere281065d2016-10-28 15:41:33 +0200981TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200982{
Etienne Carriere102092e2019-03-28 15:24:22 +0100983 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200984
985 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100986 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
987 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200988 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200989
990 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
991 TEE_MEMORY_ACCESS_ANY_OWNER,
992 params[0].memref.buffer,
993 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200994 if (res != TEE_SUCCESS)
995 return res;
996
997 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
998 params[0].memref.buffer,
999 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +02001000 if (res != TEE_ERROR_ACCESS_DENIED)
1001 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +01001002 if (params[1].memref.buffer || params[1].memref.size)
1003 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +02001004
Etienne Carriere281065d2016-10-28 15:41:33 +02001005 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +02001006}
1007
1008TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
1009{
1010 TEE_Result res = TEE_SUCCESS;
1011 (void)param_types;
1012
1013 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
1014 /* Wait */
1015 res = TEE_Wait(params[0].value.a);
1016
1017 return res;
1018}
1019
Jens Wiklander1425f952016-07-21 09:02:30 +02001020static void undef_instr(void)
1021{
1022#if defined(ARM64)
1023 __asm__(".word 0x0");
1024#elif defined(ARM32)
1025 __asm__(".word 0xe7ffffff");
Marouene Boubakri38fd7892023-01-06 10:45:15 +01001026#elif defined(RV64) || defined(RV32)
1027 __asm__(".word 0x0");
Jens Wiklander1425f952016-07-21 09:02:30 +02001028#else
1029#error "Unsupported architecture"
1030#endif
1031}
1032
Pascal Brandc639ac82015-07-02 08:53:34 +02001033TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
1034{
Etienne Carriere102092e2019-03-28 15:24:22 +01001035 long int stack = 0;
1036 long int stack_addr = (long int)&stack;
Jerome Forissiere2a58c62019-09-19 16:01:54 +02001037 void (*volatile null_fn_ptr)(void) = NULL;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001038 char *zero_size_malloc = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +02001039
Etienne Carriere92c34422018-02-09 13:11:40 +01001040 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
1041 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
1042 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +02001043 return TEE_ERROR_GENERIC;
1044
1045 switch (params[0].value.a) {
1046 case 1:
Jerome Forissier71da60f2019-09-19 15:59:56 +02001047 *((volatile uint32_t *)0) = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +02001048 break;
1049 case 2:
1050 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
1051 break;
1052 case 3:
Jerome Forissiere2a58c62019-09-19 16:01:54 +02001053 null_fn_ptr();
Pascal Brandc639ac82015-07-02 08:53:34 +02001054 break;
1055 case 4:
1056 ((void (*)(void))(stack_addr + 0x40000000)) ();
1057 break;
1058 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +02001059 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +02001060 break;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001061 case 6:
1062 zero_size_malloc = TEE_Malloc(0, 0);
1063 if (!zero_size_malloc)
1064 return TEE_ERROR_GENERIC;
Etienne Carriere713db5a2021-09-29 20:32:32 +02001065 if (*zero_size_malloc)
1066 return TEE_ERROR_GENERIC;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001067 break;
1068 case 7:
1069 zero_size_malloc = TEE_Malloc(0, 0);
1070 if (!zero_size_malloc)
1071 return TEE_ERROR_GENERIC;
1072 *zero_size_malloc = 0;
1073 break;
Pascal Brandc639ac82015-07-02 08:53:34 +02001074 default:
1075 break;
1076 }
1077
1078 return TEE_SUCCESS;
1079}
Jerome Forissiere916b102017-06-07 17:55:52 +02001080
1081static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
1082{
Etienne Carriere102092e2019-03-28 15:24:22 +01001083 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001084
1085 for (i = 0; i < bufsize; i++) {
1086 a[i]++; b[i]++; c[i]++;
1087 }
1088}
1089
Etienne Carriere102092e2019-03-28 15:24:22 +01001090#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +02001091TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
1092{
1093 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
1094 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +01001095 TEE_Param l_params[4] = { };
1096 uint8_t in[TA2TA_BUF_SIZE] = { };
1097 uint8_t inout[TA2TA_BUF_SIZE] = { };
1098 uint8_t out[TA2TA_BUF_SIZE] = { };
1099 TEE_Result res = TEE_ERROR_GENERIC;
1100 uint32_t ret_orig = 0;
1101 uint32_t l_pts = 0;
1102 size_t i = 0;
1103
Jerome Forissiere916b102017-06-07 17:55:52 +02001104 (void)params;
1105
1106 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
1107 return TEE_ERROR_GENERIC;
1108
Cedric Augere668b3f2019-09-11 13:41:21 +02001109 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
1110 &sess, &ret_orig);
Jerome Forissiere916b102017-06-07 17:55:52 +02001111 if (res != TEE_SUCCESS) {
1112 EMSG("TEE_OpenTASession failed");
1113 goto cleanup_return;
1114 }
1115
1116 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1117 TEE_PARAM_TYPE_MEMREF_INOUT,
1118 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
1119 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +01001120 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001121 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +01001122 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001123 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +01001124 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001125
1126 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +01001127 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001128 in[i] = 5;
1129 inout[i] = 10;
1130 out[i] = 0;
1131 }
1132
1133 /*
1134 * TA will compute: out = ++inout + in
1135 * Expected values after this step: in: 5, inout: 11, out: 16
1136 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001137 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1138 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001139 l_pts, l_params, &ret_orig);
1140 if (res != TEE_SUCCESS) {
1141 EMSG("TEE_InvokeTACommand failed");
1142 goto cleanup_return;
1143 }
Etienne Carriere102092e2019-03-28 15:24:22 +01001144
Jerome Forissiere916b102017-06-07 17:55:52 +02001145 /*
1146 * Increment all values by one.
1147 * Expected values after this step: in: 6, inout: 12, out: 17
1148 */
Etienne Carriere102092e2019-03-28 15:24:22 +01001149 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +02001150
1151 /*
1152 * TA will compute: out = ++inout + in
1153 * Expected values after this step: in: 6, inout: 13, out: 19
1154 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001155 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1156 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001157 l_pts, l_params, &ret_orig);
1158 if (res != TEE_SUCCESS) {
1159 EMSG("TEE_InvokeTACommand failed");
1160 goto cleanup_return;
1161 }
1162
1163 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001164 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001165 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1166 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001167 DHEXDUMP(in, TA2TA_BUF_SIZE);
1168 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1169 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001170 return TEE_ERROR_GENERIC;
1171 }
1172 }
1173
1174cleanup_return:
1175 TEE_CloseTASession(sess);
1176 return res;
1177}
1178
1179TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1180{
Etienne Carriere102092e2019-03-28 15:24:22 +01001181 uint8_t *in = NULL;
1182 uint8_t *inout = NULL;
1183 uint8_t *out = NULL;
1184 size_t bufsize = 0;
1185 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001186
1187 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1188 TEE_PARAM_TYPE_MEMREF_INOUT,
1189 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1190 return TEE_ERROR_GENERIC;
1191
1192 bufsize = params[0].memref.size;
1193 if (params[1].memref.size != bufsize ||
1194 params[2].memref.size != bufsize)
1195 return TEE_ERROR_GENERIC;
1196
1197 in = params[0].memref.buffer;
1198 inout = params[1].memref.buffer;
1199 out = params[2].memref.buffer;
1200
1201 for (i = 0; i < bufsize; i++)
1202 out[i] = ++inout[i] + in[i];
1203
1204 return TEE_SUCCESS;
1205}
Jens Wiklander87e81702018-03-20 12:00:00 +08001206
1207TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1208{
Etienne Carriere102092e2019-03-28 15:24:22 +01001209 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001210
1211 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1212 TEE_PARAM_TYPE_MEMREF_INPUT,
1213 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1214 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1215 return TEE_ERROR_BAD_PARAMETERS;
1216
1217 for (n = 0; n < TEE_NUM_PARAMS; n++)
1218 if (!params[n].memref.buffer || !params[n].memref.size)
1219 return TEE_ERROR_BAD_PARAMETERS;
1220
1221 return TEE_SUCCESS;
1222}
Jerome Forissier53bde722018-05-31 09:14:54 +02001223
Cedric Neveux9f483bb2019-03-04 08:58:06 +01001224TEE_Result ta_entry_null_memref(uint32_t param_types, TEE_Param params[4])
1225{
1226 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1227 TEE_PARAM_TYPE_MEMREF_INPUT,
1228 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1229 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1230 return TEE_ERROR_BAD_PARAMETERS;
1231
1232 /*
1233 * Tests how client can provide null or non-null memref parameters
1234 * param[0] expected as a 0 byte input mapped memeref.
1235 * param[1] expected as a 0 byte input not-mapped memeref.
1236 * param[2] expected as a 0 byte output mapped memeref.
1237 * param[3] expected as a 0 byte output not-mapped memeref.
1238 */
1239 if (!params[0].memref.buffer || params[0].memref.size ||
1240 params[1].memref.buffer || params[1].memref.size ||
1241 !params[2].memref.buffer || params[2].memref.size ||
1242 params[3].memref.buffer || params[3].memref.size)
1243 return TEE_ERROR_BAD_PARAMETERS;
1244
1245 return TEE_SUCCESS;
1246}
1247
Jerome Forissier53bde722018-05-31 09:14:54 +02001248TEE_Result ta_entry_call_lib(uint32_t param_types,
1249 TEE_Param params[4] __unused)
1250{
1251 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1252 TEE_PARAM_TYPE_NONE,
1253 TEE_PARAM_TYPE_NONE,
1254 TEE_PARAM_TYPE_NONE))
1255 return TEE_ERROR_BAD_PARAMETERS;
1256
1257 if (os_test_shlib_add(1, 2) != 3)
1258 return TEE_ERROR_GENERIC;
1259
1260 return TEE_SUCCESS;
1261}
1262
1263TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1264 TEE_Param params[4] __unused)
1265{
1266 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1267 TEE_PARAM_TYPE_NONE,
1268 TEE_PARAM_TYPE_NONE,
1269 TEE_PARAM_TYPE_NONE))
1270 return TEE_ERROR_BAD_PARAMETERS;
1271
1272 os_test_shlib_panic();
1273
1274 return TEE_ERROR_GENERIC;
1275}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001276
1277TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1278 TEE_Param params[4] __unused)
1279{
1280 int (*add_func)(int a, int b) = NULL;
1281 TEE_Result res = TEE_ERROR_GENERIC;
1282 void *handle = NULL;
1283 void *hnull = NULL;
1284
1285 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1286 TEE_PARAM_TYPE_NONE,
1287 TEE_PARAM_TYPE_NONE,
1288 TEE_PARAM_TYPE_NONE))
1289 return TEE_ERROR_BAD_PARAMETERS;
1290
1291 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1292 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1293 if (!handle)
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001294 return TEE_ERROR_GENERIC;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001295
1296 add_func = dlsym(handle, "os_test_shlib_dl_add");
1297 if (!add_func)
1298 goto err;
1299 if (add_func(3, 4) != 7)
1300 goto err;
1301
1302 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001303 if (!hnull)
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001304 goto err;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001305
1306 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1307 if (!add_func)
1308 goto err;
1309 if (add_func(5, 6) != 11)
1310 goto err;
1311
1312 res = TEE_SUCCESS;
1313 dlclose(hnull);
1314err:
1315 dlclose(handle);
1316 return res;
1317}
1318
1319TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1320 TEE_Param params[4] __unused)
1321{
1322 int (*panic_func)(void) = NULL;
1323 void *handle = NULL;
1324 TEE_Result res = TEE_ERROR_GENERIC;
1325
1326 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1327 TEE_PARAM_TYPE_NONE,
1328 TEE_PARAM_TYPE_NONE,
1329 TEE_PARAM_TYPE_NONE))
1330 return TEE_ERROR_BAD_PARAMETERS;
1331
1332 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1333 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1334 if (!handle)
1335 return res;
1336
1337 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1338 if (!panic_func)
1339 goto err;
1340 panic_func();
1341 return TEE_ERROR_GENERIC;
1342err:
1343 dlclose(handle);
1344 return res;
1345}
Jerome Forissiere9571e82020-02-18 15:26:20 +01001346
1347/* ELF initialization/finalization test */
1348
Jerome Forissier391168e2020-06-15 09:52:25 +02001349volatile int os_test_global;
Jerome Forissiere9571e82020-02-18 15:26:20 +01001350
1351static void __attribute__((constructor)) os_test_init(void)
1352{
1353 os_test_global *= 10;
1354 os_test_global += 1;
1355 DMSG("os_test_global=%d", os_test_global);
1356}
1357
1358TEE_Result ta_entry_get_global_var(uint32_t param_types, TEE_Param params[4])
1359{
1360 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1361 TEE_PARAM_TYPE_NONE,
1362 TEE_PARAM_TYPE_NONE,
1363 TEE_PARAM_TYPE_NONE))
1364 return TEE_ERROR_BAD_PARAMETERS;
1365
1366 params[0].value.a = os_test_global;
1367
1368 return TEE_SUCCESS;
1369}
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001370
1371TEE_Result ta_entry_client_identity(uint32_t param_types, TEE_Param params[4])
1372{
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001373 TEE_Result res = TEE_ERROR_GENERIC;
1374 TEE_Identity identity = { };
1375
1376 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1377 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1378 TEE_PARAM_TYPE_NONE,
1379 TEE_PARAM_TYPE_NONE))
1380 return TEE_ERROR_BAD_PARAMETERS;
1381
1382 if (params[1].memref.size < sizeof(TEE_UUID)) {
1383 params[1].memref.size = sizeof(TEE_UUID);
1384 return TEE_ERROR_SHORT_BUFFER;
1385 }
1386
1387 res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
1388 "gpd.client.identity", &identity);
1389 if (res != TEE_SUCCESS) {
1390 EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32, res);
1391 return res;
1392 }
1393
1394 params[0].value.a = identity.login;
1395 memcpy(params[1].memref.buffer, &identity.uuid, sizeof(TEE_UUID));
1396 params[1].memref.size = sizeof(TEE_UUID);
1397
1398 return res;
1399}
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001400
Jerome Forissier6d66ca92020-11-10 15:56:06 +01001401#if defined(WITH_TLS_TESTS)
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001402__thread int os_test_tls_a;
1403__thread int os_test_tls_b = 42;
1404
1405TEE_Result ta_entry_tls_test_main(void)
1406{
1407 if (os_test_tls_a != 0) {
1408 EMSG("os_test_tls_a=%d, expected 0", os_test_tls_a);
1409 return TEE_ERROR_GENERIC;
1410 }
1411 if (os_test_tls_b != 42) {
1412 EMSG("os_test_tls_b=%d, expected 42", os_test_tls_b);
1413 return TEE_ERROR_GENERIC;
1414 }
1415
1416 return TEE_SUCCESS;
1417}
1418
1419TEE_Result ta_entry_tls_test_shlib(void)
1420{
1421 if (os_test_shlib_tls_a != 0) {
1422 EMSG("os_test_shlib_tls_a=%d, expected 0", os_test_shlib_tls_a);
1423 return TEE_ERROR_GENERIC;
1424 }
1425 if (os_test_shlib_tls_b != 123) {
1426 EMSG("os_test_shlib_tls_b=%d, expected 123",
1427 os_test_shlib_tls_b);
1428 return TEE_ERROR_GENERIC;
1429 }
1430
1431 return TEE_SUCCESS;
1432}
Jerome Forissier6d66ca92020-11-10 15:56:06 +01001433#else
1434TEE_Result ta_entry_tls_test_main(void)
1435{
1436 return TEE_ERROR_NOT_SUPPORTED;
1437}
1438
1439TEE_Result ta_entry_tls_test_shlib(void)
1440{
1441 return TEE_ERROR_NOT_SUPPORTED;
1442}
1443#endif
Jerome Forissier4565c452020-06-17 17:55:00 +02001444
1445static int iterate_hdr_cb(struct dl_phdr_info *info __maybe_unused,
1446 size_t size __unused, void *data)
1447{
1448 int *count = data;
1449
1450 (*count)++;
1451 IMSG("ELF module index: %d", *count);
1452 IMSG(" dlpi_addr=%p", (void *)info->dlpi_addr);
1453 IMSG(" dlpi_name='%s'", info->dlpi_name);
1454 IMSG(" dlpi_phdr=%p", (void *)info->dlpi_phdr);
1455 IMSG(" dlpi_phnum=%hu", info->dlpi_phnum);
1456 IMSG(" dlpi_adds=%llu", info->dlpi_adds);
1457 IMSG(" dlpi_subs=%llu", info->dlpi_subs);
1458 IMSG(" dlpi_tls_modid=%zu", info->dlpi_tls_modid);
1459 IMSG(" dlpi_tls_data=%p", info->dlpi_tls_data);
1460
1461 return 123;
1462}
1463
1464static TEE_Result expect_dl_count_ge(size_t exp_count)
1465{
1466 int st = 0;
1467 size_t count = 0;
1468
1469 st = dl_iterate_phdr(iterate_hdr_cb, (void *)&count);
1470 if (st != 123) {
1471 /*
1472 * dl_iterate_phdr() should return the last value returned by
1473 * the callback
1474 */
1475 EMSG("Expected return value 123, got %d", st);
1476 return TEE_ERROR_GENERIC;
1477 }
1478 if (count < exp_count) {
1479 /*
1480 * Expect >= and not == since there could be more shared
1481 * libraries (for instance, CFG_ULIBS_SHARED=y)
1482 */
1483 EMSG("Expected count > %zu, got: %zu", exp_count, count);
1484 return TEE_ERROR_GENERIC;
1485 }
1486
1487 return TEE_SUCCESS;
1488}
1489
1490TEE_Result ta_entry_dl_phdr(void)
1491{
1492 return expect_dl_count_ge(2);
1493}
1494
1495TEE_Result ta_entry_dl_phdr_dl(void)
1496{
1497 TEE_Result res = TEE_ERROR_GENERIC;
1498 void *handle = NULL;
1499
1500 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1501 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1502 if (!handle)
1503 return TEE_ERROR_GENERIC;
1504
1505 res = expect_dl_count_ge(3);
1506 dlclose(handle);
1507
1508 return res;
1509}
Jens Wiklander50339ef2022-04-12 20:47:27 +02001510
1511TEE_Result ta_entry_memtag_use_after_free(void)
1512{
1513 uint32_t *p = NULL;
1514
1515 if (!memtag_is_enabled())
1516 return TEE_ERROR_NOT_SUPPORTED;
1517
1518 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1519 *p = 43;
1520 TEE_Free(p);
1521 (*p) += 2;
1522 return TEE_ERROR_GENERIC;
1523}
1524
1525TEE_Result ta_entry_memtag_invalid_tag(void)
1526{
1527 uint32_t *p = NULL;
1528 uint32_t *p2 = NULL;
1529
1530 if (!memtag_is_enabled())
1531 return TEE_ERROR_NOT_SUPPORTED;
1532
1533 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1534
1535 if (!memtag_get_tag(p)) {
1536 EMSG("missing tag in %p", (void *)p);
1537 goto err;
1538 }
1539 *p = 32;
1540
1541 p2 = memtag_insert_tag(p, (memtag_get_tag(p) + 1) & 0xf);
1542 *p2 = 42;
1543 EMSG("Expected to crash when writing to %p which was allocated as %p",
1544 (void *)p2, (void *)p);
1545err:
1546 TEE_Free(p);
1547 return TEE_ERROR_GENERIC;
1548}
1549
1550TEE_Result ta_entry_memtag_double_free(void)
1551{
1552 uint32_t *p = NULL;
1553
1554 if (!memtag_is_enabled())
1555 return TEE_ERROR_NOT_SUPPORTED;
1556
1557 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1558 *p = 43;
1559 TEE_Free(p);
1560 TEE_Free(p);
1561 return TEE_ERROR_GENERIC;
1562}
1563
1564TEE_Result ta_entry_memtag_buffer_overrun(void)
1565{
1566 uint64_t *p = NULL;
1567
1568 if (!memtag_is_enabled())
1569 return TEE_ERROR_NOT_SUPPORTED;
1570
1571 p = TEE_Malloc(sizeof(*p) * 2, TEE_MALLOC_FILL_ZERO);
1572 p[2] += 44;
1573 TEE_Free(p);
1574 return TEE_ERROR_GENERIC;
1575}