xref: /optee_os/lib/libutee/tee_api.c (revision 8f07fe6f754c642bcc33224df2772359b36f7d2b)
1b0104773SPascal Brand /*
2b0104773SPascal Brand  * Copyright (c) 2014, STMicroelectronics International N.V.
3b0104773SPascal Brand  * All rights reserved.
4b0104773SPascal Brand  *
5b0104773SPascal Brand  * Redistribution and use in source and binary forms, with or without
6b0104773SPascal Brand  * modification, are permitted provided that the following conditions are met:
7b0104773SPascal Brand  *
8b0104773SPascal Brand  * 1. Redistributions of source code must retain the above copyright notice,
9b0104773SPascal Brand  * this list of conditions and the following disclaimer.
10b0104773SPascal Brand  *
11b0104773SPascal Brand  * 2. Redistributions in binary form must reproduce the above copyright notice,
12b0104773SPascal Brand  * this list of conditions and the following disclaimer in the documentation
13b0104773SPascal Brand  * and/or other materials provided with the distribution.
14b0104773SPascal Brand  *
15b0104773SPascal Brand  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16b0104773SPascal Brand  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17b0104773SPascal Brand  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18b0104773SPascal Brand  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19b0104773SPascal Brand  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20b0104773SPascal Brand  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21b0104773SPascal Brand  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22b0104773SPascal Brand  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23b0104773SPascal Brand  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24b0104773SPascal Brand  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25b0104773SPascal Brand  * POSSIBILITY OF SUCH DAMAGE.
26b0104773SPascal Brand  */
27b0104773SPascal Brand #include <stdlib.h>
28b0104773SPascal Brand #include <string.h>
29b0104773SPascal Brand 
30b0104773SPascal Brand #include <tee_api.h>
31b0104773SPascal Brand #include <utee_syscalls.h>
32b0104773SPascal Brand #include <user_ta_header.h>
33b0104773SPascal Brand #include "tee_user_mem.h"
34e86f1266SJens Wiklander #include "tee_api_private.h"
35b0104773SPascal Brand 
36*8f07fe6fSJerome Forissier static const void *tee_api_instance_data;
37b0104773SPascal Brand 
38b0104773SPascal Brand /* System API - Internal Client API */
39b0104773SPascal Brand 
40e86f1266SJens Wiklander void __utee_from_param(struct utee_params *up, uint32_t param_types,
41e86f1266SJens Wiklander 			const TEE_Param params[TEE_NUM_PARAMS])
42e86f1266SJens Wiklander {
43e86f1266SJens Wiklander 	size_t n;
44e86f1266SJens Wiklander 
45e86f1266SJens Wiklander 	up->types = param_types;
46e86f1266SJens Wiklander 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
47e86f1266SJens Wiklander 		switch (TEE_PARAM_TYPE_GET(param_types, n)) {
48e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_VALUE_INPUT:
49e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_VALUE_OUTPUT:
50e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_VALUE_INOUT:
51e86f1266SJens Wiklander 			up->vals[n * 2] = params[n].value.a;
52e86f1266SJens Wiklander 			up->vals[n * 2 + 1] = params[n].value.b;
53e86f1266SJens Wiklander 			break;
54e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INPUT:
55e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
56e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
57e86f1266SJens Wiklander 			up->vals[n * 2] = (uintptr_t)params[n].memref.buffer;
58e86f1266SJens Wiklander 			up->vals[n * 2 + 1] = params[n].memref.size;
59e86f1266SJens Wiklander 			break;
60e86f1266SJens Wiklander 		default:
61e86f1266SJens Wiklander 			up->vals[n * 2] = 0;
62e86f1266SJens Wiklander 			up->vals[n * 2 + 1] = 0;
63e86f1266SJens Wiklander 			break;
64e86f1266SJens Wiklander 		}
65e86f1266SJens Wiklander 	}
66e86f1266SJens Wiklander }
67e86f1266SJens Wiklander 
68e86f1266SJens Wiklander void __utee_to_param(TEE_Param params[TEE_NUM_PARAMS],
69e86f1266SJens Wiklander 			uint32_t *param_types, const struct utee_params *up)
70e86f1266SJens Wiklander {
71e86f1266SJens Wiklander 	size_t n;
72e86f1266SJens Wiklander 	uint32_t types = up->types;
73e86f1266SJens Wiklander 
74e86f1266SJens Wiklander 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
75e86f1266SJens Wiklander 		uintptr_t a = up->vals[n * 2];
76e86f1266SJens Wiklander 		uintptr_t b = up->vals[n * 2 + 1];
77e86f1266SJens Wiklander 
78e86f1266SJens Wiklander 		switch (TEE_PARAM_TYPE_GET(types, n)) {
79e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_VALUE_INPUT:
80e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_VALUE_OUTPUT:
81e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_VALUE_INOUT:
82e86f1266SJens Wiklander 			params[n].value.a = a;
83e86f1266SJens Wiklander 			params[n].value.b = b;
84e86f1266SJens Wiklander 			break;
85e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INPUT:
86e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
87e86f1266SJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
88e86f1266SJens Wiklander 			params[n].memref.buffer = (void *)a;
89e86f1266SJens Wiklander 			params[n].memref.size = b;
90e86f1266SJens Wiklander 			break;
91e86f1266SJens Wiklander 		default:
92e86f1266SJens Wiklander 			break;
93e86f1266SJens Wiklander 		}
94e86f1266SJens Wiklander 	}
95e86f1266SJens Wiklander 
96e86f1266SJens Wiklander 	if (param_types)
97e86f1266SJens Wiklander 		*param_types = types;
98e86f1266SJens Wiklander }
99e86f1266SJens Wiklander 
100b0104773SPascal Brand TEE_Result TEE_OpenTASession(const TEE_UUID *destination,
101b0104773SPascal Brand 				uint32_t cancellationRequestTimeout,
10268540524SIgor Opaniuk 				uint32_t paramTypes,
10368540524SIgor Opaniuk 				TEE_Param params[TEE_NUM_PARAMS],
104b0104773SPascal Brand 				TEE_TASessionHandle *session,
105b0104773SPascal Brand 				uint32_t *returnOrigin)
106b0104773SPascal Brand {
107b0104773SPascal Brand 	TEE_Result res;
108e86f1266SJens Wiklander 	struct utee_params up;
109e86f1266SJens Wiklander 	uint32_t s;
110b0104773SPascal Brand 
111e86f1266SJens Wiklander 	__utee_from_param(&up, paramTypes, params);
112b0104773SPascal Brand 	res = utee_open_ta_session(destination, cancellationRequestTimeout,
113e86f1266SJens Wiklander 				   &up, &s, returnOrigin);
114e86f1266SJens Wiklander 	__utee_to_param(params, NULL, &up);
115b0104773SPascal Brand 	/*
116b0104773SPascal Brand 	 * Specification says that *session must hold TEE_HANDLE_NULL is
117b0104773SPascal Brand 	 * TEE_SUCCESS isn't returned. Set it here explicitly in case
118b0104773SPascal Brand 	 * the syscall fails before out parameters has been updated.
119b0104773SPascal Brand 	 */
120b0104773SPascal Brand 	if (res != TEE_SUCCESS)
121e86f1266SJens Wiklander 		s = TEE_HANDLE_NULL;
122b0104773SPascal Brand 
123e86f1266SJens Wiklander 	*session = (TEE_TASessionHandle)(uintptr_t)s;
124b0104773SPascal Brand 	return res;
125b0104773SPascal Brand }
126b0104773SPascal Brand 
127b0104773SPascal Brand void TEE_CloseTASession(TEE_TASessionHandle session)
128b0104773SPascal Brand {
129b0104773SPascal Brand 	if (session != TEE_HANDLE_NULL) {
130e86f1266SJens Wiklander 		TEE_Result res = utee_close_ta_session((uintptr_t)session);
131e86f1266SJens Wiklander 
132b0104773SPascal Brand 		if (res != TEE_SUCCESS)
133b0104773SPascal Brand 			TEE_Panic(res);
134b0104773SPascal Brand 	}
135b0104773SPascal Brand }
136b0104773SPascal Brand 
137b0104773SPascal Brand TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session,
138b0104773SPascal Brand 				uint32_t cancellationRequestTimeout,
139b0104773SPascal Brand 				uint32_t commandID, uint32_t paramTypes,
14068540524SIgor Opaniuk 				TEE_Param params[TEE_NUM_PARAMS],
14168540524SIgor Opaniuk 				uint32_t *returnOrigin)
142b0104773SPascal Brand {
143c15e5835SCedric Chaumont 	TEE_Result res;
1446709c3eaSCedric Chaumont 	uint32_t ret_origin;
145e86f1266SJens Wiklander 	struct utee_params up;
146c15e5835SCedric Chaumont 
147e86f1266SJens Wiklander 	__utee_from_param(&up, paramTypes, params);
148e86f1266SJens Wiklander 	res = utee_invoke_ta_command((uintptr_t)session,
149e86f1266SJens Wiklander 				      cancellationRequestTimeout,
150e86f1266SJens Wiklander 				      commandID, &up, &ret_origin);
151e86f1266SJens Wiklander 	__utee_to_param(params, NULL, &up);
1526709c3eaSCedric Chaumont 
1536709c3eaSCedric Chaumont 	if (returnOrigin != NULL)
1546709c3eaSCedric Chaumont 		*returnOrigin = ret_origin;
1556709c3eaSCedric Chaumont 
1566709c3eaSCedric Chaumont 	if (ret_origin == TEE_ORIGIN_TRUSTED_APP)
1576709c3eaSCedric Chaumont 		return res;
1586709c3eaSCedric Chaumont 
159c15e5835SCedric Chaumont 	if (res != TEE_SUCCESS &&
160c15e5835SCedric Chaumont 	    res != TEE_ERROR_OUT_OF_MEMORY &&
161c15e5835SCedric Chaumont 	    res != TEE_ERROR_TARGET_DEAD)
162c15e5835SCedric Chaumont 		TEE_Panic(res);
163c15e5835SCedric Chaumont 
164c15e5835SCedric Chaumont 	return res;
165b0104773SPascal Brand }
166b0104773SPascal Brand 
167b0104773SPascal Brand /* System API - Cancellations */
168b0104773SPascal Brand 
169b0104773SPascal Brand bool TEE_GetCancellationFlag(void)
170b0104773SPascal Brand {
171e86f1266SJens Wiklander 	uint32_t c;
172b0104773SPascal Brand 	TEE_Result res = utee_get_cancellation_flag(&c);
173e86f1266SJens Wiklander 
174b0104773SPascal Brand 	if (res != TEE_SUCCESS)
175e86f1266SJens Wiklander 		c = 0;
176e86f1266SJens Wiklander 	return !!c;
177b0104773SPascal Brand }
178b0104773SPascal Brand 
179b0104773SPascal Brand bool TEE_UnmaskCancellation(void)
180b0104773SPascal Brand {
181e86f1266SJens Wiklander 	uint32_t old_mask;
182b0104773SPascal Brand 	TEE_Result res = utee_unmask_cancellation(&old_mask);
183b0104773SPascal Brand 
184b0104773SPascal Brand 	if (res != TEE_SUCCESS)
185b0104773SPascal Brand 		TEE_Panic(res);
186e86f1266SJens Wiklander 	return !!old_mask;
187b0104773SPascal Brand }
188b0104773SPascal Brand 
189b0104773SPascal Brand bool TEE_MaskCancellation(void)
190b0104773SPascal Brand {
191e86f1266SJens Wiklander 	uint32_t old_mask;
192b0104773SPascal Brand 	TEE_Result res = utee_mask_cancellation(&old_mask);
193b0104773SPascal Brand 
194b0104773SPascal Brand 	if (res != TEE_SUCCESS)
195b0104773SPascal Brand 		TEE_Panic(res);
196e86f1266SJens Wiklander 	return !!old_mask;
197b0104773SPascal Brand }
198b0104773SPascal Brand 
199b0104773SPascal Brand /* System API - Memory Management */
200b0104773SPascal Brand 
201b0104773SPascal Brand TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void *buffer,
20279a3c601SCedric Chaumont 				       uint32_t size)
203b0104773SPascal Brand {
204b0104773SPascal Brand 	TEE_Result res;
205b0104773SPascal Brand 
206b0104773SPascal Brand 	if (size == 0)
207b0104773SPascal Brand 		return TEE_SUCCESS;
208b0104773SPascal Brand 
209b0104773SPascal Brand 	/* Check access rights against memory mapping */
210b0104773SPascal Brand 	res = utee_check_access_rights(accessFlags, buffer, size);
211b0104773SPascal Brand 	if (res != TEE_SUCCESS)
212b0104773SPascal Brand 		goto out;
213b0104773SPascal Brand 
214b0104773SPascal Brand 	/*
215b0104773SPascal Brand 	* Check access rights against input parameters
216b0104773SPascal Brand 	* Previous legacy code was removed and will need to be restored
217b0104773SPascal Brand 	*/
218b0104773SPascal Brand 
219b0104773SPascal Brand 	res = TEE_SUCCESS;
220b0104773SPascal Brand out:
221b0104773SPascal Brand 	return res;
222b0104773SPascal Brand }
223b0104773SPascal Brand 
224*8f07fe6fSJerome Forissier void TEE_SetInstanceData(const void *instanceData)
225b0104773SPascal Brand {
226b0104773SPascal Brand 	tee_api_instance_data = instanceData;
227b0104773SPascal Brand }
228b0104773SPascal Brand 
229*8f07fe6fSJerome Forissier const void *TEE_GetInstanceData(void)
230b0104773SPascal Brand {
231b0104773SPascal Brand 	return tee_api_instance_data;
232b0104773SPascal Brand }
233b0104773SPascal Brand 
234b0104773SPascal Brand void *TEE_MemMove(void *dest, const void *src, uint32_t size)
235b0104773SPascal Brand {
236b0104773SPascal Brand 	return memmove(dest, src, size);
237b0104773SPascal Brand }
238b0104773SPascal Brand 
239b0104773SPascal Brand int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, uint32_t size)
240b0104773SPascal Brand {
241b0104773SPascal Brand 	return memcmp(buffer1, buffer2, size);
242b0104773SPascal Brand }
243b0104773SPascal Brand 
244b0104773SPascal Brand void *TEE_MemFill(void *buff, uint32_t x, uint32_t size)
245b0104773SPascal Brand {
246b0104773SPascal Brand 	return memset(buff, x, size);
247b0104773SPascal Brand }
248b0104773SPascal Brand 
249b0104773SPascal Brand /* Date & Time API */
250b0104773SPascal Brand 
251b0104773SPascal Brand void TEE_GetSystemTime(TEE_Time *time)
252b0104773SPascal Brand {
253b0104773SPascal Brand 	TEE_Result res = utee_get_time(UTEE_TIME_CAT_SYSTEM, time);
254b0104773SPascal Brand 
255b0104773SPascal Brand 	if (res != TEE_SUCCESS)
256b36311adSJerome Forissier 		TEE_Panic(res);
257b0104773SPascal Brand }
258b0104773SPascal Brand 
259b0104773SPascal Brand TEE_Result TEE_Wait(uint32_t timeout)
260b0104773SPascal Brand {
261b0104773SPascal Brand 	TEE_Result res = utee_wait(timeout);
262b0104773SPascal Brand 
263b0104773SPascal Brand 	if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL)
264b0104773SPascal Brand 		TEE_Panic(res);
265b0104773SPascal Brand 
266b0104773SPascal Brand 	return res;
267b0104773SPascal Brand }
268b0104773SPascal Brand 
269b0104773SPascal Brand TEE_Result TEE_GetTAPersistentTime(TEE_Time *time)
270b0104773SPascal Brand {
271b64d6909SCedric Chaumont 	TEE_Result res;
272b64d6909SCedric Chaumont 
273b64d6909SCedric Chaumont 	res = utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time);
274b64d6909SCedric Chaumont 
275b64d6909SCedric Chaumont 	if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) {
276b64d6909SCedric Chaumont 		time->seconds = 0;
277b64d6909SCedric Chaumont 		time->millis = 0;
278b64d6909SCedric Chaumont 	}
279b64d6909SCedric Chaumont 
280b64d6909SCedric Chaumont 	if (res != TEE_SUCCESS &&
281b64d6909SCedric Chaumont 	    res != TEE_ERROR_TIME_NOT_SET &&
282b64d6909SCedric Chaumont 	    res != TEE_ERROR_TIME_NEEDS_RESET &&
283b64d6909SCedric Chaumont 	    res != TEE_ERROR_OVERFLOW &&
284b64d6909SCedric Chaumont 	    res != TEE_ERROR_OUT_OF_MEMORY)
285b64d6909SCedric Chaumont 		TEE_Panic(res);
286b64d6909SCedric Chaumont 
287b64d6909SCedric Chaumont 	return res;
288b0104773SPascal Brand }
289b0104773SPascal Brand 
290b0104773SPascal Brand TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time)
291b0104773SPascal Brand {
292b64d6909SCedric Chaumont 	TEE_Result res;
293b64d6909SCedric Chaumont 
294b64d6909SCedric Chaumont 	res = utee_set_ta_time(time);
295b64d6909SCedric Chaumont 
296b64d6909SCedric Chaumont 	if (res != TEE_SUCCESS &&
297b64d6909SCedric Chaumont 	    res != TEE_ERROR_OUT_OF_MEMORY &&
298b64d6909SCedric Chaumont 	    res != TEE_ERROR_STORAGE_NO_SPACE)
299b64d6909SCedric Chaumont 		TEE_Panic(res);
300b64d6909SCedric Chaumont 
301b64d6909SCedric Chaumont 	return res;
302b0104773SPascal Brand }
303b0104773SPascal Brand 
304b0104773SPascal Brand void TEE_GetREETime(TEE_Time *time)
305b0104773SPascal Brand {
306b0104773SPascal Brand 	TEE_Result res = utee_get_time(UTEE_TIME_CAT_REE, time);
307b0104773SPascal Brand 
308b0104773SPascal Brand 	if (res != TEE_SUCCESS)
309b36311adSJerome Forissier 		TEE_Panic(res);
310b0104773SPascal Brand }
311b0104773SPascal Brand 
31279a3c601SCedric Chaumont void *TEE_Malloc(uint32_t len, uint32_t hint)
313b0104773SPascal Brand {
314b0104773SPascal Brand 	return tee_user_mem_alloc(len, hint);
315b0104773SPascal Brand }
316b0104773SPascal Brand 
317*8f07fe6fSJerome Forissier void *TEE_Realloc(const void *buffer, uint32_t newSize)
318b0104773SPascal Brand {
319b0104773SPascal Brand 	/*
320b0104773SPascal Brand 	 * GP TEE Internal API specifies newSize as 'uint32_t'.
321b0104773SPascal Brand 	 * use unsigned 'size_t' type. it is at least 32bit!
322b0104773SPascal Brand 	 */
323*8f07fe6fSJerome Forissier 	return tee_user_mem_realloc((void *)buffer, (size_t) newSize);
324b0104773SPascal Brand }
325b0104773SPascal Brand 
326b0104773SPascal Brand void TEE_Free(void *buffer)
327b0104773SPascal Brand {
328b0104773SPascal Brand 	tee_user_mem_free(buffer);
329b0104773SPascal Brand }
330fa530828SPascal Brand 
331fa530828SPascal Brand /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */
332fa530828SPascal Brand TEE_Result TEE_CacheClean(char *buf, size_t len)
333fa530828SPascal Brand {
334fa530828SPascal Brand 	return utee_cache_operation(buf, len, TEE_CACHECLEAN);
335fa530828SPascal Brand }
336fa530828SPascal Brand TEE_Result TEE_CacheFlush(char *buf, size_t len)
337fa530828SPascal Brand {
338fa530828SPascal Brand 	return utee_cache_operation(buf, len, TEE_CACHEFLUSH);
339fa530828SPascal Brand }
340fa530828SPascal Brand 
341fa530828SPascal Brand TEE_Result TEE_CacheInvalidate(char *buf, size_t len)
342fa530828SPascal Brand {
343fa530828SPascal Brand 	return utee_cache_operation(buf, len, TEE_CACHEINVALIDATE);
344fa530828SPascal Brand }
345