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