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