/*
 * Greybus Component Authentication Protocol (CAP) Driver.
 *
 * Copyright 2016 Google Inc.
 * Copyright 2016 Linaro Ltd.
 *
 * Released under the GPLv2 only.
 */

#include "greybus.h"

#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>

#include "greybus_authentication.h"
#include "firmware.h"

#define CAP_TIMEOUT_MS		1000

/*
 * Number of minor devices this driver supports.
 * There will be exactly one required per Interface.
 */
#define NUM_MINORS		U8_MAX

struct gb_cap {
	struct device		*parent;
	struct gb_connection	*connection;
	struct kref		kref;
	struct list_head	node;
	bool			disabled; /* connection getting disabled */

	struct mutex		mutex;
	struct cdev		cdev;
	struct device		*class_device;
	dev_t			dev_num;
};

static struct class *cap_class;
static dev_t cap_dev_num;
static DEFINE_IDA(cap_minors_map);
static LIST_HEAD(cap_list);
static DEFINE_MUTEX(list_mutex);

static void cap_kref_release(struct kref *kref)
{
	struct gb_cap *cap = container_of(kref, struct gb_cap, kref);

	kfree(cap);
}

/*
 * All users of cap take a reference (from within list_mutex lock), before
 * they get a pointer to play with. And the structure will be freed only after
 * the last user has put the reference to it.
 */
static void put_cap(struct gb_cap *cap)
{
	kref_put(&cap->kref, cap_kref_release);
}

/* Caller must call put_cap() after using struct gb_cap */
static struct gb_cap *get_cap(struct cdev *cdev)
{
	struct gb_cap *cap;

	mutex_lock(&list_mutex);

	list_for_each_entry(cap, &cap_list, node) {
		if (&cap->cdev == cdev) {
			kref_get(&cap->kref);
			goto unlock;
		}
	}

	cap = NULL;

unlock:
	mutex_unlock(&list_mutex);

	return cap;
}

static int cap_get_endpoint_uid(struct gb_cap *cap, u8 *euid)
{
	struct gb_connection *connection = cap->connection;
	struct gb_cap_get_endpoint_uid_response response;
	int ret;

	ret = gb_operation_sync(connection, GB_CAP_TYPE_GET_ENDPOINT_UID, NULL,
				0, &response, sizeof(response));
	if (ret) {
		dev_err(cap->parent, "failed to get endpoint uid (%d)\n", ret);
		return ret;
	}

	memcpy(euid, response.uid, sizeof(response.uid));

	return 0;
}

static int cap_get_ims_certificate(struct gb_cap *cap, u32 class, u32 id,
				   u8 *certificate, u32 *size, u8 *result)
{
	struct gb_connection *connection = cap->connection;
	struct gb_cap_get_ims_certificate_request *request;
	struct gb_cap_get_ims_certificate_response *response;
	size_t max_size = gb_operation_get_payload_size_max(connection);
	struct gb_operation *op;
	int ret;

	op = gb_operation_create_flags(connection,
				       GB_CAP_TYPE_GET_IMS_CERTIFICATE,
				       sizeof(*request), max_size,
				       GB_OPERATION_FLAG_SHORT_RESPONSE,
				       GFP_KERNEL);
	if (!op)
		return -ENOMEM;

	request = op->request->payload;
	request->certificate_class = cpu_to_le32(class);
	request->certificate_id = cpu_to_le32(id);

	ret = gb_operation_request_send_sync(op);
	if (ret) {
		dev_err(cap->parent, "failed to get certificate (%d)\n", ret);
		goto done;
	}

	response = op->response->payload;
	*result = response->result_code;
	*size = op->response->payload_size - sizeof(*response);
	memcpy(certificate, response->certificate, *size);

done:
	gb_operation_put(op);
	return ret;
}

static int cap_authenticate(struct gb_cap *cap, u32 auth_type, u8 *uid,
			    u8 *challenge, u8 *result, u8 *auth_response,
			    u32 *signature_size, u8 *signature)
{
	struct gb_connection *connection = cap->connection;
	struct gb_cap_authenticate_request *request;
	struct gb_cap_authenticate_response *response;
	size_t max_size = gb_operation_get_payload_size_max(connection);
	struct gb_operation *op;
	int ret;

	op = gb_operation_create_flags(connection, GB_CAP_TYPE_AUTHENTICATE,
				       sizeof(*request), max_size,
				       GB_OPERATION_FLAG_SHORT_RESPONSE,
				       GFP_KERNEL);
	if (!op)
		return -ENOMEM;

	request = op->request->payload;
	request->auth_type = cpu_to_le32(auth_type);
	memcpy(request->uid, uid, sizeof(request->uid));
	memcpy(request->challenge, challenge, sizeof(request->challenge));

	ret = gb_operation_request_send_sync(op);
	if (ret) {
		dev_err(cap->parent, "failed to authenticate (%d)\n", ret);
		goto done;
	}

	response = op->response->payload;
	*result = response->result_code;
	*signature_size = op->response->payload_size - sizeof(*response);
	memcpy(auth_response, response->response, sizeof(response->response));
	memcpy(signature, response->signature, *signature_size);

done:
	gb_operation_put(op);
	return ret;
}

/* Char device fops */

static int cap_open(struct inode *inode, struct file *file)
{
	struct gb_cap *cap = get_cap(inode->i_cdev);

	/* cap structure can't get freed until file descriptor is closed */
	if (cap) {
		file->private_data = cap;
		return 0;
	}

	return -ENODEV;
}

static int cap_release(struct inode *inode, struct file *file)
{
	struct gb_cap *cap = file->private_data;

	put_cap(cap);
	return 0;
}

static int cap_ioctl(struct gb_cap *cap, unsigned int cmd,
			 void __user *buf)
{
	struct cap_ioc_get_endpoint_uid endpoint_uid;
	struct cap_ioc_get_ims_certificate *ims_cert;
	struct cap_ioc_authenticate *authenticate;
	size_t size;
	int ret;

	switch (cmd) {
	case CAP_IOC_GET_ENDPOINT_UID:
		ret = cap_get_endpoint_uid(cap, endpoint_uid.uid);
		if (ret)
			return ret;

		if (copy_to_user(buf, &endpoint_uid, sizeof(endpoint_uid)))
			return -EFAULT;

		return 0;
	case CAP_IOC_GET_IMS_CERTIFICATE:
		size = sizeof(*ims_cert);
		ims_cert = memdup_user(buf, size);
		if (IS_ERR(ims_cert))
			return PTR_ERR(ims_cert);

		ret = cap_get_ims_certificate(cap, ims_cert->certificate_class,
					      ims_cert->certificate_id,
					      ims_cert->certificate,
					      &ims_cert->cert_size,
					      &ims_cert->result_code);
		if (!ret && copy_to_user(buf, ims_cert, size))
			ret = -EFAULT;
		kfree(ims_cert);

		return ret;
	case CAP_IOC_AUTHENTICATE:
		size = sizeof(*authenticate);
		authenticate = memdup_user(buf, size);
		if (IS_ERR(authenticate))
			return PTR_ERR(authenticate);

		ret = cap_authenticate(cap, authenticate->auth_type,
				       authenticate->uid,
				       authenticate->challenge,
				       &authenticate->result_code,
				       authenticate->response,
				       &authenticate->signature_size,
				       authenticate->signature);
		if (!ret && copy_to_user(buf, authenticate, size))
			ret = -EFAULT;
		kfree(authenticate);

		return ret;
	default:
		return -ENOTTY;
	}
}

static long cap_ioctl_unlocked(struct file *file, unsigned int cmd,
			       unsigned long arg)
{
	struct gb_cap *cap = file->private_data;
	struct gb_bundle *bundle = cap->connection->bundle;
	int ret = -ENODEV;

	/*
	 * Serialize ioctls.
	 *
	 * We don't want the user to do multiple authentication operations in
	 * parallel.
	 *
	 * This is also used to protect ->disabled, which is used to check if
	 * the connection is getting disconnected, so that we don't start any
	 * new operations.
	 */
	mutex_lock(&cap->mutex);
	if (!cap->disabled) {
		ret = gb_pm_runtime_get_sync(bundle);
		if (!ret) {
			ret = cap_ioctl(cap, cmd, (void __user *)arg);
			gb_pm_runtime_put_autosuspend(bundle);
		}
	}
	mutex_unlock(&cap->mutex);

	return ret;
}

static const struct file_operations cap_fops = {
	.owner		= THIS_MODULE,
	.open		= cap_open,
	.release	= cap_release,
	.unlocked_ioctl	= cap_ioctl_unlocked,
};

int gb_cap_connection_init(struct gb_connection *connection)
{
	struct gb_cap *cap;
	int ret, minor;

	if (!connection)
		return 0;

	cap = kzalloc(sizeof(*cap), GFP_KERNEL);
	if (!cap)
		return -ENOMEM;

	cap->parent = &connection->bundle->dev;
	cap->connection = connection;
	mutex_init(&cap->mutex);
	gb_connection_set_data(connection, cap);
	kref_init(&cap->kref);

	mutex_lock(&list_mutex);
	list_add(&cap->node, &cap_list);
	mutex_unlock(&list_mutex);

	ret = gb_connection_enable(connection);
	if (ret)
		goto err_list_del;

	minor = ida_simple_get(&cap_minors_map, 0, NUM_MINORS, GFP_KERNEL);
	if (minor < 0) {
		ret = minor;
		goto err_connection_disable;
	}

	/* Add a char device to allow userspace to interact with cap */
	cap->dev_num = MKDEV(MAJOR(cap_dev_num), minor);
	cdev_init(&cap->cdev, &cap_fops);

	ret = cdev_add(&cap->cdev, cap->dev_num, 1);
	if (ret)
		goto err_remove_ida;

	/* Add a soft link to the previously added char-dev within the bundle */
	cap->class_device = device_create(cap_class, cap->parent, cap->dev_num,
					  NULL, "gb-authenticate-%d", minor);
	if (IS_ERR(cap->class_device)) {
		ret = PTR_ERR(cap->class_device);
		goto err_del_cdev;
	}

	return 0;

err_del_cdev:
	cdev_del(&cap->cdev);
err_remove_ida:
	ida_simple_remove(&cap_minors_map, minor);
err_connection_disable:
	gb_connection_disable(connection);
err_list_del:
	mutex_lock(&list_mutex);
	list_del(&cap->node);
	mutex_unlock(&list_mutex);

	put_cap(cap);

	return ret;
}

void gb_cap_connection_exit(struct gb_connection *connection)
{
	struct gb_cap *cap;

	if (!connection)
		return;

	cap = gb_connection_get_data(connection);

	device_destroy(cap_class, cap->dev_num);
	cdev_del(&cap->cdev);
	ida_simple_remove(&cap_minors_map, MINOR(cap->dev_num));

	/*
	 * Disallow any new ioctl operations on the char device and wait for
	 * existing ones to finish.
	 */
	mutex_lock(&cap->mutex);
	cap->disabled = true;
	mutex_unlock(&cap->mutex);

	/* All pending greybus operations should have finished by now */
	gb_connection_disable(cap->connection);

	/* Disallow new users to get access to the cap structure */
	mutex_lock(&list_mutex);
	list_del(&cap->node);
	mutex_unlock(&list_mutex);

	/*
	 * All current users of cap would have taken a reference to it by
	 * now, we can drop our reference and wait the last user will get
	 * cap freed.
	 */
	put_cap(cap);
}

int cap_init(void)
{
	int ret;

	cap_class = class_create(THIS_MODULE, "gb_authenticate");
	if (IS_ERR(cap_class))
		return PTR_ERR(cap_class);

	ret = alloc_chrdev_region(&cap_dev_num, 0, NUM_MINORS,
				  "gb_authenticate");
	if (ret)
		goto err_remove_class;

	return 0;

err_remove_class:
	class_destroy(cap_class);
	return ret;
}

void cap_exit(void)
{
	unregister_chrdev_region(cap_dev_num, NUM_MINORS);
	class_destroy(cap_class);
	ida_destroy(&cap_minors_map);
}
