xref: /optee_os/lib/libutee/tee_api.c (revision 65551e69a006c496fb18d8374389b7b3617c2076)
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 
9 #include <tee_api.h>
10 #include <tee_internal_api_extensions.h>
11 #include <user_ta_header.h>
12 #include <utee_syscalls.h>
13 #include "tee_api_private.h"
14 
15 static const void *tee_api_instance_data;
16 
17 /* System API - Internal Client API */
18 
19 void __utee_from_param(struct utee_params *up, uint32_t param_types,
20 			const TEE_Param params[TEE_NUM_PARAMS])
21 {
22 	size_t n;
23 
24 	up->types = param_types;
25 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
26 		switch (TEE_PARAM_TYPE_GET(param_types, n)) {
27 		case TEE_PARAM_TYPE_VALUE_INPUT:
28 		case TEE_PARAM_TYPE_VALUE_OUTPUT:
29 		case TEE_PARAM_TYPE_VALUE_INOUT:
30 			up->vals[n * 2] = params[n].value.a;
31 			up->vals[n * 2 + 1] = params[n].value.b;
32 			break;
33 		case TEE_PARAM_TYPE_MEMREF_INPUT:
34 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
35 		case TEE_PARAM_TYPE_MEMREF_INOUT:
36 			up->vals[n * 2] = (uintptr_t)params[n].memref.buffer;
37 			up->vals[n * 2 + 1] = params[n].memref.size;
38 			break;
39 		default:
40 			up->vals[n * 2] = 0;
41 			up->vals[n * 2 + 1] = 0;
42 			break;
43 		}
44 	}
45 }
46 
47 void __utee_to_param(TEE_Param params[TEE_NUM_PARAMS],
48 			uint32_t *param_types, const struct utee_params *up)
49 {
50 	size_t n;
51 	uint32_t types = up->types;
52 
53 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
54 		uintptr_t a = up->vals[n * 2];
55 		uintptr_t b = up->vals[n * 2 + 1];
56 
57 		switch (TEE_PARAM_TYPE_GET(types, n)) {
58 		case TEE_PARAM_TYPE_VALUE_INPUT:
59 		case TEE_PARAM_TYPE_VALUE_OUTPUT:
60 		case TEE_PARAM_TYPE_VALUE_INOUT:
61 			params[n].value.a = a;
62 			params[n].value.b = b;
63 			break;
64 		case TEE_PARAM_TYPE_MEMREF_INPUT:
65 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
66 		case TEE_PARAM_TYPE_MEMREF_INOUT:
67 			params[n].memref.buffer = (void *)a;
68 			params[n].memref.size = b;
69 			break;
70 		default:
71 			break;
72 		}
73 	}
74 
75 	if (param_types)
76 		*param_types = types;
77 }
78 
79 TEE_Result TEE_OpenTASession(const TEE_UUID *destination,
80 				uint32_t cancellationRequestTimeout,
81 				uint32_t paramTypes,
82 				TEE_Param params[TEE_NUM_PARAMS],
83 				TEE_TASessionHandle *session,
84 				uint32_t *returnOrigin)
85 {
86 	TEE_Result res;
87 	struct utee_params up;
88 	uint32_t s;
89 
90 	__utee_from_param(&up, paramTypes, params);
91 	res = utee_open_ta_session(destination, cancellationRequestTimeout,
92 				   &up, &s, returnOrigin);
93 	__utee_to_param(params, NULL, &up);
94 	/*
95 	 * Specification says that *session must hold TEE_HANDLE_NULL is
96 	 * TEE_SUCCESS isn't returned. Set it here explicitly in case
97 	 * the syscall fails before out parameters has been updated.
98 	 */
99 	if (res != TEE_SUCCESS)
100 		s = TEE_HANDLE_NULL;
101 
102 	*session = (TEE_TASessionHandle)(uintptr_t)s;
103 	return res;
104 }
105 
106 void TEE_CloseTASession(TEE_TASessionHandle session)
107 {
108 	if (session != TEE_HANDLE_NULL) {
109 		TEE_Result res = utee_close_ta_session((uintptr_t)session);
110 
111 		if (res != TEE_SUCCESS)
112 			TEE_Panic(res);
113 	}
114 }
115 
116 TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session,
117 				uint32_t cancellationRequestTimeout,
118 				uint32_t commandID, uint32_t paramTypes,
119 				TEE_Param params[TEE_NUM_PARAMS],
120 				uint32_t *returnOrigin)
121 {
122 	TEE_Result res;
123 	uint32_t ret_origin;
124 	struct utee_params up;
125 
126 	__utee_from_param(&up, paramTypes, params);
127 	res = utee_invoke_ta_command((uintptr_t)session,
128 				      cancellationRequestTimeout,
129 				      commandID, &up, &ret_origin);
130 	__utee_to_param(params, NULL, &up);
131 
132 	if (returnOrigin != NULL)
133 		*returnOrigin = ret_origin;
134 
135 	if (ret_origin == TEE_ORIGIN_TRUSTED_APP)
136 		return res;
137 
138 	if (res != TEE_SUCCESS &&
139 	    res != TEE_ERROR_OUT_OF_MEMORY &&
140 	    res != TEE_ERROR_TARGET_DEAD)
141 		TEE_Panic(res);
142 
143 	return res;
144 }
145 
146 /* System API - Cancellations */
147 
148 bool TEE_GetCancellationFlag(void)
149 {
150 	uint32_t c;
151 	TEE_Result res = utee_get_cancellation_flag(&c);
152 
153 	if (res != TEE_SUCCESS)
154 		c = 0;
155 	return !!c;
156 }
157 
158 bool TEE_UnmaskCancellation(void)
159 {
160 	uint32_t old_mask;
161 	TEE_Result res = utee_unmask_cancellation(&old_mask);
162 
163 	if (res != TEE_SUCCESS)
164 		TEE_Panic(res);
165 	return !!old_mask;
166 }
167 
168 bool TEE_MaskCancellation(void)
169 {
170 	uint32_t old_mask;
171 	TEE_Result res = utee_mask_cancellation(&old_mask);
172 
173 	if (res != TEE_SUCCESS)
174 		TEE_Panic(res);
175 	return !!old_mask;
176 }
177 
178 /* System API - Memory Management */
179 
180 TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void *buffer,
181 				       uint32_t size)
182 {
183 	TEE_Result res;
184 
185 	if (size == 0)
186 		return TEE_SUCCESS;
187 
188 	/* Check access rights against memory mapping */
189 	res = utee_check_access_rights(accessFlags, buffer, size);
190 	if (res != TEE_SUCCESS)
191 		goto out;
192 
193 	/*
194 	* Check access rights against input parameters
195 	* Previous legacy code was removed and will need to be restored
196 	*/
197 
198 	res = TEE_SUCCESS;
199 out:
200 	return res;
201 }
202 
203 void TEE_SetInstanceData(const void *instanceData)
204 {
205 	tee_api_instance_data = instanceData;
206 }
207 
208 const void *TEE_GetInstanceData(void)
209 {
210 	return tee_api_instance_data;
211 }
212 
213 void *TEE_MemMove(void *dest, const void *src, uint32_t size)
214 {
215 	return memmove(dest, src, size);
216 }
217 
218 int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, uint32_t size)
219 {
220 	return consttime_memcmp(buffer1, buffer2, size);
221 }
222 
223 void *TEE_MemFill(void *buff, uint32_t x, uint32_t size)
224 {
225 	return memset(buff, x, size);
226 }
227 
228 /* Date & Time API */
229 
230 void TEE_GetSystemTime(TEE_Time *time)
231 {
232 	TEE_Result res = utee_get_time(UTEE_TIME_CAT_SYSTEM, time);
233 
234 	if (res != TEE_SUCCESS)
235 		TEE_Panic(res);
236 }
237 
238 TEE_Result TEE_Wait(uint32_t timeout)
239 {
240 	TEE_Result res = utee_wait(timeout);
241 
242 	if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL)
243 		TEE_Panic(res);
244 
245 	return res;
246 }
247 
248 TEE_Result TEE_GetTAPersistentTime(TEE_Time *time)
249 {
250 	TEE_Result res;
251 
252 	res = utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time);
253 
254 	if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) {
255 		time->seconds = 0;
256 		time->millis = 0;
257 	}
258 
259 	if (res != TEE_SUCCESS &&
260 	    res != TEE_ERROR_TIME_NOT_SET &&
261 	    res != TEE_ERROR_TIME_NEEDS_RESET &&
262 	    res != TEE_ERROR_OVERFLOW &&
263 	    res != TEE_ERROR_OUT_OF_MEMORY)
264 		TEE_Panic(res);
265 
266 	return res;
267 }
268 
269 TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time)
270 {
271 	TEE_Result res;
272 
273 	res = utee_set_ta_time(time);
274 
275 	if (res != TEE_SUCCESS &&
276 	    res != TEE_ERROR_OUT_OF_MEMORY &&
277 	    res != TEE_ERROR_STORAGE_NO_SPACE)
278 		TEE_Panic(res);
279 
280 	return res;
281 }
282 
283 void TEE_GetREETime(TEE_Time *time)
284 {
285 	TEE_Result res = utee_get_time(UTEE_TIME_CAT_REE, time);
286 
287 	if (res != TEE_SUCCESS)
288 		TEE_Panic(res);
289 }
290 
291 void *TEE_Malloc(uint32_t len, uint32_t hint)
292 {
293 	if (hint == TEE_MALLOC_FILL_ZERO)
294 		return calloc(1, len);
295 	else if (hint == TEE_USER_MEM_HINT_NO_FILL_ZERO)
296 		return malloc(len);
297 
298 	EMSG("Invalid hint %#" PRIx32, hint);
299 
300 	return NULL;
301 }
302 
303 void *TEE_Realloc(void *buffer, uint32_t newSize)
304 {
305 	return realloc(buffer, newSize);
306 }
307 
308 void TEE_Free(void *buffer)
309 {
310 	free(buffer);
311 }
312 
313 /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */
314 TEE_Result TEE_CacheClean(char *buf, size_t len)
315 {
316 	return utee_cache_operation(buf, len, TEE_CACHECLEAN);
317 }
318 TEE_Result TEE_CacheFlush(char *buf, size_t len)
319 {
320 	return utee_cache_operation(buf, len, TEE_CACHEFLUSH);
321 }
322 
323 TEE_Result TEE_CacheInvalidate(char *buf, size_t len)
324 {
325 	return utee_cache_operation(buf, len, TEE_CACHEINVALIDATE);
326 }
327