xref: /optee_os/lib/libutee/tee_api.c (revision 32b3180828fa15a49ccc86ecb4be9d274c140c89)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  */
5 #include <stdlib.h>
6 #include <string.h>
7 #include <string_ext.h>
8 #include <tee_api.h>
9 #include <tee_internal_api_extensions.h>
10 #include <types_ext.h>
11 #include <user_ta_header.h>
12 #include <utee_syscalls.h>
13 #include "tee_api_private.h"
14 
15 /*
16  * return a known non-NULL invalid pointer when the
17  * requested size is zero
18  */
19 #define TEE_NULL_SIZED_VA		((void *)1)
20 #define TEE_NULL_SIZED_NO_SHARE_VA	((void *)2)
21 
22 /*
23  * Workaround build error in Teaclave TrustZone SDK
24  *
25  * These are supposed to be provided by ta/arch/arm/user_ta_header.c, but
26  * Teaclave TrustZone SDK seems to roll their own in Rust.
27  */
28 uint8_t __ta_no_share_heap[0] __weak;
29 const size_t __ta_no_share_heap_size __weak;
30 struct malloc_ctx *__ta_no_share_malloc_ctx __weak;
31 
32 static const void *tee_api_instance_data;
33 
34 /* System API - Internal Client API */
35 
36 static void copy_param(struct utee_params *up, uint32_t param_types,
37 		       const TEE_Param params[TEE_NUM_PARAMS])
38 {
39 	size_t n = 0;
40 	uint64_t a = 0;
41 	uint64_t b = 0;
42 
43 	up->types = param_types;
44 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
45 		switch (TEE_PARAM_TYPE_GET(up->types, n)) {
46 		case TEE_PARAM_TYPE_VALUE_INPUT:
47 		case TEE_PARAM_TYPE_VALUE_INOUT:
48 			a = params[n].value.a;
49 			b = params[n].value.b;
50 			break;
51 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
52 		case TEE_PARAM_TYPE_MEMREF_INOUT:
53 		case TEE_PARAM_TYPE_MEMREF_INPUT:
54 			a = (vaddr_t)params[n].memref.buffer;
55 			b = params[n].memref.size;
56 			break;
57 		default:
58 			a = 0;
59 			b = 0;
60 		}
61 		up->vals[n * 2] = a;
62 		up->vals[n * 2 + 1] = b;
63 	}
64 }
65 
66 static void copy_gp11_param(struct utee_params *up, uint32_t param_types,
67 			    const __GP11_TEE_Param params[TEE_NUM_PARAMS])
68 {
69 	size_t n = 0;
70 	uint64_t a = 0;
71 	uint64_t b = 0;
72 
73 	up->types = param_types;
74 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
75 		switch (TEE_PARAM_TYPE_GET(up->types, n)) {
76 		case TEE_PARAM_TYPE_VALUE_INPUT:
77 		case TEE_PARAM_TYPE_VALUE_INOUT:
78 			a = params[n].value.a;
79 			b = params[n].value.b;
80 			break;
81 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
82 		case TEE_PARAM_TYPE_MEMREF_INOUT:
83 		case TEE_PARAM_TYPE_MEMREF_INPUT:
84 			a = (vaddr_t)params[n].memref.buffer;
85 			b = params[n].memref.size;
86 			break;
87 		default:
88 			a = 0;
89 			b = 0;
90 		}
91 		up->vals[n * 2] = a;
92 		up->vals[n * 2 + 1] = b;
93 	}
94 }
95 
96 static TEE_Result map_tmp_param(struct utee_params *up, void **tmp_buf,
97 				size_t *tmp_len, void *tmp_va[TEE_NUM_PARAMS])
98 {
99 	size_t n = 0;
100 	uint8_t *tb = NULL;
101 	size_t tbl = 0;
102 	size_t tmp_align = sizeof(vaddr_t) * 2;
103 	bool is_tmp_mem[TEE_NUM_PARAMS] = { false };
104 	void *b = NULL;
105 	size_t s = 0;
106 	const uint32_t flags = TEE_MEMORY_ACCESS_READ;
107 
108 	/*
109 	 * If a memory parameter points to TA private memory we need to
110 	 * allocate a temporary buffer to avoid exposing the memory
111 	 * directly to the called TA.
112 	 */
113 
114 	*tmp_buf = NULL;
115 	*tmp_len = 0;
116 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
117 		tmp_va[n] = NULL;
118 		switch (TEE_PARAM_TYPE_GET(up->types, n)) {
119 		case TEE_PARAM_TYPE_MEMREF_INPUT:
120 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
121 		case TEE_PARAM_TYPE_MEMREF_INOUT:
122 			b = (void *)(vaddr_t)up->vals[n * 2];
123 			s = up->vals[n * 2 + 1];
124 			/*
125 			 * We're only allocating temporary memory if the
126 			 * buffer is completely within TA memory. If it's
127 			 * NULL, empty, partially outside or completely
128 			 * outside TA memory there's nothing more we need
129 			 * to do here. If there's security/permissions
130 			 * problem we'll get an error in the
131 			 * invoke_command/open_session below.
132 			 */
133 			if (b && s &&
134 			    !TEE_CheckMemoryAccessRights(flags, b, s)) {
135 				is_tmp_mem[n] = true;
136 				tbl += ROUNDUP(s, tmp_align);
137 			}
138 			break;
139 		default:
140 			break;
141 		}
142 	}
143 
144 	if (tbl) {
145 		tb = tee_map_zi(tbl, TEE_MEMORY_ACCESS_ANY_OWNER);
146 		if (!tb)
147 			return TEE_ERROR_OUT_OF_MEMORY;
148 		*tmp_buf = tb;
149 		*tmp_len = tbl;
150 	}
151 
152 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
153 		switch (TEE_PARAM_TYPE_GET(up->types, n)) {
154 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
155 		case TEE_PARAM_TYPE_MEMREF_INOUT:
156 		case TEE_PARAM_TYPE_MEMREF_INPUT:
157 			if (!is_tmp_mem[n])
158 				break;
159 			s = up->vals[n * 2 + 1];
160 			b = (void *)(vaddr_t)up->vals[n * 2];
161 			tmp_va[n] = tb;
162 			tb += ROUNDUP(s, tmp_align);
163 			up->vals[n * 2] = (vaddr_t)tmp_va[n];
164 			if (TEE_PARAM_TYPE_GET(up->types, n) !=
165 			    TEE_PARAM_TYPE_MEMREF_OUTPUT)
166 				memcpy(tmp_va[n], b, s);
167 			break;
168 		default:
169 			break;
170 		}
171 	}
172 
173 	return TEE_SUCCESS;
174 
175 }
176 
177 static void update_out_param(TEE_Param params[TEE_NUM_PARAMS],
178 			     void *tmp_va[TEE_NUM_PARAMS],
179 			     const struct utee_params *up)
180 {
181 	size_t n;
182 	uint32_t types = up->types;
183 
184 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
185 		uintptr_t a = up->vals[n * 2];
186 		uintptr_t b = up->vals[n * 2 + 1];
187 
188 		switch (TEE_PARAM_TYPE_GET(types, n)) {
189 		case TEE_PARAM_TYPE_VALUE_OUTPUT:
190 		case TEE_PARAM_TYPE_VALUE_INOUT:
191 			params[n].value.a = a;
192 			params[n].value.b = b;
193 			break;
194 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
195 		case TEE_PARAM_TYPE_MEMREF_INOUT:
196 			if (tmp_va[n])
197 				memcpy(params[n].memref.buffer, tmp_va[n],
198 				       MIN(b, params[n].memref.size));
199 			params[n].memref.size = b;
200 			break;
201 		default:
202 			break;
203 		}
204 	}
205 }
206 
207 static void update_out_gp11_param(__GP11_TEE_Param params[TEE_NUM_PARAMS],
208 				  void *tmp_va[TEE_NUM_PARAMS],
209 				  const struct utee_params *up)
210 {
211 	size_t n = 0;
212 	uint32_t types = up->types;
213 
214 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
215 		uintptr_t a = up->vals[n * 2];
216 		uintptr_t b = up->vals[n * 2 + 1];
217 
218 		switch (TEE_PARAM_TYPE_GET(types, n)) {
219 		case TEE_PARAM_TYPE_VALUE_OUTPUT:
220 		case TEE_PARAM_TYPE_VALUE_INOUT:
221 			params[n].value.a = a;
222 			params[n].value.b = b;
223 			break;
224 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
225 		case TEE_PARAM_TYPE_MEMREF_INOUT:
226 			if (tmp_va[n])
227 				memcpy(params[n].memref.buffer, tmp_va[n],
228 				       MIN(b, params[n].memref.size));
229 			params[n].memref.size = b;
230 			break;
231 		default:
232 			break;
233 		}
234 	}
235 }
236 
237 static bool bufs_intersect(void *buf1, size_t sz1, void *buf2, size_t sz2)
238 {
239 	vaddr_t b1 = (vaddr_t)buf1;
240 	vaddr_t b2 = (vaddr_t)buf2;
241 	vaddr_t e1 = b1 + sz1 - 1;
242 	vaddr_t e2 = b2 + sz2 - 1;
243 
244 	if (!sz1 || !sz2)
245 		return false;
246 
247 	if (e1 < b2 || e2 < b1)
248 		return false;
249 
250 	return true;
251 }
252 
253 static TEE_Result check_mem_access_rights_params(uint32_t flags, void *buf,
254 						 size_t len)
255 {
256 	size_t n = 0;
257 
258 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
259 		uint32_t f = TEE_MEMORY_ACCESS_ANY_OWNER;
260 
261 		switch (TEE_PARAM_TYPE_GET(ta_param_types, n)) {
262 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
263 		case TEE_PARAM_TYPE_MEMREF_INOUT:
264 			f |= TEE_MEMORY_ACCESS_WRITE;
265 			fallthrough;
266 		case TEE_PARAM_TYPE_MEMREF_INPUT:
267 			f |= TEE_MEMORY_ACCESS_READ;
268 			if (bufs_intersect(buf, len,
269 					   ta_params[n].memref.buffer,
270 					   ta_params[n].memref.size)) {
271 				if ((flags & f) != flags)
272 					return TEE_ERROR_ACCESS_DENIED;
273 			}
274 			break;
275 		default:
276 			break;
277 		}
278 	}
279 
280 	return TEE_SUCCESS;
281 }
282 
283 static bool buf_overlaps_no_share_heap(void *buf, size_t size)
284 {
285 	struct malloc_ctx *ctx = __ta_no_share_malloc_ctx;
286 
287 	return ctx && raw_malloc_buffer_overlaps_heap(ctx, buf, size);
288 }
289 
290 static void check_invoke_param(uint32_t pt, TEE_Param params[TEE_NUM_PARAMS])
291 {
292 	size_t n = 0;
293 
294 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
295 		uint32_t f = TEE_MEMORY_ACCESS_ANY_OWNER;
296 		void *buf = params[n].memref.buffer;
297 		size_t size = params[n].memref.size;
298 
299 		switch (TEE_PARAM_TYPE_GET(pt, n)) {
300 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
301 		case TEE_PARAM_TYPE_MEMREF_INOUT:
302 			f |= TEE_MEMORY_ACCESS_WRITE;
303 			fallthrough;
304 		case TEE_PARAM_TYPE_MEMREF_INPUT:
305 			f |= TEE_MEMORY_ACCESS_READ;
306 			if (check_mem_access_rights_params(f, buf, size))
307 				TEE_Panic(0);
308 			if (buf_overlaps_no_share_heap(buf, size))
309 				TEE_Panic(0);
310 			break;
311 		default:
312 			break;
313 		}
314 	}
315 }
316 
317 TEE_Result TEE_OpenTASession(const TEE_UUID *destination,
318 				uint32_t cancellationRequestTimeout,
319 				uint32_t paramTypes,
320 				TEE_Param params[TEE_NUM_PARAMS],
321 				TEE_TASessionHandle *session,
322 				uint32_t *returnOrigin)
323 {
324 	TEE_Result res = TEE_SUCCESS;
325 	struct utee_params up = { };
326 	uint32_t s = 0;
327 	void *tmp_buf = NULL;
328 	size_t tmp_len = 0;
329 	void *tmp_va[TEE_NUM_PARAMS] = { NULL };
330 
331 	if (paramTypes) {
332 		__utee_check_inout_annotation(params,
333 					      sizeof(TEE_Param) *
334 					      TEE_NUM_PARAMS);
335 		check_invoke_param(paramTypes, params);
336 	}
337 	__utee_check_out_annotation(session, sizeof(*session));
338 
339 	copy_param(&up, paramTypes, params);
340 	res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va);
341 	if (res)
342 		goto out;
343 	res = _utee_open_ta_session(destination, cancellationRequestTimeout,
344 				    &up, &s, returnOrigin);
345 	update_out_param(params, tmp_va, &up);
346 	if (tmp_buf) {
347 		TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
348 
349 		if (res2)
350 			TEE_Panic(res2);
351 	}
352 
353 out:
354 	/*
355 	 * Specification says that *session must hold TEE_HANDLE_NULL is
356 	 * TEE_SUCCESS isn't returned. Set it here explicitly in case
357 	 * the syscall fails before out parameters has been updated.
358 	 */
359 	if (res != TEE_SUCCESS)
360 		s = TEE_HANDLE_NULL;
361 
362 	*session = (TEE_TASessionHandle)(uintptr_t)s;
363 	return res;
364 }
365 
366 TEE_Result __GP11_TEE_OpenTASession(const TEE_UUID *destination,
367 				    uint32_t cancellationRequestTimeout,
368 				    uint32_t paramTypes,
369 				    __GP11_TEE_Param params[TEE_NUM_PARAMS],
370 				    TEE_TASessionHandle *session,
371 				    uint32_t *returnOrigin)
372 {
373 	TEE_Result res = TEE_SUCCESS;
374 	struct utee_params up = { };
375 	uint32_t s = 0;
376 	void *tmp_buf = NULL;
377 	size_t tmp_len = 0;
378 	void *tmp_va[TEE_NUM_PARAMS] = { NULL };
379 
380 	if (paramTypes)
381 		__utee_check_inout_annotation(params,
382 					      sizeof(__GP11_TEE_Param) *
383 					      TEE_NUM_PARAMS);
384 	__utee_check_out_annotation(session, sizeof(*session));
385 
386 	copy_gp11_param(&up, paramTypes, params);
387 	res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va);
388 	if (res)
389 		goto out;
390 	res = _utee_open_ta_session(destination, cancellationRequestTimeout,
391 				    &up, &s, returnOrigin);
392 	update_out_gp11_param(params, tmp_va, &up);
393 	if (tmp_buf) {
394 		TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
395 
396 		if (res2)
397 			TEE_Panic(res2);
398 	}
399 
400 out:
401 	/*
402 	 * Specification says that *session must hold TEE_HANDLE_NULL if
403 	 * TEE_SUCCESS isn't returned. Set it here explicitly in case
404 	 * the syscall fails before out parameters has been updated.
405 	 */
406 	if (res != TEE_SUCCESS)
407 		s = TEE_HANDLE_NULL;
408 
409 	*session = (TEE_TASessionHandle)(uintptr_t)s;
410 	return res;
411 }
412 
413 void TEE_CloseTASession(TEE_TASessionHandle session)
414 {
415 	if (session != TEE_HANDLE_NULL) {
416 		TEE_Result res = _utee_close_ta_session((uintptr_t)session);
417 
418 		if (res != TEE_SUCCESS)
419 			TEE_Panic(res);
420 	}
421 }
422 
423 TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session,
424 				uint32_t cancellationRequestTimeout,
425 				uint32_t commandID, uint32_t paramTypes,
426 				TEE_Param params[TEE_NUM_PARAMS],
427 				uint32_t *returnOrigin)
428 {
429 	TEE_Result res = TEE_SUCCESS;
430 	uint32_t ret_origin = TEE_ORIGIN_TEE;
431 	struct utee_params up = { };
432 	void *tmp_buf = NULL;
433 	size_t tmp_len = 0;
434 	void *tmp_va[TEE_NUM_PARAMS] = { NULL };
435 
436 	if (paramTypes) {
437 		__utee_check_inout_annotation(params,
438 					      sizeof(TEE_Param) *
439 					      TEE_NUM_PARAMS);
440 		check_invoke_param(paramTypes, params);
441 	}
442 	if (returnOrigin)
443 		__utee_check_out_annotation(returnOrigin,
444 					    sizeof(*returnOrigin));
445 
446 	copy_param(&up, paramTypes, params);
447 	res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va);
448 	if (res)
449 		goto out;
450 	res = _utee_invoke_ta_command((uintptr_t)session,
451 				      cancellationRequestTimeout,
452 				      commandID, &up, &ret_origin);
453 	update_out_param(params, tmp_va, &up);
454 	if (tmp_buf) {
455 		TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
456 
457 		if (res2)
458 			TEE_Panic(res2);
459 	}
460 
461 out:
462 	if (returnOrigin != NULL)
463 		*returnOrigin = ret_origin;
464 
465 	if (ret_origin == TEE_ORIGIN_TRUSTED_APP)
466 		return res;
467 
468 	if (res != TEE_SUCCESS &&
469 	    res != TEE_ERROR_OUT_OF_MEMORY &&
470 	    res != TEE_ERROR_TARGET_DEAD)
471 		TEE_Panic(res);
472 
473 	return res;
474 }
475 
476 TEE_Result __GP11_TEE_InvokeTACommand(TEE_TASessionHandle session,
477 				      uint32_t cancellationRequestTimeout,
478 				      uint32_t commandID, uint32_t paramTypes,
479 				      __GP11_TEE_Param params[TEE_NUM_PARAMS],
480 				      uint32_t *returnOrigin)
481 {
482 	TEE_Result res = TEE_SUCCESS;
483 	uint32_t ret_origin = TEE_ORIGIN_TEE;
484 	struct utee_params up = { };
485 	void *tmp_buf = NULL;
486 	size_t tmp_len = 0;
487 	void *tmp_va[TEE_NUM_PARAMS] = { NULL };
488 
489 	if (paramTypes)
490 		__utee_check_inout_annotation(params,
491 					      sizeof(__GP11_TEE_Param) *
492 					      TEE_NUM_PARAMS);
493 	if (returnOrigin)
494 		__utee_check_out_annotation(returnOrigin,
495 					    sizeof(*returnOrigin));
496 
497 	copy_gp11_param(&up, paramTypes, params);
498 	res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va);
499 	if (res)
500 		goto out;
501 	res = _utee_invoke_ta_command((uintptr_t)session,
502 				      cancellationRequestTimeout,
503 				      commandID, &up, &ret_origin);
504 	update_out_gp11_param(params, tmp_va, &up);
505 	if (tmp_buf) {
506 		TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
507 
508 		if (res2)
509 			TEE_Panic(res2);
510 	}
511 
512 out:
513 	if (returnOrigin)
514 		*returnOrigin = ret_origin;
515 
516 	if (ret_origin == TEE_ORIGIN_TRUSTED_APP)
517 		return res;
518 
519 	if (res != TEE_SUCCESS &&
520 	    res != TEE_ERROR_OUT_OF_MEMORY &&
521 	    res != TEE_ERROR_TARGET_DEAD)
522 		TEE_Panic(res);
523 
524 	return res;
525 }
526 
527 /* System API - Cancellations */
528 
529 bool TEE_GetCancellationFlag(void)
530 {
531 	uint32_t c;
532 	TEE_Result res = _utee_get_cancellation_flag(&c);
533 
534 	if (res != TEE_SUCCESS)
535 		c = 0;
536 	return !!c;
537 }
538 
539 bool TEE_UnmaskCancellation(void)
540 {
541 	uint32_t old_mask;
542 	TEE_Result res = _utee_unmask_cancellation(&old_mask);
543 
544 	if (res != TEE_SUCCESS)
545 		TEE_Panic(res);
546 	return !!old_mask;
547 }
548 
549 bool TEE_MaskCancellation(void)
550 {
551 	uint32_t old_mask;
552 	TEE_Result res = _utee_mask_cancellation(&old_mask);
553 
554 	if (res != TEE_SUCCESS)
555 		TEE_Panic(res);
556 	return !!old_mask;
557 }
558 
559 /* System API - Memory Management */
560 
561 TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void *buffer,
562 				       size_t size)
563 {
564 	uint32_t flags = accessFlags;
565 
566 	if (!size)
567 		return TEE_SUCCESS;
568 
569 	/*
570 	 * Check access rights against memory mapping. If this check is
571 	 * OK the size can't cause an overflow when added with buffer.
572 	 */
573 	if (_utee_check_access_rights(accessFlags, buffer, size))
574 		return TEE_ERROR_ACCESS_DENIED;
575 
576 	/*
577 	 * Check access rights against input parameters.
578 	 *
579 	 * Clear eventual extension flags like TEE_MEMORY_ACCESS_NONSECURE
580 	 * and TEE_MEMORY_ACCESS_SECURE.
581 	 */
582 	flags &= TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE |
583 		 TEE_MEMORY_ACCESS_ANY_OWNER;
584 	if (check_mem_access_rights_params(flags, buffer, size))
585 		return TEE_ERROR_ACCESS_DENIED;
586 
587 	if (malloc_buffer_overlaps_heap(buffer, size) &&
588 	    !malloc_buffer_is_within_alloced(buffer, size))
589 		return TEE_ERROR_ACCESS_DENIED;
590 
591 	return TEE_SUCCESS;
592 }
593 
594 TEE_Result __GP11_TEE_CheckMemoryAccessRights(uint32_t accessFlags,
595 					      void *buffer, uint32_t size)
596 {
597 	return TEE_CheckMemoryAccessRights(accessFlags, buffer, size);
598 }
599 
600 void TEE_SetInstanceData(const void *instanceData)
601 {
602 	tee_api_instance_data = instanceData;
603 }
604 
605 const void *TEE_GetInstanceData(void)
606 {
607 	return tee_api_instance_data;
608 }
609 
610 void *TEE_MemMove(void *dest, const void *src, size_t size)
611 {
612 	return memmove(dest, src, size);
613 }
614 
615 void *__GP11_TEE_MemMove(void *dest, const void *src, uint32_t size)
616 {
617 	return TEE_MemMove(dest, src, size);
618 }
619 
620 int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, size_t size)
621 {
622 	return consttime_memcmp(buffer1, buffer2, size);
623 }
624 
625 int32_t __GP11_TEE_MemCompare(const void *buffer1, const void *buffer2,
626 			      uint32_t size)
627 {
628 	return TEE_MemCompare(buffer1, buffer2, size);
629 }
630 
631 void TEE_MemFill(void *buff, uint32_t x, size_t size)
632 {
633 	memset(buff, x, size);
634 }
635 
636 void __GP11_TEE_MemFill(void *buff, uint32_t x, uint32_t size)
637 {
638 	TEE_MemFill(buff, x, size);
639 }
640 
641 /* Date & Time API */
642 
643 void TEE_GetSystemTime(TEE_Time *time)
644 {
645 	TEE_Result res = _utee_get_time(UTEE_TIME_CAT_SYSTEM, time);
646 
647 	if (res != TEE_SUCCESS)
648 		TEE_Panic(res);
649 }
650 
651 TEE_Result TEE_Wait(uint32_t timeout)
652 {
653 	TEE_Result res = _utee_wait(timeout);
654 
655 	if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL)
656 		TEE_Panic(res);
657 
658 	return res;
659 }
660 
661 TEE_Result TEE_GetTAPersistentTime(TEE_Time *time)
662 {
663 	TEE_Result res;
664 
665 	res = _utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time);
666 
667 	if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) {
668 		time->seconds = 0;
669 		time->millis = 0;
670 	}
671 
672 	if (res != TEE_SUCCESS &&
673 	    res != TEE_ERROR_TIME_NOT_SET &&
674 	    res != TEE_ERROR_TIME_NEEDS_RESET &&
675 	    res != TEE_ERROR_OVERFLOW &&
676 	    res != TEE_ERROR_OUT_OF_MEMORY)
677 		TEE_Panic(res);
678 
679 	return res;
680 }
681 
682 TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time)
683 {
684 	TEE_Result res;
685 
686 	res = _utee_set_ta_time(time);
687 
688 	if (res != TEE_SUCCESS &&
689 	    res != TEE_ERROR_OUT_OF_MEMORY &&
690 	    res != TEE_ERROR_STORAGE_NO_SPACE)
691 		TEE_Panic(res);
692 
693 	return res;
694 }
695 
696 void TEE_GetREETime(TEE_Time *time)
697 {
698 	TEE_Result res = _utee_get_time(UTEE_TIME_CAT_REE, time);
699 
700 	if (res != TEE_SUCCESS)
701 		TEE_Panic(res);
702 }
703 
704 void *TEE_Malloc(size_t len, uint32_t hint)
705 {
706 	switch (hint) {
707 	case TEE_MALLOC_FILL_ZERO:
708 		if (!len)
709 			return TEE_NULL_SIZED_VA;
710 		return calloc(1, len);
711 
712 	case TEE_MALLOC_NO_FILL:
713 		TEE_Panic(0);
714 		break;
715 
716 	case TEE_MALLOC_NO_SHARE:
717 		if (!len)
718 			return TEE_NULL_SIZED_NO_SHARE_VA;
719 		if (!__ta_no_share_malloc_ctx)
720 			return NULL;
721 		return raw_calloc(0, 0, 1, len, __ta_no_share_malloc_ctx);
722 
723 	case TEE_MALLOC_NO_FILL | TEE_MALLOC_NO_SHARE:
724 		if (!len)
725 			return TEE_NULL_SIZED_NO_SHARE_VA;
726 		if (!__ta_no_share_malloc_ctx)
727 			return NULL;
728 		return raw_malloc(0, 0, len, __ta_no_share_malloc_ctx);
729 
730 	case TEE_USER_MEM_HINT_NO_FILL_ZERO:
731 		if (!len)
732 			return TEE_NULL_SIZED_VA;
733 		return malloc(len);
734 
735 	default:
736 		break;
737 	}
738 
739 	EMSG("Invalid hint %#" PRIx32, hint);
740 
741 	return NULL;
742 }
743 
744 void *__GP11_TEE_Malloc(uint32_t size, uint32_t hint)
745 {
746 	return TEE_Malloc(size, hint);
747 }
748 
749 static bool addr_is_in_no_share_heap(void *p)
750 {
751 	return buf_overlaps_no_share_heap(p, 1);
752 }
753 
754 void *TEE_Realloc(void *buffer, size_t newSize)
755 {
756 	if (!newSize) {
757 		void *ret = NULL;
758 
759 		if (addr_is_in_no_share_heap(buffer))
760 			ret = TEE_NULL_SIZED_NO_SHARE_VA;
761 		else
762 			ret = TEE_NULL_SIZED_VA;
763 
764 		TEE_Free(buffer);
765 
766 		return ret;
767 	}
768 
769 	if (buffer == TEE_NULL_SIZED_VA)
770 		return calloc(1, newSize);
771 	if (buffer == TEE_NULL_SIZED_NO_SHARE_VA) {
772 		if (!__ta_no_share_malloc_ctx)
773 			return NULL;
774 		return raw_calloc(0, 0, 1, newSize, __ta_no_share_malloc_ctx);
775 	}
776 
777 	if (addr_is_in_no_share_heap(buffer))
778 		return raw_realloc(buffer, 0, 0, newSize,
779 				   __ta_no_share_malloc_ctx);
780 	else
781 		return realloc(buffer, newSize);
782 }
783 
784 void *__GP11_TEE_Realloc(void *buffer, uint32_t newSize)
785 {
786 	return TEE_Realloc(buffer, newSize);
787 }
788 
789 void TEE_Free(void *buffer)
790 {
791 	if (buffer != TEE_NULL_SIZED_VA &&
792 	    buffer != TEE_NULL_SIZED_NO_SHARE_VA) {
793 		if (addr_is_in_no_share_heap(buffer))
794 			raw_free(buffer, __ta_no_share_malloc_ctx, false);
795 		else
796 			free(buffer);
797 	}
798 }
799 
800 /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */
801 TEE_Result TEE_CacheClean(char *buf, size_t len)
802 {
803 	return _utee_cache_operation(buf, len, TEE_CACHECLEAN);
804 }
805 TEE_Result TEE_CacheFlush(char *buf, size_t len)
806 {
807 	return _utee_cache_operation(buf, len, TEE_CACHEFLUSH);
808 }
809 
810 TEE_Result TEE_CacheInvalidate(char *buf, size_t len)
811 {
812 	return _utee_cache_operation(buf, len, TEE_CACHEINVALIDATE);
813 }
814