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