blob: 0e68cc695fcc1b18b1b0f60b5da2d92a058f5adc [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;
Etienne Carriere58e3a832020-07-08 16:56:01 +020077 uint32_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 Wiklanderc5231592015-11-11 09:27:27 +0100120 uint32_t nblen = sizeof(nbuf);
Etienne Carriere102092e2019-03-28 15:24:22 +0100121 uint32_t nblen_small = 0;
Jens Wiklanderc5231592015-11-11 09:27:27 +0100122 uint32_t vblen = sizeof(vbuf);
123 uint32_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) {
Pascal Brand5b68cd62016-02-22 10:31:01 +0100134 EMSG("Name has wrong size: %u vs %zu", nblen, strlen(nbuf) + 1);
Pascal Brand624b6a32016-02-16 12:51:34 +0100135 return TEE_ERROR_GENERIC;
136 }
Pascal Brandc639ac82015-07-02 08:53:34 +0200137
Pascal Brand624b6a32016-02-16 12:51:34 +0100138
139 /* Get the property name with a very small buffer */
140 nblen_small = 2;
141 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
142 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
143 nblen_small, nblen);
144 if (res != TEE_SUCCESS)
145 return res;
146
147 /* Get the property name with almost the correct buffer */
148 nblen_small = nblen - 1;
149 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
150 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
151 nblen_small, nblen);
152 if (res != TEE_SUCCESS)
153 return res;
154
155 /* Get the property name with the exact buffer length */
156 nblen_small = nblen;
157 res = TEE_GetPropertyName(h, nbuf_small, &nblen_small);
158 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
159 nblen_small, nblen);
160 if (res != TEE_SUCCESS)
161 return res;
162
163 /* Get the property value */
Pascal Brandc639ac82015-07-02 08:53:34 +0200164 res = TEE_GetPropertyAsString(h, NULL, vbuf, &vblen);
Pascal Brand624b6a32016-02-16 12:51:34 +0100165 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
166 vblen, strlen(vbuf) + 1);
167 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200168 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100169
Pascal Brandc639ac82015-07-02 08:53:34 +0200170 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
Pascal Brand624b6a32016-02-16 12:51:34 +0100171 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS,
172 vblen2, strlen(vbuf2) + 1);
173 if (res != TEE_SUCCESS)
Pascal Brandc639ac82015-07-02 08:53:34 +0200174 return res;
Pascal Brand624b6a32016-02-16 12:51:34 +0100175
Jens Wiklander8324ff22018-11-21 14:16:04 +0100176 if (strcmp(vbuf, vbuf2) != 0) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200177 EMSG("String of \"%s\" differs\n", nbuf);
178 return TEE_ERROR_GENERIC;
179 }
180
Pascal Brand624b6a32016-02-16 12:51:34 +0100181 /* Get the property with a very small buffer */
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200182 if (vblen > 1) {
183 vblen2 = 1;
184 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
185 res = check_returned_prop(__LINE__, nbuf, res,
186 TEE_ERROR_SHORT_BUFFER,
187 vblen2, vblen);
188 if (res != TEE_SUCCESS)
189 return res;
190 }
Pascal Brand624b6a32016-02-16 12:51:34 +0100191
192 /* Get the property with almost the correct buffer */
193 vblen2 = vblen - 1;
194 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
195 res = check_returned_prop(__LINE__, nbuf, res, TEE_ERROR_SHORT_BUFFER,
196 vblen2, vblen);
197 if (res != TEE_SUCCESS)
198 return res;
199
200 /* Get the property name with the exact buffer length */
201 vblen2 = vblen;
202 res = TEE_GetPropertyAsString(prop_set, nbuf, vbuf2, &vblen2);
203 res = check_returned_prop(__LINE__, nbuf, res, TEE_SUCCESS, vblen2, vblen);
204 if (res != TEE_SUCCESS)
205 return res;
206
207 /* check specific myprop.hello property, which is larger than 80 */
208 if (!strcmp("myprop.hello", nbuf) &&
209 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")) {
210 EMSG("TEE_GetPropertyAsString(\"%s\") is truncated - returned \"%s\"\n",
211 nbuf, vbuf);
212 return TEE_ERROR_GENERIC;
213 }
214
Pascal Brandc639ac82015-07-02 08:53:34 +0200215 DMSG("Found \"%s\" value \"%s\"\n", nbuf, vbuf);
216
217 for (n = 0; n < num_p_attrs; n++) {
Jens Wiklander8324ff22018-11-21 14:16:04 +0100218 if (strcmp(nbuf, p_attrs[n].str) != 0)
Pascal Brandc639ac82015-07-02 08:53:34 +0200219 continue;
220
221 if (p_attrs[n].retrieved) {
222 EMSG("Value \"%s\" already retrieved\n",
223 p_attrs[n].str);
224 return TEE_ERROR_GENERIC;
225 }
226 p_attrs[n].retrieved = true;
227
228 switch (p_attrs[n].type) {
229 case P_TYPE_BOOL:
230 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100231 bool v = false;
Pascal Brandc639ac82015-07-02 08:53:34 +0200232
233 res =
234 TEE_GetPropertyAsBool(h, NULL, &v);
235 if (res != TEE_SUCCESS) {
236 EMSG(
237 "TEE_GetPropertyAsBool(\"%s\") returned 0x%x\n",
238 nbuf, (unsigned int)res);
239 return res;
240 }
241 }
242 break;
243
244 case P_TYPE_INT:
245 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100246 uint32_t v = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200247
248 res = TEE_GetPropertyAsU32(h, NULL, &v);
249 if (res != TEE_SUCCESS) {
250 EMSG(
251 "TEE_GetPropertyAsU32(\"%s\") returned 0x%x\n",
252 nbuf, (unsigned int)res);
253 return res;
254 }
255 }
256 break;
257
258 case P_TYPE_UUID:
259 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100260 TEE_UUID v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200261
262 res =
263 TEE_GetPropertyAsUUID(h, NULL, &v);
264 if (res != TEE_SUCCESS) {
265 EMSG(
266 "TEE_GetPropertyAsUUID(\"%s\") returned 0x%x\n",
267 nbuf, (unsigned int)res);
268 return res;
269 }
270 }
271 break;
272
273 case P_TYPE_IDENTITY:
274 {
Etienne Carriere102092e2019-03-28 15:24:22 +0100275 TEE_Identity v = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200276
277 res =
278 TEE_GetPropertyAsIdentity(h, NULL,
279 &v);
280 if (res != TEE_SUCCESS) {
281 EMSG(
282 "TEE_GetPropertyAsIdentity(\"%s\") returned 0x%x\n",
283 nbuf, (unsigned int)res);
284 return res;
285 }
286 }
287 break;
288
289 case P_TYPE_STRING:
290 /* Already read as string */
291 break;
292
293 case P_TYPE_BINARY_BLOCK:
Etienne Carriereb34caff2020-05-26 09:25:35 +0200294 res = get_binblock_property(h, nbuf, &bbuf, &bblen);
295 if (res)
296 return res;
Pascal Brandc639ac82015-07-02 08:53:34 +0200297
Etienne Carriereb34caff2020-05-26 09:25:35 +0200298 if (!strcmp("myprop.binaryblock", nbuf)) {
299 const char exp_bin_value[] = "Hello world!";
300
301 if (bblen != strlen(exp_bin_value) ||
302 TEE_MemCompare(exp_bin_value, bbuf,
303 bblen)) {
304 EMSG("Binary buffer of \"%s\" differs from \"%s\"",
305 nbuf, exp_bin_value);
306 EMSG("Got \"%s\"", bbuf);
307 return TEE_ERROR_GENERIC;
308 }
309 } else if (!strcmp("myprop.binaryblock.1byte-ones",
310 nbuf)) {
311 res = check_binprop_ones(1, bbuf, bblen);
312 if (res)
Pascal Brandc639ac82015-07-02 08:53:34 +0200313 return res;
Etienne Carriereb34caff2020-05-26 09:25:35 +0200314 } else if (!strcmp("myprop.binaryblock.2byte-ones",
315 nbuf)) {
316 res = check_binprop_ones(2, bbuf, bblen);
317 if (res)
318 return res;
319 } else if (!strcmp("myprop.binaryblock.3byte-ones",
320 nbuf)) {
321 res = check_binprop_ones(3, bbuf, bblen);
322 if (res)
323 return res;
324 } else if (!strcmp("myprop.binaryblock.4byte-ones",
325 nbuf)) {
326 res = check_binprop_ones(4, bbuf, bblen);
327 if (res)
328 return res;
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200329 } else if (!strcmp("myprop.binaryblock.empty1", nbuf) ||
330 !strcmp("myprop.binaryblock.empty2", nbuf) ||
331 !strcmp("myprop.binaryblock.empty3", nbuf)) {
332 if (bblen) {
333 EMSG("Property \"%s\": %zu byte(s)",
334 nbuf, bblen);
335 return TEE_ERROR_GENERIC;
336 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200337 } else {
338 EMSG("Unexpected property \"%s\"", nbuf);
339 TEE_Panic(0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200340 }
Etienne Carriereb34caff2020-05-26 09:25:35 +0200341
342 TEE_Free(bbuf);
Pascal Brandc639ac82015-07-02 08:53:34 +0200343 break;
344
345 default:
346 EMSG("Unknown type (%d) for \"%s\"\n",
347 p_attrs[n].type, p_attrs[n].str);
348 return TEE_ERROR_GENERIC;
349 }
350 }
351
352 res = TEE_GetNextProperty(h);
353 if (res != TEE_SUCCESS) {
354 if (res == TEE_ERROR_ITEM_NOT_FOUND)
355 return TEE_SUCCESS;
356 return res;
357 }
358}
359}
360
361static TEE_Result test_malloc(void)
362{
363 void *p = TEE_Malloc(4, 0);
364
365 if (p == NULL) {
366 EMSG("TEE_Malloc failed\n");
367 return TEE_ERROR_OUT_OF_MEMORY;
368 }
369 TEE_Free(p);
370 TEE_Free(NULL);
371
372 return TEE_SUCCESS;
373}
374
375static TEE_Result test_properties(void)
376{
377 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriere102092e2019-03-28 15:24:22 +0100378 TEE_PropSetHandle h = TEE_HANDLE_NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200379 struct p_attr p_attrs[] = {
380 {"gpd.ta.appID", P_TYPE_UUID},
381 {"gpd.ta.singleInstance", P_TYPE_BOOL},
382 {"gpd.ta.multiSession", P_TYPE_BOOL},
383 {"gpd.ta.instanceKeepAlive", P_TYPE_BOOL},
384 {"gpd.ta.dataSize", P_TYPE_INT},
385 {"gpd.ta.stackSize", P_TYPE_INT},
386 {"gpd.ta.version", P_TYPE_STRING},
387 {"gpd.ta.description", P_TYPE_STRING},
388 {"gpd.client.identity", P_TYPE_IDENTITY},
389 {"gpd.tee.apiversion", P_TYPE_STRING},
390 {"gpd.tee.description", P_TYPE_STRING},
391 {"gpd.tee.deviceID", P_TYPE_UUID},
392 {"gpd.tee.systemTime.protectionLevel", P_TYPE_INT},
393 {"gpd.tee.TAPersistentTime.protectionLevel", P_TYPE_INT},
394 {"gpd.tee.arith.maxBigIntSize", P_TYPE_INT},
395 {"gpd.tee.cryptography.ecc", P_TYPE_BOOL},
396 {"gpd.tee.trustedStorage.antiRollback.protectionLevel", P_TYPE_INT},
397 {"gpd.tee.trustedos.implementation.version", P_TYPE_STRING},
398 {"gpd.tee.trustedos.implementation.binaryversion", P_TYPE_INT},
399 {"gpd.tee.trustedos.manufacturer", P_TYPE_STRING},
400 {"gpd.tee.firmware.implementation.version", P_TYPE_STRING},
401 {"gpd.tee.firmware.implementation.binaryversion", P_TYPE_INT},
402 {"gpd.tee.firmware.manufacturer", P_TYPE_STRING},
403 {"myprop.true", P_TYPE_BOOL},
404 {"myprop.42", P_TYPE_INT},
405 {"myprop.123", P_TYPE_UUID},
406 {"myprop.1234", P_TYPE_IDENTITY},
407 {"myprop.hello", P_TYPE_STRING},
408 {"myprop.binaryblock", P_TYPE_BINARY_BLOCK},
Etienne Carriereb34caff2020-05-26 09:25:35 +0200409 {"myprop.binaryblock.1byte-ones", P_TYPE_BINARY_BLOCK},
410 {"myprop.binaryblock.2byte-ones", P_TYPE_BINARY_BLOCK},
411 {"myprop.binaryblock.3byte-ones", P_TYPE_BINARY_BLOCK},
412 {"myprop.binaryblock.4byte-ones", P_TYPE_BINARY_BLOCK},
Etienne Carriere3ef6bf92020-05-26 11:25:04 +0200413 {"myprop.binaryblock.empty1", P_TYPE_BINARY_BLOCK},
414 {"myprop.binaryblock.empty2", P_TYPE_BINARY_BLOCK},
415 {"myprop.binaryblock.empty3", P_TYPE_BINARY_BLOCK},
Pascal Brandc639ac82015-07-02 08:53:34 +0200416 };
417 const size_t num_p_attrs = sizeof(p_attrs) / sizeof(p_attrs[0]);
Etienne Carriere102092e2019-03-28 15:24:22 +0100418 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200419
420 res = TEE_AllocatePropertyEnumerator(&h);
421 if (res != TEE_SUCCESS) {
422 EMSG("TEE_AllocatePropertyEnumerator: returned 0x%x\n",
423 (unsigned int)res);
424 return TEE_ERROR_GENERIC;
425 }
426
427 printf("Getting properties for current TA\n");
428 res = print_properties(h, TEE_PROPSET_CURRENT_TA, p_attrs, num_p_attrs);
429 if (res != TEE_SUCCESS)
430 goto cleanup_return;
431
432 printf("Getting properties for current client\n");
433 res = print_properties(h, TEE_PROPSET_CURRENT_CLIENT, p_attrs,
434 num_p_attrs);
435 if (res != TEE_SUCCESS)
436 goto cleanup_return;
437
438 printf("Getting properties for implementation\n");
439 res = print_properties(h, TEE_PROPSET_TEE_IMPLEMENTATION, p_attrs,
440 num_p_attrs);
441 if (res != TEE_SUCCESS)
442 goto cleanup_return;
443
444 for (n = 0; n < num_p_attrs; n++) {
445 if (!p_attrs[n].retrieved) {
446 EMSG("\"%s\" not retrieved\n", p_attrs[n].str);
447 res = TEE_ERROR_GENERIC;
448 goto cleanup_return;
449 }
450 }
451
452cleanup_return:
453 TEE_FreePropertyEnumerator(h);
454 return res;
455}
456
457static TEE_Result test_mem_access_right(uint32_t param_types,
458 TEE_Param params[4])
459{
460 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100461 TEE_Result res = TEE_ERROR_GENERIC;
462 uint32_t ret_orig = 0;
463 uint32_t l_pts = 0;
464 TEE_Param l_params[4] = { };
465 uint8_t buf[32] = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200466 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100467 TEE_UUID *uuid = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200468
469 if (param_types !=
470 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0, 0))
471 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200472
473 /* test access rights on memref parameter */
474 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
475 TEE_MEMORY_ACCESS_ANY_OWNER,
476 params[0].memref.buffer,
477 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200478 if (res != TEE_SUCCESS)
479 return res;
Etienne Carriere281065d2016-10-28 15:41:33 +0200480
Pascal Brandc639ac82015-07-02 08:53:34 +0200481 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
482 params[0].memref.buffer,
483 params[0].memref.size);
484 if (res != TEE_ERROR_ACCESS_DENIED)
485 return TEE_ERROR_GENERIC;
486
Etienne Carriere281065d2016-10-28 15:41:33 +0200487 /* test access rights on private read-only and read-write memory */
488 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
489 (void *)&test_uuid, sizeof(test_uuid));
490 if (res != TEE_SUCCESS)
491 return res;
492
493 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_WRITE,
494 (void *)&test_uuid, sizeof(test_uuid));
495 if (res == TEE_SUCCESS)
496 return TEE_ERROR_GENERIC;
497
498 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
499 TEE_MEMORY_ACCESS_WRITE,
500 &ret_orig, sizeof(ret_orig));
501 if (res != TEE_SUCCESS)
502 return res;
503
504 uuid = TEE_Malloc(sizeof(*uuid), 0);
505 if (!uuid)
506 return TEE_ERROR_OUT_OF_MEMORY;
507
508 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
509 TEE_MEMORY_ACCESS_WRITE,
510 uuid, sizeof(*uuid));
511 TEE_Free(uuid);
512 if (res != TEE_SUCCESS)
513 return res;
514
515 /* test access rights on invalid memory (at least lower 256kB) */
516 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
517 NULL, 1);
518 if (res == TEE_SUCCESS)
519 return TEE_ERROR_GENERIC;
520
521 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
522 (void*)(256 * 1024), 1);
523 if (res == TEE_SUCCESS)
524 return TEE_ERROR_GENERIC;
525
Cedric Augere668b3f2019-09-11 13:41:21 +0200526 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
527 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200528 if (res != TEE_SUCCESS) {
529 EMSG("test_mem_access_right: TEE_OpenTASession failed\n");
530 goto cleanup_return;
531 }
532
Jerome Forissier04511d82018-01-30 14:33:49 +0100533 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
534 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0);
Pascal Brandc639ac82015-07-02 08:53:34 +0200535 l_params[0].memref.buffer = buf;
536 l_params[0].memref.size = sizeof(buf);
Jerome Forissier04511d82018-01-30 14:33:49 +0100537 l_params[1].memref.buffer = NULL;
538 l_params[1].memref.size = 0;
Cedric Augere668b3f2019-09-11 13:41:21 +0200539 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
540 TA_OS_TEST_CMD_PARAMS_ACCESS,
Pascal Brandc639ac82015-07-02 08:53:34 +0200541 l_pts, l_params, &ret_orig);
542 if (res != TEE_SUCCESS) {
543 EMSG("test_mem_access_right: TEE_InvokeTACommand failed\n");
544 goto cleanup_return;
545 }
546
547cleanup_return:
548 TEE_CloseTASession(sess);
549 return res;
550}
551
552static TEE_Result test_time(void)
553{
Etienne Carriere102092e2019-03-28 15:24:22 +0100554 TEE_Result res = TEE_ERROR_GENERIC;
555 TEE_Time t = { };
556 TEE_Time sys_t = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200557 static const TEE_Time null_time = { 0, 0 };
558 static const TEE_Time wrap_time = { UINT32_MAX, 999 };
559
560 TEE_GetSystemTime(&sys_t);
561 printf("system time %u.%03u\n", (unsigned int)sys_t.seconds,
562 (unsigned int)sys_t.millis);
563
564 TEE_GetREETime(&t);
565 printf("REE time %u.%03u\n", (unsigned int)t.seconds,
566 (unsigned int)t.millis);
567
568 res = TEE_GetTAPersistentTime(&t);
569 switch (res) {
570 case TEE_SUCCESS:
571 printf("Stored TA time %u.%03u\n", (unsigned int)t.seconds,
572 (unsigned int)t.millis);
573 break;
574 case TEE_ERROR_OVERFLOW:
575 EMSG("Stored TA time overflowed %u.%03u\n",
576 (unsigned int)t.seconds, (unsigned int)t.millis);
577 break;
578 case TEE_ERROR_TIME_NOT_SET:
579 EMSG("TA time not stored\n");
580 break;
581 case TEE_ERROR_TIME_NEEDS_RESET:
582 EMSG("TA time needs reset\n");
583 break;
584 default:
585 return res;
586 }
587
588 res = TEE_SetTAPersistentTime(&null_time);
589 if (res != TEE_SUCCESS) {
590 EMSG("TEE_SetTAPersistentTime: failed\n");
591 return res;
592 }
593
594 res = TEE_GetTAPersistentTime(&t);
595 if (res != TEE_SUCCESS) {
596 EMSG("TEE_GetTAPersistentTime null: failed\n");
597 return res;
598 }
599 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
600 (unsigned int)t.millis);
601 /*
602 * The time between TEE_SetTAPersistentTime() and
603 * TEE_GetTAPersistentTime() should be much less than 1 second, in fact
604 * it's not even a millisecond.
605 */
606 if (t.seconds > 1 || t.millis >= 1000) {
607 EMSG("Unexpected stored TA time %u.%03u\n",
608 (unsigned int)t.seconds, (unsigned int)t.millis);
609 return TEE_ERROR_BAD_STATE;
610 }
611
612 res = TEE_SetTAPersistentTime(&wrap_time);
613 if (res != TEE_SUCCESS) {
614 EMSG("TEE_SetTAPersistentTime wrap: failed\n");
615 return res;
616 }
617
618 res = TEE_Wait(1000);
619 if (res != TEE_SUCCESS)
620 EMSG("TEE_Wait wrap: failed\n");
621
622 res = TEE_GetTAPersistentTime(&t);
623 if (res != TEE_ERROR_OVERFLOW) {
624 EMSG("TEE_GetTAPersistentTime: failed\n");
625 return TEE_ERROR_BAD_STATE;
626 }
627 printf("TA time %u.%03u\n", (unsigned int)t.seconds,
628 (unsigned int)t.millis);
629
630 if (t.seconds > sys_t.seconds) {
631 EMSG("Unexpected wrapped time %u.%03u (sys_t %u.%03u)\n",
632 (unsigned int)t.seconds, (unsigned int)t.millis,
633 (unsigned int)sys_t.seconds, (unsigned int)sys_t.millis);
634 return TEE_ERROR_BAD_STATE;
635 }
636
637 return TEE_SUCCESS;
638}
639
Jens Wiklander246184a2015-12-11 08:28:59 +0100640#ifdef CFG_TA_FLOAT_SUPPORT
641static bool my_dcmpeq(double v1, double v2, double prec)
642{
643 return v1 > (v2 - prec) && v1 < (v2 + prec);
644}
645
646static bool my_fcmpeq(float v1, float v2, float prec)
647{
648 return v1 > (v2 - prec) && v1 < (v2 + prec);
649}
650
651
652static TEE_Result test_float(void)
653{
654#define VAL1 2.6
655#define VAL1_INT 2
656#define VAL2 5.3
657#define DPREC 0.000000000000001
658#define FPREC 0.000001
659#define EXPECT(expr) do { \
660 if (!(expr)) { \
661 EMSG("Expression %s failed", #expr); \
662 return TEE_ERROR_GENERIC; \
663 } \
664 } while (0)
665
666 IMSG("Testing floating point operations");
667
668 EXPECT(my_dcmpeq(test_float_dadd(VAL1, VAL2), VAL1 + VAL2, DPREC));
669 EXPECT(my_dcmpeq(test_float_ddiv(VAL1, VAL2), VAL1 / VAL2, DPREC));
670 EXPECT(my_dcmpeq(test_float_dmul(VAL1, VAL2), VAL1 * VAL2, DPREC));
671 EXPECT(my_dcmpeq(test_float_drsub(VAL1, VAL2), VAL2 - VAL1, DPREC));
672 EXPECT(my_dcmpeq(test_float_dsub(VAL1, VAL2), VAL1 - VAL2, DPREC));
673
674 EXPECT(test_float_dcmpeq(VAL1, VAL1) == 1);
675 EXPECT(test_float_dcmplt(VAL1, VAL2) == 1);
676 EXPECT(test_float_dcmple(VAL1, VAL1) == 1);
677 EXPECT(test_float_dcmpge(VAL1, VAL1) == 1);
678 EXPECT(test_float_dcmpgt(VAL2, VAL1) == 1);
679
680 EXPECT(my_fcmpeq(test_float_fadd(VAL1, VAL2), VAL1 + VAL2, FPREC));
681 EXPECT(my_fcmpeq(test_float_fdiv(VAL1, VAL2), VAL1 / VAL2, FPREC));
682 EXPECT(my_fcmpeq(test_float_fmul(VAL1, VAL2), VAL1 * VAL2, FPREC));
683 EXPECT(my_fcmpeq(test_float_frsub(VAL1, VAL2), VAL2 - VAL1, FPREC));
684 EXPECT(my_fcmpeq(test_float_fsub(VAL1, VAL2), VAL1 - VAL2, FPREC));
685
686 EXPECT(test_float_fcmpeq(VAL1, VAL1) == 1);
687 EXPECT(test_float_fcmplt(VAL1, VAL2) == 1);
688 EXPECT(test_float_fcmple(VAL1, VAL1) == 1);
689 EXPECT(test_float_fcmpge(VAL1, VAL1) == 1);
690 EXPECT(test_float_fcmpgt(VAL2, VAL1) == 1);
691
692 EXPECT(test_float_d2iz(VAL1) == VAL1_INT);
693 EXPECT(test_float_d2uiz(VAL1) == VAL1_INT);
694 EXPECT(test_float_d2lz(VAL1) == VAL1_INT);
695 EXPECT(test_float_d2ulz(VAL1) == VAL1_INT);
696
697 EXPECT(test_float_f2iz(VAL1) == VAL1_INT);
698 EXPECT(test_float_f2uiz(VAL1) == VAL1_INT);
699 EXPECT(test_float_f2lz(VAL1) == VAL1_INT);
700 EXPECT(test_float_f2ulz(VAL1) == VAL1_INT);
701
702 EXPECT(my_fcmpeq(test_float_d2f(VAL1), VAL1, FPREC));
703 EXPECT(my_dcmpeq(test_float_f2d(VAL1), VAL1, FPREC));
704
705 EXPECT(my_dcmpeq(test_float_i2d(VAL1_INT), VAL1_INT, DPREC));
706 EXPECT(my_dcmpeq(test_float_ui2d(VAL1_INT), VAL1_INT, DPREC));
707 EXPECT(my_dcmpeq(test_float_l2d(VAL1_INT), VAL1_INT, DPREC));
708 EXPECT(my_dcmpeq(test_float_ul2d(VAL1_INT), VAL1_INT, DPREC));
709
710 EXPECT(my_fcmpeq(test_float_i2f(VAL1_INT), VAL1_INT, FPREC));
711 EXPECT(my_fcmpeq(test_float_ui2f(VAL1_INT), VAL1_INT, FPREC));
712 EXPECT(my_fcmpeq(test_float_l2f(VAL1_INT), VAL1_INT, FPREC));
713 EXPECT(my_fcmpeq(test_float_ul2f(VAL1_INT), VAL1_INT, FPREC));
714 return TEE_SUCCESS;
715}
716#else /*CFG_TA_FLOAT_SUPPORT*/
717static TEE_Result test_float(void)
718{
719 IMSG("Floating point disabled");
720 return TEE_SUCCESS;
721}
722#endif /*CFG_TA_FLOAT_SUPPORT*/
723
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100724#if defined(CFG_TA_BGET_TEST)
725/* From libutils */
726int bget_main_test(void *(*malloc_func)(size_t), void (*free_func)(void *));
727
728static void *malloc_wrapper(size_t size)
729{
730 return tee_map_zi(size, 0);
731}
732
733static void free_wrapper(void *ptr __unused)
734{
735}
736
737static TEE_Result test_bget(void)
738{
739 DMSG("Testing bget");
740 if (bget_main_test(malloc_wrapper, free_wrapper)) {
741 EMSG("bget_main_test failed");
742 return TEE_ERROR_GENERIC;
743 }
744 DMSG("Bget OK");
745 return TEE_SUCCESS;
746}
747#else
748static TEE_Result test_bget(void)
749{
750 IMSG("Bget test disabled");
751 return TEE_SUCCESS;
752}
753#endif
754
755
Jerome Forissier892ae4d2020-03-09 09:58:09 +0100756static __noinline __noreturn void call_longjmp(jmp_buf env)
Jens Wiklander9f682c62016-03-27 20:23:06 +0200757{
758 DMSG("Calling longjmp");
759 longjmp(env, 1);
760 EMSG("error: longjmp returned to calling function");
761}
762
763static TEE_Result test_setjmp(void)
764{
Etienne Carriere102092e2019-03-28 15:24:22 +0100765 jmp_buf env = { };
Jens Wiklander9f682c62016-03-27 20:23:06 +0200766
767 if (setjmp(env)) {
768 IMSG("Returned via longjmp");
769 return TEE_SUCCESS;
770 } else {
771 call_longjmp(env);
772 return TEE_ERROR_GENERIC;
773 }
774}
775
Pascal Brandc639ac82015-07-02 08:53:34 +0200776TEE_Result ta_entry_basic(uint32_t param_types, TEE_Param params[4])
777{
778 TEE_Result res = TEE_ERROR_GENERIC;
779
780 printf("ta_entry_basic: enter\n");
781
782 res = test_malloc();
783 if (res != TEE_SUCCESS)
784 return res;
785
786 res = test_properties();
787 if (res != TEE_SUCCESS)
788 return res;
789
790 res = test_mem_access_right(param_types, params);
791 if (res != TEE_SUCCESS)
792 return res;
793
794 res = test_time();
795 if (res != TEE_SUCCESS)
796 return res;
797
Jens Wiklander246184a2015-12-11 08:28:59 +0100798 res = test_float();
799 if (res != TEE_SUCCESS)
800 return res;
801
Jens Wiklander9f682c62016-03-27 20:23:06 +0200802 res = test_setjmp();
803 if (res != TEE_SUCCESS)
804 return res;
805
Jens Wiklander04ee6c42020-12-27 23:04:36 +0100806 res = test_bget();
807 if (res != TEE_SUCCESS)
808 return res;
809
Pascal Brandc639ac82015-07-02 08:53:34 +0200810 return TEE_SUCCESS;
811}
812
813TEE_Result ta_entry_panic(uint32_t param_types, TEE_Param params[4])
814{
815 volatile bool mytrue = true;
816 (void)param_types;
817 (void)params;
818
819 printf("ta_entry_panic: enter\n");
820 /*
821 * Somewhat clumsy way of avoiding compile errors if TEE_Panic() has
822 * the __noreturn attribute.
823 */
824 if (mytrue)
825 TEE_Panic(0xbeef);
826
827 /*
828 * Should not be reached, but if it is the testsuite can detect that
829 * TEE_Panic() returned instead of panicking the TA.
830 */
831 return TEE_SUCCESS;
832}
833
834TEE_Result ta_entry_client_with_timeout(uint32_t param_types,
835 TEE_Param params[4])
836{
837 static const TEE_UUID os_test_uuid = TA_OS_TEST_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100838 TEE_Result res = TEE_ERROR_GENERIC;
839 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
840 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200841
842 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
843 TEE_PARAM_TYPE_NONE,
844 TEE_PARAM_TYPE_NONE,
845 TEE_PARAM_TYPE_NONE)) {
846 EMSG("ta_entry_client_with_timeout: bad parameters\n");
847 return TEE_ERROR_BAD_PARAMETERS;
848 }
849
Cedric Augere668b3f2019-09-11 13:41:21 +0200850 res = TEE_OpenTASession(&os_test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
851 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200852 if (res != TEE_SUCCESS) {
853 EMSG(
854 "ta_entry_client_with_timeout: TEE_OpenTASession failed\n");
855 return res;
856 }
857
858 res =
859 TEE_InvokeTACommand(sess, params[0].value.a / 2,
860 TA_OS_TEST_CMD_WAIT, param_types, params,
861 &ret_orig);
862
863 if (ret_orig != TEE_ORIGIN_TRUSTED_APP || res != TEE_ERROR_CANCEL) {
864 EMSG("ta_entry_client_with_timeout: TEE_InvokeTACommand: "
865 "res 0x%x ret_orig 0x%x\n", (unsigned int)res,
866 (unsigned int)ret_orig);
867 res = TEE_ERROR_GENERIC;
868 } else
869 res = TEE_SUCCESS;
870
871 TEE_CloseTASession(sess);
872 return res;
873
874}
875
876TEE_Result ta_entry_client(uint32_t param_types, TEE_Param params[4])
877{
878 static const TEE_UUID crypt_uuid = TA_CRYPT_UUID;
Etienne Carriere102092e2019-03-28 15:24:22 +0100879 TEE_Result res = TEE_ERROR_GENERIC;
880 uint32_t l_pts = 0;
881 TEE_Param l_params[4] = { };
882 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
883 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200884 static const uint8_t sha256_in[] = { 'a', 'b', 'c' };
885 static const uint8_t sha256_out[] = {
886 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
887 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
888 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
889 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
890 };
891 uint8_t out[32] = { 0 };
892 void *in = NULL;
893
894 (void)param_types;
895 (void)params;
896
897 printf("ta_entry_client: enter\n");
898
899 in = TEE_Malloc(sizeof(sha256_in), 0);
900 if (in == NULL)
901 return TEE_ERROR_OUT_OF_MEMORY;
902 TEE_MemMove(in, sha256_in, sizeof(sha256_in));
903
Cedric Augere668b3f2019-09-11 13:41:21 +0200904 res = TEE_OpenTASession(&crypt_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
905 &sess, &ret_orig);
Pascal Brandc639ac82015-07-02 08:53:34 +0200906 if (res != TEE_SUCCESS) {
907 EMSG("ta_entry_client: TEE_OpenTASession failed\n");
908 goto cleanup_return;
909 }
910
911 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
912 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0);
913 l_params[0].memref.buffer = in;
914 l_params[0].memref.size = sizeof(sha256_in);
915 l_params[1].memref.buffer = out;
916 l_params[1].memref.size = sizeof(out);
917
Cedric Augere668b3f2019-09-11 13:41:21 +0200918 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
919 TA_CRYPT_CMD_SHA256, l_pts, l_params,
Pascal Brandc639ac82015-07-02 08:53:34 +0200920 &ret_orig);
921 if (res != TEE_SUCCESS) {
922 EMSG("ta_entry_client: TEE_InvokeTACommand failed\n");
923 goto cleanup_return;
924 }
925
926 if (TEE_MemCompare(sha256_out, out, sizeof(sha256_out)) != 0) {
927 EMSG("ta_entry_client: out parameter failed\n");
928 res = TEE_ERROR_GENERIC;
929 goto cleanup_return;
930 }
931
932cleanup_return:
933 TEE_Free(in);
934 TEE_CloseTASession(sess);
935 return res;
936}
937
Etienne Carriere281065d2016-10-28 15:41:33 +0200938TEE_Result ta_entry_params_access_rights(uint32_t param_types, TEE_Param params[4])
Pascal Brandc639ac82015-07-02 08:53:34 +0200939{
Etienne Carriere102092e2019-03-28 15:24:22 +0100940 TEE_Result res = TEE_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200941
942 if (param_types !=
Jerome Forissier04511d82018-01-30 14:33:49 +0100943 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
944 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200945 return TEE_ERROR_GENERIC;
Etienne Carriere281065d2016-10-28 15:41:33 +0200946
947 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ |
948 TEE_MEMORY_ACCESS_ANY_OWNER,
949 params[0].memref.buffer,
950 params[0].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200951 if (res != TEE_SUCCESS)
952 return res;
953
954 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_READ,
955 params[0].memref.buffer,
956 params[0].memref.size);
Etienne Carriere281065d2016-10-28 15:41:33 +0200957 if (res != TEE_ERROR_ACCESS_DENIED)
958 return TEE_ERROR_GENERIC;
Jerome Forissier04511d82018-01-30 14:33:49 +0100959 if (params[1].memref.buffer || params[1].memref.size)
960 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200961
Etienne Carriere281065d2016-10-28 15:41:33 +0200962 return TEE_SUCCESS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200963}
964
965TEE_Result ta_entry_wait(uint32_t param_types, TEE_Param params[4])
966{
967 TEE_Result res = TEE_SUCCESS;
968 (void)param_types;
969
970 printf("ta_entry_wait: waiting %d\n", (unsigned int)params[0].value.a);
971 /* Wait */
972 res = TEE_Wait(params[0].value.a);
973
974 return res;
975}
976
Jens Wiklander1425f952016-07-21 09:02:30 +0200977static void undef_instr(void)
978{
979#if defined(ARM64)
980 __asm__(".word 0x0");
981#elif defined(ARM32)
982 __asm__(".word 0xe7ffffff");
983#else
984#error "Unsupported architecture"
985#endif
986}
987
Pascal Brandc639ac82015-07-02 08:53:34 +0200988TEE_Result ta_entry_bad_mem_access(uint32_t param_types, TEE_Param params[4])
989{
Etienne Carriere102092e2019-03-28 15:24:22 +0100990 long int stack = 0;
991 long int stack_addr = (long int)&stack;
Jerome Forissiere2a58c62019-09-19 16:01:54 +0200992 void (*volatile null_fn_ptr)(void) = NULL;
Jerome Forissiere4c33f42021-09-21 11:26:17 +0200993 char *zero_size_malloc = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +0200994
Etienne Carriere92c34422018-02-09 13:11:40 +0100995 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 0, 0, 0) &&
996 param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
997 TEE_PARAM_TYPE_MEMREF_INOUT, 0, 0))
Pascal Brandc639ac82015-07-02 08:53:34 +0200998 return TEE_ERROR_GENERIC;
999
1000 switch (params[0].value.a) {
1001 case 1:
Jerome Forissier71da60f2019-09-19 15:59:56 +02001002 *((volatile uint32_t *)0) = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +02001003 break;
1004 case 2:
1005 *((uint32_t *)(stack_addr + 0x40000000)) = 0;
1006 break;
1007 case 3:
Jerome Forissiere2a58c62019-09-19 16:01:54 +02001008 null_fn_ptr();
Pascal Brandc639ac82015-07-02 08:53:34 +02001009 break;
1010 case 4:
1011 ((void (*)(void))(stack_addr + 0x40000000)) ();
1012 break;
1013 case 5:
Jens Wiklander1425f952016-07-21 09:02:30 +02001014 undef_instr();
Pascal Brandc639ac82015-07-02 08:53:34 +02001015 break;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001016 case 6:
1017 zero_size_malloc = TEE_Malloc(0, 0);
1018 if (!zero_size_malloc)
1019 return TEE_ERROR_GENERIC;
Etienne Carriere713db5a2021-09-29 20:32:32 +02001020 if (*zero_size_malloc)
1021 return TEE_ERROR_GENERIC;
Jerome Forissiere4c33f42021-09-21 11:26:17 +02001022 break;
1023 case 7:
1024 zero_size_malloc = TEE_Malloc(0, 0);
1025 if (!zero_size_malloc)
1026 return TEE_ERROR_GENERIC;
1027 *zero_size_malloc = 0;
1028 break;
Pascal Brandc639ac82015-07-02 08:53:34 +02001029 default:
1030 break;
1031 }
1032
1033 return TEE_SUCCESS;
1034}
Jerome Forissiere916b102017-06-07 17:55:52 +02001035
1036static void incr_values(size_t bufsize, uint8_t *a, uint8_t *b, uint8_t *c)
1037{
Etienne Carriere102092e2019-03-28 15:24:22 +01001038 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001039
1040 for (i = 0; i < bufsize; i++) {
1041 a[i]++; b[i]++; c[i]++;
1042 }
1043}
1044
Etienne Carriere102092e2019-03-28 15:24:22 +01001045#define TA2TA_BUF_SIZE (2 * 1024)
Jerome Forissiere916b102017-06-07 17:55:52 +02001046TEE_Result ta_entry_ta2ta_memref(uint32_t param_types, TEE_Param params[4])
1047{
1048 static const TEE_UUID test_uuid = TA_OS_TEST_UUID;
1049 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +01001050 TEE_Param l_params[4] = { };
1051 uint8_t in[TA2TA_BUF_SIZE] = { };
1052 uint8_t inout[TA2TA_BUF_SIZE] = { };
1053 uint8_t out[TA2TA_BUF_SIZE] = { };
1054 TEE_Result res = TEE_ERROR_GENERIC;
1055 uint32_t ret_orig = 0;
1056 uint32_t l_pts = 0;
1057 size_t i = 0;
1058
Jerome Forissiere916b102017-06-07 17:55:52 +02001059 (void)params;
1060
1061 if (param_types != TEE_PARAM_TYPES(0, 0, 0, 0))
1062 return TEE_ERROR_GENERIC;
1063
Cedric Augere668b3f2019-09-11 13:41:21 +02001064 res = TEE_OpenTASession(&test_uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
1065 &sess, &ret_orig);
Jerome Forissiere916b102017-06-07 17:55:52 +02001066 if (res != TEE_SUCCESS) {
1067 EMSG("TEE_OpenTASession failed");
1068 goto cleanup_return;
1069 }
1070
1071 l_pts = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1072 TEE_PARAM_TYPE_MEMREF_INOUT,
1073 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0);
1074 l_params[0].memref.buffer = in;
Etienne Carriere102092e2019-03-28 15:24:22 +01001075 l_params[0].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001076 l_params[1].memref.buffer = inout;
Etienne Carriere102092e2019-03-28 15:24:22 +01001077 l_params[1].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001078 l_params[2].memref.buffer = out;
Etienne Carriere102092e2019-03-28 15:24:22 +01001079 l_params[2].memref.size = TA2TA_BUF_SIZE;
Jerome Forissiere916b102017-06-07 17:55:52 +02001080
1081 /* Initialize buffers */
Etienne Carriere102092e2019-03-28 15:24:22 +01001082 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001083 in[i] = 5;
1084 inout[i] = 10;
1085 out[i] = 0;
1086 }
1087
1088 /*
1089 * TA will compute: out = ++inout + in
1090 * Expected values after this step: in: 5, inout: 11, out: 16
1091 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001092 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1093 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001094 l_pts, l_params, &ret_orig);
1095 if (res != TEE_SUCCESS) {
1096 EMSG("TEE_InvokeTACommand failed");
1097 goto cleanup_return;
1098 }
Etienne Carriere102092e2019-03-28 15:24:22 +01001099
Jerome Forissiere916b102017-06-07 17:55:52 +02001100 /*
1101 * Increment all values by one.
1102 * Expected values after this step: in: 6, inout: 12, out: 17
1103 */
Etienne Carriere102092e2019-03-28 15:24:22 +01001104 incr_values(TA2TA_BUF_SIZE, in, inout, out);
Jerome Forissiere916b102017-06-07 17:55:52 +02001105
1106 /*
1107 * TA will compute: out = ++inout + in
1108 * Expected values after this step: in: 6, inout: 13, out: 19
1109 */
Cedric Augere668b3f2019-09-11 13:41:21 +02001110 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
1111 TA_OS_TEST_CMD_TA2TA_MEMREF_MIX,
Jerome Forissiere916b102017-06-07 17:55:52 +02001112 l_pts, l_params, &ret_orig);
1113 if (res != TEE_SUCCESS) {
1114 EMSG("TEE_InvokeTACommand failed");
1115 goto cleanup_return;
1116 }
1117
1118 /* Check the actual values */
Etienne Carriere102092e2019-03-28 15:24:22 +01001119 for (i = 0; i < TA2TA_BUF_SIZE; i++) {
Jerome Forissiere916b102017-06-07 17:55:52 +02001120 if (in[i] != 6 || inout[i] != 13 || out[i] != 19) {
1121 EMSG("Unexpected value in buffer(s)");
Etienne Carriere102092e2019-03-28 15:24:22 +01001122 DHEXDUMP(in, TA2TA_BUF_SIZE);
1123 DHEXDUMP(inout, TA2TA_BUF_SIZE);
1124 DHEXDUMP(out, TA2TA_BUF_SIZE);
Jerome Forissiere916b102017-06-07 17:55:52 +02001125 return TEE_ERROR_GENERIC;
1126 }
1127 }
1128
1129cleanup_return:
1130 TEE_CloseTASession(sess);
1131 return res;
1132}
1133
1134TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types, TEE_Param params[4])
1135{
Etienne Carriere102092e2019-03-28 15:24:22 +01001136 uint8_t *in = NULL;
1137 uint8_t *inout = NULL;
1138 uint8_t *out = NULL;
1139 size_t bufsize = 0;
1140 size_t i = 0;
Jerome Forissiere916b102017-06-07 17:55:52 +02001141
1142 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1143 TEE_PARAM_TYPE_MEMREF_INOUT,
1144 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0))
1145 return TEE_ERROR_GENERIC;
1146
1147 bufsize = params[0].memref.size;
1148 if (params[1].memref.size != bufsize ||
1149 params[2].memref.size != bufsize)
1150 return TEE_ERROR_GENERIC;
1151
1152 in = params[0].memref.buffer;
1153 inout = params[1].memref.buffer;
1154 out = params[2].memref.buffer;
1155
1156 for (i = 0; i < bufsize; i++)
1157 out[i] = ++inout[i] + in[i];
1158
1159 return TEE_SUCCESS;
1160}
Jens Wiklander87e81702018-03-20 12:00:00 +08001161
1162TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4])
1163{
Etienne Carriere102092e2019-03-28 15:24:22 +01001164 size_t n = 0;
Jens Wiklander87e81702018-03-20 12:00:00 +08001165
1166 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1167 TEE_PARAM_TYPE_MEMREF_INPUT,
1168 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1169 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1170 return TEE_ERROR_BAD_PARAMETERS;
1171
1172 for (n = 0; n < TEE_NUM_PARAMS; n++)
1173 if (!params[n].memref.buffer || !params[n].memref.size)
1174 return TEE_ERROR_BAD_PARAMETERS;
1175
1176 return TEE_SUCCESS;
1177}
Jerome Forissier53bde722018-05-31 09:14:54 +02001178
Cedric Neveux9f483bb2019-03-04 08:58:06 +01001179TEE_Result ta_entry_null_memref(uint32_t param_types, TEE_Param params[4])
1180{
1181 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1182 TEE_PARAM_TYPE_MEMREF_INPUT,
1183 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1184 TEE_PARAM_TYPE_MEMREF_OUTPUT))
1185 return TEE_ERROR_BAD_PARAMETERS;
1186
1187 /*
1188 * Tests how client can provide null or non-null memref parameters
1189 * param[0] expected as a 0 byte input mapped memeref.
1190 * param[1] expected as a 0 byte input not-mapped memeref.
1191 * param[2] expected as a 0 byte output mapped memeref.
1192 * param[3] expected as a 0 byte output not-mapped memeref.
1193 */
1194 if (!params[0].memref.buffer || params[0].memref.size ||
1195 params[1].memref.buffer || params[1].memref.size ||
1196 !params[2].memref.buffer || params[2].memref.size ||
1197 params[3].memref.buffer || params[3].memref.size)
1198 return TEE_ERROR_BAD_PARAMETERS;
1199
1200 return TEE_SUCCESS;
1201}
1202
Jerome Forissier53bde722018-05-31 09:14:54 +02001203TEE_Result ta_entry_call_lib(uint32_t param_types,
1204 TEE_Param params[4] __unused)
1205{
1206 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1207 TEE_PARAM_TYPE_NONE,
1208 TEE_PARAM_TYPE_NONE,
1209 TEE_PARAM_TYPE_NONE))
1210 return TEE_ERROR_BAD_PARAMETERS;
1211
1212 if (os_test_shlib_add(1, 2) != 3)
1213 return TEE_ERROR_GENERIC;
1214
1215 return TEE_SUCCESS;
1216}
1217
1218TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
1219 TEE_Param params[4] __unused)
1220{
1221 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1222 TEE_PARAM_TYPE_NONE,
1223 TEE_PARAM_TYPE_NONE,
1224 TEE_PARAM_TYPE_NONE))
1225 return TEE_ERROR_BAD_PARAMETERS;
1226
1227 os_test_shlib_panic();
1228
1229 return TEE_ERROR_GENERIC;
1230}
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001231
1232TEE_Result ta_entry_call_lib_dl(uint32_t param_types __maybe_unused,
1233 TEE_Param params[4] __unused)
1234{
1235 int (*add_func)(int a, int b) = NULL;
1236 TEE_Result res = TEE_ERROR_GENERIC;
1237 void *handle = NULL;
1238 void *hnull = NULL;
1239
1240 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1241 TEE_PARAM_TYPE_NONE,
1242 TEE_PARAM_TYPE_NONE,
1243 TEE_PARAM_TYPE_NONE))
1244 return TEE_ERROR_BAD_PARAMETERS;
1245
1246 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1247 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1248 if (!handle)
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001249 return TEE_ERROR_GENERIC;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001250
1251 add_func = dlsym(handle, "os_test_shlib_dl_add");
1252 if (!add_func)
1253 goto err;
1254 if (add_func(3, 4) != 7)
1255 goto err;
1256
1257 hnull = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
Jerome Forissier7c68d7b2019-10-22 15:02:11 +02001258 if (!hnull)
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001259 goto err;
Jerome Forissiera9ab5d02019-03-17 21:14:06 +01001260
1261 add_func = dlsym(hnull, "os_test_shlib_dl_add");
1262 if (!add_func)
1263 goto err;
1264 if (add_func(5, 6) != 11)
1265 goto err;
1266
1267 res = TEE_SUCCESS;
1268 dlclose(hnull);
1269err:
1270 dlclose(handle);
1271 return res;
1272}
1273
1274TEE_Result ta_entry_call_lib_dl_panic(uint32_t param_types __maybe_unused,
1275 TEE_Param params[4] __unused)
1276{
1277 int (*panic_func)(void) = NULL;
1278 void *handle = NULL;
1279 TEE_Result res = TEE_ERROR_GENERIC;
1280
1281 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
1282 TEE_PARAM_TYPE_NONE,
1283 TEE_PARAM_TYPE_NONE,
1284 TEE_PARAM_TYPE_NONE))
1285 return TEE_ERROR_BAD_PARAMETERS;
1286
1287 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1288 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1289 if (!handle)
1290 return res;
1291
1292 panic_func = dlsym(handle, "os_test_shlib_dl_panic");
1293 if (!panic_func)
1294 goto err;
1295 panic_func();
1296 return TEE_ERROR_GENERIC;
1297err:
1298 dlclose(handle);
1299 return res;
1300}
Jerome Forissiere9571e82020-02-18 15:26:20 +01001301
1302/* ELF initialization/finalization test */
1303
Jerome Forissier391168e2020-06-15 09:52:25 +02001304volatile int os_test_global;
Jerome Forissiere9571e82020-02-18 15:26:20 +01001305
1306static void __attribute__((constructor)) os_test_init(void)
1307{
1308 os_test_global *= 10;
1309 os_test_global += 1;
1310 DMSG("os_test_global=%d", os_test_global);
1311}
1312
1313TEE_Result ta_entry_get_global_var(uint32_t param_types, TEE_Param params[4])
1314{
1315 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1316 TEE_PARAM_TYPE_NONE,
1317 TEE_PARAM_TYPE_NONE,
1318 TEE_PARAM_TYPE_NONE))
1319 return TEE_ERROR_BAD_PARAMETERS;
1320
1321 params[0].value.a = os_test_global;
1322
1323 return TEE_SUCCESS;
1324}
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001325
1326TEE_Result ta_entry_client_identity(uint32_t param_types, TEE_Param params[4])
1327{
Vesa Jääskeläinen41ff0802020-04-05 20:11:46 +03001328 TEE_Result res = TEE_ERROR_GENERIC;
1329 TEE_Identity identity = { };
1330
1331 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
1332 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1333 TEE_PARAM_TYPE_NONE,
1334 TEE_PARAM_TYPE_NONE))
1335 return TEE_ERROR_BAD_PARAMETERS;
1336
1337 if (params[1].memref.size < sizeof(TEE_UUID)) {
1338 params[1].memref.size = sizeof(TEE_UUID);
1339 return TEE_ERROR_SHORT_BUFFER;
1340 }
1341
1342 res = TEE_GetPropertyAsIdentity(TEE_PROPSET_CURRENT_CLIENT,
1343 "gpd.client.identity", &identity);
1344 if (res != TEE_SUCCESS) {
1345 EMSG("TEE_GetPropertyAsIdentity: returned %#"PRIx32, res);
1346 return res;
1347 }
1348
1349 params[0].value.a = identity.login;
1350 memcpy(params[1].memref.buffer, &identity.uuid, sizeof(TEE_UUID));
1351 params[1].memref.size = sizeof(TEE_UUID);
1352
1353 return res;
1354}
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001355
Jerome Forissier6d66ca92020-11-10 15:56:06 +01001356#if defined(WITH_TLS_TESTS)
Jerome Forissier9a7101b2020-06-17 17:55:00 +02001357__thread int os_test_tls_a;
1358__thread int os_test_tls_b = 42;
1359
1360TEE_Result ta_entry_tls_test_main(void)
1361{
1362 if (os_test_tls_a != 0) {
1363 EMSG("os_test_tls_a=%d, expected 0", os_test_tls_a);
1364 return TEE_ERROR_GENERIC;
1365 }
1366 if (os_test_tls_b != 42) {
1367 EMSG("os_test_tls_b=%d, expected 42", os_test_tls_b);
1368 return TEE_ERROR_GENERIC;
1369 }
1370
1371 return TEE_SUCCESS;
1372}
1373
1374TEE_Result ta_entry_tls_test_shlib(void)
1375{
1376 if (os_test_shlib_tls_a != 0) {
1377 EMSG("os_test_shlib_tls_a=%d, expected 0", os_test_shlib_tls_a);
1378 return TEE_ERROR_GENERIC;
1379 }
1380 if (os_test_shlib_tls_b != 123) {
1381 EMSG("os_test_shlib_tls_b=%d, expected 123",
1382 os_test_shlib_tls_b);
1383 return TEE_ERROR_GENERIC;
1384 }
1385
1386 return TEE_SUCCESS;
1387}
Jerome Forissier6d66ca92020-11-10 15:56:06 +01001388#else
1389TEE_Result ta_entry_tls_test_main(void)
1390{
1391 return TEE_ERROR_NOT_SUPPORTED;
1392}
1393
1394TEE_Result ta_entry_tls_test_shlib(void)
1395{
1396 return TEE_ERROR_NOT_SUPPORTED;
1397}
1398#endif
Jerome Forissier4565c452020-06-17 17:55:00 +02001399
1400static int iterate_hdr_cb(struct dl_phdr_info *info __maybe_unused,
1401 size_t size __unused, void *data)
1402{
1403 int *count = data;
1404
1405 (*count)++;
1406 IMSG("ELF module index: %d", *count);
1407 IMSG(" dlpi_addr=%p", (void *)info->dlpi_addr);
1408 IMSG(" dlpi_name='%s'", info->dlpi_name);
1409 IMSG(" dlpi_phdr=%p", (void *)info->dlpi_phdr);
1410 IMSG(" dlpi_phnum=%hu", info->dlpi_phnum);
1411 IMSG(" dlpi_adds=%llu", info->dlpi_adds);
1412 IMSG(" dlpi_subs=%llu", info->dlpi_subs);
1413 IMSG(" dlpi_tls_modid=%zu", info->dlpi_tls_modid);
1414 IMSG(" dlpi_tls_data=%p", info->dlpi_tls_data);
1415
1416 return 123;
1417}
1418
1419static TEE_Result expect_dl_count_ge(size_t exp_count)
1420{
1421 int st = 0;
1422 size_t count = 0;
1423
1424 st = dl_iterate_phdr(iterate_hdr_cb, (void *)&count);
1425 if (st != 123) {
1426 /*
1427 * dl_iterate_phdr() should return the last value returned by
1428 * the callback
1429 */
1430 EMSG("Expected return value 123, got %d", st);
1431 return TEE_ERROR_GENERIC;
1432 }
1433 if (count < exp_count) {
1434 /*
1435 * Expect >= and not == since there could be more shared
1436 * libraries (for instance, CFG_ULIBS_SHARED=y)
1437 */
1438 EMSG("Expected count > %zu, got: %zu", exp_count, count);
1439 return TEE_ERROR_GENERIC;
1440 }
1441
1442 return TEE_SUCCESS;
1443}
1444
1445TEE_Result ta_entry_dl_phdr(void)
1446{
1447 return expect_dl_count_ge(2);
1448}
1449
1450TEE_Result ta_entry_dl_phdr_dl(void)
1451{
1452 TEE_Result res = TEE_ERROR_GENERIC;
1453 void *handle = NULL;
1454
1455 handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba",
1456 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
1457 if (!handle)
1458 return TEE_ERROR_GENERIC;
1459
1460 res = expect_dl_count_ge(3);
1461 dlclose(handle);
1462
1463 return res;
1464}
Jens Wiklander50339ef2022-04-12 20:47:27 +02001465
1466TEE_Result ta_entry_memtag_use_after_free(void)
1467{
1468 uint32_t *p = NULL;
1469
1470 if (!memtag_is_enabled())
1471 return TEE_ERROR_NOT_SUPPORTED;
1472
1473 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1474 *p = 43;
1475 TEE_Free(p);
1476 (*p) += 2;
1477 return TEE_ERROR_GENERIC;
1478}
1479
1480TEE_Result ta_entry_memtag_invalid_tag(void)
1481{
1482 uint32_t *p = NULL;
1483 uint32_t *p2 = NULL;
1484
1485 if (!memtag_is_enabled())
1486 return TEE_ERROR_NOT_SUPPORTED;
1487
1488 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1489
1490 if (!memtag_get_tag(p)) {
1491 EMSG("missing tag in %p", (void *)p);
1492 goto err;
1493 }
1494 *p = 32;
1495
1496 p2 = memtag_insert_tag(p, (memtag_get_tag(p) + 1) & 0xf);
1497 *p2 = 42;
1498 EMSG("Expected to crash when writing to %p which was allocated as %p",
1499 (void *)p2, (void *)p);
1500err:
1501 TEE_Free(p);
1502 return TEE_ERROR_GENERIC;
1503}
1504
1505TEE_Result ta_entry_memtag_double_free(void)
1506{
1507 uint32_t *p = NULL;
1508
1509 if (!memtag_is_enabled())
1510 return TEE_ERROR_NOT_SUPPORTED;
1511
1512 p = TEE_Malloc(sizeof(*p), TEE_MALLOC_FILL_ZERO);
1513 *p = 43;
1514 TEE_Free(p);
1515 TEE_Free(p);
1516 return TEE_ERROR_GENERIC;
1517}
1518
1519TEE_Result ta_entry_memtag_buffer_overrun(void)
1520{
1521 uint64_t *p = NULL;
1522
1523 if (!memtag_is_enabled())
1524 return TEE_ERROR_NOT_SUPPORTED;
1525
1526 p = TEE_Malloc(sizeof(*p) * 2, TEE_MALLOC_FILL_ZERO);
1527 p[2] += 44;
1528 TEE_Free(p);
1529 return TEE_ERROR_GENERIC;
1530}
1531
1532