xref: /optee_os/lib/libutee/tee_api.c (revision 30e5e0be8c4e663f68ba88716dde9cad2ae33f06)
11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2b0104773SPascal Brand /*
3b0104773SPascal Brand  * Copyright (c) 2014, STMicroelectronics International N.V.
4b0104773SPascal Brand  */
5b0104773SPascal Brand #include <stdlib.h>
6b0104773SPascal Brand #include <string.h>
765551e69SJerome Forissier #include <string_ext.h>
8b0104773SPascal Brand #include <tee_api.h>
996c1d8c5SJens Wiklander #include <tee_internal_api_extensions.h>
10ef305e54SJens Wiklander #include <types_ext.h>
11b0104773SPascal Brand #include <user_ta_header.h>
1296c1d8c5SJens Wiklander #include <utee_syscalls.h>
13e86f1266SJens Wiklander #include "tee_api_private.h"
14b0104773SPascal Brand 
15a83ee50aSSadiq Hussain /*
16a83ee50aSSadiq Hussain  * return a known non-NULL invalid pointer when the
17a83ee50aSSadiq Hussain  * requested size is zero
18a83ee50aSSadiq Hussain  */
19a83ee50aSSadiq Hussain #define TEE_NULL_SIZED_VA	((void *)1)
20a83ee50aSSadiq Hussain 
218f07fe6fSJerome Forissier static const void *tee_api_instance_data;
22b0104773SPascal Brand 
23b0104773SPascal Brand /* System API - Internal Client API */
24b0104773SPascal Brand 
257509620bSJens Wiklander static void copy_param(struct utee_params *up, uint32_t param_types,
267509620bSJens Wiklander 		       const TEE_Param params[TEE_NUM_PARAMS])
277509620bSJens Wiklander {
287509620bSJens Wiklander 	size_t n = 0;
297509620bSJens Wiklander 	uint64_t a = 0;
307509620bSJens Wiklander 	uint64_t b = 0;
317509620bSJens Wiklander 
327509620bSJens Wiklander 	up->types = param_types;
337509620bSJens Wiklander 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
347509620bSJens Wiklander 		switch (TEE_PARAM_TYPE_GET(up->types, n)) {
357509620bSJens Wiklander 		case TEE_PARAM_TYPE_VALUE_INPUT:
367509620bSJens Wiklander 		case TEE_PARAM_TYPE_VALUE_INOUT:
377509620bSJens Wiklander 			a = params[n].value.a;
387509620bSJens Wiklander 			b = params[n].value.b;
397509620bSJens Wiklander 			break;
407509620bSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
417509620bSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
427509620bSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INPUT:
437509620bSJens Wiklander 			a = (vaddr_t)params[n].memref.buffer;
447509620bSJens Wiklander 			b = params[n].memref.size;
457509620bSJens Wiklander 			break;
467509620bSJens Wiklander 		default:
477509620bSJens Wiklander 			a = 0;
487509620bSJens Wiklander 			b = 0;
497509620bSJens Wiklander 		}
507509620bSJens Wiklander 		up->vals[n * 2] = a;
517509620bSJens Wiklander 		up->vals[n * 2 + 1] = b;
527509620bSJens Wiklander 	}
537509620bSJens Wiklander }
547509620bSJens Wiklander 
557509620bSJens Wiklander static void copy_gp11_param(struct utee_params *up, uint32_t param_types,
567509620bSJens Wiklander 			    const __GP11_TEE_Param params[TEE_NUM_PARAMS])
577509620bSJens Wiklander {
587509620bSJens Wiklander 	size_t n = 0;
597509620bSJens Wiklander 	uint64_t a = 0;
607509620bSJens Wiklander 	uint64_t b = 0;
617509620bSJens Wiklander 
627509620bSJens Wiklander 	up->types = param_types;
637509620bSJens Wiklander 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
647509620bSJens Wiklander 		switch (TEE_PARAM_TYPE_GET(up->types, n)) {
657509620bSJens Wiklander 		case TEE_PARAM_TYPE_VALUE_INPUT:
667509620bSJens Wiklander 		case TEE_PARAM_TYPE_VALUE_INOUT:
677509620bSJens Wiklander 			a = params[n].value.a;
687509620bSJens Wiklander 			b = params[n].value.b;
697509620bSJens Wiklander 			break;
707509620bSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
717509620bSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
727509620bSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INPUT:
737509620bSJens Wiklander 			a = (vaddr_t)params[n].memref.buffer;
747509620bSJens Wiklander 			b = params[n].memref.size;
757509620bSJens Wiklander 			break;
767509620bSJens Wiklander 		default:
777509620bSJens Wiklander 			a = 0;
787509620bSJens Wiklander 			b = 0;
797509620bSJens Wiklander 		}
807509620bSJens Wiklander 		up->vals[n * 2] = a;
817509620bSJens Wiklander 		up->vals[n * 2 + 1] = b;
827509620bSJens Wiklander 	}
837509620bSJens Wiklander }
847509620bSJens Wiklander 
857509620bSJens Wiklander static TEE_Result map_tmp_param(struct utee_params *up, void **tmp_buf,
867509620bSJens Wiklander 				size_t *tmp_len, void *tmp_va[TEE_NUM_PARAMS])
87e86f1266SJens Wiklander {
88ef305e54SJens Wiklander 	size_t n = 0;
89ef305e54SJens Wiklander 	uint8_t *tb = NULL;
90ef305e54SJens Wiklander 	size_t tbl = 0;
91ef305e54SJens Wiklander 	size_t tmp_align = sizeof(vaddr_t) * 2;
92ef305e54SJens Wiklander 	bool is_tmp_mem[TEE_NUM_PARAMS] = { false };
93ef305e54SJens Wiklander 	void *b = NULL;
94ef305e54SJens Wiklander 	size_t s = 0;
95ef305e54SJens Wiklander 	const uint32_t flags = TEE_MEMORY_ACCESS_READ;
96ef305e54SJens Wiklander 
97ef305e54SJens Wiklander 	/*
98ef305e54SJens Wiklander 	 * If a memory parameter points to TA private memory we need to
99ef305e54SJens Wiklander 	 * allocate a temporary buffer to avoid exposing the memory
100ef305e54SJens Wiklander 	 * directly to the called TA.
101ef305e54SJens Wiklander 	 */
102ef305e54SJens Wiklander 
103ef305e54SJens Wiklander 	*tmp_buf = NULL;
104ef305e54SJens Wiklander 	*tmp_len = 0;
105ef305e54SJens Wiklander 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
106ef305e54SJens Wiklander 		tmp_va[n] = NULL;
1077509620bSJens Wiklander 		switch (TEE_PARAM_TYPE_GET(up->types, n)) {
108ef305e54SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INPUT:
109ef305e54SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
110ef305e54SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
1117509620bSJens Wiklander 			b = (void *)(vaddr_t)up->vals[n * 2];
1127509620bSJens Wiklander 			s = up->vals[n * 2 + 1];
113ef305e54SJens Wiklander 			/*
114ef305e54SJens Wiklander 			 * We're only allocating temporary memory if the
115ef305e54SJens Wiklander 			 * buffer is completely within TA memory. If it's
116ef305e54SJens Wiklander 			 * NULL, empty, partially outside or completely
117ef305e54SJens Wiklander 			 * outside TA memory there's nothing more we need
118ef305e54SJens Wiklander 			 * to do here. If there's security/permissions
119ef305e54SJens Wiklander 			 * problem we'll get an error in the
120ef305e54SJens Wiklander 			 * invoke_command/open_session below.
121ef305e54SJens Wiklander 			 */
122ef305e54SJens Wiklander 			if (b && s &&
123ef305e54SJens Wiklander 			    !TEE_CheckMemoryAccessRights(flags, b, s)) {
124ef305e54SJens Wiklander 				is_tmp_mem[n] = true;
125ef305e54SJens Wiklander 				tbl += ROUNDUP(s, tmp_align);
126ef305e54SJens Wiklander 			}
127ef305e54SJens Wiklander 			break;
128ef305e54SJens Wiklander 		default:
129ef305e54SJens Wiklander 			break;
130ef305e54SJens Wiklander 		}
131ef305e54SJens Wiklander 	}
132ef305e54SJens Wiklander 
133ef305e54SJens Wiklander 	if (tbl) {
134ef305e54SJens Wiklander 		tb = tee_map_zi(tbl, TEE_MEMORY_ACCESS_ANY_OWNER);
135ef305e54SJens Wiklander 		if (!tb)
136ef305e54SJens Wiklander 			return TEE_ERROR_OUT_OF_MEMORY;
137ef305e54SJens Wiklander 		*tmp_buf = tb;
138ef305e54SJens Wiklander 		*tmp_len = tbl;
139ef305e54SJens Wiklander 	}
140e86f1266SJens Wiklander 
141e86f1266SJens Wiklander 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
1427509620bSJens Wiklander 		switch (TEE_PARAM_TYPE_GET(up->types, n)) {
143e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
144e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
145ef305e54SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INPUT:
1467509620bSJens Wiklander 			if (!is_tmp_mem[n])
1477509620bSJens Wiklander 				break;
1487509620bSJens Wiklander 			s = up->vals[n * 2 + 1];
1497509620bSJens Wiklander 			b = (void *)(vaddr_t)up->vals[n * 2];
150ef305e54SJens Wiklander 			tmp_va[n] = tb;
151ef305e54SJens Wiklander 			tb += ROUNDUP(s, tmp_align);
1527509620bSJens Wiklander 			up->vals[n * 2] = (vaddr_t)tmp_va[n];
1537509620bSJens Wiklander 			if (TEE_PARAM_TYPE_GET(up->types, n) !=
154ef305e54SJens Wiklander 			    TEE_PARAM_TYPE_MEMREF_OUTPUT)
1557509620bSJens Wiklander 				memcpy(tmp_va[n], b, s);
156e86f1266SJens Wiklander 			break;
157e86f1266SJens Wiklander 		default:
158e86f1266SJens Wiklander 			break;
159e86f1266SJens Wiklander 		}
160e86f1266SJens Wiklander 	}
161ef305e54SJens Wiklander 
162ef305e54SJens Wiklander 	return TEE_SUCCESS;
1637509620bSJens Wiklander 
164e86f1266SJens Wiklander }
165e86f1266SJens Wiklander 
166ef305e54SJens Wiklander static void update_out_param(TEE_Param params[TEE_NUM_PARAMS],
167ef305e54SJens Wiklander 			     void *tmp_va[TEE_NUM_PARAMS],
168ef305e54SJens Wiklander 			     const struct utee_params *up)
169e86f1266SJens Wiklander {
170e86f1266SJens Wiklander 	size_t n;
171e86f1266SJens Wiklander 	uint32_t types = up->types;
172e86f1266SJens Wiklander 
173e86f1266SJens Wiklander 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
174e86f1266SJens Wiklander 		uintptr_t a = up->vals[n * 2];
175e86f1266SJens Wiklander 		uintptr_t b = up->vals[n * 2 + 1];
176e86f1266SJens Wiklander 
177e86f1266SJens Wiklander 		switch (TEE_PARAM_TYPE_GET(types, n)) {
178e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_VALUE_OUTPUT:
179e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_VALUE_INOUT:
180e86f1266SJens Wiklander 			params[n].value.a = a;
181e86f1266SJens Wiklander 			params[n].value.b = b;
182e86f1266SJens Wiklander 			break;
183e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
184e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
185ef305e54SJens Wiklander 			if (tmp_va[n])
186ef305e54SJens Wiklander 				memcpy(params[n].memref.buffer, tmp_va[n],
187ef305e54SJens Wiklander 				       MIN(b, params[n].memref.size));
188e86f1266SJens Wiklander 			params[n].memref.size = b;
189e86f1266SJens Wiklander 			break;
190e86f1266SJens Wiklander 		default:
191e86f1266SJens Wiklander 			break;
192e86f1266SJens Wiklander 		}
193e86f1266SJens Wiklander 	}
194e86f1266SJens Wiklander }
195e86f1266SJens Wiklander 
1967509620bSJens Wiklander static void update_out_gp11_param(__GP11_TEE_Param params[TEE_NUM_PARAMS],
1977509620bSJens Wiklander 				  void *tmp_va[TEE_NUM_PARAMS],
1987509620bSJens Wiklander 				  const struct utee_params *up)
1997509620bSJens Wiklander {
2007509620bSJens Wiklander 	size_t n = 0;
2017509620bSJens Wiklander 	uint32_t types = up->types;
2027509620bSJens Wiklander 
2037509620bSJens Wiklander 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
2047509620bSJens Wiklander 		uintptr_t a = up->vals[n * 2];
2057509620bSJens Wiklander 		uintptr_t b = up->vals[n * 2 + 1];
2067509620bSJens Wiklander 
2077509620bSJens Wiklander 		switch (TEE_PARAM_TYPE_GET(types, n)) {
2087509620bSJens Wiklander 		case TEE_PARAM_TYPE_VALUE_OUTPUT:
2097509620bSJens Wiklander 		case TEE_PARAM_TYPE_VALUE_INOUT:
2107509620bSJens Wiklander 			params[n].value.a = a;
2117509620bSJens Wiklander 			params[n].value.b = b;
2127509620bSJens Wiklander 			break;
2137509620bSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
2147509620bSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
2157509620bSJens Wiklander 			if (tmp_va[n])
2167509620bSJens Wiklander 				memcpy(params[n].memref.buffer, tmp_va[n],
2177509620bSJens Wiklander 				       MIN(b, params[n].memref.size));
2187509620bSJens Wiklander 			params[n].memref.size = b;
2197509620bSJens Wiklander 			break;
2207509620bSJens Wiklander 		default:
2217509620bSJens Wiklander 			break;
2227509620bSJens Wiklander 		}
2237509620bSJens Wiklander 	}
2247509620bSJens Wiklander }
2257509620bSJens Wiklander 
226c8bf6a25SJens Wiklander static bool bufs_intersect(void *buf1, size_t sz1, void *buf2, size_t sz2)
227c8bf6a25SJens Wiklander {
228c8bf6a25SJens Wiklander 	vaddr_t b1 = (vaddr_t)buf1;
229c8bf6a25SJens Wiklander 	vaddr_t b2 = (vaddr_t)buf2;
230c8bf6a25SJens Wiklander 	vaddr_t e1 = b1 + sz1 - 1;
231c8bf6a25SJens Wiklander 	vaddr_t e2 = b2 + sz2 - 1;
232c8bf6a25SJens Wiklander 
233c8bf6a25SJens Wiklander 	if (!sz1 || !sz2)
234c8bf6a25SJens Wiklander 		return false;
235c8bf6a25SJens Wiklander 
236c8bf6a25SJens Wiklander 	if (e1 < b2 || e2 < b1)
237c8bf6a25SJens Wiklander 		return false;
238c8bf6a25SJens Wiklander 
239c8bf6a25SJens Wiklander 	return true;
240c8bf6a25SJens Wiklander }
241c8bf6a25SJens Wiklander 
242c8bf6a25SJens Wiklander static TEE_Result check_mem_access_rights_params(uint32_t flags, void *buf,
243c8bf6a25SJens Wiklander 						 size_t len)
244c8bf6a25SJens Wiklander {
245c8bf6a25SJens Wiklander 	size_t n = 0;
246c8bf6a25SJens Wiklander 
247c8bf6a25SJens Wiklander 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
248c8bf6a25SJens Wiklander 		uint32_t f = TEE_MEMORY_ACCESS_ANY_OWNER;
249c8bf6a25SJens Wiklander 
250c8bf6a25SJens Wiklander 		switch (TEE_PARAM_TYPE_GET(ta_param_types, n)) {
251c8bf6a25SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
252c8bf6a25SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
253c8bf6a25SJens Wiklander 			f |= TEE_MEMORY_ACCESS_WRITE;
254c8bf6a25SJens Wiklander 			fallthrough;
255c8bf6a25SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INPUT:
256c8bf6a25SJens Wiklander 			f |= TEE_MEMORY_ACCESS_READ;
257c8bf6a25SJens Wiklander 			if (bufs_intersect(buf, len,
258c8bf6a25SJens Wiklander 					   ta_params[n].memref.buffer,
259c8bf6a25SJens Wiklander 					   ta_params[n].memref.size)) {
260c8bf6a25SJens Wiklander 				if ((flags & f) != flags)
261c8bf6a25SJens Wiklander 					return TEE_ERROR_ACCESS_DENIED;
262c8bf6a25SJens Wiklander 			}
263c8bf6a25SJens Wiklander 			break;
264c8bf6a25SJens Wiklander 		default:
265c8bf6a25SJens Wiklander 			break;
266c8bf6a25SJens Wiklander 		}
267c8bf6a25SJens Wiklander 	}
268c8bf6a25SJens Wiklander 
269c8bf6a25SJens Wiklander 	return TEE_SUCCESS;
270c8bf6a25SJens Wiklander }
271c8bf6a25SJens Wiklander 
272*30e5e0beSJens Wiklander static void check_invoke_param(uint32_t pt, TEE_Param params[TEE_NUM_PARAMS])
273*30e5e0beSJens Wiklander {
274*30e5e0beSJens Wiklander 	size_t n = 0;
275*30e5e0beSJens Wiklander 
276*30e5e0beSJens Wiklander 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
277*30e5e0beSJens Wiklander 		uint32_t f = TEE_MEMORY_ACCESS_ANY_OWNER;
278*30e5e0beSJens Wiklander 		void *buf = params[n].memref.buffer;
279*30e5e0beSJens Wiklander 		size_t size = params[n].memref.size;
280*30e5e0beSJens Wiklander 
281*30e5e0beSJens Wiklander 		switch (TEE_PARAM_TYPE_GET(pt, n)) {
282*30e5e0beSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
283*30e5e0beSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
284*30e5e0beSJens Wiklander 			f |= TEE_MEMORY_ACCESS_WRITE;
285*30e5e0beSJens Wiklander 			fallthrough;
286*30e5e0beSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INPUT:
287*30e5e0beSJens Wiklander 			f |= TEE_MEMORY_ACCESS_READ;
288*30e5e0beSJens Wiklander 			if (check_mem_access_rights_params(f, buf, size))
289*30e5e0beSJens Wiklander 				TEE_Panic(0);
290*30e5e0beSJens Wiklander 			break;
291*30e5e0beSJens Wiklander 		default:
292*30e5e0beSJens Wiklander 			break;
293*30e5e0beSJens Wiklander 		}
294*30e5e0beSJens Wiklander 	}
295*30e5e0beSJens Wiklander }
296*30e5e0beSJens Wiklander 
297b0104773SPascal Brand TEE_Result TEE_OpenTASession(const TEE_UUID *destination,
298b0104773SPascal Brand 				uint32_t cancellationRequestTimeout,
29968540524SIgor Opaniuk 				uint32_t paramTypes,
30068540524SIgor Opaniuk 				TEE_Param params[TEE_NUM_PARAMS],
301b0104773SPascal Brand 				TEE_TASessionHandle *session,
302b0104773SPascal Brand 				uint32_t *returnOrigin)
303b0104773SPascal Brand {
304ef305e54SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
3057509620bSJens Wiklander 	struct utee_params up = { };
306ef305e54SJens Wiklander 	uint32_t s = 0;
307ef305e54SJens Wiklander 	void *tmp_buf = NULL;
308ef305e54SJens Wiklander 	size_t tmp_len = 0;
309ef305e54SJens Wiklander 	void *tmp_va[TEE_NUM_PARAMS] = { NULL };
310b0104773SPascal Brand 
311*30e5e0beSJens Wiklander 	if (paramTypes) {
3126915bbbbSJens Wiklander 		__utee_check_inout_annotation(params,
3136915bbbbSJens Wiklander 					      sizeof(TEE_Param) *
3146915bbbbSJens Wiklander 					      TEE_NUM_PARAMS);
315*30e5e0beSJens Wiklander 		check_invoke_param(paramTypes, params);
316*30e5e0beSJens Wiklander 	}
3176915bbbbSJens Wiklander 	__utee_check_out_annotation(session, sizeof(*session));
3186915bbbbSJens Wiklander 
3197509620bSJens Wiklander 	copy_param(&up, paramTypes, params);
3207509620bSJens Wiklander 	res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va);
321ef305e54SJens Wiklander 	if (res)
322ef305e54SJens Wiklander 		goto out;
3232c028fdeSJerome Forissier 	res = _utee_open_ta_session(destination, cancellationRequestTimeout,
324e86f1266SJens Wiklander 				    &up, &s, returnOrigin);
325ef305e54SJens Wiklander 	update_out_param(params, tmp_va, &up);
326ef305e54SJens Wiklander 	if (tmp_buf) {
327ef305e54SJens Wiklander 		TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
328ef305e54SJens Wiklander 
329ef305e54SJens Wiklander 		if (res2)
330ef305e54SJens Wiklander 			TEE_Panic(res2);
331ef305e54SJens Wiklander 	}
332ef305e54SJens Wiklander 
333ef305e54SJens Wiklander out:
334b0104773SPascal Brand 	/*
335b0104773SPascal Brand 	 * Specification says that *session must hold TEE_HANDLE_NULL is
336b0104773SPascal Brand 	 * TEE_SUCCESS isn't returned. Set it here explicitly in case
337b0104773SPascal Brand 	 * the syscall fails before out parameters has been updated.
338b0104773SPascal Brand 	 */
339b0104773SPascal Brand 	if (res != TEE_SUCCESS)
340e86f1266SJens Wiklander 		s = TEE_HANDLE_NULL;
341b0104773SPascal Brand 
342e86f1266SJens Wiklander 	*session = (TEE_TASessionHandle)(uintptr_t)s;
343b0104773SPascal Brand 	return res;
344b0104773SPascal Brand }
345b0104773SPascal Brand 
3467509620bSJens Wiklander TEE_Result __GP11_TEE_OpenTASession(const TEE_UUID *destination,
3477509620bSJens Wiklander 				    uint32_t cancellationRequestTimeout,
3487509620bSJens Wiklander 				    uint32_t paramTypes,
3497509620bSJens Wiklander 				    __GP11_TEE_Param params[TEE_NUM_PARAMS],
3507509620bSJens Wiklander 				    TEE_TASessionHandle *session,
3517509620bSJens Wiklander 				    uint32_t *returnOrigin)
3527509620bSJens Wiklander {
3537509620bSJens Wiklander 	TEE_Result res = TEE_SUCCESS;
3547509620bSJens Wiklander 	struct utee_params up = { };
3557509620bSJens Wiklander 	uint32_t s = 0;
3567509620bSJens Wiklander 	void *tmp_buf = NULL;
3577509620bSJens Wiklander 	size_t tmp_len = 0;
3587509620bSJens Wiklander 	void *tmp_va[TEE_NUM_PARAMS] = { NULL };
3597509620bSJens Wiklander 
3607509620bSJens Wiklander 	if (paramTypes)
3617509620bSJens Wiklander 		__utee_check_inout_annotation(params,
3627509620bSJens Wiklander 					      sizeof(__GP11_TEE_Param) *
3637509620bSJens Wiklander 					      TEE_NUM_PARAMS);
3647509620bSJens Wiklander 	__utee_check_out_annotation(session, sizeof(*session));
3657509620bSJens Wiklander 
3667509620bSJens Wiklander 	copy_gp11_param(&up, paramTypes, params);
3677509620bSJens Wiklander 	res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va);
3687509620bSJens Wiklander 	if (res)
3697509620bSJens Wiklander 		goto out;
3707509620bSJens Wiklander 	res = _utee_open_ta_session(destination, cancellationRequestTimeout,
3717509620bSJens Wiklander 				    &up, &s, returnOrigin);
3727509620bSJens Wiklander 	update_out_gp11_param(params, tmp_va, &up);
3737509620bSJens Wiklander 	if (tmp_buf) {
3747509620bSJens Wiklander 		TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
3757509620bSJens Wiklander 
3767509620bSJens Wiklander 		if (res2)
3777509620bSJens Wiklander 			TEE_Panic(res2);
3787509620bSJens Wiklander 	}
3797509620bSJens Wiklander 
3807509620bSJens Wiklander out:
3817509620bSJens Wiklander 	/*
3827509620bSJens Wiklander 	 * Specification says that *session must hold TEE_HANDLE_NULL if
3837509620bSJens Wiklander 	 * TEE_SUCCESS isn't returned. Set it here explicitly in case
3847509620bSJens Wiklander 	 * the syscall fails before out parameters has been updated.
3857509620bSJens Wiklander 	 */
3867509620bSJens Wiklander 	if (res != TEE_SUCCESS)
3877509620bSJens Wiklander 		s = TEE_HANDLE_NULL;
3887509620bSJens Wiklander 
3897509620bSJens Wiklander 	*session = (TEE_TASessionHandle)(uintptr_t)s;
3907509620bSJens Wiklander 	return res;
3917509620bSJens Wiklander }
3927509620bSJens Wiklander 
393b0104773SPascal Brand void TEE_CloseTASession(TEE_TASessionHandle session)
394b0104773SPascal Brand {
395b0104773SPascal Brand 	if (session != TEE_HANDLE_NULL) {
3962c028fdeSJerome Forissier 		TEE_Result res = _utee_close_ta_session((uintptr_t)session);
397e86f1266SJens Wiklander 
398b0104773SPascal Brand 		if (res != TEE_SUCCESS)
399b0104773SPascal Brand 			TEE_Panic(res);
400b0104773SPascal Brand 	}
401b0104773SPascal Brand }
402b0104773SPascal Brand 
403b0104773SPascal Brand TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session,
404b0104773SPascal Brand 				uint32_t cancellationRequestTimeout,
405b0104773SPascal Brand 				uint32_t commandID, uint32_t paramTypes,
40668540524SIgor Opaniuk 				TEE_Param params[TEE_NUM_PARAMS],
40768540524SIgor Opaniuk 				uint32_t *returnOrigin)
408b0104773SPascal Brand {
409ef305e54SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
410ef305e54SJens Wiklander 	uint32_t ret_origin = TEE_ORIGIN_TEE;
4117509620bSJens Wiklander 	struct utee_params up = { };
412ef305e54SJens Wiklander 	void *tmp_buf = NULL;
413ef305e54SJens Wiklander 	size_t tmp_len = 0;
414ef305e54SJens Wiklander 	void *tmp_va[TEE_NUM_PARAMS] = { NULL };
415c15e5835SCedric Chaumont 
416*30e5e0beSJens Wiklander 	if (paramTypes) {
4176915bbbbSJens Wiklander 		__utee_check_inout_annotation(params,
4186915bbbbSJens Wiklander 					      sizeof(TEE_Param) *
4196915bbbbSJens Wiklander 					      TEE_NUM_PARAMS);
420*30e5e0beSJens Wiklander 		check_invoke_param(paramTypes, params);
421*30e5e0beSJens Wiklander 	}
4226915bbbbSJens Wiklander 	if (returnOrigin)
4236915bbbbSJens Wiklander 		__utee_check_out_annotation(returnOrigin,
4246915bbbbSJens Wiklander 					    sizeof(*returnOrigin));
4256915bbbbSJens Wiklander 
4267509620bSJens Wiklander 	copy_param(&up, paramTypes, params);
4277509620bSJens Wiklander 	res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va);
428ef305e54SJens Wiklander 	if (res)
429ef305e54SJens Wiklander 		goto out;
4302c028fdeSJerome Forissier 	res = _utee_invoke_ta_command((uintptr_t)session,
431e86f1266SJens Wiklander 				      cancellationRequestTimeout,
432e86f1266SJens Wiklander 				      commandID, &up, &ret_origin);
433ef305e54SJens Wiklander 	update_out_param(params, tmp_va, &up);
434ef305e54SJens Wiklander 	if (tmp_buf) {
435ef305e54SJens Wiklander 		TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
4366709c3eaSCedric Chaumont 
437ef305e54SJens Wiklander 		if (res2)
438ef305e54SJens Wiklander 			TEE_Panic(res2);
439ef305e54SJens Wiklander 	}
440ef305e54SJens Wiklander 
441ef305e54SJens Wiklander out:
4426709c3eaSCedric Chaumont 	if (returnOrigin != NULL)
4436709c3eaSCedric Chaumont 		*returnOrigin = ret_origin;
4446709c3eaSCedric Chaumont 
4456709c3eaSCedric Chaumont 	if (ret_origin == TEE_ORIGIN_TRUSTED_APP)
4466709c3eaSCedric Chaumont 		return res;
4476709c3eaSCedric Chaumont 
448c15e5835SCedric Chaumont 	if (res != TEE_SUCCESS &&
449c15e5835SCedric Chaumont 	    res != TEE_ERROR_OUT_OF_MEMORY &&
450c15e5835SCedric Chaumont 	    res != TEE_ERROR_TARGET_DEAD)
451c15e5835SCedric Chaumont 		TEE_Panic(res);
452c15e5835SCedric Chaumont 
453c15e5835SCedric Chaumont 	return res;
454b0104773SPascal Brand }
455b0104773SPascal Brand 
4567509620bSJens Wiklander TEE_Result __GP11_TEE_InvokeTACommand(TEE_TASessionHandle session,
4577509620bSJens Wiklander 				      uint32_t cancellationRequestTimeout,
4587509620bSJens Wiklander 				      uint32_t commandID, uint32_t paramTypes,
4597509620bSJens Wiklander 				      __GP11_TEE_Param params[TEE_NUM_PARAMS],
4607509620bSJens Wiklander 				      uint32_t *returnOrigin)
4617509620bSJens Wiklander {
4627509620bSJens Wiklander 	TEE_Result res = TEE_SUCCESS;
4637509620bSJens Wiklander 	uint32_t ret_origin = TEE_ORIGIN_TEE;
4647509620bSJens Wiklander 	struct utee_params up = { };
4657509620bSJens Wiklander 	void *tmp_buf = NULL;
4667509620bSJens Wiklander 	size_t tmp_len = 0;
4677509620bSJens Wiklander 	void *tmp_va[TEE_NUM_PARAMS] = { NULL };
4687509620bSJens Wiklander 
4697509620bSJens Wiklander 	if (paramTypes)
4707509620bSJens Wiklander 		__utee_check_inout_annotation(params,
4717509620bSJens Wiklander 					      sizeof(__GP11_TEE_Param) *
4727509620bSJens Wiklander 					      TEE_NUM_PARAMS);
4737509620bSJens Wiklander 	if (returnOrigin)
4747509620bSJens Wiklander 		__utee_check_out_annotation(returnOrigin,
4757509620bSJens Wiklander 					    sizeof(*returnOrigin));
4767509620bSJens Wiklander 
4777509620bSJens Wiklander 	copy_gp11_param(&up, paramTypes, params);
4787509620bSJens Wiklander 	res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va);
4797509620bSJens Wiklander 	if (res)
4807509620bSJens Wiklander 		goto out;
4817509620bSJens Wiklander 	res = _utee_invoke_ta_command((uintptr_t)session,
4827509620bSJens Wiklander 				      cancellationRequestTimeout,
4837509620bSJens Wiklander 				      commandID, &up, &ret_origin);
4847509620bSJens Wiklander 	update_out_gp11_param(params, tmp_va, &up);
4857509620bSJens Wiklander 	if (tmp_buf) {
4867509620bSJens Wiklander 		TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
4877509620bSJens Wiklander 
4887509620bSJens Wiklander 		if (res2)
4897509620bSJens Wiklander 			TEE_Panic(res2);
4907509620bSJens Wiklander 	}
4917509620bSJens Wiklander 
4927509620bSJens Wiklander out:
4937509620bSJens Wiklander 	if (returnOrigin)
4947509620bSJens Wiklander 		*returnOrigin = ret_origin;
4957509620bSJens Wiklander 
4967509620bSJens Wiklander 	if (ret_origin == TEE_ORIGIN_TRUSTED_APP)
4977509620bSJens Wiklander 		return res;
4987509620bSJens Wiklander 
4997509620bSJens Wiklander 	if (res != TEE_SUCCESS &&
5007509620bSJens Wiklander 	    res != TEE_ERROR_OUT_OF_MEMORY &&
5017509620bSJens Wiklander 	    res != TEE_ERROR_TARGET_DEAD)
5027509620bSJens Wiklander 		TEE_Panic(res);
5037509620bSJens Wiklander 
5047509620bSJens Wiklander 	return res;
5057509620bSJens Wiklander }
5067509620bSJens Wiklander 
507b0104773SPascal Brand /* System API - Cancellations */
508b0104773SPascal Brand 
509b0104773SPascal Brand bool TEE_GetCancellationFlag(void)
510b0104773SPascal Brand {
511e86f1266SJens Wiklander 	uint32_t c;
5122c028fdeSJerome Forissier 	TEE_Result res = _utee_get_cancellation_flag(&c);
513e86f1266SJens Wiklander 
514b0104773SPascal Brand 	if (res != TEE_SUCCESS)
515e86f1266SJens Wiklander 		c = 0;
516e86f1266SJens Wiklander 	return !!c;
517b0104773SPascal Brand }
518b0104773SPascal Brand 
519b0104773SPascal Brand bool TEE_UnmaskCancellation(void)
520b0104773SPascal Brand {
521e86f1266SJens Wiklander 	uint32_t old_mask;
5222c028fdeSJerome Forissier 	TEE_Result res = _utee_unmask_cancellation(&old_mask);
523b0104773SPascal Brand 
524b0104773SPascal Brand 	if (res != TEE_SUCCESS)
525b0104773SPascal Brand 		TEE_Panic(res);
526e86f1266SJens Wiklander 	return !!old_mask;
527b0104773SPascal Brand }
528b0104773SPascal Brand 
529b0104773SPascal Brand bool TEE_MaskCancellation(void)
530b0104773SPascal Brand {
531e86f1266SJens Wiklander 	uint32_t old_mask;
5322c028fdeSJerome Forissier 	TEE_Result res = _utee_mask_cancellation(&old_mask);
533b0104773SPascal Brand 
534b0104773SPascal Brand 	if (res != TEE_SUCCESS)
535b0104773SPascal Brand 		TEE_Panic(res);
536e86f1266SJens Wiklander 	return !!old_mask;
537b0104773SPascal Brand }
538b0104773SPascal Brand 
539b0104773SPascal Brand /* System API - Memory Management */
540b0104773SPascal Brand 
541b0104773SPascal Brand TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void *buffer,
542cd3a8caeSJens Wiklander 				       size_t size)
543b0104773SPascal Brand {
544c8bf6a25SJens Wiklander 	uint32_t flags = accessFlags;
545b0104773SPascal Brand 
546c8bf6a25SJens Wiklander 	if (!size)
547b0104773SPascal Brand 		return TEE_SUCCESS;
548b0104773SPascal Brand 
549c8bf6a25SJens Wiklander 	/*
550c8bf6a25SJens Wiklander 	 * Check access rights against memory mapping. If this check is
551c8bf6a25SJens Wiklander 	 * OK the size can't cause an overflow when added with buffer.
552c8bf6a25SJens Wiklander 	 */
553c8bf6a25SJens Wiklander 	if (_utee_check_access_rights(accessFlags, buffer, size))
554c8bf6a25SJens Wiklander 		return TEE_ERROR_ACCESS_DENIED;
555b0104773SPascal Brand 
556b0104773SPascal Brand 	/*
557c8bf6a25SJens Wiklander 	 * Check access rights against input parameters.
558c8bf6a25SJens Wiklander 	 *
559c8bf6a25SJens Wiklander 	 * Clear eventual extension flags like TEE_MEMORY_ACCESS_NONSECURE
560c8bf6a25SJens Wiklander 	 * and TEE_MEMORY_ACCESS_SECURE.
561b0104773SPascal Brand 	 */
562c8bf6a25SJens Wiklander 	flags &= TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE |
563c8bf6a25SJens Wiklander 		 TEE_MEMORY_ACCESS_ANY_OWNER;
564c8bf6a25SJens Wiklander 	if (check_mem_access_rights_params(flags, buffer, size))
565c8bf6a25SJens Wiklander 		return TEE_ERROR_ACCESS_DENIED;
566b0104773SPascal Brand 
567c8bf6a25SJens Wiklander 	if (malloc_buffer_overlaps_heap(buffer, size) &&
568c8bf6a25SJens Wiklander 	    !malloc_buffer_is_within_alloced(buffer, size))
569c8bf6a25SJens Wiklander 		return TEE_ERROR_ACCESS_DENIED;
570c8bf6a25SJens Wiklander 
571c8bf6a25SJens Wiklander 	return TEE_SUCCESS;
572b0104773SPascal Brand }
573b0104773SPascal Brand 
574cd3a8caeSJens Wiklander TEE_Result __GP11_TEE_CheckMemoryAccessRights(uint32_t accessFlags,
575cd3a8caeSJens Wiklander 					      void *buffer, uint32_t size)
576cd3a8caeSJens Wiklander {
577cd3a8caeSJens Wiklander 	return TEE_CheckMemoryAccessRights(accessFlags, buffer, size);
578cd3a8caeSJens Wiklander }
579cd3a8caeSJens Wiklander 
5808f07fe6fSJerome Forissier void TEE_SetInstanceData(const void *instanceData)
581b0104773SPascal Brand {
582b0104773SPascal Brand 	tee_api_instance_data = instanceData;
583b0104773SPascal Brand }
584b0104773SPascal Brand 
5858f07fe6fSJerome Forissier const void *TEE_GetInstanceData(void)
586b0104773SPascal Brand {
587b0104773SPascal Brand 	return tee_api_instance_data;
588b0104773SPascal Brand }
589b0104773SPascal Brand 
5901d0ed95aSJens Wiklander void *TEE_MemMove(void *dest, const void *src, size_t size)
591b0104773SPascal Brand {
592b0104773SPascal Brand 	return memmove(dest, src, size);
593b0104773SPascal Brand }
594b0104773SPascal Brand 
5951d0ed95aSJens Wiklander void *__GP11_TEE_MemMove(void *dest, const void *src, uint32_t size)
5961d0ed95aSJens Wiklander {
5971d0ed95aSJens Wiklander 	return TEE_MemMove(dest, src, size);
5981d0ed95aSJens Wiklander }
5991d0ed95aSJens Wiklander 
6001d0ed95aSJens Wiklander int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, size_t size)
601b0104773SPascal Brand {
60265551e69SJerome Forissier 	return consttime_memcmp(buffer1, buffer2, size);
603b0104773SPascal Brand }
604b0104773SPascal Brand 
6051d0ed95aSJens Wiklander int32_t __GP11_TEE_MemCompare(const void *buffer1, const void *buffer2,
6061d0ed95aSJens Wiklander 			      uint32_t size)
6071d0ed95aSJens Wiklander {
6081d0ed95aSJens Wiklander 	return TEE_MemCompare(buffer1, buffer2, size);
6091d0ed95aSJens Wiklander }
6101d0ed95aSJens Wiklander 
6111d0ed95aSJens Wiklander void TEE_MemFill(void *buff, uint32_t x, size_t size)
612b0104773SPascal Brand {
61332c75600SJens Wiklander 	memset(buff, x, size);
614b0104773SPascal Brand }
615b0104773SPascal Brand 
6161d0ed95aSJens Wiklander void __GP11_TEE_MemFill(void *buff, uint32_t x, uint32_t size)
6171d0ed95aSJens Wiklander {
6181d0ed95aSJens Wiklander 	TEE_MemFill(buff, x, size);
6191d0ed95aSJens Wiklander }
6201d0ed95aSJens Wiklander 
621b0104773SPascal Brand /* Date & Time API */
622b0104773SPascal Brand 
623b0104773SPascal Brand void TEE_GetSystemTime(TEE_Time *time)
624b0104773SPascal Brand {
6252c028fdeSJerome Forissier 	TEE_Result res = _utee_get_time(UTEE_TIME_CAT_SYSTEM, time);
626b0104773SPascal Brand 
627b0104773SPascal Brand 	if (res != TEE_SUCCESS)
628b36311adSJerome Forissier 		TEE_Panic(res);
629b0104773SPascal Brand }
630b0104773SPascal Brand 
631b0104773SPascal Brand TEE_Result TEE_Wait(uint32_t timeout)
632b0104773SPascal Brand {
6332c028fdeSJerome Forissier 	TEE_Result res = _utee_wait(timeout);
634b0104773SPascal Brand 
635b0104773SPascal Brand 	if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL)
636b0104773SPascal Brand 		TEE_Panic(res);
637b0104773SPascal Brand 
638b0104773SPascal Brand 	return res;
639b0104773SPascal Brand }
640b0104773SPascal Brand 
641b0104773SPascal Brand TEE_Result TEE_GetTAPersistentTime(TEE_Time *time)
642b0104773SPascal Brand {
643b64d6909SCedric Chaumont 	TEE_Result res;
644b64d6909SCedric Chaumont 
6452c028fdeSJerome Forissier 	res = _utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time);
646b64d6909SCedric Chaumont 
647b64d6909SCedric Chaumont 	if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) {
648b64d6909SCedric Chaumont 		time->seconds = 0;
649b64d6909SCedric Chaumont 		time->millis = 0;
650b64d6909SCedric Chaumont 	}
651b64d6909SCedric Chaumont 
652b64d6909SCedric Chaumont 	if (res != TEE_SUCCESS &&
653b64d6909SCedric Chaumont 	    res != TEE_ERROR_TIME_NOT_SET &&
654b64d6909SCedric Chaumont 	    res != TEE_ERROR_TIME_NEEDS_RESET &&
655b64d6909SCedric Chaumont 	    res != TEE_ERROR_OVERFLOW &&
656b64d6909SCedric Chaumont 	    res != TEE_ERROR_OUT_OF_MEMORY)
657b64d6909SCedric Chaumont 		TEE_Panic(res);
658b64d6909SCedric Chaumont 
659b64d6909SCedric Chaumont 	return res;
660b0104773SPascal Brand }
661b0104773SPascal Brand 
662b0104773SPascal Brand TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time)
663b0104773SPascal Brand {
664b64d6909SCedric Chaumont 	TEE_Result res;
665b64d6909SCedric Chaumont 
6662c028fdeSJerome Forissier 	res = _utee_set_ta_time(time);
667b64d6909SCedric Chaumont 
668b64d6909SCedric Chaumont 	if (res != TEE_SUCCESS &&
669b64d6909SCedric Chaumont 	    res != TEE_ERROR_OUT_OF_MEMORY &&
670b64d6909SCedric Chaumont 	    res != TEE_ERROR_STORAGE_NO_SPACE)
671b64d6909SCedric Chaumont 		TEE_Panic(res);
672b64d6909SCedric Chaumont 
673b64d6909SCedric Chaumont 	return res;
674b0104773SPascal Brand }
675b0104773SPascal Brand 
676b0104773SPascal Brand void TEE_GetREETime(TEE_Time *time)
677b0104773SPascal Brand {
6782c028fdeSJerome Forissier 	TEE_Result res = _utee_get_time(UTEE_TIME_CAT_REE, time);
679b0104773SPascal Brand 
680b0104773SPascal Brand 	if (res != TEE_SUCCESS)
681b36311adSJerome Forissier 		TEE_Panic(res);
682b0104773SPascal Brand }
683b0104773SPascal Brand 
68411285ebcSJens Wiklander void *TEE_Malloc(size_t len, uint32_t hint)
685b0104773SPascal Brand {
68611285ebcSJens Wiklander 	switch (hint) {
68711285ebcSJens Wiklander 	case TEE_MALLOC_FILL_ZERO:
688a83ee50aSSadiq Hussain 		if (!len)
689a83ee50aSSadiq Hussain 			return TEE_NULL_SIZED_VA;
69096c1d8c5SJens Wiklander 		return calloc(1, len);
69111285ebcSJens Wiklander 
69211285ebcSJens Wiklander 	case TEE_MALLOC_NO_FILL:
69311285ebcSJens Wiklander 		TEE_Panic(0);
69411285ebcSJens Wiklander 		break;
69511285ebcSJens Wiklander 
69611285ebcSJens Wiklander 	case TEE_MALLOC_NO_FILL | TEE_MALLOC_NO_SHARE:
69711285ebcSJens Wiklander 		return NULL; /* TEE_MALLOC_NO_SHARE is not yet supported */
69811285ebcSJens Wiklander 
69911285ebcSJens Wiklander 	case TEE_USER_MEM_HINT_NO_FILL_ZERO:
70011285ebcSJens Wiklander 		if (!len)
70111285ebcSJens Wiklander 			return TEE_NULL_SIZED_VA;
70296c1d8c5SJens Wiklander 		return malloc(len);
70396c1d8c5SJens Wiklander 
70411285ebcSJens Wiklander 	default:
70511285ebcSJens Wiklander 		break;
70611285ebcSJens Wiklander 	}
70711285ebcSJens Wiklander 
70896c1d8c5SJens Wiklander 	EMSG("Invalid hint %#" PRIx32, hint);
70996c1d8c5SJens Wiklander 
71096c1d8c5SJens Wiklander 	return NULL;
711b0104773SPascal Brand }
712b0104773SPascal Brand 
71311285ebcSJens Wiklander void *__GP11_TEE_Malloc(uint32_t size, uint32_t hint)
71411285ebcSJens Wiklander {
71511285ebcSJens Wiklander 	return TEE_Malloc(size, hint);
71611285ebcSJens Wiklander }
71711285ebcSJens Wiklander 
71811285ebcSJens Wiklander void *TEE_Realloc(void *buffer, size_t newSize)
719b0104773SPascal Brand {
720a83ee50aSSadiq Hussain 	if (!newSize) {
721a83ee50aSSadiq Hussain 		TEE_Free(buffer);
722a83ee50aSSadiq Hussain 		return TEE_NULL_SIZED_VA;
723a83ee50aSSadiq Hussain 	}
724a83ee50aSSadiq Hussain 
725a83ee50aSSadiq Hussain 	if (buffer == TEE_NULL_SIZED_VA)
726a83ee50aSSadiq Hussain 		return calloc(1, newSize);
727a83ee50aSSadiq Hussain 
72896c1d8c5SJens Wiklander 	return realloc(buffer, newSize);
729b0104773SPascal Brand }
730b0104773SPascal Brand 
73111285ebcSJens Wiklander void *__GP11_TEE_Realloc(void *buffer, uint32_t newSize)
73211285ebcSJens Wiklander {
73311285ebcSJens Wiklander 	return TEE_Realloc(buffer, newSize);
73411285ebcSJens Wiklander }
73511285ebcSJens Wiklander 
736b0104773SPascal Brand void TEE_Free(void *buffer)
737b0104773SPascal Brand {
738a83ee50aSSadiq Hussain 	if (buffer != TEE_NULL_SIZED_VA)
73996c1d8c5SJens Wiklander 		free(buffer);
740b0104773SPascal Brand }
741fa530828SPascal Brand 
742fa530828SPascal Brand /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */
743fa530828SPascal Brand TEE_Result TEE_CacheClean(char *buf, size_t len)
744fa530828SPascal Brand {
7452c028fdeSJerome Forissier 	return _utee_cache_operation(buf, len, TEE_CACHECLEAN);
746fa530828SPascal Brand }
747fa530828SPascal Brand TEE_Result TEE_CacheFlush(char *buf, size_t len)
748fa530828SPascal Brand {
7492c028fdeSJerome Forissier 	return _utee_cache_operation(buf, len, TEE_CACHEFLUSH);
750fa530828SPascal Brand }
751fa530828SPascal Brand 
752fa530828SPascal Brand TEE_Result TEE_CacheInvalidate(char *buf, size_t len)
753fa530828SPascal Brand {
7542c028fdeSJerome Forissier 	return _utee_cache_operation(buf, len, TEE_CACHEINVALIDATE);
755fa530828SPascal Brand }
756