blob: b95c0a1a5b0225f39fda68801bf023df1d23f577 [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
22enum p_type {
23 P_TYPE_BOOL,
24 P_TYPE_INT,
25 P_TYPE_UUID,
26 P_TYPE_IDENTITY,
27 P_TYPE_STRING,
28 P_TYPE_BINARY_BLOCK,
29};
30
31struct p_attr {
32 const char *str;
33 enum p_type type;
34 bool retrieved;
35};
36
Pascal Brand624b6a32016-02-16 12:51:34 +010037static TEE_Result check_returned_prop(
Pascal Brandaf77fdd2016-03-08 13:59:01 +010038 int line __maybe_unused, char *prop_name __maybe_unused,
Pascal Brand624b6a32016-02-16 12:51:34 +010039 TEE_Result return_res, TEE_Result expected_res,
40 uint32_t return_len, uint32_t expected_len)
41{
42 if (return_res != expected_res) {
43 EMSG("From line %d (property name=%s): return_res=0x%x vs expected_res=0x%x",
44 line, (prop_name ? prop_name : "unknown"),
45 (unsigned int)return_res, (unsigned int)expected_res);
46 return TEE_ERROR_GENERIC;
47 }
48 if (return_len != expected_len) {
Pascal Brand07bb09f2016-02-19 16:04:10 +010049 EMSG("From line %d (property name=%s): return_len=%u vs expected_res=%u",
50 line, (prop_name ? prop_name : "unknown"),
51 return_len, expected_len);
Pascal Brand624b6a32016-02-16 12:51:34 +010052 return TEE_ERROR_GENERIC;
53 }
54 return TEE_SUCCESS;
55}
56
Etienne Carriere58e3a832020-07-08 16:56:01 +020057static TEE_Result check_binprop_ones(size_t size, char *bbuf, size_t bblen)
Etienne Carriereb34caff2020-05-26 09:25:35 +020058{
Etienne Carriere58e3a832020-07-08 16:56:01 +020059 char ones[4] = { 0xff, 0xff, 0xff, 0xff };
Etienne Carriereb34caff2020-05-26 09:25:35 +020060
61 if (size > 4 || bblen != size) {
62 EMSG("Size error (size=%zu, bblen=%zu)", size, bblen);
63 return TEE_ERROR_GENERIC;
64 }
65 if (strncmp(bbuf, ones, bblen)) {
66 EMSG("Unexpected content");
67 DHEXDUMP(bbuf, bblen);
68 return TEE_ERROR_GENERIC;
69 }
70 return TEE_SUCCESS;
71}
72
73static TEE_Result get_binblock_property(TEE_PropSetHandle h,
Vesa Jääskeläinena9ab8f82021-02-06 21:16:20 +020074 char *nbuf __unused, char **bbuf, size_t *bblen)
Etienne Carriereb34caff2020-05-26 09:25:35 +020075{
76 TEE_Result res = TEE_ERROR_GENERIC;
Jens Wiklandere1634fa2022-12-12 12:59:28 +010077 size_t block_len = 0;
Etienne Carriereb34caff2020-05-26 09:25:35 +020078
79 *bbuf = NULL;
80 *bblen = 0;
Etienne Carriere58e3a832020-07-08 16:56:01 +020081 res = TEE_GetPropertyAsBinaryBlock(h, NULL, *bbuf, &block_len);
Etienne Carriereb34caff2020-05-26 09:25:35 +020082
Etienne Carriere58e3a832020-07-08 16:56:01 +020083 if (res == TEE_SUCCESS && !block_len)
Etienne Carriereb34caff2020-05-26 09:25:35 +020084 return TEE_SUCCESS;
85
86 if (res != TEE_ERROR_SHORT_BUFFER) {
87 EMSG("TEE_GetPropertyAsBinaryBlock() size query returned 0x%x",
88 (unsigned int)res);
89 return res ? res : TEE_ERROR_GENERIC;
90 }
91
Etienne Carriere58e3a832020-07-08 16:56:01 +020092 *bbuf = TEE_Malloc(block_len, TEE_MALLOC_FILL_ZERO);
Etienne Carriereb34caff2020-05-26 09:25:35 +020093 if (!bbuf)
94 return TEE_ERROR_OUT_OF_MEMORY;
95
Etienne Carriere58e3a832020-07-08 16:56:01 +020096 res = TEE_GetPropertyAsBinaryBlock(h, NULL, *bbuf, &block_len);
Etienne Carriereb34caff2020-05-26 09:25:35 +020097 if (res != TEE_SUCCESS)
98 EMSG("TEE_GetPropertyAsBinaryBlock(\"%s\") returned 0x%x",
99 nbuf, (unsigned int)res);
Etienne Carriere58e3a832020-07-08 16:56:01 +0200100 else
101 *bblen = block_len;
Etienne Carriereb34caff2020-05-26 09:25:35 +0200102
103 return res;
104}
105
Pascal Brandc639ac82015-07-02 08:53:34 +0200106static TEE_Result print_properties(TEE_PropSetHandle h,
107 TEE_PropSetHandle prop_set,
108 struct p_attr *p_attrs, size_t num_p_attrs)
109{
Etienne Carriere102092e2019-03-28 15:24:22 +0100110TEE_Result res = TEE_ERROR_GENERIC;
111size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200112
113TEE_StartPropertyEnumerator(h, prop_set);
114
115while (true) {
Etienne Carriere102092e2019-03-28 15:24:22 +0100116 char nbuf[256] = { };
117 char nbuf_small[256] = { };
118 char vbuf[256] = { };
119 char vbuf2[256] = { };
Jens Wiklandere1634fa2022-12-12 12:59:28 +0100120 size_t nblen = sizeof(nbuf);
121 size_t nblen_small = 0;
122 size_t vblen = sizeof(vbuf);
123 size_t vblen2 = sizeof(vbuf2);
Etienne Carriere58e3a832020-07-08 16:56:01 +0200124 char *bbuf = NULL;
Etienne Carriereb34caff2020-05-26 09:25:35 +0200125 size_t bblen = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200126
127 res = TEE_GetPropertyName(h, nbuf, &nblen);
128 if (res != TEE_SUCCESS) {
129 EMSG("TEE_GetPropertyName returned 0x%x\n",
130 (unsigned int)res);
131 return res;
132 }
Pascal Brand624b6a32016-02-16 12:51:34 +0100133 if (nblen != strlen(nbuf) + 1) {
Jens Wiklandere1634fa2022-12-12 12:59:28 +0100134 EMSG("Name has wrong size: %zu vs %zu",
135 nblen, strlen(nbuf) + 1);
Pascal Brand624b6a32016-02-16 12:51:34 +0100136 return TEE_ERROR_GENERIC;
137 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200138
Pascal Brand624b6a32016-02-16 12:51:34 +0100139
140 /* Get the property name with a very small buffer */
141 nblen_small = 2;
142 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
143 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
144 nblen_small, nblen);
145 if (res != TEE_SUCCESS)
146 return res;
147
148 /* Get the property name with almost the correct buffer */
149 nblen_small = nblen - 1;
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 the exact buffer length */
157 nblen_small = nblen;
158 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
159 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
160 nblen_small, nblen);
161 if (res != TEE_SUCCESS)
162 return res;
163
164 /* Get the property value */
Pascal Brandc639ac82015-07-02 08:53:34 +0200165 res = TEE_GetPropertyAsString(h, NULL, vbuf, &vblen);
Pascal Brand624b6a32016-02-16 12:51:34 +0100166 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
167 vblen, strlen(vbuf) + 1);
168 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200169 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100170
Pascal Brandc639ac82015-07-02 08:53:34 +0200171 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
Pascal Brand624b6a32016-02-16 12:51:34 +0100172 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
173 vblen2, strlen(vbuf2) + 1);
174 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200175 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100176
Jens Wiklander8324ff22018-11-21 14:16:04 +0100177 if (strcmp(vbuf, vbuf2) != 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200178 EMSG("String of \"%s\" differs\n", nbuf);
179 return TEE_ERROR_GENERIC;
180 }
181
Pascal Brand624b6a32016-02-16 12:51:34 +0100182 /* Get the property with a very small buffer */
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200183 if (vblen > 1) {
184 vblen2 = 1;
185 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
186 res = check_returned_prop(__LINE__, nbuf, res,
187 TEE_ERROR_SHORT_BUFFER,
188 vblen2, vblen);
189 if (res != TEE_SUCCESS)
190 return res;
191 }
Pascal Brand624b6a32016-02-16 12:51:34 +0100192
193 /* Get the property with almost the correct buffer */
194 vblen2 = vblen - 1;
195 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
196 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
197 vblen2, vblen);
198 if (res != TEE_SUCCESS)
199 return res;
200
201 /* Get the property name with the exact buffer length */
202 vblen2 = vblen;
203 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
204 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS, vblen2, vblen);
205 if (res != TEE_SUCCESS)
206 return res;
207
208 /* check specific myprop.hello property, which is larger than 80 */
209 if (!strcmp("myprop.hello", nbuf) &&
210 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")) {
211 EMSG("TEE_GetPropertyAsString(\"%s\") is truncated - returned \"%s\"\n",
212 nbuf, vbuf);
213 return TEE_ERROR_GENERIC;
214 }
215
Pascal Brandc639ac82015-07-02 08:53:34 +0200216 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
217
218 for (n = 0; n < num_p_attrs; n++) {
Jens Wiklander8324ff22018-11-21 14:16:04 +0100219 if (strcmp(nbuf, p_attrs[n].str) != 0)
Pascal Brandc639ac82015-07-02 08:53:34 +0200220 continue;
221
222 if (p_attrs[n].retrieved) {
223 EMSG("Value \"%s\" already retrieved\n",
224 p_attrs[n].str);
225 return TEE_ERROR_GENERIC;
226 }
227 p_attrs[n].retrieved = true;
228
229 switch (p_attrs[n].type) {
230 case P_TYPE_BOOL:
231 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100232 bool v = false;
Pascal Brandc639ac82015-07-02 08:53:34 +0200233
234 res =
235 TEE_GetPropertyAsBool(h, NULL, &v);
236 if (res != TEE_SUCCESS) {
237 EMSG(
238 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
239 nbuf, (unsigned int)res);
240 return res;
241 }
242 }
243 break;
244
245 case P_TYPE_INT:
246 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100247 uint32_t v = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200248
249 res = TEE_GetPropertyAsU32(h, NULL, &v);
250 if (res != TEE_SUCCESS) {
251 EMSG(
252 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
253 nbuf, (unsigned int)res);
254 return res;
255 }
256 }
257 break;
258
259 case P_TYPE_UUID:
260 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100261 TEE_UUID v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200262
263 res =
264 TEE_GetPropertyAsUUID(h, NULL, &v);
265 if (res != TEE_SUCCESS) {
266 EMSG(
267 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
268 nbuf, (unsigned int)res);
269 return res;
270 }
271 }
272 break;
273
274 case P_TYPE_IDENTITY:
275 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100276 TEE_Identity v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200277
278 res =
279 TEE_GetPropertyAsIdentity(h, NULL,
280 &v);
281 if (res != TEE_SUCCESS) {
282 EMSG(
283 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
284 nbuf, (unsigned int)res);
285 return res;
286 }
287 }
288 break;
289
290 case P_TYPE_STRING:
291 /* Already read as string */
292 break;
293
294 case P_TYPE_BINARY_BLOCK:
Etienne Carriereb34caff2020-05-26 09:25:35 +0200295 res = get_binblock_property(h, nbuf, &bbuf, &bblen);
296 if (res)
297 return res;
Pascal Brandc639ac82015-07-02 08:53:34 +0200298
Etienne Carriereb34caff2020-05-26 09:25:35 +0200299 if (!strcmp("myprop.binaryblock", nbuf)) {
300 const char exp_bin_value[] = "Hello world!";
301
302 if (bblen != strlen(exp_bin_value) ||
303 TEE_MemCompare(exp_bin_value, bbuf,
304 bblen)) {
305 EMSG("Binary buffer of \"%s\" differs from \"%s\"",
306 nbuf, exp_bin_value);
307 EMSG("Got \"%s\"", bbuf);
308 return TEE_ERROR_GENERIC;
309 }
310 } else if (!strcmp("myprop.binaryblock.1byte-ones",
311 nbuf)) {
312 res = check_binprop_ones(1, bbuf, bblen);
313 if (res)
Pascal Brandc639ac82015-07-02 08:53:34 +0200314 return res;
Etienne Carriereb34caff2020-05-26 09:25:35 +0200315 } else if (!strcmp("myprop.binaryblock.2byte-ones",
316 nbuf)) {
317 res = check_binprop_ones(2, bbuf, bblen);
318 if (res)
319 return res;
320 } else if (!strcmp("myprop.binaryblock.3byte-ones",
321 nbuf)) {
322 res = check_binprop_ones(3, bbuf, bblen);
323 if (res)
324 return res;
325 } else if (!strcmp("myprop.binaryblock.4byte-ones",
326 nbuf)) {
327 res = check_binprop_ones(4, bbuf, bblen);
328 if (res)
329 return res;
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200330 } else if (!strcmp("myprop.binaryblock.empty1", nbuf) ||
331 !strcmp("myprop.binaryblock.empty2", nbuf) ||
332 !strcmp("myprop.binaryblock.empty3", nbuf)) {
333 if (bblen) {
334 EMSG("Property \"%s\": %zu byte(s)",
335 nbuf, bblen);
336 return TEE_ERROR_GENERIC;
337 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200338 } else {
339 EMSG("Unexpected property \"%s\"", nbuf);
340 TEE_Panic(0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200341 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200342
343 TEE_Free(bbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200344 break;
345
346 default:
347 EMSG("Unknown type (%d) for \"%s\"\n",
348 p_attrs[n].type, p_attrs[n].str);
349 return TEE_ERROR_GENERIC;
350 }
351 }
352
353 res = TEE_GetNextProperty(h);
354 if (res != TEE_SUCCESS) {
355 if (res == TEE_ERROR_ITEM_NOT_FOUND)
356 return TEE_SUCCESS;
357 return res;
358 }
359}
360}
361
362static TEE_Result test_malloc(void)
363{
364 void *p = TEE_Malloc(4, 0);
365
366 if (p == NULL) {
367 EMSG("TEE_Malloc failed\n");
368 return TEE_ERROR_OUT_OF_MEMORY;
369 }
370 TEE_Free(p);
371 TEE_Free(NULL);
372
373 return TEE_SUCCESS;
374}
375
376static TEE_Result test_properties(void)
377{
378 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriere102092e2019-03-28 15:24:22 +0100379 TEE_PropSetHandle h = TEE_HANDLE_NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200380 struct p_attr p_attrs[] = {
381 {"gpd.ta.appID", P_TYPE_UUID},
382 {"gpd.ta.singleInstance", P_TYPE_BOOL},
383 {"gpd.ta.multiSession", P_TYPE_BOOL},
384 {"gpd.ta.instanceKeepAlive", P_TYPE_BOOL},
385 {"gpd.ta.dataSize", P_TYPE_INT},
386 {"gpd.ta.stackSize", P_TYPE_INT},
387 {"gpd.ta.version", P_TYPE_STRING},
388 {"gpd.ta.description", P_TYPE_STRING},
389 {"gpd.client.identity", P_TYPE_IDENTITY},
390 {"gpd.tee.apiversion", P_TYPE_STRING},
391 {"gpd.tee.description", P_TYPE_STRING},
392 {"gpd.tee.deviceID", P_TYPE_UUID},
393 {"gpd.tee.systemTime.protectionLevel", P_TYPE_INT},
394 {"gpd.tee.TAPersistentTime.protectionLevel", P_TYPE_INT},
395 {"gpd.tee.arith.maxBigIntSize", P_TYPE_INT},
396 {"gpd.tee.cryptography.ecc", P_TYPE_BOOL},
397 {"gpd.tee.trustedStorage.antiRollback.protectionLevel", P_TYPE_INT},
398 {"gpd.tee.trustedos.implementation.version", P_TYPE_STRING},
399 {"gpd.tee.trustedos.implementation.binaryversion", P_TYPE_INT},
400 {"gpd.tee.trustedos.manufacturer", P_TYPE_STRING},
401 {"gpd.tee.firmware.implementation.version", P_TYPE_STRING},
402 {"gpd.tee.firmware.implementation.binaryversion", P_TYPE_INT},
403 {"gpd.tee.firmware.manufacturer", P_TYPE_STRING},
404 {"myprop.true", P_TYPE_BOOL},
405 {"myprop.42", P_TYPE_INT},
406 {"myprop.123", P_TYPE_UUID},
407 {"myprop.1234", P_TYPE_IDENTITY},
408 {"myprop.hello", P_TYPE_STRING},
409 {"myprop.binaryblock", P_TYPE_BINARY_BLOCK},
Etienne Carriereb34caff2020-05-26 09:25:35 +0200410 {"myprop.binaryblock.1byte-ones", P_TYPE_BINARY_BLOCK},
411 {"myprop.binaryblock.2byte-ones", P_TYPE_BINARY_BLOCK},
412 {"myprop.binaryblock.3byte-ones", P_TYPE_BINARY_BLOCK},
413 {"myprop.binaryblock.4byte-ones", P_TYPE_BINARY_BLOCK},
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200414 {"myprop.binaryblock.empty1", P_TYPE_BINARY_BLOCK},
415 {"myprop.binaryblock.empty2", P_TYPE_BINARY_BLOCK},
416 {"myprop.binaryblock.empty3", P_TYPE_BINARY_BLOCK},
Pascal Brandc639ac82015-07-02 08:53:34 +0200417 };
418 const size_t num_p_attrs = sizeof(p_attrs) / sizeof(p_attrs[0]);
Etienne Carriere102092e2019-03-28 15:24:22 +0100419 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200420
421 res = TEE_AllocatePropertyEnumerator(&h);
422 if (res != TEE_SUCCESS) {
423 EMSG("TEE_AllocatePropertyEnumerator: returned 0x%x\n",
424 (unsigned int)res);
425 return TEE_ERROR_GENERIC;
426 }
427
428 printf("Getting properties for current TA\n");
429 res = print_properties(h, TEE_PROPSET_CURRENT_TA, p_attrs, num_p_attrs);
430 if (res != TEE_SUCCESS)
431 goto cleanup_return;
432
433 printf("Getting properties for current client\n");
434 res = print_properties(h, TEE_PROPSET_CURRENT_CLIENT, p_attrs,
435 num_p_attrs);
436 if (res != TEE_SUCCESS)
437 goto cleanup_return;
438
439 printf("Getting properties for implementation\n");
440 res = print_properties(h, TEE_PROPSET_TEE_IMPLEMENTATION, p_attrs,
441 num_p_attrs);
442 if (res != TEE_SUCCESS)
443 goto cleanup_return;
444
445 for (n = 0; n < num_p_attrs; n++) {
446 if (!p_attrs[n].retrieved) {
447 EMSG("\"%s\" not retrieved\n", p_attrs[n].str);
448 res = TEE_ERROR_GENERIC;
449 goto cleanup_return;
450 }
451 }
452
453cleanup_return:
454 TEE_FreePropertyEnumerator(h);
455 return res;
456}
457
458static TEE_Result test_mem_access_right(uint32_t param_types,
459 TEE_Param params[4])
460{
461 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100462 TEE_Result res = TEE_ERROR_GENERIC;
463 uint32_t ret_orig = 0;
464 uint32_t l_pts = 0;
465 TEE_Param l_params[4] = { };
466 uint8_t buf[32] = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200467 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100468 TEE_UUID *uuid = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200469
470 if (param_types !=
471 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
472 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200473
474 /* test access rights on memref parameter */
475 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
476 TEE_MEMORY_ACCESS_ANY_OWNER,
477 params[0].memref.buffer,
478 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200479 if (res != TEE_SUCCESS)
480 return res;
Etienne Carriere281065d2016-10-28 15:41:33 +0200481
Pascal Brandc639ac82015-07-02 08:53:34 +0200482 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
483 params[0].memref.buffer,
484 params[0].memref.size);
485 if (res != TEE_ERROR_ACCESS_DENIED)
486 return TEE_ERROR_GENERIC;
487
Etienne Carriere281065d2016-10-28 15:41:33 +0200488 /* test access rights on private read-only and read-write memory */
489 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
490 (void *)&test_uuid, sizeof(test_uuid));
491 if (res != TEE_SUCCESS)
492 return res;
493
494 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_WRITE,
495 (void *)&test_uuid, sizeof(test_uuid));
496 if (res == TEE_SUCCESS)
497 return TEE_ERROR_GENERIC;
498
499 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
500 TEE_MEMORY_ACCESS_WRITE,
501 &ret_orig, sizeof(ret_orig));
502 if (res != TEE_SUCCESS)
503 return res;
504
505 uuid = TEE_Malloc(sizeof(*uuid), 0);
506 if (!uuid)
507 return TEE_ERROR_OUT_OF_MEMORY;
508
509 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
510 TEE_MEMORY_ACCESS_WRITE,
511 uuid, sizeof(*uuid));
512 TEE_Free(uuid);
513 if (res != TEE_SUCCESS)
514 return res;
515
516 /* test access rights on invalid memory (at least lower 256kB) */
517 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
518 NULL, 1);
519 if (res == TEE_SUCCESS)
520 return TEE_ERROR_GENERIC;
521
522 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
523 (void*)(256 * 1024), 1);
524 if (res == TEE_SUCCESS)
525 return TEE_ERROR_GENERIC;
526
Cedric Augere668b3f2019-09-11 13:41:21 +0200527 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
528 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200529 if (res != TEE_SUCCESS) {
530 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
531 goto cleanup_return;
532 }
533
Jerome Forissier04511d82018-01-30 14:33:49 +0100534 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
535 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200536 l_params[0].memref.buffer = buf;
537 l_params[0].memref.size = sizeof(buf);
Jerome Forissier04511d82018-01-30 14:33:49 +0100538 l_params[1].memref.buffer = NULL;
539 l_params[1].memref.size = 0;
Cedric Augere668b3f2019-09-11 13:41:21 +0200540 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
541 TA_OS_TEST_CMD_PARAMS_ACCESS,
Pascal Brandc639ac82015-07-02 08:53:34 +0200542 l_pts, l_params, &ret_orig);
543 if (res != TEE_SUCCESS) {
544 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
545 goto cleanup_return;
546 }
547
548cleanup_return:
549 TEE_CloseTASession(sess);
550 return res;
551}
552
553static TEE_Result test_time(void)
554{
Etienne Carriere102092e2019-03-28 15:24:22 +0100555 TEE_Result res = TEE_ERROR_GENERIC;
556 TEE_Time t = { };
557 TEE_Time sys_t = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200558 static const TEE_Time null_time = { 0, 0 };
559 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
560
561 TEE_GetSystemTime(&sys_t);
562 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
563 (unsigned int)sys_t.millis);
564
565 TEE_GetREETime(&t);
566 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
567 (unsigned int)t.millis);
568
569 res = TEE_GetTAPersistentTime(&t);
570 switch (res) {
571 case TEE_SUCCESS:
572 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
573 (unsigned int)t.millis);
574 break;
575 case TEE_ERROR_OVERFLOW:
576 EMSG("Stored TA time overflowed %u.%03u\n",
577 (unsigned int)t.seconds, (unsigned int)t.millis);
578 break;
579 case TEE_ERROR_TIME_NOT_SET:
580 EMSG("TA time not stored\n");
581 break;
582 case TEE_ERROR_TIME_NEEDS_RESET:
583 EMSG("TA time needs reset\n");
584 break;
585 default:
586 return res;
587 }
588
589 res = TEE_SetTAPersistentTime(&null_time);
590 if (res != TEE_SUCCESS) {
591 EMSG("TEE_SetTAPersistentTime: failed\n");
592 return res;
593 }
594
595 res = TEE_GetTAPersistentTime(&t);
596 if (res != TEE_SUCCESS) {
597 EMSG("TEE_GetTAPersistentTime null: failed\n");
598 return res;
599 }
600 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
601 (unsigned int)t.millis);
602 /*
603 * The time between TEE_SetTAPersistentTime() and
604 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
605 * it's not even a millisecond.
606 */
607 if (t.seconds > 1 || t.millis >= 1000) {
608 EMSG("Unexpected stored TA time %u.%03u\n",
609 (unsigned int)t.seconds, (unsigned int)t.millis);
610 return TEE_ERROR_BAD_STATE;
611 }
612
613 res = TEE_SetTAPersistentTime(&wrap_time);
614 if (res != TEE_SUCCESS) {
615 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
616 return res;
617 }
618
619 res = TEE_Wait(1000);
620 if (res != TEE_SUCCESS)
621 EMSG("TEE_Wait wrap: failed\n");
622
623 res = TEE_GetTAPersistentTime(&t);
624 if (res != TEE_ERROR_OVERFLOW) {
625 EMSG("TEE_GetTAPersistentTime: failed\n");
626 return TEE_ERROR_BAD_STATE;
627 }
628 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
629 (unsigned int)t.millis);
630
631 if (t.seconds > sys_t.seconds) {
632 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
633 (unsigned int)t.seconds, (unsigned int)t.millis,
634 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
635 return TEE_ERROR_BAD_STATE;
636 }
637
638 return TEE_SUCCESS;
639}
640
Jens Wiklander246184a2015-12-11 08:28:59 +0100641#ifdef CFG_TA_FLOAT_SUPPORT
642static bool my_dcmpeq(double v1, double v2, double prec)
643{
644 return v1 > (v2 - prec) && v1 < (v2 + prec);
645}
646
647static bool my_fcmpeq(float v1, float v2, float prec)
648{
649 return v1 > (v2 - prec) && v1 < (v2 + prec);
650}
651
652
653static TEE_Result test_float(void)
654{
655#define VAL1 2.6
656#define VAL1_INT 2
657#define VAL2 5.3
658#define DPREC 0.000000000000001
659#define FPREC 0.000001
660#define EXPECT(expr) do { \
661 if (!(expr)) { \
662 EMSG("Expression %s failed", #expr); \
663 return TEE_ERROR_GENERIC; \
664 } \
665 } while (0)
666
667 IMSG("Testing floating point operations");
668
669 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
670 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
671 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
672 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
673 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
674
675 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
676 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
677 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
678 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
679 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
680
681 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
682 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
683 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
684 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
685 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
686
687 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
688 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
689 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
690 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
691 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
692
693 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
694 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
695 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
696 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
697
698 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
699 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
700 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
701 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
702
703 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
704 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
705
706 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
707 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
708 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
709 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
710
711 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
712 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
713 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
714 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
715 return TEE_SUCCESS;
716}
717#else /*CFG_TA_FLOAT_SUPPORT*/
718static TEE_Result test_float(void)
719{
720 IMSG("Floating point disabled");
721 return TEE_SUCCESS;
722}
723#endif /*CFG_TA_FLOAT_SUPPORT*/
724
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100725#if defined(CFG_TA_BGET_TEST)
726/* From libutils */
727int bget_main_test(void *(*malloc_func)(size_t), void (*free_func)(void *));
728
729static void *malloc_wrapper(size_t size)
730{
731 return tee_map_zi(size, 0);
732}
733
734static void free_wrapper(void *ptr __unused)
735{
736}
737
738static TEE_Result test_bget(void)
739{
740 DMSG("Testing bget");
741 if (bget_main_test(malloc_wrapper, free_wrapper)) {
742 EMSG("bget_main_test failed");
743 return TEE_ERROR_GENERIC;
744 }
745 DMSG("Bget OK");
746 return TEE_SUCCESS;
747}
748#else
749static TEE_Result test_bget(void)
750{
751 IMSG("Bget test disabled");
752 return TEE_SUCCESS;
753}
754#endif
755
756
Jerome Forissier892ae4d2020-03-09 09:58:09 +0100757static __noinline __noreturn void call_longjmp(jmp_buf env)
Jens Wiklander9f682c62016-03-27 20:23:06 +0200758{
759 DMSG("Calling longjmp");
760 longjmp(env, 1);
761 EMSG("error: longjmp returned to calling function");
762}
763
764static TEE_Result test_setjmp(void)
765{
Etienne Carriere102092e2019-03-28 15:24:22 +0100766 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200767
768 if (setjmp(env)) {
769 IMSG("Returned via longjmp");
770 return TEE_SUCCESS;
771 } else {
772 call_longjmp(env);
773 return TEE_ERROR_GENERIC;
774 }
775}
776
Pascal Brandc639ac82015-07-02 08:53:34 +0200777TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
778{
779 TEE_Result res = TEE_ERROR_GENERIC;
780
781 printf("ta_entry_basic: enter\n");
782
783 res = test_malloc();
784 if (res != TEE_SUCCESS)
785 return res;
786
787 res = test_properties();
788 if (res != TEE_SUCCESS)
789 return res;
790
791 res = test_mem_access_right(param_types, params);
792 if (res != TEE_SUCCESS)
793 return res;
794
795 res = test_time();
796 if (res != TEE_SUCCESS)
797 return res;
798
Jens Wiklander246184a2015-12-11 08:28:59 +0100799 res = test_float();
800 if (res != TEE_SUCCESS)
801 return res;
802
Jens Wiklander9f682c62016-03-27 20:23:06 +0200803 res = test_setjmp();
804 if (res != TEE_SUCCESS)
805 return res;
806
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100807 res = test_bget();
808 if (res != TEE_SUCCESS)
809 return res;
810
Pascal Brandc639ac82015-07-02 08:53:34 +0200811 return TEE_SUCCESS;
812}
813
814TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
815{
816 volatile bool mytrue = true;
817 (void)param_types;
818 (void)params;
819
820 printf("ta_entry_panic: enter\n");
821 /*
822 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
823 * the __noreturn attribute.
824 */
825 if (mytrue)
826 TEE_Panic(0xbeef);
827
828 /*
829 * Should not be reached, but if it is the testsuite can detect that
830 * TEE_Panic() returned instead of panicking the TA.
831 */
832 return TEE_SUCCESS;
833}
834
835TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
836 TEE_Param params[4])
837{
838 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100839 TEE_Result res = TEE_ERROR_GENERIC;
840 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
841 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200842
843 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
844 TEE_PARAM_TYPE_NONE,
845 TEE_PARAM_TYPE_NONE,
846 TEE_PARAM_TYPE_NONE)) {
847 EMSG("ta_entry_client_with_timeout: bad parameters\n");
848 return TEE_ERROR_BAD_PARAMETERS;
849 }
850
Cedric Augere668b3f2019-09-11 13:41:21 +0200851 res = TEE_OpenTASession(&os_test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
852 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200853 if (res != TEE_SUCCESS) {
854 EMSG(
855 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
856 return res;
857 }
858
859 res =
860 TEE_InvokeTACommand(sess, params[0].value.a / 2,
861 TA_OS_TEST_CMD_WAIT, param_types, params,
862 &ret_orig);
863
864 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
865 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
866 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
867 (unsigned int)ret_orig);
868 res = TEE_ERROR_GENERIC;
869 } else
870 res = TEE_SUCCESS;
871
872 TEE_CloseTASession(sess);
873 return res;
874
875}
876
877TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
878{
879 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100880 TEE_Result res = TEE_ERROR_GENERIC;
881 uint32_t l_pts = 0;
882 TEE_Param l_params[4] = { };
883 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
884 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200885 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
886 static const uint8_t sha256_out[] = {
887 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
888 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
889 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
890 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
891 };
892 uint8_t out[32] = { 0 };
893 void *in = NULL;
894
895 (void)param_types;
896 (void)params;
897
898 printf("ta_entry_client: enter\n");
899
900 in = TEE_Malloc(sizeof(sha256_in), 0);
901 if (in == NULL)
902 return TEE_ERROR_OUT_OF_MEMORY;
903 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
904
Cedric Augere668b3f2019-09-11 13:41:21 +0200905 res = TEE_OpenTASession(&crypt_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
906 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200907 if (res != TEE_SUCCESS) {
908 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
909 goto cleanup_return;
910 }
911
912 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
913 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
914 l_params[0].memref.buffer = in;
915 l_params[0].memref.size = sizeof(sha256_in);
916 l_params[1].memref.buffer = out;
917 l_params[1].memref.size = sizeof(out);
918
Cedric Augere668b3f2019-09-11 13:41:21 +0200919 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
920 TA_CRYPT_CMD_SHA256, l_pts, l_params,
Pascal Brandc639ac82015-07-02 08:53:34 +0200921 &ret_orig);
922 if (res != TEE_SUCCESS) {
923 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
924 goto cleanup_return;
925 }
926
927 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
928 EMSG("ta_entry_client: out parameter failed\n");
929 res = TEE_ERROR_GENERIC;
930 goto cleanup_return;
931 }
932
933cleanup_return:
934 TEE_Free(in);
935 TEE_CloseTASession(sess);
936 return res;
937}
938
Etienne Carriere281065d2016-10-28 15:41:33 +0200939TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200940{
Etienne Carriere102092e2019-03-28 15:24:22 +0100941 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200942
943 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100944 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
945 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200946 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200947
948 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
949 TEE_MEMORY_ACCESS_ANY_OWNER,
950 params[0].memref.buffer,
951 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200952 if (res != TEE_SUCCESS)
953 return res;
954
955 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
956 params[0].memref.buffer,
957 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200958 if (res != TEE_ERROR_ACCESS_DENIED)
959 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +0100960 if (params[1].memref.buffer || params[1].memref.size)
961 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200962
Etienne Carriere281065d2016-10-28 15:41:33 +0200963 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200964}
965
966TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
967{
968 TEE_Result res = TEE_SUCCESS;
969 (void)param_types;
970
971 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
972 /* Wait */
973 res = TEE_Wait(params[0].value.a);
974
975 return res;
976}
977
Jens Wiklander1425f952016-07-21 09:02:30 +0200978static void undef_instr(void)
979{
980#if defined(ARM64)
981 __asm__(".word 0x0");
982#elif defined(ARM32)
983 __asm__(".word 0xe7ffffff");
Marouene Boubakri38fd7892023-01-06 10:45:15 +0100984#elif defined(RV64) || defined(RV32)
985 __asm__(".word 0x0");
Jens Wiklander1425f952016-07-21 09:02:30 +0200986#else
987#error "Unsupported architecture"
988#endif
989}
990
Pascal Brandc639ac82015-07-02 08:53:34 +0200991TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
992{
Etienne Carriere102092e2019-03-28 15:24:22 +0100993 long int stack = 0;
994 long int stack_addr = (long int)&stack;
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200995 void (*volatile null_fn_ptr)(void) = NULL;
Jerome Forissiere4c33f42021-09-21 11:26:17 +0200996 char *zero_size_malloc = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200997
Etienne Carriere92c34422018-02-09 13:11:40 +0100998 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
999 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
1000 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +02001001 return TEE_ERROR_GENERIC;
1002
1003 switch (params[0].value.a) {
1004 case 1:
Jerome Forissier71da60f2019-09-19 15:59:56 +02001005 *((volatile uint32_t *)0) = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +02001006 break;
1007 case 2:
1008 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
1009 break;
1010 case 3:
Jerome Forissiere2a58c62019-09-19 16:01:54 +02001011 null_fn_ptr();
Pascal Brandc639ac82015-07-02 08:53:34 +02001012 break;
1013 case 4:
1014 ((void (*)(void))(stack_addr + 0x40000000)) ();
1015 break;
1016 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +02001017 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +02001018 break;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001019 case 6:
1020 zero_size_malloc = TEE_Malloc(0, 0);
1021 if (!zero_size_malloc)
1022 return TEE_ERROR_GENERIC;
Etienne Carriere713db5a2021-09-29 20:32:32 +02001023 if (*zero_size_malloc)
1024 return TEE_ERROR_GENERIC;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001025 break;
1026 case 7:
1027 zero_size_malloc = TEE_Malloc(0, 0);
1028 if (!zero_size_malloc)
1029 return TEE_ERROR_GENERIC;
1030 *zero_size_malloc = 0;
1031 break;
Pascal Brandc639ac82015-07-02 08:53:34 +02001032 default:
1033 break;
1034 }
1035
1036 return TEE_SUCCESS;
1037}
Jerome Forissiere916b102017-06-07 17:55:52 +02001038
1039static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
1040{
Etienne Carriere102092e2019-03-28 15:24:22 +01001041 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001042
1043 for (i = 0; i < bufsize; i++) {
1044 a[i]++; b[i]++; c[i]++;
1045 }
1046}
1047
Etienne Carriere102092e2019-03-28 15:24:22 +01001048#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +02001049TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
1050{
1051 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
1052 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +01001053 TEE_Param l_params[4] = { };
1054 uint8_t in[TA2TA_BUF_SIZE] = { };
1055 uint8_t inout[TA2TA_BUF_SIZE] = { };
1056 uint8_t out[TA2TA_BUF_SIZE] = { };
1057 TEE_Result res = TEE_ERROR_GENERIC;
1058 uint32_t ret_orig = 0;
1059 uint32_t l_pts = 0;
1060 size_t i = 0;
1061
Jerome Forissiere916b102017-06-07 17:55:52 +02001062 (void)params;
1063
1064 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
1065 return TEE_ERROR_GENERIC;
1066
Cedric Augere668b3f2019-09-11 13:41:21 +02001067 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
1068 &sess, &ret_orig);
Jerome Forissiere916b102017-06-07 17:55:52 +02001069 if (res != TEE_SUCCESS) {
1070 EMSG("TEE_OpenTASession failed");
1071 goto cleanup_return;
1072 }
1073
1074 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1075 TEE_PARAM_TYPE_MEMREF_INOUT,
1076 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
1077 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +01001078 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001079 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +01001080 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001081 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +01001082 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001083
1084 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +01001085 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001086 in[i] = 5;
1087 inout[i] = 10;
1088 out[i] = 0;
1089 }
1090
1091 /*
1092 * TA will compute: out = ++inout + in
1093 * Expected values after this step: in: 5, inout: 11, out: 16
1094 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001095 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1096 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001097 l_pts, l_params, &ret_orig);
1098 if (res != TEE_SUCCESS) {
1099 EMSG("TEE_InvokeTACommand failed");
1100 goto cleanup_return;
1101 }
Etienne Carriere102092e2019-03-28 15:24:22 +01001102
Jerome Forissiere916b102017-06-07 17:55:52 +02001103 /*
1104 * Increment all values by one.
1105 * Expected values after this step: in: 6, inout: 12, out: 17
1106 */
Etienne Carriere102092e2019-03-28 15:24:22 +01001107 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +02001108
1109 /*
1110 * TA will compute: out = ++inout + in
1111 * Expected values after this step: in: 6, inout: 13, out: 19
1112 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001113 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1114 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001115 l_pts, l_params, &ret_orig);
1116 if (res != TEE_SUCCESS) {
1117 EMSG("TEE_InvokeTACommand failed");
1118 goto cleanup_return;
1119 }
1120
1121 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001122 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001123 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1124 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001125 DHEXDUMP(in, TA2TA_BUF_SIZE);
1126 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1127 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001128 return TEE_ERROR_GENERIC;
1129 }
1130 }
1131
1132cleanup_return:
1133 TEE_CloseTASession(sess);
1134 return res;
1135}
1136
1137TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1138{
Etienne Carriere102092e2019-03-28 15:24:22 +01001139 uint8_t *in = NULL;
1140 uint8_t *inout = NULL;
1141 uint8_t *out = NULL;
1142 size_t bufsize = 0;
1143 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001144
1145 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1146 TEE_PARAM_TYPE_MEMREF_INOUT,
1147 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1148 return TEE_ERROR_GENERIC;
1149
1150 bufsize = params[0].memref.size;
1151 if (params[1].memref.size != bufsize ||
1152 params[2].memref.size != bufsize)
1153 return TEE_ERROR_GENERIC;
1154
1155 in = params[0].memref.buffer;
1156 inout = params[1].memref.buffer;
1157 out = params[2].memref.buffer;
1158
1159 for (i = 0; i < bufsize; i++)
1160 out[i] = ++inout[i] + in[i];
1161
1162 return TEE_SUCCESS;
1163}
Jens Wiklander87e81702018-03-20 12:00:00 +08001164
1165TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1166{
Etienne Carriere102092e2019-03-28 15:24:22 +01001167 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001168
1169 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1170 TEE_PARAM_TYPE_MEMREF_INPUT,
1171 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1172 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1173 return TEE_ERROR_BAD_PARAMETERS;
1174
1175 for (n = 0; n < TEE_NUM_PARAMS; n++)
1176 if (!params[n].memref.buffer || !params[n].memref.size)
1177 return TEE_ERROR_BAD_PARAMETERS;
1178
1179 return TEE_SUCCESS;
1180}
Jerome Forissier53bde722018-05-31 09:14:54 +02001181
Cedric Neveux9f483bb2019-03-04 08:58:06 +01001182TEE_Result ta_entry_null_memref(uint32_t param_types, TEE_Param params[4])
1183{
1184 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1185 TEE_PARAM_TYPE_MEMREF_INPUT,
1186 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1187 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1188 return TEE_ERROR_BAD_PARAMETERS;
1189
1190 /*
1191 * Tests how client can provide null or non-null memref parameters
1192 * param[0] expected as a 0 byte input mapped memeref.
1193 * param[1] expected as a 0 byte input not-mapped memeref.
1194 * param[2] expected as a 0 byte output mapped memeref.
1195 * param[3] expected as a 0 byte output not-mapped memeref.
1196 */
1197 if (!params[0].memref.buffer || params[0].memref.size ||
1198 params[1].memref.buffer || params[1].memref.size ||
1199 !params[2].memref.buffer || params[2].memref.size ||
1200 params[3].memref.buffer || params[3].memref.size)
1201 return TEE_ERROR_BAD_PARAMETERS;
1202
1203 return TEE_SUCCESS;
1204}
1205
Jerome Forissier53bde722018-05-31 09:14:54 +02001206TEE_Result ta_entry_call_lib(uint32_t param_types,
1207 TEE_Param params[4] __unused)
1208{
1209 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1210 TEE_PARAM_TYPE_NONE,
1211 TEE_PARAM_TYPE_NONE,
1212 TEE_PARAM_TYPE_NONE))
1213 return TEE_ERROR_BAD_PARAMETERS;
1214
1215 if (os_test_shlib_add(1, 2) != 3)
1216 return TEE_ERROR_GENERIC;
1217
1218 return TEE_SUCCESS;
1219}
1220
1221TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1222 TEE_Param params[4] __unused)
1223{
1224 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1225 TEE_PARAM_TYPE_NONE,
1226 TEE_PARAM_TYPE_NONE,
1227 TEE_PARAM_TYPE_NONE))
1228 return TEE_ERROR_BAD_PARAMETERS;
1229
1230 os_test_shlib_panic();
1231
1232 return TEE_ERROR_GENERIC;
1233}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001234
1235TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1236 TEE_Param params[4] __unused)
1237{
1238 int (*add_func)(int a, int b) = NULL;
1239 TEE_Result res = TEE_ERROR_GENERIC;
1240 void *handle = NULL;
1241 void *hnull = NULL;
1242
1243 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1244 TEE_PARAM_TYPE_NONE,
1245 TEE_PARAM_TYPE_NONE,
1246 TEE_PARAM_TYPE_NONE))
1247 return TEE_ERROR_BAD_PARAMETERS;
1248
1249 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1250 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1251 if (!handle)
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001252 return TEE_ERROR_GENERIC;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001253
1254 add_func = dlsym(handle, "os_test_shlib_dl_add");
1255 if (!add_func)
1256 goto err;
1257 if (add_func(3, 4) != 7)
1258 goto err;
1259
1260 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001261 if (!hnull)
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001262 goto err;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001263
1264 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1265 if (!add_func)
1266 goto err;
1267 if (add_func(5, 6) != 11)
1268 goto err;
1269
1270 res = TEE_SUCCESS;
1271 dlclose(hnull);
1272err:
1273 dlclose(handle);
1274 return res;
1275}
1276
1277TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1278 TEE_Param params[4] __unused)
1279{
1280 int (*panic_func)(void) = NULL;
1281 void *handle = NULL;
1282 TEE_Result res = TEE_ERROR_GENERIC;
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)
1293 return res;
1294
1295 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1296 if (!panic_func)
1297 goto err;
1298 panic_func();
1299 return TEE_ERROR_GENERIC;
1300err:
1301 dlclose(handle);
1302 return res;
1303}
Jerome Forissiere9571e82020-02-18 15:26:20 +01001304
1305/* ELF initialization/finalization test */
1306
Jerome Forissier391168e2020-06-15 09:52:25 +02001307volatile int os_test_global;
Jerome Forissiere9571e82020-02-18 15:26:20 +01001308
1309static void __attribute__((constructor)) os_test_init(void)
1310{
1311 os_test_global *= 10;
1312 os_test_global += 1;
1313 DMSG("os_test_global=%d", os_test_global);
1314}
1315
1316TEE_Result ta_entry_get_global_var(uint32_t param_types, TEE_Param params[4])
1317{
1318 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1319 TEE_PARAM_TYPE_NONE,
1320 TEE_PARAM_TYPE_NONE,
1321 TEE_PARAM_TYPE_NONE))
1322 return TEE_ERROR_BAD_PARAMETERS;
1323
1324 params[0].value.a = os_test_global;
1325
1326 return TEE_SUCCESS;
1327}
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001328
1329TEE_Result ta_entry_client_identity(uint32_t param_types, TEE_Param params[4])
1330{
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001331 TEE_Result res = TEE_ERROR_GENERIC;
1332 TEE_Identity identity = { };
1333
1334 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1335 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1336 TEE_PARAM_TYPE_NONE,
1337 TEE_PARAM_TYPE_NONE))
1338 return TEE_ERROR_BAD_PARAMETERS;
1339
1340 if (params[1].memref.size < sizeof(TEE_UUID)) {
1341 params[1].memref.size = sizeof(TEE_UUID);
1342 return TEE_ERROR_SHORT_BUFFER;
1343 }
1344
1345 res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
1346 "gpd.client.identity", &identity);
1347 if (res != TEE_SUCCESS) {
1348 EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32, res);
1349 return res;
1350 }
1351
1352 params[0].value.a = identity.login;
1353 memcpy(params[1].memref.buffer, &identity.uuid, sizeof(TEE_UUID));
1354 params[1].memref.size = sizeof(TEE_UUID);
1355
1356 return res;
1357}
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001358
Jerome Forissier6d66ca92020-11-10 15:56:06 +01001359#if defined(WITH_TLS_TESTS)
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001360__thread int os_test_tls_a;
1361__thread int os_test_tls_b = 42;
1362
1363TEE_Result ta_entry_tls_test_main(void)
1364{
1365 if (os_test_tls_a != 0) {
1366 EMSG("os_test_tls_a=%d, expected 0", os_test_tls_a);
1367 return TEE_ERROR_GENERIC;
1368 }
1369 if (os_test_tls_b != 42) {
1370 EMSG("os_test_tls_b=%d, expected 42", os_test_tls_b);
1371 return TEE_ERROR_GENERIC;
1372 }
1373
1374 return TEE_SUCCESS;
1375}
1376
1377TEE_Result ta_entry_tls_test_shlib(void)
1378{
1379 if (os_test_shlib_tls_a != 0) {
1380 EMSG("os_test_shlib_tls_a=%d, expected 0", os_test_shlib_tls_a);
1381 return TEE_ERROR_GENERIC;
1382 }
1383 if (os_test_shlib_tls_b != 123) {
1384 EMSG("os_test_shlib_tls_b=%d, expected 123",
1385 os_test_shlib_tls_b);
1386 return TEE_ERROR_GENERIC;
1387 }
1388
1389 return TEE_SUCCESS;
1390}
Jerome Forissier6d66ca92020-11-10 15:56:06 +01001391#else
1392TEE_Result ta_entry_tls_test_main(void)
1393{
1394 return TEE_ERROR_NOT_SUPPORTED;
1395}
1396
1397TEE_Result ta_entry_tls_test_shlib(void)
1398{
1399 return TEE_ERROR_NOT_SUPPORTED;
1400}
1401#endif
Jerome Forissier4565c452020-06-17 17:55:00 +02001402
1403static int iterate_hdr_cb(struct dl_phdr_info *info __maybe_unused,
1404 size_t size __unused, void *data)
1405{
1406 int *count = data;
1407
1408 (*count)++;
1409 IMSG("ELF module index: %d", *count);
1410 IMSG(" dlpi_addr=%p", (void *)info->dlpi_addr);
1411 IMSG(" dlpi_name='%s'", info->dlpi_name);
1412 IMSG(" dlpi_phdr=%p", (void *)info->dlpi_phdr);
1413 IMSG(" dlpi_phnum=%hu", info->dlpi_phnum);
1414 IMSG(" dlpi_adds=%llu", info->dlpi_adds);
1415 IMSG(" dlpi_subs=%llu", info->dlpi_subs);
1416 IMSG(" dlpi_tls_modid=%zu", info->dlpi_tls_modid);
1417 IMSG(" dlpi_tls_data=%p", info->dlpi_tls_data);
1418
1419 return 123;
1420}
1421
1422static TEE_Result expect_dl_count_ge(size_t exp_count)
1423{
1424 int st = 0;
1425 size_t count = 0;
1426
1427 st = dl_iterate_phdr(iterate_hdr_cb, (void *)&count);
1428 if (st != 123) {
1429 /*
1430 * dl_iterate_phdr() should return the last value returned by
1431 * the callback
1432 */
1433 EMSG("Expected return value 123, got %d", st);
1434 return TEE_ERROR_GENERIC;
1435 }
1436 if (count < exp_count) {
1437 /*
1438 * Expect >= and not == since there could be more shared
1439 * libraries (for instance, CFG_ULIBS_SHARED=y)
1440 */
1441 EMSG("Expected count > %zu, got: %zu", exp_count, count);
1442 return TEE_ERROR_GENERIC;
1443 }
1444
1445 return TEE_SUCCESS;
1446}
1447
1448TEE_Result ta_entry_dl_phdr(void)
1449{
1450 return expect_dl_count_ge(2);
1451}
1452
1453TEE_Result ta_entry_dl_phdr_dl(void)
1454{
1455 TEE_Result res = TEE_ERROR_GENERIC;
1456 void *handle = NULL;
1457
1458 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1459 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1460 if (!handle)
1461 return TEE_ERROR_GENERIC;
1462
1463 res = expect_dl_count_ge(3);
1464 dlclose(handle);
1465
1466 return res;
1467}
Jens Wiklander50339ef2022-04-12 20:47:27 +02001468
1469TEE_Result ta_entry_memtag_use_after_free(void)
1470{
1471 uint32_t *p = NULL;
1472
1473 if (!memtag_is_enabled())
1474 return TEE_ERROR_NOT_SUPPORTED;
1475
1476 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1477 *p = 43;
1478 TEE_Free(p);
1479 (*p) += 2;
1480 return TEE_ERROR_GENERIC;
1481}
1482
1483TEE_Result ta_entry_memtag_invalid_tag(void)
1484{
1485 uint32_t *p = NULL;
1486 uint32_t *p2 = NULL;
1487
1488 if (!memtag_is_enabled())
1489 return TEE_ERROR_NOT_SUPPORTED;
1490
1491 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1492
1493 if (!memtag_get_tag(p)) {
1494 EMSG("missing tag in %p", (void *)p);
1495 goto err;
1496 }
1497 *p = 32;
1498
1499 p2 = memtag_insert_tag(p, (memtag_get_tag(p) + 1) & 0xf);
1500 *p2 = 42;
1501 EMSG("Expected to crash when writing to %p which was allocated as %p",
1502 (void *)p2, (void *)p);
1503err:
1504 TEE_Free(p);
1505 return TEE_ERROR_GENERIC;
1506}
1507
1508TEE_Result ta_entry_memtag_double_free(void)
1509{
1510 uint32_t *p = NULL;
1511
1512 if (!memtag_is_enabled())
1513 return TEE_ERROR_NOT_SUPPORTED;
1514
1515 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1516 *p = 43;
1517 TEE_Free(p);
1518 TEE_Free(p);
1519 return TEE_ERROR_GENERIC;
1520}
1521
1522TEE_Result ta_entry_memtag_buffer_overrun(void)
1523{
1524 uint64_t *p = NULL;
1525
1526 if (!memtag_is_enabled())
1527 return TEE_ERROR_NOT_SUPPORTED;
1528
1529 p = TEE_Malloc(sizeof(*p) * 2, TEE_MALLOC_FILL_ZERO);
1530 p[2] += 44;
1531 TEE_Free(p);
1532 return TEE_ERROR_GENERIC;
1533}