Lines Matching +full:op +full:- +full:tee

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2015-2016, Linaro Limited
27 * TEE Client UUID name space identifier (UUIDv4)
30 * forming Client UUID's for TEE environment using UUIDv5 scheme.
52 return ERR_PTR(-EINVAL); in teedev_open()
56 rc = -ENOMEM; in teedev_open()
60 kref_init(&ctx->refcount); in teedev_open()
61 ctx->teedev = teedev; in teedev_open()
62 rc = teedev->desc->ops->open(ctx); in teedev_open()
76 if (ctx->releasing) in teedev_ctx_get()
79 kref_get(&ctx->refcount); in teedev_ctx_get()
86 ctx->releasing = true; in teedev_ctx_release()
87 ctx->teedev->desc->ops->release(ctx); in teedev_ctx_release()
93 if (ctx->releasing) in teedev_ctx_put()
96 kref_put(&ctx->refcount, teedev_ctx_release); in teedev_ctx_put()
101 tee_device_put(ctx->teedev); in teedev_close_context()
109 ctx = teedev_open(container_of(inode->i_cdev, struct tee_device, cdev)); in tee_open()
114 * Default user-space behaviour is to wait for tee-supplicant in tee_open()
117 ctx->supp_nowait = false; in tee_open()
118 filp->private_data = ctx; in tee_open()
124 teedev_close_context(filp->private_data); in tee_release()
129 * uuid_v5() - Calculate UUIDv5
137 * This implements section (for SHA-1):
138 * 4.3. Algorithm for Creating a Name-Based UUID
158 rc = -ENOMEM; in uuid_v5()
162 desc->tfm = shash; in uuid_v5()
180 memcpy(uuid->b, hash, UUID_SIZE); in uuid_v5()
183 uuid->b[6] = (hash[6] & 0x0F) | 0x50; in uuid_v5()
184 uuid->b[8] = (hash[8] & 0x3F) | 0x80; in uuid_v5()
197 gid_t ns_grp = (gid_t)-1; in tee_session_calc_client_uuid()
205 /* Nil UUID to be passed to TEE environment */ in tee_session_calc_client_uuid()
225 return -ENOMEM; in tee_session_calc_client_uuid()
232 rc = -E2BIG; in tee_session_calc_client_uuid()
241 rc = -EPERM; in tee_session_calc_client_uuid()
248 rc = -E2BIG; in tee_session_calc_client_uuid()
254 rc = -EINVAL; in tee_session_calc_client_uuid()
271 ctx->teedev->desc->ops->get_version(ctx->teedev, &vers); in tee_ioctl_version()
273 if (ctx->teedev->desc->flags & TEE_DESC_PRIVILEGED) in tee_ioctl_version()
277 return -EFAULT; in tee_ioctl_version()
290 return -EFAULT; in tee_ioctl_shm_alloc()
294 return -EINVAL; in tee_ioctl_shm_alloc()
300 data.id = shm->id; in tee_ioctl_shm_alloc()
301 data.flags = shm->flags; in tee_ioctl_shm_alloc()
302 data.size = shm->size; in tee_ioctl_shm_alloc()
305 ret = -EFAULT; in tee_ioctl_shm_alloc()
327 return -EFAULT; in tee_ioctl_shm_register()
331 return -EINVAL; in tee_ioctl_shm_register()
338 data.id = shm->id; in tee_ioctl_shm_register()
339 data.flags = shm->flags; in tee_ioctl_shm_register()
340 data.length = shm->size; in tee_ioctl_shm_register()
343 ret = -EFAULT; in tee_ioctl_shm_register()
366 return -EFAULT; in params_from_user()
370 return -EINVAL; in params_from_user()
387 * If a NULL pointer is passed to a TA in the TEE, in params_from_user()
411 (ip.a + ip.b) > shm->size) { in params_from_user()
413 return -EINVAL; in params_from_user()
415 } else if (ctx->cap_memref_null) { in params_from_user()
416 /* Pass NULL pointer to OP-TEE */ in params_from_user()
419 return -EINVAL; in params_from_user()
428 return -EINVAL; in params_from_user()
443 switch (p->attr) { in params_to_user()
446 if (put_user(p->u.value.a, &up->a) || in params_to_user()
447 put_user(p->u.value.b, &up->b) || in params_to_user()
448 put_user(p->u.value.c, &up->c)) in params_to_user()
449 return -EFAULT; in params_to_user()
453 if (put_user((u64)p->u.memref.size, &up->b)) in params_to_user()
454 return -EFAULT; in params_to_user()
475 if (!ctx->teedev->desc->ops->open_session) in tee_ioctl_open_session()
476 return -EINVAL; in tee_ioctl_open_session()
479 return -EFAULT; in tee_ioctl_open_session()
483 return -EINVAL; in tee_ioctl_open_session()
487 return -EFAULT; in tee_ioctl_open_session()
490 return -EINVAL; in tee_ioctl_open_session()
496 return -ENOMEM; in tee_ioctl_open_session()
497 uparams = uarg->params; in tee_ioctl_open_session()
505 pr_debug("login method not allowed for user-space client\n"); in tee_ioctl_open_session()
506 rc = -EPERM; in tee_ioctl_open_session()
510 rc = ctx->teedev->desc->ops->open_session(ctx, &arg, params); in tee_ioctl_open_session()
515 if (put_user(arg.session, &uarg->session) || in tee_ioctl_open_session()
516 put_user(arg.ret, &uarg->ret) || in tee_ioctl_open_session()
517 put_user(arg.ret_origin, &uarg->ret_origin)) { in tee_ioctl_open_session()
518 rc = -EFAULT; in tee_ioctl_open_session()
527 if (rc && have_session && ctx->teedev->desc->ops->close_session) in tee_ioctl_open_session()
528 ctx->teedev->desc->ops->close_session(ctx, arg.session); in tee_ioctl_open_session()
553 if (!ctx->teedev->desc->ops->invoke_func) in tee_ioctl_invoke()
554 return -EINVAL; in tee_ioctl_invoke()
557 return -EFAULT; in tee_ioctl_invoke()
561 return -EINVAL; in tee_ioctl_invoke()
565 return -EFAULT; in tee_ioctl_invoke()
568 return -EINVAL; in tee_ioctl_invoke()
574 return -ENOMEM; in tee_ioctl_invoke()
575 uparams = uarg->params; in tee_ioctl_invoke()
581 rc = ctx->teedev->desc->ops->invoke_func(ctx, &arg, params); in tee_ioctl_invoke()
585 if (put_user(arg.ret, &uarg->ret) || in tee_ioctl_invoke()
586 put_user(arg.ret_origin, &uarg->ret_origin)) { in tee_ioctl_invoke()
587 rc = -EFAULT; in tee_ioctl_invoke()
608 if (!ctx->teedev->desc->ops->cancel_req) in tee_ioctl_cancel()
609 return -EINVAL; in tee_ioctl_cancel()
612 return -EFAULT; in tee_ioctl_cancel()
614 return ctx->teedev->desc->ops->cancel_req(ctx, arg.cancel_id, in tee_ioctl_cancel()
624 if (!ctx->teedev->desc->ops->close_session) in tee_ioctl_close_session()
625 return -EINVAL; in tee_ioctl_close_session()
628 return -EFAULT; in tee_ioctl_close_session()
630 return ctx->teedev->desc->ops->close_session(ctx, arg.session); in tee_ioctl_close_session()
643 ip.attr = p->attr; in params_to_supp()
644 switch (p->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { in params_to_supp()
647 ip.a = p->u.value.a; in params_to_supp()
648 ip.b = p->u.value.b; in params_to_supp()
649 ip.c = p->u.value.c; in params_to_supp()
654 ip.b = p->u.memref.size; in params_to_supp()
655 if (!p->u.memref.shm) { in params_to_supp()
657 ip.c = (u64)-1; /* invalid shm id */ in params_to_supp()
660 ip.a = p->u.memref.shm_offs; in params_to_supp()
661 ip.c = p->u.memref.shm->id; in params_to_supp()
671 return -EFAULT; in params_to_supp()
687 if (!ctx->teedev->desc->ops->supp_recv) in tee_ioctl_supp_recv()
688 return -EINVAL; in tee_ioctl_supp_recv()
691 return -EFAULT; in tee_ioctl_supp_recv()
695 return -EINVAL; in tee_ioctl_supp_recv()
698 if (get_user(num_params, &uarg->num_params)) in tee_ioctl_supp_recv()
699 return -EFAULT; in tee_ioctl_supp_recv()
702 return -EINVAL; in tee_ioctl_supp_recv()
706 return -ENOMEM; in tee_ioctl_supp_recv()
708 rc = params_from_user(ctx, params, num_params, uarg->params); in tee_ioctl_supp_recv()
712 rc = ctx->teedev->desc->ops->supp_recv(ctx, &func, &num_params, params); in tee_ioctl_supp_recv()
716 if (put_user(func, &uarg->func) || in tee_ioctl_supp_recv()
717 put_user(num_params, &uarg->num_params)) { in tee_ioctl_supp_recv()
718 rc = -EFAULT; in tee_ioctl_supp_recv()
722 rc = params_to_supp(ctx, uarg->params, num_params, params); in tee_ioctl_supp_recv()
738 return -EFAULT; in params_from_supp()
742 return -EINVAL; in params_from_supp()
744 p->attr = ip.attr; in params_from_supp()
749 p->u.value.a = ip.a; in params_from_supp()
750 p->u.value.b = ip.b; in params_from_supp()
751 p->u.value.c = ip.c; in params_from_supp()
762 p->u.memref.shm = NULL; in params_from_supp()
763 p->u.memref.shm_offs = 0; in params_from_supp()
764 p->u.memref.size = ip.b; in params_from_supp()
767 memset(&p->u, 0, sizeof(p->u)); in params_from_supp()
785 if (!ctx->teedev->desc->ops->supp_send) in tee_ioctl_supp_send()
786 return -EINVAL; in tee_ioctl_supp_send()
789 return -EFAULT; in tee_ioctl_supp_send()
793 return -EINVAL; in tee_ioctl_supp_send()
796 if (get_user(ret, &uarg->ret) || in tee_ioctl_supp_send()
797 get_user(num_params, &uarg->num_params)) in tee_ioctl_supp_send()
798 return -EFAULT; in tee_ioctl_supp_send()
801 return -EINVAL; in tee_ioctl_supp_send()
805 return -ENOMEM; in tee_ioctl_supp_send()
807 rc = params_from_supp(params, num_params, uarg->params); in tee_ioctl_supp_send()
811 rc = ctx->teedev->desc->ops->supp_send(ctx, ret, num_params, params); in tee_ioctl_supp_send()
819 struct tee_context *ctx = filp->private_data; in tee_ioctl()
842 return -EINVAL; in tee_ioctl()
859 clear_bit(teedev->id, dev_mask); in tee_release_device()
861 mutex_destroy(&teedev->mutex); in tee_release_device()
862 idr_destroy(&teedev->idr); in tee_release_device()
867 * tee_device_alloc() - Allocate a new struct tee_device instance
888 if (!teedesc || !teedesc->name || !teedesc->ops || in tee_device_alloc()
889 !teedesc->ops->get_version || !teedesc->ops->open || in tee_device_alloc()
890 !teedesc->ops->release || !pool) in tee_device_alloc()
891 return ERR_PTR(-EINVAL); in tee_device_alloc()
895 ret = ERR_PTR(-ENOMEM); in tee_device_alloc()
901 if (teedesc->flags & TEE_DESC_PRIVILEGED) { in tee_device_alloc()
907 teedev->id = find_next_zero_bit(dev_mask, max_id, offs); in tee_device_alloc()
908 if (teedev->id < max_id) in tee_device_alloc()
909 set_bit(teedev->id, dev_mask); in tee_device_alloc()
912 if (teedev->id >= max_id) { in tee_device_alloc()
913 ret = ERR_PTR(-ENOMEM); in tee_device_alloc()
917 snprintf(teedev->name, sizeof(teedev->name), "tee%s%d", in tee_device_alloc()
918 teedesc->flags & TEE_DESC_PRIVILEGED ? "priv" : "", in tee_device_alloc()
919 teedev->id - offs); in tee_device_alloc()
921 teedev->dev.class = tee_class; in tee_device_alloc()
922 teedev->dev.release = tee_release_device; in tee_device_alloc()
923 teedev->dev.parent = dev; in tee_device_alloc()
925 teedev->dev.devt = MKDEV(MAJOR(tee_devt), teedev->id); in tee_device_alloc()
927 rc = dev_set_name(&teedev->dev, "%s", teedev->name); in tee_device_alloc()
933 cdev_init(&teedev->cdev, &tee_fops); in tee_device_alloc()
934 teedev->cdev.owner = teedesc->owner; in tee_device_alloc()
936 dev_set_drvdata(&teedev->dev, driver_data); in tee_device_alloc()
937 device_initialize(&teedev->dev); in tee_device_alloc()
940 teedev->num_users = 1; in tee_device_alloc()
941 init_completion(&teedev->c_no_users); in tee_device_alloc()
942 mutex_init(&teedev->mutex); in tee_device_alloc()
943 idr_init(&teedev->idr); in tee_device_alloc()
945 teedev->desc = teedesc; in tee_device_alloc()
946 teedev->pool = pool; in tee_device_alloc()
950 unregister_chrdev_region(teedev->dev.devt, 1); in tee_device_alloc()
953 teedesc->flags & TEE_DESC_PRIVILEGED ? "privileged" : "client"); in tee_device_alloc()
954 if (teedev && teedev->id < TEE_NUM_DEVICES) { in tee_device_alloc()
956 clear_bit(teedev->id, dev_mask); in tee_device_alloc()
970 teedev->desc->ops->get_version(teedev, &vers); in implementation_id_show()
983 * tee_device_register() - Registers a TEE device
995 if (teedev->flags & TEE_DEVICE_FLAG_REGISTERED) { in tee_device_register()
996 dev_err(&teedev->dev, "attempt to register twice\n"); in tee_device_register()
997 return -EINVAL; in tee_device_register()
1000 teedev->dev.groups = tee_dev_groups; in tee_device_register()
1002 rc = cdev_device_add(&teedev->cdev, &teedev->dev); in tee_device_register()
1004 dev_err(&teedev->dev, in tee_device_register()
1006 teedev->name, MAJOR(teedev->dev.devt), in tee_device_register()
1007 MINOR(teedev->dev.devt), rc); in tee_device_register()
1011 teedev->flags |= TEE_DEVICE_FLAG_REGISTERED; in tee_device_register()
1018 mutex_lock(&teedev->mutex); in tee_device_put()
1020 if (!WARN_ON(!teedev->desc)) { in tee_device_put()
1021 teedev->num_users--; in tee_device_put()
1022 if (!teedev->num_users) { in tee_device_put()
1023 teedev->desc = NULL; in tee_device_put()
1024 complete(&teedev->c_no_users); in tee_device_put()
1027 mutex_unlock(&teedev->mutex); in tee_device_put()
1032 mutex_lock(&teedev->mutex); in tee_device_get()
1033 if (!teedev->desc) { in tee_device_get()
1034 mutex_unlock(&teedev->mutex); in tee_device_get()
1037 teedev->num_users++; in tee_device_get()
1038 mutex_unlock(&teedev->mutex); in tee_device_get()
1043 * tee_device_unregister() - Removes a TEE device
1055 if (teedev->flags & TEE_DEVICE_FLAG_REGISTERED) in tee_device_unregister()
1056 cdev_device_del(&teedev->cdev, &teedev->dev); in tee_device_unregister()
1059 wait_for_completion(&teedev->c_no_users); in tee_device_unregister()
1062 * No need to take a mutex any longer now since teedev->desc was in tee_device_unregister()
1063 * set to NULL before teedev->c_no_users was completed. in tee_device_unregister()
1066 teedev->pool = NULL; in tee_device_unregister()
1068 put_device(&teedev->dev); in tee_device_unregister()
1073 * tee_get_drvdata() - Return driver_data pointer
1079 return dev_get_drvdata(&teedev->dev); in tee_get_drvdata()
1094 teedev->desc->ops->get_version(teedev, match_data->vers); in match_dev()
1095 return match_data->match(match_data->vers, match_data->data); in match_dev()
1111 dev = &start->teedev->dev; in tee_client_open_context()
1116 ctx = ERR_PTR(-ENOENT); in tee_client_open_context()
1124 } while (IS_ERR(ctx) && PTR_ERR(ctx) != -ENOMEM); in tee_client_open_context()
1129 * tee-supplicant if not present for any requests in this context. in tee_client_open_context()
1135 ctx->supp_nowait = true; in tee_client_open_context()
1150 ctx->teedev->desc->ops->get_version(ctx->teedev, vers); in tee_client_get_version()
1158 if (!ctx->teedev->desc->ops->open_session) in tee_client_open_session()
1159 return -EINVAL; in tee_client_open_session()
1160 return ctx->teedev->desc->ops->open_session(ctx, arg, param); in tee_client_open_session()
1166 if (!ctx->teedev->desc->ops->close_session) in tee_client_close_session()
1167 return -EINVAL; in tee_client_close_session()
1168 return ctx->teedev->desc->ops->close_session(ctx, session); in tee_client_close_session()
1176 if (!ctx->teedev->desc->ops->invoke_func) in tee_client_invoke_func()
1177 return -EINVAL; in tee_client_invoke_func()
1178 return ctx->teedev->desc->ops->invoke_func(ctx, arg, param); in tee_client_invoke_func()
1185 if (!ctx->teedev->desc->ops->cancel_req) in tee_client_cancel_req()
1186 return -EINVAL; in tee_client_cancel_req()
1187 return ctx->teedev->desc->ops->cancel_req(ctx, arg->cancel_id, in tee_client_cancel_req()
1188 arg->session); in tee_client_cancel_req()
1197 id_table = to_tee_client_driver(drv)->id_table; in tee_client_device_match()
1200 while (!uuid_is_null(&id_table->uuid)) { in tee_client_device_match()
1201 if (uuid_equal(&tee_device->id.uuid, &id_table->uuid)) in tee_client_device_match()
1212 uuid_t *dev_id = &to_tee_client_device(dev)->id.uuid; in tee_client_device_uevent()
1214 return add_uevent_var(env, "MODALIAS=tee:%pUb", dev_id); in tee_client_device_uevent()
1218 .name = "tee",
1228 tee_class = class_create(THIS_MODULE, "tee"); in tee_init()
1234 rc = alloc_chrdev_region(&tee_devt, 0, TEE_NUM_DEVICES, "tee"); in tee_init()
1242 pr_err("failed to register tee bus\n"); in tee_init()
1269 MODULE_DESCRIPTION("TEE Driver");