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