xref: /optee_os/lib/libutee/tee_api.c (revision 32c756004c1965ae3628d33f7e29999ccf1ac97c)
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 
25ef305e54SJens Wiklander static TEE_Result copy_param(struct utee_params *up, uint32_t param_types,
26ef305e54SJens Wiklander 			     const TEE_Param params[TEE_NUM_PARAMS],
27ef305e54SJens Wiklander 			     void **tmp_buf, size_t *tmp_len,
28ef305e54SJens Wiklander 			     void *tmp_va[TEE_NUM_PARAMS])
29e86f1266SJens Wiklander {
30ef305e54SJens Wiklander 	size_t n = 0;
31ef305e54SJens Wiklander 	uint8_t *tb = NULL;
32ef305e54SJens Wiklander 	size_t tbl = 0;
33ef305e54SJens Wiklander 	size_t tmp_align = sizeof(vaddr_t) * 2;
34ef305e54SJens Wiklander 	bool is_tmp_mem[TEE_NUM_PARAMS] = { false };
35ef305e54SJens Wiklander 	void *b = NULL;
36ef305e54SJens Wiklander 	size_t s = 0;
37ef305e54SJens Wiklander 	const uint32_t flags = TEE_MEMORY_ACCESS_READ;
38ef305e54SJens Wiklander 
39ef305e54SJens Wiklander 	/*
40ef305e54SJens Wiklander 	 * If a memory parameter points to TA private memory we need to
41ef305e54SJens Wiklander 	 * allocate a temporary buffer to avoid exposing the memory
42ef305e54SJens Wiklander 	 * directly to the called TA.
43ef305e54SJens Wiklander 	 */
44ef305e54SJens Wiklander 
45ef305e54SJens Wiklander 	*tmp_buf = NULL;
46ef305e54SJens Wiklander 	*tmp_len = 0;
47ef305e54SJens Wiklander 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
48ef305e54SJens Wiklander 		tmp_va[n] = NULL;
49ef305e54SJens Wiklander 		switch (TEE_PARAM_TYPE_GET(param_types, n)) {
50ef305e54SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INPUT:
51ef305e54SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
52ef305e54SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
53ef305e54SJens Wiklander 			b = params[n].memref.buffer;
54ef305e54SJens Wiklander 			s = params[n].memref.size;
55ef305e54SJens Wiklander 			/*
56ef305e54SJens Wiklander 			 * We're only allocating temporary memory if the
57ef305e54SJens Wiklander 			 * buffer is completely within TA memory. If it's
58ef305e54SJens Wiklander 			 * NULL, empty, partially outside or completely
59ef305e54SJens Wiklander 			 * outside TA memory there's nothing more we need
60ef305e54SJens Wiklander 			 * to do here. If there's security/permissions
61ef305e54SJens Wiklander 			 * problem we'll get an error in the
62ef305e54SJens Wiklander 			 * invoke_command/open_session below.
63ef305e54SJens Wiklander 			 */
64ef305e54SJens Wiklander 			if (b && s &&
65ef305e54SJens Wiklander 			    !TEE_CheckMemoryAccessRights(flags, b, s)) {
66ef305e54SJens Wiklander 				is_tmp_mem[n] = true;
67ef305e54SJens Wiklander 				tbl += ROUNDUP(s, tmp_align);
68ef305e54SJens Wiklander 			}
69ef305e54SJens Wiklander 			break;
70ef305e54SJens Wiklander 		default:
71ef305e54SJens Wiklander 			break;
72ef305e54SJens Wiklander 		}
73ef305e54SJens Wiklander 	}
74ef305e54SJens Wiklander 
75ef305e54SJens Wiklander 	if (tbl) {
76ef305e54SJens Wiklander 		tb = tee_map_zi(tbl, TEE_MEMORY_ACCESS_ANY_OWNER);
77ef305e54SJens Wiklander 		if (!tb)
78ef305e54SJens Wiklander 			return TEE_ERROR_OUT_OF_MEMORY;
79ef305e54SJens Wiklander 		*tmp_buf = tb;
80ef305e54SJens Wiklander 		*tmp_len = tbl;
81ef305e54SJens Wiklander 	}
82e86f1266SJens Wiklander 
83e86f1266SJens Wiklander 	up->types = param_types;
84e86f1266SJens Wiklander 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
85e86f1266SJens Wiklander 		switch (TEE_PARAM_TYPE_GET(param_types, n)) {
86e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_VALUE_INPUT:
87e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_VALUE_INOUT:
88e86f1266SJens Wiklander 			up->vals[n * 2] = params[n].value.a;
89e86f1266SJens Wiklander 			up->vals[n * 2 + 1] = params[n].value.b;
90e86f1266SJens Wiklander 			break;
91e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
92e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
93ef305e54SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INPUT:
94ef305e54SJens Wiklander 			s = params[n].memref.size;
95ef305e54SJens Wiklander 			if (is_tmp_mem[n]) {
96ef305e54SJens Wiklander 				b = tb;
97ef305e54SJens Wiklander 				tmp_va[n] = tb;
98ef305e54SJens Wiklander 				tb += ROUNDUP(s, tmp_align);
99ef305e54SJens Wiklander 				if (TEE_PARAM_TYPE_GET(param_types, n) !=
100ef305e54SJens Wiklander 				    TEE_PARAM_TYPE_MEMREF_OUTPUT)
101ef305e54SJens Wiklander 					memcpy(b, params[n].memref.buffer, s);
102ef305e54SJens Wiklander 			} else {
103ef305e54SJens Wiklander 				b = params[n].memref.buffer;
104ef305e54SJens Wiklander 			}
105ef305e54SJens Wiklander 			up->vals[n * 2] = (vaddr_t)b;
106ef305e54SJens Wiklander 			up->vals[n * 2 + 1] = s;
107e86f1266SJens Wiklander 			break;
108e86f1266SJens Wiklander 		default:
109e86f1266SJens Wiklander 			up->vals[n * 2] = 0;
110e86f1266SJens Wiklander 			up->vals[n * 2 + 1] = 0;
111e86f1266SJens Wiklander 			break;
112e86f1266SJens Wiklander 		}
113e86f1266SJens Wiklander 	}
114ef305e54SJens Wiklander 
115ef305e54SJens Wiklander 	return TEE_SUCCESS;
116e86f1266SJens Wiklander }
117e86f1266SJens Wiklander 
118ef305e54SJens Wiklander static void update_out_param(TEE_Param params[TEE_NUM_PARAMS],
119ef305e54SJens Wiklander 			     void *tmp_va[TEE_NUM_PARAMS],
120ef305e54SJens Wiklander 			     const struct utee_params *up)
121e86f1266SJens Wiklander {
122e86f1266SJens Wiklander 	size_t n;
123e86f1266SJens Wiklander 	uint32_t types = up->types;
124e86f1266SJens Wiklander 
125e86f1266SJens Wiklander 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
126e86f1266SJens Wiklander 		uintptr_t a = up->vals[n * 2];
127e86f1266SJens Wiklander 		uintptr_t b = up->vals[n * 2 + 1];
128e86f1266SJens Wiklander 
129e86f1266SJens Wiklander 		switch (TEE_PARAM_TYPE_GET(types, n)) {
130e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_VALUE_OUTPUT:
131e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_VALUE_INOUT:
132e86f1266SJens Wiklander 			params[n].value.a = a;
133e86f1266SJens Wiklander 			params[n].value.b = b;
134e86f1266SJens Wiklander 			break;
135e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
136e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
137ef305e54SJens Wiklander 			if (tmp_va[n])
138ef305e54SJens Wiklander 				memcpy(params[n].memref.buffer, tmp_va[n],
139ef305e54SJens Wiklander 				       MIN(b, params[n].memref.size));
140e86f1266SJens Wiklander 			params[n].memref.size = b;
141e86f1266SJens Wiklander 			break;
142e86f1266SJens Wiklander 		default:
143e86f1266SJens Wiklander 			break;
144e86f1266SJens Wiklander 		}
145e86f1266SJens Wiklander 	}
146e86f1266SJens Wiklander }
147e86f1266SJens Wiklander 
148b0104773SPascal Brand TEE_Result TEE_OpenTASession(const TEE_UUID *destination,
149b0104773SPascal Brand 				uint32_t cancellationRequestTimeout,
15068540524SIgor Opaniuk 				uint32_t paramTypes,
15168540524SIgor Opaniuk 				TEE_Param params[TEE_NUM_PARAMS],
152b0104773SPascal Brand 				TEE_TASessionHandle *session,
153b0104773SPascal Brand 				uint32_t *returnOrigin)
154b0104773SPascal Brand {
155ef305e54SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
156e86f1266SJens Wiklander 	struct utee_params up;
157ef305e54SJens Wiklander 	uint32_t s = 0;
158ef305e54SJens Wiklander 	void *tmp_buf = NULL;
159ef305e54SJens Wiklander 	size_t tmp_len = 0;
160ef305e54SJens Wiklander 	void *tmp_va[TEE_NUM_PARAMS] = { NULL };
161b0104773SPascal Brand 
1626915bbbbSJens Wiklander 	if (paramTypes)
1636915bbbbSJens Wiklander 		__utee_check_inout_annotation(params,
1646915bbbbSJens Wiklander 					      sizeof(TEE_Param) *
1656915bbbbSJens Wiklander 					      TEE_NUM_PARAMS);
1666915bbbbSJens Wiklander 	__utee_check_out_annotation(session, sizeof(*session));
1676915bbbbSJens Wiklander 
168ef305e54SJens Wiklander 	res = copy_param(&up, paramTypes, params, &tmp_buf, &tmp_len, tmp_va);
169ef305e54SJens Wiklander 	if (res)
170ef305e54SJens Wiklander 		goto out;
1712c028fdeSJerome Forissier 	res = _utee_open_ta_session(destination, cancellationRequestTimeout,
172e86f1266SJens Wiklander 				    &up, &s, returnOrigin);
173ef305e54SJens Wiklander 	update_out_param(params, tmp_va, &up);
174ef305e54SJens Wiklander 	if (tmp_buf) {
175ef305e54SJens Wiklander 		TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
176ef305e54SJens Wiklander 
177ef305e54SJens Wiklander 		if (res2)
178ef305e54SJens Wiklander 			TEE_Panic(res2);
179ef305e54SJens Wiklander 	}
180ef305e54SJens Wiklander 
181ef305e54SJens Wiklander out:
182b0104773SPascal Brand 	/*
183b0104773SPascal Brand 	 * Specification says that *session must hold TEE_HANDLE_NULL is
184b0104773SPascal Brand 	 * TEE_SUCCESS isn't returned. Set it here explicitly in case
185b0104773SPascal Brand 	 * the syscall fails before out parameters has been updated.
186b0104773SPascal Brand 	 */
187b0104773SPascal Brand 	if (res != TEE_SUCCESS)
188e86f1266SJens Wiklander 		s = TEE_HANDLE_NULL;
189b0104773SPascal Brand 
190e86f1266SJens Wiklander 	*session = (TEE_TASessionHandle)(uintptr_t)s;
191b0104773SPascal Brand 	return res;
192b0104773SPascal Brand }
193b0104773SPascal Brand 
194b0104773SPascal Brand void TEE_CloseTASession(TEE_TASessionHandle session)
195b0104773SPascal Brand {
196b0104773SPascal Brand 	if (session != TEE_HANDLE_NULL) {
1972c028fdeSJerome Forissier 		TEE_Result res = _utee_close_ta_session((uintptr_t)session);
198e86f1266SJens Wiklander 
199b0104773SPascal Brand 		if (res != TEE_SUCCESS)
200b0104773SPascal Brand 			TEE_Panic(res);
201b0104773SPascal Brand 	}
202b0104773SPascal Brand }
203b0104773SPascal Brand 
204b0104773SPascal Brand TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session,
205b0104773SPascal Brand 				uint32_t cancellationRequestTimeout,
206b0104773SPascal Brand 				uint32_t commandID, uint32_t paramTypes,
20768540524SIgor Opaniuk 				TEE_Param params[TEE_NUM_PARAMS],
20868540524SIgor Opaniuk 				uint32_t *returnOrigin)
209b0104773SPascal Brand {
210ef305e54SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
211ef305e54SJens Wiklander 	uint32_t ret_origin = TEE_ORIGIN_TEE;
212e86f1266SJens Wiklander 	struct utee_params up;
213ef305e54SJens Wiklander 	void *tmp_buf = NULL;
214ef305e54SJens Wiklander 	size_t tmp_len = 0;
215ef305e54SJens Wiklander 	void *tmp_va[TEE_NUM_PARAMS] = { NULL };
216c15e5835SCedric Chaumont 
2176915bbbbSJens Wiklander 	if (paramTypes)
2186915bbbbSJens Wiklander 		__utee_check_inout_annotation(params,
2196915bbbbSJens Wiklander 					      sizeof(TEE_Param) *
2206915bbbbSJens Wiklander 					      TEE_NUM_PARAMS);
2216915bbbbSJens Wiklander 	if (returnOrigin)
2226915bbbbSJens Wiklander 		__utee_check_out_annotation(returnOrigin,
2236915bbbbSJens Wiklander 					    sizeof(*returnOrigin));
2246915bbbbSJens Wiklander 
225ef305e54SJens Wiklander 	res = copy_param(&up, paramTypes, params, &tmp_buf, &tmp_len, tmp_va);
226ef305e54SJens Wiklander 	if (res)
227ef305e54SJens Wiklander 		goto out;
2282c028fdeSJerome Forissier 	res = _utee_invoke_ta_command((uintptr_t)session,
229e86f1266SJens Wiklander 				      cancellationRequestTimeout,
230e86f1266SJens Wiklander 				      commandID, &up, &ret_origin);
231ef305e54SJens Wiklander 	update_out_param(params, tmp_va, &up);
232ef305e54SJens Wiklander 	if (tmp_buf) {
233ef305e54SJens Wiklander 		TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
2346709c3eaSCedric Chaumont 
235ef305e54SJens Wiklander 		if (res2)
236ef305e54SJens Wiklander 			TEE_Panic(res2);
237ef305e54SJens Wiklander 	}
238ef305e54SJens Wiklander 
239ef305e54SJens Wiklander out:
2406709c3eaSCedric Chaumont 	if (returnOrigin != NULL)
2416709c3eaSCedric Chaumont 		*returnOrigin = ret_origin;
2426709c3eaSCedric Chaumont 
2436709c3eaSCedric Chaumont 	if (ret_origin == TEE_ORIGIN_TRUSTED_APP)
2446709c3eaSCedric Chaumont 		return res;
2456709c3eaSCedric Chaumont 
246c15e5835SCedric Chaumont 	if (res != TEE_SUCCESS &&
247c15e5835SCedric Chaumont 	    res != TEE_ERROR_OUT_OF_MEMORY &&
248c15e5835SCedric Chaumont 	    res != TEE_ERROR_TARGET_DEAD)
249c15e5835SCedric Chaumont 		TEE_Panic(res);
250c15e5835SCedric Chaumont 
251c15e5835SCedric Chaumont 	return res;
252b0104773SPascal Brand }
253b0104773SPascal Brand 
254b0104773SPascal Brand /* System API - Cancellations */
255b0104773SPascal Brand 
256b0104773SPascal Brand bool TEE_GetCancellationFlag(void)
257b0104773SPascal Brand {
258e86f1266SJens Wiklander 	uint32_t c;
2592c028fdeSJerome Forissier 	TEE_Result res = _utee_get_cancellation_flag(&c);
260e86f1266SJens Wiklander 
261b0104773SPascal Brand 	if (res != TEE_SUCCESS)
262e86f1266SJens Wiklander 		c = 0;
263e86f1266SJens Wiklander 	return !!c;
264b0104773SPascal Brand }
265b0104773SPascal Brand 
266b0104773SPascal Brand bool TEE_UnmaskCancellation(void)
267b0104773SPascal Brand {
268e86f1266SJens Wiklander 	uint32_t old_mask;
2692c028fdeSJerome Forissier 	TEE_Result res = _utee_unmask_cancellation(&old_mask);
270b0104773SPascal Brand 
271b0104773SPascal Brand 	if (res != TEE_SUCCESS)
272b0104773SPascal Brand 		TEE_Panic(res);
273e86f1266SJens Wiklander 	return !!old_mask;
274b0104773SPascal Brand }
275b0104773SPascal Brand 
276b0104773SPascal Brand bool TEE_MaskCancellation(void)
277b0104773SPascal Brand {
278e86f1266SJens Wiklander 	uint32_t old_mask;
2792c028fdeSJerome Forissier 	TEE_Result res = _utee_mask_cancellation(&old_mask);
280b0104773SPascal Brand 
281b0104773SPascal Brand 	if (res != TEE_SUCCESS)
282b0104773SPascal Brand 		TEE_Panic(res);
283e86f1266SJens Wiklander 	return !!old_mask;
284b0104773SPascal Brand }
285b0104773SPascal Brand 
286b0104773SPascal Brand /* System API - Memory Management */
287b0104773SPascal Brand 
288b0104773SPascal Brand TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void *buffer,
28979a3c601SCedric Chaumont 				       uint32_t size)
290b0104773SPascal Brand {
291b0104773SPascal Brand 	TEE_Result res;
292b0104773SPascal Brand 
293b0104773SPascal Brand 	if (size == 0)
294b0104773SPascal Brand 		return TEE_SUCCESS;
295b0104773SPascal Brand 
296b0104773SPascal Brand 	/* Check access rights against memory mapping */
2972c028fdeSJerome Forissier 	res = _utee_check_access_rights(accessFlags, buffer, size);
298b0104773SPascal Brand 	if (res != TEE_SUCCESS)
299b0104773SPascal Brand 		goto out;
300b0104773SPascal Brand 
301b0104773SPascal Brand 	/*
302b0104773SPascal Brand 	* Check access rights against input parameters
303b0104773SPascal Brand 	* Previous legacy code was removed and will need to be restored
304b0104773SPascal Brand 	*/
305b0104773SPascal Brand 
306b0104773SPascal Brand 	res = TEE_SUCCESS;
307b0104773SPascal Brand out:
308b0104773SPascal Brand 	return res;
309b0104773SPascal Brand }
310b0104773SPascal Brand 
3118f07fe6fSJerome Forissier void TEE_SetInstanceData(const void *instanceData)
312b0104773SPascal Brand {
313b0104773SPascal Brand 	tee_api_instance_data = instanceData;
314b0104773SPascal Brand }
315b0104773SPascal Brand 
3168f07fe6fSJerome Forissier const void *TEE_GetInstanceData(void)
317b0104773SPascal Brand {
318b0104773SPascal Brand 	return tee_api_instance_data;
319b0104773SPascal Brand }
320b0104773SPascal Brand 
321b0104773SPascal Brand void *TEE_MemMove(void *dest, const void *src, uint32_t size)
322b0104773SPascal Brand {
323b0104773SPascal Brand 	return memmove(dest, src, size);
324b0104773SPascal Brand }
325b0104773SPascal Brand 
326b0104773SPascal Brand int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, uint32_t size)
327b0104773SPascal Brand {
32865551e69SJerome Forissier 	return consttime_memcmp(buffer1, buffer2, size);
329b0104773SPascal Brand }
330b0104773SPascal Brand 
331*32c75600SJens Wiklander void TEE_MemFill(void *buff, uint32_t x, uint32_t size)
332b0104773SPascal Brand {
333*32c75600SJens Wiklander 	memset(buff, x, size);
334b0104773SPascal Brand }
335b0104773SPascal Brand 
336b0104773SPascal Brand /* Date & Time API */
337b0104773SPascal Brand 
338b0104773SPascal Brand void TEE_GetSystemTime(TEE_Time *time)
339b0104773SPascal Brand {
3402c028fdeSJerome Forissier 	TEE_Result res = _utee_get_time(UTEE_TIME_CAT_SYSTEM, time);
341b0104773SPascal Brand 
342b0104773SPascal Brand 	if (res != TEE_SUCCESS)
343b36311adSJerome Forissier 		TEE_Panic(res);
344b0104773SPascal Brand }
345b0104773SPascal Brand 
346b0104773SPascal Brand TEE_Result TEE_Wait(uint32_t timeout)
347b0104773SPascal Brand {
3482c028fdeSJerome Forissier 	TEE_Result res = _utee_wait(timeout);
349b0104773SPascal Brand 
350b0104773SPascal Brand 	if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL)
351b0104773SPascal Brand 		TEE_Panic(res);
352b0104773SPascal Brand 
353b0104773SPascal Brand 	return res;
354b0104773SPascal Brand }
355b0104773SPascal Brand 
356b0104773SPascal Brand TEE_Result TEE_GetTAPersistentTime(TEE_Time *time)
357b0104773SPascal Brand {
358b64d6909SCedric Chaumont 	TEE_Result res;
359b64d6909SCedric Chaumont 
3602c028fdeSJerome Forissier 	res = _utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time);
361b64d6909SCedric Chaumont 
362b64d6909SCedric Chaumont 	if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) {
363b64d6909SCedric Chaumont 		time->seconds = 0;
364b64d6909SCedric Chaumont 		time->millis = 0;
365b64d6909SCedric Chaumont 	}
366b64d6909SCedric Chaumont 
367b64d6909SCedric Chaumont 	if (res != TEE_SUCCESS &&
368b64d6909SCedric Chaumont 	    res != TEE_ERROR_TIME_NOT_SET &&
369b64d6909SCedric Chaumont 	    res != TEE_ERROR_TIME_NEEDS_RESET &&
370b64d6909SCedric Chaumont 	    res != TEE_ERROR_OVERFLOW &&
371b64d6909SCedric Chaumont 	    res != TEE_ERROR_OUT_OF_MEMORY)
372b64d6909SCedric Chaumont 		TEE_Panic(res);
373b64d6909SCedric Chaumont 
374b64d6909SCedric Chaumont 	return res;
375b0104773SPascal Brand }
376b0104773SPascal Brand 
377b0104773SPascal Brand TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time)
378b0104773SPascal Brand {
379b64d6909SCedric Chaumont 	TEE_Result res;
380b64d6909SCedric Chaumont 
3812c028fdeSJerome Forissier 	res = _utee_set_ta_time(time);
382b64d6909SCedric Chaumont 
383b64d6909SCedric Chaumont 	if (res != TEE_SUCCESS &&
384b64d6909SCedric Chaumont 	    res != TEE_ERROR_OUT_OF_MEMORY &&
385b64d6909SCedric Chaumont 	    res != TEE_ERROR_STORAGE_NO_SPACE)
386b64d6909SCedric Chaumont 		TEE_Panic(res);
387b64d6909SCedric Chaumont 
388b64d6909SCedric Chaumont 	return res;
389b0104773SPascal Brand }
390b0104773SPascal Brand 
391b0104773SPascal Brand void TEE_GetREETime(TEE_Time *time)
392b0104773SPascal Brand {
3932c028fdeSJerome Forissier 	TEE_Result res = _utee_get_time(UTEE_TIME_CAT_REE, time);
394b0104773SPascal Brand 
395b0104773SPascal Brand 	if (res != TEE_SUCCESS)
396b36311adSJerome Forissier 		TEE_Panic(res);
397b0104773SPascal Brand }
398b0104773SPascal Brand 
39979a3c601SCedric Chaumont void *TEE_Malloc(uint32_t len, uint32_t hint)
400b0104773SPascal Brand {
401a83ee50aSSadiq Hussain 	if (!len)
402a83ee50aSSadiq Hussain 		return TEE_NULL_SIZED_VA;
403a83ee50aSSadiq Hussain 
40496c1d8c5SJens Wiklander 	if (hint == TEE_MALLOC_FILL_ZERO)
40596c1d8c5SJens Wiklander 		return calloc(1, len);
40696c1d8c5SJens Wiklander 	else if (hint == TEE_USER_MEM_HINT_NO_FILL_ZERO)
40796c1d8c5SJens Wiklander 		return malloc(len);
40896c1d8c5SJens Wiklander 
40996c1d8c5SJens Wiklander 	EMSG("Invalid hint %#" PRIx32, hint);
41096c1d8c5SJens Wiklander 
41196c1d8c5SJens Wiklander 	return NULL;
412b0104773SPascal Brand }
413b0104773SPascal Brand 
414c0ce02edSJens Wiklander void *TEE_Realloc(void *buffer, uint32_t newSize)
415b0104773SPascal Brand {
416a83ee50aSSadiq Hussain 	if (!newSize) {
417a83ee50aSSadiq Hussain 		TEE_Free(buffer);
418a83ee50aSSadiq Hussain 		return TEE_NULL_SIZED_VA;
419a83ee50aSSadiq Hussain 	}
420a83ee50aSSadiq Hussain 
421a83ee50aSSadiq Hussain 	if (buffer == TEE_NULL_SIZED_VA)
422a83ee50aSSadiq Hussain 		return calloc(1, newSize);
423a83ee50aSSadiq Hussain 
42496c1d8c5SJens Wiklander 	return realloc(buffer, newSize);
425b0104773SPascal Brand }
426b0104773SPascal Brand 
427b0104773SPascal Brand void TEE_Free(void *buffer)
428b0104773SPascal Brand {
429a83ee50aSSadiq Hussain 	if (buffer != TEE_NULL_SIZED_VA)
43096c1d8c5SJens Wiklander 		free(buffer);
431b0104773SPascal Brand }
432fa530828SPascal Brand 
433fa530828SPascal Brand /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */
434fa530828SPascal Brand TEE_Result TEE_CacheClean(char *buf, size_t len)
435fa530828SPascal Brand {
4362c028fdeSJerome Forissier 	return _utee_cache_operation(buf, len, TEE_CACHECLEAN);
437fa530828SPascal Brand }
438fa530828SPascal Brand TEE_Result TEE_CacheFlush(char *buf, size_t len)
439fa530828SPascal Brand {
4402c028fdeSJerome Forissier 	return _utee_cache_operation(buf, len, TEE_CACHEFLUSH);
441fa530828SPascal Brand }
442fa530828SPascal Brand 
443fa530828SPascal Brand TEE_Result TEE_CacheInvalidate(char *buf, size_t len)
444fa530828SPascal Brand {
4452c028fdeSJerome Forissier 	return _utee_cache_operation(buf, len, TEE_CACHEINVALIDATE);
446fa530828SPascal Brand }
447