xref: /optee_os/core/tee/tee_svc.c (revision 355fa0952acfcf09a77043376af79cbf11454d5d)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  * Copyright (c) 2020, Linaro Limited
5  */
6 
7 #include <kernel/chip_services.h>
8 #include <kernel/pseudo_ta.h>
9 #include <kernel/tee_common.h>
10 #include <kernel/tee_common_otp.h>
11 #include <kernel/tee_ta_manager.h>
12 #include <kernel/tee_time.h>
13 #include <kernel/trace_ta.h>
14 #include <kernel/user_access.h>
15 #include <mm/core_memprot.h>
16 #include <mm/mobj.h>
17 #include <mm/tee_mm.h>
18 #include <mm/tee_mmu.h>
19 #include <stdlib_ext.h>
20 #include <tee_api_types.h>
21 #include <tee/tee_cryp_utl.h>
22 #include <tee/tee_svc.h>
23 #include <trace.h>
24 #include <user_ta_header.h>
25 #include <utee_types.h>
26 #include <util.h>
27 
28 vaddr_t tee_svc_uref_base;
29 
30 void syscall_log(const void *buf __maybe_unused, size_t len __maybe_unused)
31 {
32 #ifdef CFG_TEE_CORE_TA_TRACE
33 	char *kbuf;
34 
35 	if (len == 0)
36 		return;
37 
38 	kbuf = malloc(len + 1);
39 	if (kbuf == NULL)
40 		return;
41 
42 	if (copy_from_user(kbuf, buf, len) == TEE_SUCCESS) {
43 		kbuf[len] = '\0';
44 		trace_ext_puts(kbuf);
45 	}
46 
47 	free_wipe(kbuf);
48 #endif
49 }
50 
51 TEE_Result syscall_not_supported(void)
52 {
53 	return TEE_ERROR_NOT_SUPPORTED;
54 }
55 
56 /* Configuration properties */
57 /* API implementation version */
58 static const char api_vers[] = TO_STR(CFG_TEE_API_VERSION);
59 
60 /* Implementation description (implementation-dependent) */
61 static const char descr[] = TO_STR(CFG_TEE_IMPL_DESCR);
62 
63 /*
64  * TA persistent time protection level
65  * 100: Persistent time based on an REE-controlled real-time clock
66  * and on the TEE Trusted Storage for the storage of origins (default).
67  * 1000: Persistent time based on a TEE-controlled real-time clock
68  * and the TEE Trusted Storage.
69  * The real-time clock MUST be out of reach of software attacks
70  * from the REE.
71  */
72 static const uint32_t ta_time_prot_lvl = 100;
73 
74 /* Elliptic Curve Cryptographic support */
75 #ifdef CFG_CRYPTO_ECC
76 static const bool crypto_ecc_en = 1;
77 #else
78 static const bool crypto_ecc_en;
79 #endif
80 
81 /*
82  * Trusted storage anti rollback protection level
83  * 0 (or missing): No antirollback protection (default)
84  * 100: Antirollback enforced at REE level
85  * 1000: Antirollback TEE-controlled hardware
86  */
87 #ifdef CFG_RPMB_FS
88 static const uint32_t ts_antiroll_prot_lvl = 1000;
89 #else
90 static const uint32_t ts_antiroll_prot_lvl;
91 #endif
92 
93 /* Trusted OS implementation version */
94 static const char trustedos_impl_version[] = TO_STR(TEE_IMPL_VERSION);
95 
96 /* Trusted OS implementation version (binary value) */
97 static const uint32_t trustedos_impl_bin_version; /* 0 by default */
98 
99 /* Trusted OS implementation manufacturer name */
100 static const char trustedos_manufacturer[] = TO_STR(CFG_TEE_MANUFACTURER);
101 
102 /* Trusted firmware version */
103 static const char fw_impl_version[] = TO_STR(CFG_TEE_FW_IMPL_VERSION);
104 
105 /* Trusted firmware version (binary value) */
106 static const uint32_t fw_impl_bin_version; /* 0 by default */
107 
108 /* Trusted firmware manufacturer name */
109 static const char fw_manufacturer[] = TO_STR(CFG_TEE_FW_MANUFACTURER);
110 
111 static TEE_Result get_prop_tee_dev_id(struct tee_ta_session *sess __unused,
112 				      void *buf, size_t *blen)
113 {
114 	TEE_Result res;
115 	TEE_UUID uuid;
116 	const size_t nslen = 5;
117 	uint8_t data[5 + FVR_DIE_ID_NUM_REGS * sizeof(uint32_t)] = {
118 	    'O', 'P', 'T', 'E', 'E' };
119 
120 	if (*blen < sizeof(uuid)) {
121 		*blen = sizeof(uuid);
122 		return TEE_ERROR_SHORT_BUFFER;
123 	}
124 	*blen = sizeof(uuid);
125 
126 	if (tee_otp_get_die_id(data + nslen, sizeof(data) - nslen))
127 		return TEE_ERROR_BAD_STATE;
128 
129 	res = tee_hash_createdigest(TEE_ALG_SHA256, data, sizeof(data),
130 				    (uint8_t *)&uuid, sizeof(uuid));
131 	if (res != TEE_SUCCESS)
132 		return TEE_ERROR_BAD_STATE;
133 
134 	/*
135 	 * Changes the random value into and UUID as specifiec
136 	 * in RFC 4122. The magic values are from the example
137 	 * code in the RFC.
138 	 *
139 	 * TEE_UUID is defined slightly different from the RFC,
140 	 * but close enough for our purpose.
141 	 */
142 
143 	uuid.timeHiAndVersion &= 0x0fff;
144 	uuid.timeHiAndVersion |= 5 << 12;
145 
146 	/* uuid.clock_seq_hi_and_reserved in the RFC */
147 	uuid.clockSeqAndNode[0] &= 0x3f;
148 	uuid.clockSeqAndNode[0] |= 0x80;
149 
150 	return copy_to_user(buf, &uuid, sizeof(TEE_UUID));
151 }
152 
153 static TEE_Result get_prop_tee_sys_time_prot_level(
154 			struct tee_ta_session *sess __unused,
155 			void *buf, size_t *blen)
156 {
157 	uint32_t prot;
158 
159 	if (*blen < sizeof(prot)) {
160 		*blen = sizeof(prot);
161 		return TEE_ERROR_SHORT_BUFFER;
162 	}
163 	*blen = sizeof(prot);
164 	prot = tee_time_get_sys_time_protection_level();
165 	return copy_to_user(buf, &prot, sizeof(prot));
166 }
167 
168 static TEE_Result get_prop_client_id(struct tee_ta_session *sess __unused,
169 				     void *buf, size_t *blen)
170 {
171 	if (*blen < sizeof(TEE_Identity)) {
172 		*blen = sizeof(TEE_Identity);
173 		return TEE_ERROR_SHORT_BUFFER;
174 	}
175 	*blen = sizeof(TEE_Identity);
176 	return copy_to_user(buf, &sess->clnt_id, sizeof(TEE_Identity));
177 }
178 
179 static TEE_Result get_prop_ta_app_id(struct tee_ta_session *sess,
180 				     void *buf, size_t *blen)
181 {
182 	if (*blen < sizeof(TEE_UUID)) {
183 		*blen = sizeof(TEE_UUID);
184 		return TEE_ERROR_SHORT_BUFFER;
185 	}
186 	*blen = sizeof(TEE_UUID);
187 	return copy_to_user(buf, &sess->ctx->uuid, sizeof(TEE_UUID));
188 }
189 
190 /* Properties of the set TEE_PROPSET_CURRENT_CLIENT */
191 const struct tee_props tee_propset_client[] = {
192 	{
193 		.name = "gpd.client.identity",
194 		.prop_type = USER_TA_PROP_TYPE_IDENTITY,
195 		.get_prop_func = get_prop_client_id
196 	},
197 };
198 
199 /* Properties of the set TEE_PROPSET_CURRENT_TA */
200 const struct tee_props tee_propset_ta[] = {
201 	{
202 		.name = "gpd.ta.appID",
203 		.prop_type = USER_TA_PROP_TYPE_UUID,
204 		.get_prop_func = get_prop_ta_app_id
205 	},
206 
207 	/*
208 	 * Following properties are processed directly in libutee:
209 	 *	TA_PROP_STR_SINGLE_INSTANCE
210 	 *	TA_PROP_STR_MULTI_SESSION
211 	 *	TA_PROP_STR_KEEP_ALIVE
212 	 *	TA_PROP_STR_DATA_SIZE
213 	 *	TA_PROP_STR_STACK_SIZE
214 	 *	TA_PROP_STR_VERSION
215 	 *	TA_PROP_STR_DESCRIPTION
216 	 *	USER_TA_PROP_TYPE_STRING,
217 	 *	TA_DESCRIPTION
218 	 */
219 };
220 
221 /* Properties of the set TEE_PROPSET_TEE_IMPLEMENTATION */
222 const struct tee_props tee_propset_tee[] = {
223 	{
224 		.name = "gpd.tee.apiversion",
225 		.prop_type = USER_TA_PROP_TYPE_STRING,
226 		.data = api_vers,
227 		.len = sizeof(api_vers),
228 	},
229 	{
230 		.name = "gpd.tee.description",
231 		.prop_type = USER_TA_PROP_TYPE_STRING,
232 		.data = descr, .len = sizeof(descr)
233 	},
234 	{
235 		.name = "gpd.tee.deviceID",
236 		.prop_type = USER_TA_PROP_TYPE_UUID,
237 		.get_prop_func = get_prop_tee_dev_id
238 	},
239 	{
240 		.name = "gpd.tee.systemTime.protectionLevel",
241 		.prop_type = USER_TA_PROP_TYPE_U32,
242 		.get_prop_func = get_prop_tee_sys_time_prot_level
243 	},
244 	{
245 		.name = "gpd.tee.TAPersistentTime.protectionLevel",
246 		.prop_type = USER_TA_PROP_TYPE_U32,
247 		.data = &ta_time_prot_lvl,
248 		.len = sizeof(ta_time_prot_lvl)
249 	},
250 	{
251 		.name = "gpd.tee.cryptography.ecc",
252 		.prop_type = USER_TA_PROP_TYPE_BOOL,
253 		.data = &crypto_ecc_en,
254 		.len = sizeof(crypto_ecc_en)
255 	},
256 	{
257 		.name = "gpd.tee.trustedStorage.antiRollback.protectionLevel",
258 		.prop_type = USER_TA_PROP_TYPE_U32,
259 		.data = &ts_antiroll_prot_lvl,
260 		.len = sizeof(ts_antiroll_prot_lvl)
261 	},
262 	{
263 		.name = "gpd.tee.trustedos.implementation.version",
264 		.prop_type = USER_TA_PROP_TYPE_STRING,
265 		.data = trustedos_impl_version,
266 		.len = sizeof(trustedos_impl_version)
267 	},
268 	{
269 		.name = "gpd.tee.trustedos.implementation.binaryversion",
270 		.prop_type = USER_TA_PROP_TYPE_U32,
271 		.data = &trustedos_impl_bin_version,
272 		.len = sizeof(trustedos_impl_bin_version)
273 	},
274 	{
275 		.name = "gpd.tee.trustedos.manufacturer",
276 		.prop_type = USER_TA_PROP_TYPE_STRING,
277 		.data = trustedos_manufacturer,
278 		.len = sizeof(trustedos_manufacturer)
279 	},
280 	{
281 		.name = "gpd.tee.firmware.implementation.version",
282 		.prop_type = USER_TA_PROP_TYPE_STRING,
283 		.data = fw_impl_version,
284 		.len = sizeof(fw_impl_version)
285 	},
286 	{
287 		.name = "gpd.tee.firmware.implementation.binaryversion",
288 		.prop_type = USER_TA_PROP_TYPE_U32,
289 		.data = &fw_impl_bin_version,
290 		.len = sizeof(fw_impl_bin_version)
291 	},
292 	{
293 		.name = "gpd.tee.firmware.manufacturer",
294 		.prop_type = USER_TA_PROP_TYPE_STRING,
295 		.data = fw_manufacturer,
296 		.len = sizeof(fw_manufacturer)
297 	},
298 
299 	/*
300 	 * Following properties are processed directly in libutee:
301 	 *	gpd.tee.arith.maxBigIntSize
302 	 */
303 };
304 
305 __weak const struct tee_vendor_props vendor_props_client;
306 __weak const struct tee_vendor_props vendor_props_ta;
307 __weak const struct tee_vendor_props vendor_props_tee;
308 
309 static void get_prop_set(unsigned long prop_set,
310 			 const struct tee_props **props,
311 			 size_t *size,
312 			 const struct tee_props **vendor_props,
313 			 size_t *vendor_size)
314 {
315 	if ((TEE_PropSetHandle)prop_set == TEE_PROPSET_CURRENT_CLIENT) {
316 		*props = tee_propset_client;
317 		*size = ARRAY_SIZE(tee_propset_client);
318 		*vendor_props = vendor_props_client.props;
319 		*vendor_size = vendor_props_client.len;
320 	} else if ((TEE_PropSetHandle)prop_set == TEE_PROPSET_CURRENT_TA) {
321 		*props = tee_propset_ta;
322 		*size = ARRAY_SIZE(tee_propset_ta);
323 		*vendor_props = vendor_props_ta.props;
324 		*vendor_size = vendor_props_ta.len;
325 	} else if ((TEE_PropSetHandle)prop_set ==
326 		   TEE_PROPSET_TEE_IMPLEMENTATION) {
327 		*props = tee_propset_tee;
328 		*size = ARRAY_SIZE(tee_propset_tee);
329 		*vendor_props = vendor_props_tee.props;
330 		*vendor_size = vendor_props_tee.len;
331 	} else {
332 		*props = NULL;
333 		*size = 0;
334 		*vendor_props = NULL;
335 		*vendor_size = 0;
336 	}
337 }
338 
339 static const struct tee_props *get_prop_struct(unsigned long prop_set,
340 					       unsigned long index)
341 {
342 	const struct tee_props *props;
343 	const struct tee_props *vendor_props;
344 	size_t size;
345 	size_t vendor_size;
346 
347 	get_prop_set(prop_set, &props, &size, &vendor_props, &vendor_size);
348 
349 	if (index < size)
350 		return &(props[index]);
351 	index -= size;
352 
353 	if (index < vendor_size)
354 		return &(vendor_props[index]);
355 
356 	return NULL;
357 }
358 
359 /*
360  * prop_set is part of TEE_PROPSET_xxx
361  * index is the index in the Property Set to retrieve
362  * if name is not NULL, the name of "index" property is returned
363  * if buf is not NULL, the property is returned
364  */
365 TEE_Result syscall_get_property(unsigned long prop_set,
366 				unsigned long index,
367 				void *name, uint32_t *name_len,
368 				void *buf, uint32_t *blen,
369 				uint32_t *prop_type)
370 {
371 	struct tee_ta_session *sess;
372 	TEE_Result res;
373 	TEE_Result res2;
374 	const struct tee_props *prop;
375 	uint32_t klen;
376 	size_t klen_size;
377 	uint32_t elen;
378 
379 	prop = get_prop_struct(prop_set, index);
380 	if (!prop)
381 		return TEE_ERROR_ITEM_NOT_FOUND;
382 
383 	res = tee_ta_get_current_session(&sess);
384 	if (res != TEE_SUCCESS)
385 		return res;
386 
387 	/* Get the property type */
388 	if (prop_type) {
389 		res = copy_to_user(prop_type, &prop->prop_type,
390 				   sizeof(*prop_type));
391 		if (res != TEE_SUCCESS)
392 			return res;
393 	}
394 
395 	/* Get the property */
396 	if (buf && blen) {
397 		res = copy_from_user(&klen, blen, sizeof(klen));
398 		if (res != TEE_SUCCESS)
399 			return res;
400 
401 		if (prop->get_prop_func) {
402 			klen_size = klen;
403 			res = prop->get_prop_func(sess, buf, &klen_size);
404 			klen = klen_size;
405 			res2 = copy_to_user(blen, &klen, sizeof(*blen));
406 		} else {
407 			if (klen < prop->len)
408 				res = TEE_ERROR_SHORT_BUFFER;
409 			else
410 				res = copy_to_user(buf, prop->data, prop->len);
411 			res2 = copy_to_user(blen, &prop->len, sizeof(*blen));
412 		}
413 		if (res2 != TEE_SUCCESS)
414 			return res2;
415 		if (res != TEE_SUCCESS)
416 			return res;
417 	}
418 
419 	/* Get the property name */
420 	if (name && name_len) {
421 		res = copy_from_user(&klen, name_len, sizeof(klen));
422 		if (res != TEE_SUCCESS)
423 			return res;
424 
425 		elen = strlen(prop->name) + 1;
426 
427 		if (klen < elen)
428 			res = TEE_ERROR_SHORT_BUFFER;
429 		else
430 			res = copy_to_user(name, prop->name, elen);
431 		res2 = copy_to_user(name_len, &elen, sizeof(*name_len));
432 		if (res2 != TEE_SUCCESS)
433 			return res2;
434 		if (res != TEE_SUCCESS)
435 			return res;
436 	}
437 
438 	return res;
439 }
440 
441 /*
442  * prop_set is part of TEE_PROPSET_xxx
443  */
444 TEE_Result syscall_get_property_name_to_index(unsigned long prop_set,
445 					      void *name,
446 					      unsigned long name_len,
447 					      uint32_t *index)
448 {
449 	TEE_Result res;
450 	struct tee_ta_session *sess;
451 	const struct tee_props *props;
452 	size_t size;
453 	const struct tee_props *vendor_props;
454 	size_t vendor_size;
455 	char *kname = 0;
456 	uint32_t i;
457 
458 	get_prop_set(prop_set, &props, &size, &vendor_props, &vendor_size);
459 	if (!props)
460 		return TEE_ERROR_ITEM_NOT_FOUND;
461 
462 	res = tee_ta_get_current_session(&sess);
463 	if (res != TEE_SUCCESS)
464 		goto out;
465 
466 	if (!name || !name_len) {
467 		res = TEE_ERROR_BAD_PARAMETERS;
468 		goto out;
469 	}
470 
471 	kname = malloc(name_len);
472 	if (!kname)
473 		return TEE_ERROR_OUT_OF_MEMORY;
474 	res = copy_from_user(kname, name, name_len);
475 	if (res != TEE_SUCCESS)
476 		goto out;
477 	kname[name_len - 1] = 0;
478 
479 	res = TEE_ERROR_ITEM_NOT_FOUND;
480 	for (i = 0; i < size; i++) {
481 		if (!strcmp(kname, props[i].name)) {
482 			res = copy_to_user(index, &i, sizeof(*index));
483 			goto out;
484 		}
485 	}
486 	for (i = size; i < size + vendor_size; i++) {
487 		if (!strcmp(kname, vendor_props[i - size].name)) {
488 			res = copy_to_user(index, &i, sizeof(*index));
489 			goto out;
490 		}
491 	}
492 
493 out:
494 	free_wipe(kname);
495 	return res;
496 }
497 
498 static TEE_Result utee_param_to_param(struct user_ta_ctx *utc,
499 				      struct tee_ta_param *p,
500 				      struct utee_params *up)
501 {
502 	size_t n = 0;
503 	uint32_t types = up->types;
504 
505 	p->types = types;
506 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
507 		uintptr_t a = up->vals[n * 2];
508 		size_t b = up->vals[n * 2 + 1];
509 		uint32_t flags = TEE_MEMORY_ACCESS_READ |
510 				 TEE_MEMORY_ACCESS_ANY_OWNER;
511 
512 		switch (TEE_PARAM_TYPE_GET(types, n)) {
513 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
514 		case TEE_PARAM_TYPE_MEMREF_INOUT:
515 			flags |= TEE_MEMORY_ACCESS_WRITE;
516 			/*FALLTHROUGH*/
517 		case TEE_PARAM_TYPE_MEMREF_INPUT:
518 			p->u[n].mem.offs = a;
519 			p->u[n].mem.size = b;
520 
521 			if (!p->u[n].mem.offs) {
522 				/* Allow NULL memrefs if of size 0 */
523 				if (p->u[n].mem.size)
524 					return TEE_ERROR_BAD_PARAMETERS;
525 				p->u[n].mem.mobj = NULL;
526 				break;
527 			}
528 
529 			p->u[n].mem.mobj = &mobj_virt;
530 
531 			if (tee_mmu_check_access_rights(&utc->uctx, flags, a,
532 							b))
533 				return TEE_ERROR_ACCESS_DENIED;
534 			break;
535 		case TEE_PARAM_TYPE_VALUE_INPUT:
536 		case TEE_PARAM_TYPE_VALUE_INOUT:
537 			p->u[n].val.a = a;
538 			p->u[n].val.b = b;
539 			break;
540 		default:
541 			memset(&p->u[n], 0, sizeof(p->u[n]));
542 			break;
543 		}
544 	}
545 
546 	return TEE_SUCCESS;
547 }
548 
549 static TEE_Result alloc_temp_sec_mem(size_t size, struct mobj **mobj,
550 				     uint8_t **va)
551 {
552 	/* Allocate section in secure DDR */
553 #ifdef CFG_PAGED_USER_TA
554 	*mobj = mobj_seccpy_shm_alloc(size);
555 #else
556 	*mobj = mobj_mm_alloc(mobj_sec_ddr, size, &tee_mm_sec_ddr);
557 #endif
558 	if (!*mobj)
559 		return TEE_ERROR_GENERIC;
560 
561 	*va = mobj_get_va(*mobj, 0);
562 	return TEE_SUCCESS;
563 }
564 
565 /*
566  * TA invokes some TA with parameter.
567  * If some parameters are memory references:
568  * - either the memref is inside TA private RAM: TA is not allowed to expose
569  *   its private RAM: use a temporary memory buffer and copy the data.
570  * - or the memref is not in the TA private RAM:
571  *   - if the memref was mapped to the TA, TA is allowed to expose it.
572  *   - if so, converts memref virtual address into a physical address.
573  */
574 static TEE_Result tee_svc_copy_param(struct tee_ta_session *sess,
575 				     struct tee_ta_session *called_sess,
576 				     struct utee_params *callee_params,
577 				     struct tee_ta_param *param,
578 				     void *tmp_buf_va[TEE_NUM_PARAMS],
579 				     size_t tmp_buf_size[TEE_NUM_PARAMS],
580 				     struct mobj **mobj_tmp)
581 {
582 	struct user_ta_ctx *utc = to_user_ta_ctx(sess->ctx);
583 	bool ta_private_memref[TEE_NUM_PARAMS] = { false, };
584 	TEE_Result res = TEE_SUCCESS;
585 	size_t dst_offs = 0;
586 	size_t req_mem = 0;
587 	uint8_t *dst = 0;
588 	void *va = NULL;
589 	size_t n = 0;
590 	size_t s = 0;
591 
592 	/* fill 'param' input struct with caller params description buffer */
593 	if (!callee_params) {
594 		memset(param, 0, sizeof(*param));
595 	} else {
596 		uint32_t flags = TEE_MEMORY_ACCESS_READ |
597 				 TEE_MEMORY_ACCESS_WRITE |
598 				 TEE_MEMORY_ACCESS_ANY_OWNER;
599 
600 		res = tee_mmu_check_access_rights(&utc->uctx, flags,
601 						  (uaddr_t)callee_params,
602 						  sizeof(struct utee_params));
603 		if (res != TEE_SUCCESS)
604 			return res;
605 		res = utee_param_to_param(utc, param, callee_params);
606 		if (res != TEE_SUCCESS)
607 			return res;
608 	}
609 
610 	if (called_sess && is_pseudo_ta_ctx(called_sess->ctx)) {
611 		/* pseudo TA borrows the mapping of the calling TA */
612 		return TEE_SUCCESS;
613 	}
614 
615 	/* All mobj in param are of type MOJB_TYPE_VIRT */
616 
617 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
618 
619 		ta_private_memref[n] = false;
620 
621 		switch (TEE_PARAM_TYPE_GET(param->types, n)) {
622 		case TEE_PARAM_TYPE_MEMREF_INPUT:
623 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
624 		case TEE_PARAM_TYPE_MEMREF_INOUT:
625 			va = (void *)param->u[n].mem.offs;
626 			s = param->u[n].mem.size;
627 			if (!va) {
628 				if (s)
629 					return TEE_ERROR_BAD_PARAMETERS;
630 				break;
631 			}
632 			/* uTA cannot expose its private memory */
633 			if (tee_mmu_is_vbuf_inside_um_private(&utc->uctx, va,
634 							      s)) {
635 
636 				s = ROUNDUP(s, sizeof(uint32_t));
637 				if (ADD_OVERFLOW(req_mem, s, &req_mem))
638 					return TEE_ERROR_BAD_PARAMETERS;
639 				ta_private_memref[n] = true;
640 				break;
641 			}
642 
643 			res = tee_mmu_vbuf_to_mobj_offs(&utc->uctx, va, s,
644 							&param->u[n].mem.mobj,
645 							&param->u[n].mem.offs);
646 			if (res != TEE_SUCCESS)
647 				return res;
648 			break;
649 		default:
650 			break;
651 		}
652 	}
653 
654 	if (req_mem == 0)
655 		return TEE_SUCCESS;
656 
657 	res = alloc_temp_sec_mem(req_mem, mobj_tmp, &dst);
658 	if (res != TEE_SUCCESS)
659 		return res;
660 	dst_offs = 0;
661 
662 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
663 
664 		if (!ta_private_memref[n])
665 			continue;
666 
667 		s = ROUNDUP(param->u[n].mem.size, sizeof(uint32_t));
668 
669 		switch (TEE_PARAM_TYPE_GET(param->types, n)) {
670 		case TEE_PARAM_TYPE_MEMREF_INPUT:
671 		case TEE_PARAM_TYPE_MEMREF_INOUT:
672 			va = (void *)param->u[n].mem.offs;
673 			if (va) {
674 				res = copy_from_user(dst, va,
675 						     param->u[n].mem.size);
676 				if (res != TEE_SUCCESS)
677 					return res;
678 				param->u[n].mem.offs = dst_offs;
679 				param->u[n].mem.mobj = *mobj_tmp;
680 				tmp_buf_va[n] = dst;
681 				tmp_buf_size[n] = param->u[n].mem.size;
682 				dst += s;
683 				dst_offs += s;
684 			}
685 			break;
686 
687 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
688 			va = (void *)param->u[n].mem.offs;
689 			if (va) {
690 				param->u[n].mem.offs = dst_offs;
691 				param->u[n].mem.mobj = *mobj_tmp;
692 				tmp_buf_va[n] = dst;
693 				tmp_buf_size[n] = param->u[n].mem.size;
694 				dst += s;
695 				dst_offs += s;
696 			}
697 			break;
698 
699 		default:
700 			continue;
701 		}
702 	}
703 
704 	return TEE_SUCCESS;
705 }
706 
707 /*
708  * Back from execution of service: update parameters passed from TA:
709  * If some parameters were memory references:
710  * - either the memref was temporary: copy back data and update size
711  * - or it was the original TA memref: update only the size value.
712  */
713 static TEE_Result tee_svc_update_out_param(
714 		struct tee_ta_param *param,
715 		void *tmp_buf_va[TEE_NUM_PARAMS],
716 		size_t tmp_buf_size[TEE_NUM_PARAMS],
717 		struct utee_params *usr_param)
718 {
719 	size_t n;
720 	uint64_t *vals = usr_param->vals;
721 	size_t sz = 0;
722 
723 	for (n = 0; n < TEE_NUM_PARAMS; n++) {
724 		switch (TEE_PARAM_TYPE_GET(param->types, n)) {
725 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
726 		case TEE_PARAM_TYPE_MEMREF_INOUT:
727 			/*
728 			 * Memory copy is only needed if there's a temporary
729 			 * buffer involved, tmp_buf_va[n] is only update if
730 			 * a temporary buffer is used. Otherwise only the
731 			 * size needs to be updated.
732 			 */
733 			sz = param->u[n].mem.size;
734 			if (tmp_buf_va[n] && sz <= vals[n * 2 + 1]) {
735 				void *src = tmp_buf_va[n];
736 				void *dst = (void *)(uintptr_t)vals[n * 2];
737 				TEE_Result res = TEE_SUCCESS;
738 
739 				/*
740 				 * TA is allowed to return a size larger than
741 				 * the original size. However, in such cases no
742 				 * data should be synchronized as per TEE Client
743 				 * API spec.
744 				 */
745 				if (sz <= tmp_buf_size[n]) {
746 					res = copy_to_user(dst, src, sz);
747 					if (res != TEE_SUCCESS)
748 						return res;
749 				}
750 			}
751 			usr_param->vals[n * 2 + 1] = sz;
752 			break;
753 
754 		case TEE_PARAM_TYPE_VALUE_OUTPUT:
755 		case TEE_PARAM_TYPE_VALUE_INOUT:
756 			vals[n * 2] = param->u[n].val.a;
757 			vals[n * 2 + 1] = param->u[n].val.b;
758 			break;
759 
760 		default:
761 			continue;
762 		}
763 	}
764 
765 	return TEE_SUCCESS;
766 }
767 
768 /* Called when a TA calls an OpenSession on another TA */
769 TEE_Result syscall_open_ta_session(const TEE_UUID *dest,
770 			unsigned long cancel_req_to,
771 			struct utee_params *usr_param, uint32_t *ta_sess,
772 			uint32_t *ret_orig)
773 {
774 	TEE_Result res;
775 	uint32_t ret_o = TEE_ORIGIN_TEE;
776 	struct tee_ta_session *s = NULL;
777 	struct tee_ta_session *sess;
778 	struct mobj *mobj_param = NULL;
779 	TEE_UUID *uuid = malloc(sizeof(TEE_UUID));
780 	struct tee_ta_param *param = malloc(sizeof(struct tee_ta_param));
781 	TEE_Identity *clnt_id = malloc(sizeof(TEE_Identity));
782 	void *tmp_buf_va[TEE_NUM_PARAMS] = { NULL };
783 	size_t tmp_buf_size[TEE_NUM_PARAMS] = { 0 };
784 	struct user_ta_ctx *utc;
785 
786 	if (uuid == NULL || param == NULL || clnt_id == NULL) {
787 		res = TEE_ERROR_OUT_OF_MEMORY;
788 		goto out_free_only;
789 	}
790 
791 	memset(param, 0, sizeof(struct tee_ta_param));
792 
793 	res = tee_ta_get_current_session(&sess);
794 	if (res != TEE_SUCCESS)
795 		goto out_free_only;
796 	utc = to_user_ta_ctx(sess->ctx);
797 
798 	res = copy_from_user_private(uuid, dest, sizeof(TEE_UUID));
799 	if (res != TEE_SUCCESS)
800 		goto function_exit;
801 
802 	clnt_id->login = TEE_LOGIN_TRUSTED_APP;
803 	memcpy(&clnt_id->uuid, &sess->ctx->uuid, sizeof(TEE_UUID));
804 
805 	res = tee_svc_copy_param(sess, NULL, usr_param, param, tmp_buf_va,
806 				 tmp_buf_size, &mobj_param);
807 	if (res != TEE_SUCCESS)
808 		goto function_exit;
809 
810 	res = tee_ta_open_session(&ret_o, &s, &utc->open_sessions, uuid,
811 				  clnt_id, cancel_req_to, param);
812 	tee_mmu_set_ctx(&utc->uctx.ctx);
813 	if (res != TEE_SUCCESS)
814 		goto function_exit;
815 
816 	res = tee_svc_update_out_param(param, tmp_buf_va, tmp_buf_size,
817 				       usr_param);
818 
819 function_exit:
820 	mobj_put_wipe(mobj_param);
821 	if (res == TEE_SUCCESS)
822 		copy_to_user_private(ta_sess, &s->id, sizeof(s->id));
823 	copy_to_user_private(ret_orig, &ret_o, sizeof(ret_o));
824 
825 out_free_only:
826 	free_wipe(param);
827 	free_wipe(uuid);
828 	free_wipe(clnt_id);
829 	return res;
830 }
831 
832 TEE_Result syscall_close_ta_session(unsigned long ta_sess)
833 {
834 	TEE_Result res;
835 	struct tee_ta_session *sess;
836 	TEE_Identity clnt_id;
837 	struct tee_ta_session *s = NULL;
838 	struct user_ta_ctx *utc;
839 
840 	res = tee_ta_get_current_session(&sess);
841 	if (res != TEE_SUCCESS)
842 		return res;
843 	utc = to_user_ta_ctx(sess->ctx);
844 	s = tee_ta_find_session(ta_sess, &utc->open_sessions);
845 
846 	clnt_id.login = TEE_LOGIN_TRUSTED_APP;
847 	memcpy(&clnt_id.uuid, &sess->ctx->uuid, sizeof(TEE_UUID));
848 
849 	return tee_ta_close_session(s, &utc->open_sessions, &clnt_id);
850 }
851 
852 TEE_Result syscall_invoke_ta_command(unsigned long ta_sess,
853 			unsigned long cancel_req_to, unsigned long cmd_id,
854 			struct utee_params *usr_param, uint32_t *ret_orig)
855 {
856 	TEE_Result res;
857 	TEE_Result res2;
858 	uint32_t ret_o = TEE_ORIGIN_TEE;
859 	struct tee_ta_param param = { 0 };
860 	TEE_Identity clnt_id;
861 	struct tee_ta_session *sess;
862 	struct tee_ta_session *called_sess;
863 	struct mobj *mobj_param = NULL;
864 	void *tmp_buf_va[TEE_NUM_PARAMS] = { NULL };
865 	size_t tmp_buf_size[TEE_NUM_PARAMS] = { };
866 	struct user_ta_ctx *utc;
867 
868 	res = tee_ta_get_current_session(&sess);
869 	if (res != TEE_SUCCESS)
870 		return res;
871 	utc = to_user_ta_ctx(sess->ctx);
872 
873 	called_sess = tee_ta_get_session((uint32_t)ta_sess, true,
874 				&utc->open_sessions);
875 	if (!called_sess)
876 		return TEE_ERROR_BAD_PARAMETERS;
877 
878 	clnt_id.login = TEE_LOGIN_TRUSTED_APP;
879 	memcpy(&clnt_id.uuid, &sess->ctx->uuid, sizeof(TEE_UUID));
880 
881 	res = tee_svc_copy_param(sess, called_sess, usr_param, &param,
882 				 tmp_buf_va, tmp_buf_size, &mobj_param);
883 	if (res != TEE_SUCCESS)
884 		goto function_exit;
885 
886 	res = tee_ta_invoke_command(&ret_o, called_sess, &clnt_id,
887 				    cancel_req_to, cmd_id, &param);
888 	if (res == TEE_ERROR_TARGET_DEAD)
889 		goto function_exit;
890 
891 	res2 = tee_svc_update_out_param(&param, tmp_buf_va, tmp_buf_size,
892 					usr_param);
893 	if (res2 != TEE_SUCCESS) {
894 		/*
895 		 * Spec for TEE_InvokeTACommand() says:
896 		 * "If the return origin is different from
897 		 * TEE_ORIGIN_TRUSTED_APP, then the function has failed
898 		 * before it could reach the destination Trusted
899 		 * Application."
900 		 *
901 		 * But if we can't update params to the caller we have no
902 		 * choice we need to return some error to indicate that
903 		 * parameters aren't updated as expected.
904 		 */
905 		ret_o = TEE_ORIGIN_TEE;
906 		res = res2;
907 	}
908 
909 function_exit:
910 	tee_ta_put_session(called_sess);
911 	mobj_put_wipe(mobj_param);
912 	copy_to_user_private(ret_orig, &ret_o, sizeof(ret_o));
913 	return res;
914 }
915 
916 TEE_Result syscall_check_access_rights(unsigned long flags, const void *buf,
917 				       size_t len)
918 {
919 	struct tee_ta_session *s = NULL;
920 	TEE_Result res = TEE_SUCCESS;
921 
922 	res = tee_ta_get_current_session(&s);
923 	if (res != TEE_SUCCESS)
924 		return res;
925 
926 	return tee_mmu_check_access_rights(&to_user_ta_ctx(s->ctx)->uctx, flags,
927 					   (uaddr_t)buf, len);
928 }
929 
930 TEE_Result syscall_get_cancellation_flag(uint32_t *cancel)
931 {
932 	TEE_Result res;
933 	struct tee_ta_session *s = NULL;
934 	uint32_t c;
935 
936 	res = tee_ta_get_current_session(&s);
937 	if (res != TEE_SUCCESS)
938 		return res;
939 
940 	c = tee_ta_session_is_cancelled(s, NULL);
941 
942 	return copy_to_user(cancel, &c, sizeof(c));
943 }
944 
945 TEE_Result syscall_unmask_cancellation(uint32_t *old_mask)
946 {
947 	TEE_Result res;
948 	struct tee_ta_session *s = NULL;
949 	uint32_t m;
950 
951 	res = tee_ta_get_current_session(&s);
952 	if (res != TEE_SUCCESS)
953 		return res;
954 
955 	m = s->cancel_mask;
956 	s->cancel_mask = false;
957 	return copy_to_user(old_mask, &m, sizeof(m));
958 }
959 
960 TEE_Result syscall_mask_cancellation(uint32_t *old_mask)
961 {
962 	TEE_Result res;
963 	struct tee_ta_session *s = NULL;
964 	uint32_t m;
965 
966 	res = tee_ta_get_current_session(&s);
967 	if (res != TEE_SUCCESS)
968 		return res;
969 
970 	m = s->cancel_mask;
971 	s->cancel_mask = true;
972 	return copy_to_user(old_mask, &m, sizeof(m));
973 }
974 
975 TEE_Result syscall_wait(unsigned long timeout)
976 {
977 	TEE_Result res = TEE_SUCCESS;
978 	uint32_t mytime = 0;
979 	struct tee_ta_session *s;
980 	TEE_Time base_time;
981 	TEE_Time current_time;
982 
983 	res = tee_ta_get_current_session(&s);
984 	if (res != TEE_SUCCESS)
985 		return res;
986 
987 	res = tee_time_get_sys_time(&base_time);
988 	if (res != TEE_SUCCESS)
989 		return res;
990 
991 	while (true) {
992 		res = tee_time_get_sys_time(&current_time);
993 		if (res != TEE_SUCCESS)
994 			return res;
995 
996 		if (tee_ta_session_is_cancelled(s, &current_time))
997 			return TEE_ERROR_CANCEL;
998 
999 		mytime = (current_time.seconds - base_time.seconds) * 1000 +
1000 		    (int)current_time.millis - (int)base_time.millis;
1001 		if (mytime >= timeout)
1002 			return TEE_SUCCESS;
1003 
1004 		tee_time_wait(timeout - mytime);
1005 	}
1006 
1007 	return res;
1008 }
1009 
1010 TEE_Result syscall_get_time(unsigned long cat, TEE_Time *mytime)
1011 {
1012 	TEE_Result res, res2;
1013 	struct tee_ta_session *s = NULL;
1014 	TEE_Time t;
1015 
1016 	res = tee_ta_get_current_session(&s);
1017 	if (res != TEE_SUCCESS)
1018 		return res;
1019 
1020 	switch (cat) {
1021 	case UTEE_TIME_CAT_SYSTEM:
1022 		res = tee_time_get_sys_time(&t);
1023 		break;
1024 	case UTEE_TIME_CAT_TA_PERSISTENT:
1025 		res = tee_time_get_ta_time((const void *)&s->ctx->uuid, &t);
1026 		break;
1027 	case UTEE_TIME_CAT_REE:
1028 		res = tee_time_get_ree_time(&t);
1029 		break;
1030 	default:
1031 		res = TEE_ERROR_BAD_PARAMETERS;
1032 		break;
1033 	}
1034 
1035 	if (res == TEE_SUCCESS || res == TEE_ERROR_OVERFLOW) {
1036 		res2 = copy_to_user_private(mytime, &t, sizeof(t));
1037 		if (res2 != TEE_SUCCESS)
1038 			res = res2;
1039 	}
1040 
1041 	return res;
1042 }
1043 
1044 TEE_Result syscall_set_ta_time(const TEE_Time *mytime)
1045 {
1046 	TEE_Result res;
1047 	struct tee_ta_session *s = NULL;
1048 	TEE_Time t;
1049 
1050 	res = tee_ta_get_current_session(&s);
1051 	if (res != TEE_SUCCESS)
1052 		return res;
1053 
1054 	res = copy_from_user_private(&t, mytime, sizeof(t));
1055 	if (res != TEE_SUCCESS)
1056 		return res;
1057 
1058 	return tee_time_set_ta_time((const void *)&s->ctx->uuid, &t);
1059 }
1060