xref: /optee_os/lib/libutee/tee_api.c (revision 983d02116743476904b68d52ca432d0f79c38c43)
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 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, TEE_Param params[4],
103 			     TEE_TASessionHandle *session,
104 			     uint32_t *returnOrigin)
105 {
106 	TEE_Result res;
107 	struct utee_params up;
108 	uint32_t s;
109 
110 	__utee_from_param(&up, paramTypes, params);
111 	res = utee_open_ta_session(destination, cancellationRequestTimeout,
112 				   &up, &s, returnOrigin);
113 	__utee_to_param(params, NULL, &up);
114 	/*
115 	 * Specification says that *session must hold TEE_HANDLE_NULL is
116 	 * TEE_SUCCESS isn't returned. Set it here explicitly in case
117 	 * the syscall fails before out parameters has been updated.
118 	 */
119 	if (res != TEE_SUCCESS)
120 		s = TEE_HANDLE_NULL;
121 
122 	*session = (TEE_TASessionHandle)(uintptr_t)s;
123 	return res;
124 }
125 
126 void TEE_CloseTASession(TEE_TASessionHandle session)
127 {
128 	if (session != TEE_HANDLE_NULL) {
129 		TEE_Result res = utee_close_ta_session((uintptr_t)session);
130 
131 		if (res != TEE_SUCCESS)
132 			TEE_Panic(res);
133 	}
134 }
135 
136 TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session,
137 			       uint32_t cancellationRequestTimeout,
138 			       uint32_t commandID, uint32_t paramTypes,
139 			       TEE_Param params[4], uint32_t *returnOrigin)
140 {
141 	TEE_Result res;
142 	uint32_t ret_origin;
143 	struct utee_params up;
144 
145 	__utee_from_param(&up, paramTypes, params);
146 	res = utee_invoke_ta_command((uintptr_t)session,
147 				      cancellationRequestTimeout,
148 				      commandID, &up, &ret_origin);
149 	__utee_to_param(params, NULL, &up);
150 
151 	if (returnOrigin != NULL)
152 		*returnOrigin = ret_origin;
153 
154 	if (ret_origin == TEE_ORIGIN_TRUSTED_APP)
155 		return res;
156 
157 	if (res != TEE_SUCCESS &&
158 	    res != TEE_ERROR_OUT_OF_MEMORY &&
159 	    res != TEE_ERROR_TARGET_DEAD)
160 		TEE_Panic(res);
161 
162 	return res;
163 }
164 
165 /* System API - Cancellations */
166 
167 bool TEE_GetCancellationFlag(void)
168 {
169 	uint32_t c;
170 	TEE_Result res = utee_get_cancellation_flag(&c);
171 
172 	if (res != TEE_SUCCESS)
173 		c = 0;
174 	return !!c;
175 }
176 
177 bool TEE_UnmaskCancellation(void)
178 {
179 	uint32_t old_mask;
180 	TEE_Result res = utee_unmask_cancellation(&old_mask);
181 
182 	if (res != TEE_SUCCESS)
183 		TEE_Panic(res);
184 	return !!old_mask;
185 }
186 
187 bool TEE_MaskCancellation(void)
188 {
189 	uint32_t old_mask;
190 	TEE_Result res = utee_mask_cancellation(&old_mask);
191 
192 	if (res != TEE_SUCCESS)
193 		TEE_Panic(res);
194 	return !!old_mask;
195 }
196 
197 /* System API - Memory Management */
198 
199 TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void *buffer,
200 				       uint32_t size)
201 {
202 	TEE_Result res;
203 
204 	if (size == 0)
205 		return TEE_SUCCESS;
206 
207 	/* Check access rights against memory mapping */
208 	res = utee_check_access_rights(accessFlags, buffer, size);
209 	if (res != TEE_SUCCESS)
210 		goto out;
211 
212 	/*
213 	* Check access rights against input parameters
214 	* Previous legacy code was removed and will need to be restored
215 	*/
216 
217 	res = TEE_SUCCESS;
218 out:
219 	return res;
220 }
221 
222 void TEE_SetInstanceData(void *instanceData)
223 {
224 	tee_api_instance_data = instanceData;
225 }
226 
227 void *TEE_GetInstanceData(void)
228 {
229 	return tee_api_instance_data;
230 }
231 
232 void *TEE_MemMove(void *dest, const void *src, uint32_t size)
233 {
234 	return memmove(dest, src, size);
235 }
236 
237 int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, uint32_t size)
238 {
239 	return memcmp(buffer1, buffer2, size);
240 }
241 
242 void *TEE_MemFill(void *buff, uint32_t x, uint32_t size)
243 {
244 	return memset(buff, x, size);
245 }
246 
247 /* Date & Time API */
248 
249 void TEE_GetSystemTime(TEE_Time *time)
250 {
251 	TEE_Result res = utee_get_time(UTEE_TIME_CAT_SYSTEM, time);
252 
253 	if (res != TEE_SUCCESS)
254 		TEE_Panic(0);
255 }
256 
257 TEE_Result TEE_Wait(uint32_t timeout)
258 {
259 	TEE_Result res = utee_wait(timeout);
260 
261 	if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL)
262 		TEE_Panic(res);
263 
264 	return res;
265 }
266 
267 TEE_Result TEE_GetTAPersistentTime(TEE_Time *time)
268 {
269 	TEE_Result res;
270 
271 	res = utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time);
272 
273 	if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) {
274 		time->seconds = 0;
275 		time->millis = 0;
276 	}
277 
278 	if (res != TEE_SUCCESS &&
279 	    res != TEE_ERROR_TIME_NOT_SET &&
280 	    res != TEE_ERROR_TIME_NEEDS_RESET &&
281 	    res != TEE_ERROR_OVERFLOW &&
282 	    res != TEE_ERROR_OUT_OF_MEMORY)
283 		TEE_Panic(res);
284 
285 	return res;
286 }
287 
288 TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time)
289 {
290 	TEE_Result res;
291 
292 	res = utee_set_ta_time(time);
293 
294 	if (res != TEE_SUCCESS &&
295 	    res != TEE_ERROR_OUT_OF_MEMORY &&
296 	    res != TEE_ERROR_STORAGE_NO_SPACE)
297 		TEE_Panic(res);
298 
299 	return res;
300 }
301 
302 void TEE_GetREETime(TEE_Time *time)
303 {
304 	TEE_Result res = utee_get_time(UTEE_TIME_CAT_REE, time);
305 
306 	if (res != TEE_SUCCESS)
307 		TEE_Panic(0);
308 }
309 
310 void *TEE_Malloc(uint32_t len, uint32_t hint)
311 {
312 	return tee_user_mem_alloc(len, hint);
313 }
314 
315 void *TEE_Realloc(void *buffer, uint32_t newSize)
316 {
317 	/*
318 	 * GP TEE Internal API specifies newSize as 'uint32_t'.
319 	 * use unsigned 'size_t' type. it is at least 32bit!
320 	 */
321 	return tee_user_mem_realloc(buffer, (size_t) newSize);
322 }
323 
324 void TEE_Free(void *buffer)
325 {
326 	tee_user_mem_free(buffer);
327 }
328 
329 /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */
330 TEE_Result TEE_CacheClean(char *buf, size_t len)
331 {
332 	return utee_cache_operation(buf, len, TEE_CACHECLEAN);
333 }
334 TEE_Result TEE_CacheFlush(char *buf, size_t len)
335 {
336 	return utee_cache_operation(buf, len, TEE_CACHEFLUSH);
337 }
338 
339 TEE_Result TEE_CacheInvalidate(char *buf, size_t len)
340 {
341 	return utee_cache_operation(buf, len, TEE_CACHEINVALIDATE);
342 }
343