forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-11 297b60346df8beafee954a0fd7c2d64f33f3b9bc
kernel/drivers/tee/tee_core.c
....@@ -1,32 +1,37 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2015-2016, Linaro Limited
3
- *
4
- * This software is licensed under the terms of the GNU General Public
5
- * License version 2, as published by the Free Software Foundation, and
6
- * may be copied, distributed, and modified under those terms.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
12
- *
134 */
145
156 #define pr_fmt(fmt) "%s: " fmt, __func__
167
178 #include <linux/cdev.h>
18
-#include <linux/device.h>
9
+#include <linux/cred.h>
1910 #include <linux/fs.h>
2011 #include <linux/idr.h>
2112 #include <linux/module.h>
2213 #include <linux/slab.h>
2314 #include <linux/tee_drv.h>
2415 #include <linux/uaccess.h>
16
+#include <crypto/hash.h>
17
+#include <crypto/sha.h>
2518 #include "tee_private.h"
2619
2720 #define TEE_NUM_DEVICES 32
2821
2922 #define TEE_IOCTL_PARAM_SIZE(x) (sizeof(struct tee_param) * (x))
23
+
24
+#define TEE_UUID_NS_NAME_SIZE 128
25
+
26
+/*
27
+ * TEE Client UUID name space identifier (UUIDv4)
28
+ *
29
+ * Value here is random UUID that is allocated as name space identifier for
30
+ * forming Client UUID's for TEE environment using UUIDv5 scheme.
31
+ */
32
+static const uuid_t tee_client_uuid_ns = UUID_INIT(0x58ac9ca0, 0x2086, 0x4683,
33
+ 0xa1, 0xb8, 0xec, 0x4b,
34
+ 0xc0, 0x8e, 0x01, 0xb6);
3035
3136 /*
3237 * Unprivileged devices in the lower half range and privileged devices in
....@@ -38,15 +43,13 @@
3843 static struct class *tee_class;
3944 static dev_t tee_devt;
4045
41
-static int tee_open(struct inode *inode, struct file *filp)
46
+struct tee_context *teedev_open(struct tee_device *teedev)
4247 {
4348 int rc;
44
- struct tee_device *teedev;
4549 struct tee_context *ctx;
4650
47
- teedev = container_of(inode->i_cdev, struct tee_device, cdev);
4851 if (!tee_device_get(teedev))
49
- return -EINVAL;
52
+ return ERR_PTR(-EINVAL);
5053
5154 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
5255 if (!ctx) {
....@@ -56,18 +59,18 @@
5659
5760 kref_init(&ctx->refcount);
5861 ctx->teedev = teedev;
59
- INIT_LIST_HEAD(&ctx->list_shm);
60
- filp->private_data = ctx;
6162 rc = teedev->desc->ops->open(ctx);
6263 if (rc)
6364 goto err;
6465
65
- return 0;
66
+ return ctx;
6667 err:
6768 kfree(ctx);
6869 tee_device_put(teedev);
69
- return rc;
70
+ return ERR_PTR(rc);
71
+
7072 }
73
+EXPORT_SYMBOL_GPL(teedev_open);
7174
7275 void teedev_ctx_get(struct tee_context *ctx)
7376 {
....@@ -94,12 +97,30 @@
9497 kref_put(&ctx->refcount, teedev_ctx_release);
9598 }
9699
97
-static void teedev_close_context(struct tee_context *ctx)
100
+void teedev_close_context(struct tee_context *ctx)
98101 {
99102 struct tee_device *teedev = ctx->teedev;
100103
101104 teedev_ctx_put(ctx);
102105 tee_device_put(teedev);
106
+}
107
+EXPORT_SYMBOL_GPL(teedev_close_context);
108
+
109
+static int tee_open(struct inode *inode, struct file *filp)
110
+{
111
+ struct tee_context *ctx;
112
+
113
+ ctx = teedev_open(container_of(inode->i_cdev, struct tee_device, cdev));
114
+ if (IS_ERR(ctx))
115
+ return PTR_ERR(ctx);
116
+
117
+ /*
118
+ * Default user-space behaviour is to wait for tee-supplicant
119
+ * if not present for any requests in this context.
120
+ */
121
+ ctx->supp_nowait = false;
122
+ filp->private_data = ctx;
123
+ return 0;
103124 }
104125
105126 static int tee_release(struct inode *inode, struct file *filp)
....@@ -107,6 +128,144 @@
107128 teedev_close_context(filp->private_data);
108129 return 0;
109130 }
131
+
132
+/**
133
+ * uuid_v5() - Calculate UUIDv5
134
+ * @uuid: Resulting UUID
135
+ * @ns: Name space ID for UUIDv5 function
136
+ * @name: Name for UUIDv5 function
137
+ * @size: Size of name
138
+ *
139
+ * UUIDv5 is specific in RFC 4122.
140
+ *
141
+ * This implements section (for SHA-1):
142
+ * 4.3. Algorithm for Creating a Name-Based UUID
143
+ */
144
+static int uuid_v5(uuid_t *uuid, const uuid_t *ns, const void *name,
145
+ size_t size)
146
+{
147
+ unsigned char hash[SHA1_DIGEST_SIZE];
148
+ struct crypto_shash *shash = NULL;
149
+ struct shash_desc *desc = NULL;
150
+ int rc;
151
+
152
+ shash = crypto_alloc_shash("sha1", 0, 0);
153
+ if (IS_ERR(shash)) {
154
+ rc = PTR_ERR(shash);
155
+ pr_err("shash(sha1) allocation failed\n");
156
+ return rc;
157
+ }
158
+
159
+ desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(shash),
160
+ GFP_KERNEL);
161
+ if (!desc) {
162
+ rc = -ENOMEM;
163
+ goto out_free_shash;
164
+ }
165
+
166
+ desc->tfm = shash;
167
+
168
+ rc = crypto_shash_init(desc);
169
+ if (rc < 0)
170
+ goto out_free_desc;
171
+
172
+ rc = crypto_shash_update(desc, (const u8 *)ns, sizeof(*ns));
173
+ if (rc < 0)
174
+ goto out_free_desc;
175
+
176
+ rc = crypto_shash_update(desc, (const u8 *)name, size);
177
+ if (rc < 0)
178
+ goto out_free_desc;
179
+
180
+ rc = crypto_shash_final(desc, hash);
181
+ if (rc < 0)
182
+ goto out_free_desc;
183
+
184
+ memcpy(uuid->b, hash, UUID_SIZE);
185
+
186
+ /* Tag for version 5 */
187
+ uuid->b[6] = (hash[6] & 0x0F) | 0x50;
188
+ uuid->b[8] = (hash[8] & 0x3F) | 0x80;
189
+
190
+out_free_desc:
191
+ kfree(desc);
192
+
193
+out_free_shash:
194
+ crypto_free_shash(shash);
195
+ return rc;
196
+}
197
+
198
+int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
199
+ const u8 connection_data[TEE_IOCTL_UUID_LEN])
200
+{
201
+ gid_t ns_grp = (gid_t)-1;
202
+ kgid_t grp = INVALID_GID;
203
+ char *name = NULL;
204
+ int name_len;
205
+ int rc;
206
+
207
+ if (connection_method == TEE_IOCTL_LOGIN_PUBLIC ||
208
+ connection_method == TEE_IOCTL_LOGIN_REE_KERNEL) {
209
+ /* Nil UUID to be passed to TEE environment */
210
+ uuid_copy(uuid, &uuid_null);
211
+ return 0;
212
+ }
213
+
214
+ /*
215
+ * In Linux environment client UUID is based on UUIDv5.
216
+ *
217
+ * Determine client UUID with following semantics for 'name':
218
+ *
219
+ * For TEEC_LOGIN_USER:
220
+ * uid=<uid>
221
+ *
222
+ * For TEEC_LOGIN_GROUP:
223
+ * gid=<gid>
224
+ *
225
+ */
226
+
227
+ name = kzalloc(TEE_UUID_NS_NAME_SIZE, GFP_KERNEL);
228
+ if (!name)
229
+ return -ENOMEM;
230
+
231
+ switch (connection_method) {
232
+ case TEE_IOCTL_LOGIN_USER:
233
+ name_len = snprintf(name, TEE_UUID_NS_NAME_SIZE, "uid=%x",
234
+ current_euid().val);
235
+ if (name_len >= TEE_UUID_NS_NAME_SIZE) {
236
+ rc = -E2BIG;
237
+ goto out_free_name;
238
+ }
239
+ break;
240
+
241
+ case TEE_IOCTL_LOGIN_GROUP:
242
+ memcpy(&ns_grp, connection_data, sizeof(gid_t));
243
+ grp = make_kgid(current_user_ns(), ns_grp);
244
+ if (!gid_valid(grp) || !in_egroup_p(grp)) {
245
+ rc = -EPERM;
246
+ goto out_free_name;
247
+ }
248
+
249
+ name_len = snprintf(name, TEE_UUID_NS_NAME_SIZE, "gid=%x",
250
+ grp.val);
251
+ if (name_len >= TEE_UUID_NS_NAME_SIZE) {
252
+ rc = -E2BIG;
253
+ goto out_free_name;
254
+ }
255
+ break;
256
+
257
+ default:
258
+ rc = -EINVAL;
259
+ goto out_free_name;
260
+ }
261
+
262
+ rc = uuid_v5(uuid, &tee_client_uuid_ns, name, name_len);
263
+out_free_name:
264
+ kfree(name);
265
+
266
+ return rc;
267
+}
268
+EXPORT_SYMBOL_GPL(tee_session_calc_client_uuid);
110269
111270 static int tee_ioctl_version(struct tee_context *ctx,
112271 struct tee_ioctl_version_data __user *uvers)
....@@ -175,6 +334,9 @@
175334 if (data.flags)
176335 return -EINVAL;
177336
337
+ if (!access_ok((void __user *)(unsigned long)data.addr, data.length))
338
+ return -EFAULT;
339
+
178340 shm = tee_shm_register(ctx, data.addr, data.length,
179341 TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED);
180342 if (IS_ERR(shm))
....@@ -229,25 +391,38 @@
229391 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
230392 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
231393 /*
232
- * If we fail to get a pointer to a shared memory
233
- * object (and increase the ref count) from an
234
- * identifier we return an error. All pointers that
235
- * has been added in params have an increased ref
236
- * count. It's the callers responibility to do
237
- * tee_shm_put() on all resolved pointers.
394
+ * If a NULL pointer is passed to a TA in the TEE,
395
+ * the ip.c IOCTL parameters is set to TEE_MEMREF_NULL
396
+ * indicating a NULL memory reference.
238397 */
239
- shm = tee_shm_get_from_id(ctx, ip.c);
240
- if (IS_ERR(shm))
241
- return PTR_ERR(shm);
398
+ if (ip.c != TEE_MEMREF_NULL) {
399
+ /*
400
+ * If we fail to get a pointer to a shared
401
+ * memory object (and increase the ref count)
402
+ * from an identifier we return an error. All
403
+ * pointers that has been added in params have
404
+ * an increased ref count. It's the callers
405
+ * responibility to do tee_shm_put() on all
406
+ * resolved pointers.
407
+ */
408
+ shm = tee_shm_get_from_id(ctx, ip.c);
409
+ if (IS_ERR(shm))
410
+ return PTR_ERR(shm);
242411
243
- /*
244
- * Ensure offset + size does not overflow offset
245
- * and does not overflow the size of the referred
246
- * shared memory object.
247
- */
248
- if ((ip.a + ip.b) < ip.a ||
249
- (ip.a + ip.b) > shm->size) {
250
- tee_shm_put(shm);
412
+ /*
413
+ * Ensure offset + size does not overflow
414
+ * offset and does not overflow the size of
415
+ * the referred shared memory object.
416
+ */
417
+ if ((ip.a + ip.b) < ip.a ||
418
+ (ip.a + ip.b) > shm->size) {
419
+ tee_shm_put(shm);
420
+ return -EINVAL;
421
+ }
422
+ } else if (ctx->cap_memref_null) {
423
+ /* Pass NULL pointer to OP-TEE */
424
+ shm = NULL;
425
+ } else {
251426 return -EINVAL;
252427 }
253428
....@@ -329,6 +504,13 @@
329504 rc = params_from_user(ctx, params, arg.num_params, uparams);
330505 if (rc)
331506 goto out;
507
+ }
508
+
509
+ if (arg.clnt_login >= TEE_IOCTL_LOGIN_REE_KERNEL_MIN &&
510
+ arg.clnt_login <= TEE_IOCTL_LOGIN_REE_KERNEL_MAX) {
511
+ pr_debug("login method not allowed for user-space client\n");
512
+ rc = -EPERM;
513
+ goto out;
332514 }
333515
334516 rc = ctx->teedev->desc->ops->open_session(ctx, &arg, params);
....@@ -672,7 +854,7 @@
672854 .open = tee_open,
673855 .release = tee_release,
674856 .unlocked_ioctl = tee_ioctl,
675
- .compat_ioctl = tee_ioctl,
857
+ .compat_ioctl = compat_ptr_ioctl,
676858 };
677859
678860 static void tee_release_device(struct device *dev)
....@@ -756,7 +938,6 @@
756938
757939 cdev_init(&teedev->cdev, &tee_fops);
758940 teedev->cdev.owner = teedesc->owner;
759
- teedev->cdev.kobj.parent = &teedev->dev.kobj;
760941
761942 dev_set_drvdata(&teedev->dev, driver_data);
762943 device_initialize(&teedev->dev);
....@@ -802,9 +983,7 @@
802983 NULL
803984 };
804985
805
-static const struct attribute_group tee_dev_group = {
806
- .attrs = tee_dev_attrs,
807
-};
986
+ATTRIBUTE_GROUPS(tee_dev);
808987
809988 /**
810989 * tee_device_register() - Registers a TEE device
....@@ -824,39 +1003,19 @@
8241003 return -EINVAL;
8251004 }
8261005
827
- rc = cdev_add(&teedev->cdev, teedev->dev.devt, 1);
1006
+ teedev->dev.groups = tee_dev_groups;
1007
+
1008
+ rc = cdev_device_add(&teedev->cdev, &teedev->dev);
8281009 if (rc) {
8291010 dev_err(&teedev->dev,
830
- "unable to cdev_add() %s, major %d, minor %d, err=%d\n",
1011
+ "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
8311012 teedev->name, MAJOR(teedev->dev.devt),
8321013 MINOR(teedev->dev.devt), rc);
8331014 return rc;
8341015 }
8351016
836
- rc = device_add(&teedev->dev);
837
- if (rc) {
838
- dev_err(&teedev->dev,
839
- "unable to device_add() %s, major %d, minor %d, err=%d\n",
840
- teedev->name, MAJOR(teedev->dev.devt),
841
- MINOR(teedev->dev.devt), rc);
842
- goto err_device_add;
843
- }
844
-
845
- rc = sysfs_create_group(&teedev->dev.kobj, &tee_dev_group);
846
- if (rc) {
847
- dev_err(&teedev->dev,
848
- "failed to create sysfs attributes, err=%d\n", rc);
849
- goto err_sysfs_create_group;
850
- }
851
-
8521017 teedev->flags |= TEE_DEVICE_FLAG_REGISTERED;
8531018 return 0;
854
-
855
-err_sysfs_create_group:
856
- device_del(&teedev->dev);
857
-err_device_add:
858
- cdev_del(&teedev->cdev);
859
- return rc;
8601019 }
8611020 EXPORT_SYMBOL_GPL(tee_device_register);
8621021
....@@ -899,11 +1058,8 @@
8991058 if (!teedev)
9001059 return;
9011060
902
- if (teedev->flags & TEE_DEVICE_FLAG_REGISTERED) {
903
- sysfs_remove_group(&teedev->dev.kobj, &tee_dev_group);
904
- cdev_del(&teedev->cdev);
905
- device_del(&teedev->dev);
906
- }
1061
+ if (teedev->flags & TEE_DEVICE_FLAG_REGISTERED)
1062
+ cdev_device_del(&teedev->cdev, &teedev->dev);
9071063
9081064 tee_device_put(teedev);
9091065 wait_for_completion(&teedev->c_no_users);
....@@ -930,6 +1086,147 @@
9301086 }
9311087 EXPORT_SYMBOL_GPL(tee_get_drvdata);
9321088
1089
+struct match_dev_data {
1090
+ struct tee_ioctl_version_data *vers;
1091
+ const void *data;
1092
+ int (*match)(struct tee_ioctl_version_data *, const void *);
1093
+};
1094
+
1095
+static int match_dev(struct device *dev, const void *data)
1096
+{
1097
+ const struct match_dev_data *match_data = data;
1098
+ struct tee_device *teedev = container_of(dev, struct tee_device, dev);
1099
+
1100
+ teedev->desc->ops->get_version(teedev, match_data->vers);
1101
+ return match_data->match(match_data->vers, match_data->data);
1102
+}
1103
+
1104
+struct tee_context *
1105
+tee_client_open_context(struct tee_context *start,
1106
+ int (*match)(struct tee_ioctl_version_data *,
1107
+ const void *),
1108
+ const void *data, struct tee_ioctl_version_data *vers)
1109
+{
1110
+ struct device *dev = NULL;
1111
+ struct device *put_dev = NULL;
1112
+ struct tee_context *ctx = NULL;
1113
+ struct tee_ioctl_version_data v;
1114
+ struct match_dev_data match_data = { vers ? vers : &v, data, match };
1115
+
1116
+ if (start)
1117
+ dev = &start->teedev->dev;
1118
+
1119
+ do {
1120
+ dev = class_find_device(tee_class, dev, &match_data, match_dev);
1121
+ if (!dev) {
1122
+ ctx = ERR_PTR(-ENOENT);
1123
+ break;
1124
+ }
1125
+
1126
+ put_device(put_dev);
1127
+ put_dev = dev;
1128
+
1129
+ ctx = teedev_open(container_of(dev, struct tee_device, dev));
1130
+ } while (IS_ERR(ctx) && PTR_ERR(ctx) != -ENOMEM);
1131
+
1132
+ put_device(put_dev);
1133
+ /*
1134
+ * Default behaviour for in kernel client is to not wait for
1135
+ * tee-supplicant if not present for any requests in this context.
1136
+ * Also this flag could be configured again before call to
1137
+ * tee_client_open_session() if any in kernel client requires
1138
+ * different behaviour.
1139
+ */
1140
+ if (!IS_ERR(ctx))
1141
+ ctx->supp_nowait = true;
1142
+
1143
+ return ctx;
1144
+}
1145
+EXPORT_SYMBOL_GPL(tee_client_open_context);
1146
+
1147
+void tee_client_close_context(struct tee_context *ctx)
1148
+{
1149
+ teedev_close_context(ctx);
1150
+}
1151
+EXPORT_SYMBOL_GPL(tee_client_close_context);
1152
+
1153
+void tee_client_get_version(struct tee_context *ctx,
1154
+ struct tee_ioctl_version_data *vers)
1155
+{
1156
+ ctx->teedev->desc->ops->get_version(ctx->teedev, vers);
1157
+}
1158
+EXPORT_SYMBOL_GPL(tee_client_get_version);
1159
+
1160
+int tee_client_open_session(struct tee_context *ctx,
1161
+ struct tee_ioctl_open_session_arg *arg,
1162
+ struct tee_param *param)
1163
+{
1164
+ if (!ctx->teedev->desc->ops->open_session)
1165
+ return -EINVAL;
1166
+ return ctx->teedev->desc->ops->open_session(ctx, arg, param);
1167
+}
1168
+EXPORT_SYMBOL_GPL(tee_client_open_session);
1169
+
1170
+int tee_client_close_session(struct tee_context *ctx, u32 session)
1171
+{
1172
+ if (!ctx->teedev->desc->ops->close_session)
1173
+ return -EINVAL;
1174
+ return ctx->teedev->desc->ops->close_session(ctx, session);
1175
+}
1176
+EXPORT_SYMBOL_GPL(tee_client_close_session);
1177
+
1178
+int tee_client_invoke_func(struct tee_context *ctx,
1179
+ struct tee_ioctl_invoke_arg *arg,
1180
+ struct tee_param *param)
1181
+{
1182
+ if (!ctx->teedev->desc->ops->invoke_func)
1183
+ return -EINVAL;
1184
+ return ctx->teedev->desc->ops->invoke_func(ctx, arg, param);
1185
+}
1186
+EXPORT_SYMBOL_GPL(tee_client_invoke_func);
1187
+
1188
+int tee_client_cancel_req(struct tee_context *ctx,
1189
+ struct tee_ioctl_cancel_arg *arg)
1190
+{
1191
+ if (!ctx->teedev->desc->ops->cancel_req)
1192
+ return -EINVAL;
1193
+ return ctx->teedev->desc->ops->cancel_req(ctx, arg->cancel_id,
1194
+ arg->session);
1195
+}
1196
+
1197
+static int tee_client_device_match(struct device *dev,
1198
+ struct device_driver *drv)
1199
+{
1200
+ const struct tee_client_device_id *id_table;
1201
+ struct tee_client_device *tee_device;
1202
+
1203
+ id_table = to_tee_client_driver(drv)->id_table;
1204
+ tee_device = to_tee_client_device(dev);
1205
+
1206
+ while (!uuid_is_null(&id_table->uuid)) {
1207
+ if (uuid_equal(&tee_device->id.uuid, &id_table->uuid))
1208
+ return 1;
1209
+ id_table++;
1210
+ }
1211
+
1212
+ return 0;
1213
+}
1214
+
1215
+static int tee_client_device_uevent(struct device *dev,
1216
+ struct kobj_uevent_env *env)
1217
+{
1218
+ uuid_t *dev_id = &to_tee_client_device(dev)->id.uuid;
1219
+
1220
+ return add_uevent_var(env, "MODALIAS=tee:%pUb", dev_id);
1221
+}
1222
+
1223
+struct bus_type tee_bus_type = {
1224
+ .name = "tee",
1225
+ .match = tee_client_device_match,
1226
+ .uevent = tee_client_device_uevent,
1227
+};
1228
+EXPORT_SYMBOL_GPL(tee_bus_type);
1229
+
9331230 static int __init tee_init(void)
9341231 {
9351232 int rc;
....@@ -943,18 +1240,32 @@
9431240 rc = alloc_chrdev_region(&tee_devt, 0, TEE_NUM_DEVICES, "tee");
9441241 if (rc) {
9451242 pr_err("failed to allocate char dev region\n");
946
- class_destroy(tee_class);
947
- tee_class = NULL;
1243
+ goto out_unreg_class;
9481244 }
1245
+
1246
+ rc = bus_register(&tee_bus_type);
1247
+ if (rc) {
1248
+ pr_err("failed to register tee bus\n");
1249
+ goto out_unreg_chrdev;
1250
+ }
1251
+
1252
+ return 0;
1253
+
1254
+out_unreg_chrdev:
1255
+ unregister_chrdev_region(tee_devt, TEE_NUM_DEVICES);
1256
+out_unreg_class:
1257
+ class_destroy(tee_class);
1258
+ tee_class = NULL;
9491259
9501260 return rc;
9511261 }
9521262
9531263 static void __exit tee_exit(void)
9541264 {
1265
+ bus_unregister(&tee_bus_type);
1266
+ unregister_chrdev_region(tee_devt, TEE_NUM_DEVICES);
9551267 class_destroy(tee_class);
9561268 tee_class = NULL;
957
- unregister_chrdev_region(tee_devt, TEE_NUM_DEVICES);
9581269 }
9591270
9601271 subsys_initcall(tee_init);