1  // SPDX-License-Identifier: GPL-2.0
2  /*
3   * Greybus Component Authentication Protocol (CAP) Driver.
4   *
5   * Copyright 2016 Google Inc.
6   * Copyright 2016 Linaro Ltd.
7   */
8  
9  #include <linux/greybus.h>
10  #include <linux/cdev.h>
11  #include <linux/fs.h>
12  #include <linux/ioctl.h>
13  #include <linux/uaccess.h>
14  
15  #include "greybus_authentication.h"
16  #include "firmware.h"
17  
18  #define CAP_TIMEOUT_MS		1000
19  
20  /*
21   * Number of minor devices this driver supports.
22   * There will be exactly one required per Interface.
23   */
24  #define NUM_MINORS		U8_MAX
25  
26  struct gb_cap {
27  	struct device		*parent;
28  	struct gb_connection	*connection;
29  	struct kref		kref;
30  	struct list_head	node;
31  	bool			disabled; /* connection getting disabled */
32  
33  	struct mutex		mutex;
34  	struct cdev		cdev;
35  	struct device		*class_device;
36  	dev_t			dev_num;
37  };
38  
39  static const struct class cap_class = {
40  	.name = "gb_authenticate",
41  };
42  
43  static dev_t cap_dev_num;
44  static DEFINE_IDA(cap_minors_map);
45  static LIST_HEAD(cap_list);
46  static DEFINE_MUTEX(list_mutex);
47  
cap_kref_release(struct kref * kref)48  static void cap_kref_release(struct kref *kref)
49  {
50  	struct gb_cap *cap = container_of(kref, struct gb_cap, kref);
51  
52  	kfree(cap);
53  }
54  
55  /*
56   * All users of cap take a reference (from within list_mutex lock), before
57   * they get a pointer to play with. And the structure will be freed only after
58   * the last user has put the reference to it.
59   */
put_cap(struct gb_cap * cap)60  static void put_cap(struct gb_cap *cap)
61  {
62  	kref_put(&cap->kref, cap_kref_release);
63  }
64  
65  /* Caller must call put_cap() after using struct gb_cap */
get_cap(struct cdev * cdev)66  static struct gb_cap *get_cap(struct cdev *cdev)
67  {
68  	struct gb_cap *cap;
69  
70  	mutex_lock(&list_mutex);
71  
72  	list_for_each_entry(cap, &cap_list, node) {
73  		if (&cap->cdev == cdev) {
74  			kref_get(&cap->kref);
75  			goto unlock;
76  		}
77  	}
78  
79  	cap = NULL;
80  
81  unlock:
82  	mutex_unlock(&list_mutex);
83  
84  	return cap;
85  }
86  
cap_get_endpoint_uid(struct gb_cap * cap,u8 * euid)87  static int cap_get_endpoint_uid(struct gb_cap *cap, u8 *euid)
88  {
89  	struct gb_connection *connection = cap->connection;
90  	struct gb_cap_get_endpoint_uid_response response;
91  	int ret;
92  
93  	ret = gb_operation_sync(connection, GB_CAP_TYPE_GET_ENDPOINT_UID, NULL,
94  				0, &response, sizeof(response));
95  	if (ret) {
96  		dev_err(cap->parent, "failed to get endpoint uid (%d)\n", ret);
97  		return ret;
98  	}
99  
100  	memcpy(euid, response.uid, sizeof(response.uid));
101  
102  	return 0;
103  }
104  
cap_get_ims_certificate(struct gb_cap * cap,u32 class,u32 id,u8 * certificate,u32 * size,u8 * result)105  static int cap_get_ims_certificate(struct gb_cap *cap, u32 class, u32 id,
106  				   u8 *certificate, u32 *size, u8 *result)
107  {
108  	struct gb_connection *connection = cap->connection;
109  	struct gb_cap_get_ims_certificate_request *request;
110  	struct gb_cap_get_ims_certificate_response *response;
111  	size_t max_size = gb_operation_get_payload_size_max(connection);
112  	struct gb_operation *op;
113  	int ret;
114  
115  	op = gb_operation_create_flags(connection,
116  				       GB_CAP_TYPE_GET_IMS_CERTIFICATE,
117  				       sizeof(*request), max_size,
118  				       GB_OPERATION_FLAG_SHORT_RESPONSE,
119  				       GFP_KERNEL);
120  	if (!op)
121  		return -ENOMEM;
122  
123  	request = op->request->payload;
124  	request->certificate_class = cpu_to_le32(class);
125  	request->certificate_id = cpu_to_le32(id);
126  
127  	ret = gb_operation_request_send_sync(op);
128  	if (ret) {
129  		dev_err(cap->parent, "failed to get certificate (%d)\n", ret);
130  		goto done;
131  	}
132  
133  	response = op->response->payload;
134  	*result = response->result_code;
135  	*size = op->response->payload_size - sizeof(*response);
136  	memcpy(certificate, response->certificate, *size);
137  
138  done:
139  	gb_operation_put(op);
140  	return ret;
141  }
142  
cap_authenticate(struct gb_cap * cap,u32 auth_type,u8 * uid,u8 * challenge,u8 * result,u8 * auth_response,u32 * signature_size,u8 * signature)143  static int cap_authenticate(struct gb_cap *cap, u32 auth_type, u8 *uid,
144  			    u8 *challenge, u8 *result, u8 *auth_response,
145  			    u32 *signature_size, u8 *signature)
146  {
147  	struct gb_connection *connection = cap->connection;
148  	struct gb_cap_authenticate_request *request;
149  	struct gb_cap_authenticate_response *response;
150  	size_t max_size = gb_operation_get_payload_size_max(connection);
151  	struct gb_operation *op;
152  	int ret;
153  
154  	op = gb_operation_create_flags(connection, GB_CAP_TYPE_AUTHENTICATE,
155  				       sizeof(*request), max_size,
156  				       GB_OPERATION_FLAG_SHORT_RESPONSE,
157  				       GFP_KERNEL);
158  	if (!op)
159  		return -ENOMEM;
160  
161  	request = op->request->payload;
162  	request->auth_type = cpu_to_le32(auth_type);
163  	memcpy(request->uid, uid, sizeof(request->uid));
164  	memcpy(request->challenge, challenge, sizeof(request->challenge));
165  
166  	ret = gb_operation_request_send_sync(op);
167  	if (ret) {
168  		dev_err(cap->parent, "failed to authenticate (%d)\n", ret);
169  		goto done;
170  	}
171  
172  	response = op->response->payload;
173  	*result = response->result_code;
174  	*signature_size = op->response->payload_size - sizeof(*response);
175  	memcpy(auth_response, response->response, sizeof(response->response));
176  	memcpy(signature, response->signature, *signature_size);
177  
178  done:
179  	gb_operation_put(op);
180  	return ret;
181  }
182  
183  /* Char device fops */
184  
cap_open(struct inode * inode,struct file * file)185  static int cap_open(struct inode *inode, struct file *file)
186  {
187  	struct gb_cap *cap = get_cap(inode->i_cdev);
188  
189  	/* cap structure can't get freed until file descriptor is closed */
190  	if (cap) {
191  		file->private_data = cap;
192  		return 0;
193  	}
194  
195  	return -ENODEV;
196  }
197  
cap_release(struct inode * inode,struct file * file)198  static int cap_release(struct inode *inode, struct file *file)
199  {
200  	struct gb_cap *cap = file->private_data;
201  
202  	put_cap(cap);
203  	return 0;
204  }
205  
cap_ioctl(struct gb_cap * cap,unsigned int cmd,void __user * buf)206  static int cap_ioctl(struct gb_cap *cap, unsigned int cmd,
207  		     void __user *buf)
208  {
209  	struct cap_ioc_get_endpoint_uid endpoint_uid;
210  	struct cap_ioc_get_ims_certificate *ims_cert;
211  	struct cap_ioc_authenticate *authenticate;
212  	size_t size;
213  	int ret;
214  
215  	switch (cmd) {
216  	case CAP_IOC_GET_ENDPOINT_UID:
217  		ret = cap_get_endpoint_uid(cap, endpoint_uid.uid);
218  		if (ret)
219  			return ret;
220  
221  		if (copy_to_user(buf, &endpoint_uid, sizeof(endpoint_uid)))
222  			return -EFAULT;
223  
224  		return 0;
225  	case CAP_IOC_GET_IMS_CERTIFICATE:
226  		size = sizeof(*ims_cert);
227  		ims_cert = memdup_user(buf, size);
228  		if (IS_ERR(ims_cert))
229  			return PTR_ERR(ims_cert);
230  
231  		ret = cap_get_ims_certificate(cap, ims_cert->certificate_class,
232  					      ims_cert->certificate_id,
233  					      ims_cert->certificate,
234  					      &ims_cert->cert_size,
235  					      &ims_cert->result_code);
236  		if (!ret && copy_to_user(buf, ims_cert, size))
237  			ret = -EFAULT;
238  		kfree(ims_cert);
239  
240  		return ret;
241  	case CAP_IOC_AUTHENTICATE:
242  		size = sizeof(*authenticate);
243  		authenticate = memdup_user(buf, size);
244  		if (IS_ERR(authenticate))
245  			return PTR_ERR(authenticate);
246  
247  		ret = cap_authenticate(cap, authenticate->auth_type,
248  				       authenticate->uid,
249  				       authenticate->challenge,
250  				       &authenticate->result_code,
251  				       authenticate->response,
252  				       &authenticate->signature_size,
253  				       authenticate->signature);
254  		if (!ret && copy_to_user(buf, authenticate, size))
255  			ret = -EFAULT;
256  		kfree(authenticate);
257  
258  		return ret;
259  	default:
260  		return -ENOTTY;
261  	}
262  }
263  
cap_ioctl_unlocked(struct file * file,unsigned int cmd,unsigned long arg)264  static long cap_ioctl_unlocked(struct file *file, unsigned int cmd,
265  			       unsigned long arg)
266  {
267  	struct gb_cap *cap = file->private_data;
268  	struct gb_bundle *bundle = cap->connection->bundle;
269  	int ret = -ENODEV;
270  
271  	/*
272  	 * Serialize ioctls.
273  	 *
274  	 * We don't want the user to do multiple authentication operations in
275  	 * parallel.
276  	 *
277  	 * This is also used to protect ->disabled, which is used to check if
278  	 * the connection is getting disconnected, so that we don't start any
279  	 * new operations.
280  	 */
281  	mutex_lock(&cap->mutex);
282  	if (!cap->disabled) {
283  		ret = gb_pm_runtime_get_sync(bundle);
284  		if (!ret) {
285  			ret = cap_ioctl(cap, cmd, (void __user *)arg);
286  			gb_pm_runtime_put_autosuspend(bundle);
287  		}
288  	}
289  	mutex_unlock(&cap->mutex);
290  
291  	return ret;
292  }
293  
294  static const struct file_operations cap_fops = {
295  	.owner		= THIS_MODULE,
296  	.open		= cap_open,
297  	.release	= cap_release,
298  	.unlocked_ioctl	= cap_ioctl_unlocked,
299  };
300  
gb_cap_connection_init(struct gb_connection * connection)301  int gb_cap_connection_init(struct gb_connection *connection)
302  {
303  	struct gb_cap *cap;
304  	int ret, minor;
305  
306  	if (!connection)
307  		return 0;
308  
309  	cap = kzalloc(sizeof(*cap), GFP_KERNEL);
310  	if (!cap)
311  		return -ENOMEM;
312  
313  	cap->parent = &connection->bundle->dev;
314  	cap->connection = connection;
315  	mutex_init(&cap->mutex);
316  	gb_connection_set_data(connection, cap);
317  	kref_init(&cap->kref);
318  
319  	mutex_lock(&list_mutex);
320  	list_add(&cap->node, &cap_list);
321  	mutex_unlock(&list_mutex);
322  
323  	ret = gb_connection_enable(connection);
324  	if (ret)
325  		goto err_list_del;
326  
327  	minor = ida_alloc_max(&cap_minors_map, NUM_MINORS - 1, GFP_KERNEL);
328  	if (minor < 0) {
329  		ret = minor;
330  		goto err_connection_disable;
331  	}
332  
333  	/* Add a char device to allow userspace to interact with cap */
334  	cap->dev_num = MKDEV(MAJOR(cap_dev_num), minor);
335  	cdev_init(&cap->cdev, &cap_fops);
336  
337  	ret = cdev_add(&cap->cdev, cap->dev_num, 1);
338  	if (ret)
339  		goto err_remove_ida;
340  
341  	/* Add a soft link to the previously added char-dev within the bundle */
342  	cap->class_device = device_create(&cap_class, cap->parent, cap->dev_num,
343  					  NULL, "gb-authenticate-%d", minor);
344  	if (IS_ERR(cap->class_device)) {
345  		ret = PTR_ERR(cap->class_device);
346  		goto err_del_cdev;
347  	}
348  
349  	return 0;
350  
351  err_del_cdev:
352  	cdev_del(&cap->cdev);
353  err_remove_ida:
354  	ida_free(&cap_minors_map, minor);
355  err_connection_disable:
356  	gb_connection_disable(connection);
357  err_list_del:
358  	mutex_lock(&list_mutex);
359  	list_del(&cap->node);
360  	mutex_unlock(&list_mutex);
361  
362  	put_cap(cap);
363  
364  	return ret;
365  }
366  
gb_cap_connection_exit(struct gb_connection * connection)367  void gb_cap_connection_exit(struct gb_connection *connection)
368  {
369  	struct gb_cap *cap;
370  
371  	if (!connection)
372  		return;
373  
374  	cap = gb_connection_get_data(connection);
375  
376  	device_destroy(&cap_class, cap->dev_num);
377  	cdev_del(&cap->cdev);
378  	ida_free(&cap_minors_map, MINOR(cap->dev_num));
379  
380  	/*
381  	 * Disallow any new ioctl operations on the char device and wait for
382  	 * existing ones to finish.
383  	 */
384  	mutex_lock(&cap->mutex);
385  	cap->disabled = true;
386  	mutex_unlock(&cap->mutex);
387  
388  	/* All pending greybus operations should have finished by now */
389  	gb_connection_disable(cap->connection);
390  
391  	/* Disallow new users to get access to the cap structure */
392  	mutex_lock(&list_mutex);
393  	list_del(&cap->node);
394  	mutex_unlock(&list_mutex);
395  
396  	/*
397  	 * All current users of cap would have taken a reference to it by
398  	 * now, we can drop our reference and wait the last user will get
399  	 * cap freed.
400  	 */
401  	put_cap(cap);
402  }
403  
cap_init(void)404  int cap_init(void)
405  {
406  	int ret;
407  
408  	ret = class_register(&cap_class);
409  	if (ret)
410  		return ret;
411  
412  	ret = alloc_chrdev_region(&cap_dev_num, 0, NUM_MINORS,
413  				  "gb_authenticate");
414  	if (ret)
415  		goto err_remove_class;
416  
417  	return 0;
418  
419  err_remove_class:
420  	class_unregister(&cap_class);
421  	return ret;
422  }
423  
cap_exit(void)424  void cap_exit(void)
425  {
426  	unregister_chrdev_region(cap_dev_num, NUM_MINORS);
427  	class_unregister(&cap_class);
428  	ida_destroy(&cap_minors_map);
429  }
430