// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) Microsoft Corporation
 *
 * Implements a firmware TPM as described here:
 * https://www.microsoft.com/en-us/research/publication/ftpm-software-implementation-tpm-chip/
 *
 * A reference implementation is available here:
 * https://github.com/microsoft/ms-tpm-20-ref/tree/master/Samples/ARM32-FirmwareTPM/optee_ta/fTPM
 */

#include <linux/acpi.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/tee_drv.h>
#include <linux/tpm.h>
#include <linux/uuid.h>

#include "tpm.h"
#include "tpm_ftpm_tee.h"

/*
 * TA_FTPM_UUID: BC50D971-D4C9-42C4-82CB-343FB7F37896
 *
 * Randomly generated, and must correspond to the GUID on the TA side.
 * Defined here in the reference implementation:
 * https://github.com/microsoft/ms-tpm-20-ref/blob/master/Samples/ARM32-FirmwareTPM/optee_ta/fTPM/include/fTPM.h#L42
 */
static const uuid_t ftpm_ta_uuid =
	UUID_INIT(0xBC50D971, 0xD4C9, 0x42C4,
		  0x82, 0xCB, 0x34, 0x3F, 0xB7, 0xF3, 0x78, 0x96);

/**
 * ftpm_tee_tpm_op_recv() - retrieve fTPM response.
 * @chip:	the tpm_chip description as specified in driver/char/tpm/tpm.h.
 * @buf:	the buffer to store data.
 * @count:	the number of bytes to read.
 *
 * Return:
 *	In case of success the number of bytes received.
 *	On failure, -errno.
 */
static int ftpm_tee_tpm_op_recv(struct tpm_chip *chip, u8 *buf, size_t count)
{
	struct ftpm_tee_private *pvt_data = dev_get_drvdata(chip->dev.parent);
	size_t len;

	len = pvt_data->resp_len;
	if (count < len) {
		dev_err(&chip->dev,
			"%s: Invalid size in recv: count=%zd, resp_len=%zd\n",
			__func__, count, len);
		return -EIO;
	}

	memcpy(buf, pvt_data->resp_buf, len);
	pvt_data->resp_len = 0;

	return len;
}

/**
 * ftpm_tee_tpm_op_send() - send TPM commands through the TEE shared memory.
 * @chip:	the tpm_chip description as specified in driver/char/tpm/tpm.h
 * @buf:	the buffer to send.
 * @len:	the number of bytes to send.
 *
 * Return:
 *	In case of success, returns 0.
 *	On failure, -errno
 */
static int ftpm_tee_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t len)
{
	struct ftpm_tee_private *pvt_data = dev_get_drvdata(chip->dev.parent);
	size_t resp_len;
	int rc;
	u8 *temp_buf;
	struct tpm_header *resp_header;
	struct tee_ioctl_invoke_arg transceive_args;
	struct tee_param command_params[4];
	struct tee_shm *shm = pvt_data->shm;

	if (len > MAX_COMMAND_SIZE) {
		dev_err(&chip->dev,
			"%s: len=%zd exceeds MAX_COMMAND_SIZE supported by fTPM TA\n",
			__func__, len);
		return -EIO;
	}

	memset(&transceive_args, 0, sizeof(transceive_args));
	memset(command_params, 0, sizeof(command_params));
	pvt_data->resp_len = 0;

	/* Invoke FTPM_OPTEE_TA_SUBMIT_COMMAND function of fTPM TA */
	transceive_args = (struct tee_ioctl_invoke_arg) {
		.func = FTPM_OPTEE_TA_SUBMIT_COMMAND,
		.session = pvt_data->session,
		.num_params = 4,
	};

	/* Fill FTPM_OPTEE_TA_SUBMIT_COMMAND parameters */
	command_params[0] = (struct tee_param) {
		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT,
		.u.memref = {
			.shm = shm,
			.size = len,
			.shm_offs = 0,
		},
	};

	temp_buf = tee_shm_get_va(shm, 0);
	if (IS_ERR(temp_buf)) {
		dev_err(&chip->dev, "%s: tee_shm_get_va failed for transmit\n",
			__func__);
		return PTR_ERR(temp_buf);
	}
	memset(temp_buf, 0, (MAX_COMMAND_SIZE + MAX_RESPONSE_SIZE));
	memcpy(temp_buf, buf, len);

	command_params[1] = (struct tee_param) {
		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT,
		.u.memref = {
			.shm = shm,
			.size = MAX_RESPONSE_SIZE,
			.shm_offs = MAX_COMMAND_SIZE,
		},
	};

	rc = tee_client_invoke_func(pvt_data->ctx, &transceive_args,
				    command_params);
	if ((rc < 0) || (transceive_args.ret != 0)) {
		dev_err(&chip->dev, "%s: SUBMIT_COMMAND invoke error: 0x%x\n",
			__func__, transceive_args.ret);
		return (rc < 0) ? rc : transceive_args.ret;
	}

	temp_buf = tee_shm_get_va(shm, command_params[1].u.memref.shm_offs);
	if (IS_ERR(temp_buf)) {
		dev_err(&chip->dev, "%s: tee_shm_get_va failed for receive\n",
			__func__);
		return PTR_ERR(temp_buf);
	}

	resp_header = (struct tpm_header *)temp_buf;
	resp_len = be32_to_cpu(resp_header->length);

	/* sanity check resp_len */
	if (resp_len < TPM_HEADER_SIZE) {
		dev_err(&chip->dev, "%s: tpm response header too small\n",
			__func__);
		return -EIO;
	}
	if (resp_len > MAX_RESPONSE_SIZE) {
		dev_err(&chip->dev,
			"%s: resp_len=%zd exceeds MAX_RESPONSE_SIZE\n",
			__func__, resp_len);
		return -EIO;
	}

	/* sanity checks look good, cache the response */
	memcpy(pvt_data->resp_buf, temp_buf, resp_len);
	pvt_data->resp_len = resp_len;

	return 0;
}

static void ftpm_tee_tpm_op_cancel(struct tpm_chip *chip)
{
	/* not supported */
}

static u8 ftpm_tee_tpm_op_status(struct tpm_chip *chip)
{
	return 0;
}

static bool ftpm_tee_tpm_req_canceled(struct tpm_chip *chip, u8 status)
{
	return false;
}

static const struct tpm_class_ops ftpm_tee_tpm_ops = {
	.flags = TPM_OPS_AUTO_STARTUP,
	.recv = ftpm_tee_tpm_op_recv,
	.send = ftpm_tee_tpm_op_send,
	.cancel = ftpm_tee_tpm_op_cancel,
	.status = ftpm_tee_tpm_op_status,
	.req_complete_mask = 0,
	.req_complete_val = 0,
	.req_canceled = ftpm_tee_tpm_req_canceled,
};

/*
 * Check whether this driver supports the fTPM TA in the TEE instance
 * represented by the params (ver/data) to this function.
 */
static int ftpm_tee_match(struct tee_ioctl_version_data *ver, const void *data)
{
	/*
	 * Currently this driver only support GP Complaint OPTEE based fTPM TA
	 */
	if ((ver->impl_id == TEE_IMPL_ID_OPTEE) &&
		(ver->gen_caps & TEE_GEN_CAP_GP))
		return 1;
	else
		return 0;
}

/**
 * ftpm_tee_probe() - initialize the fTPM
 * @dev: the device description.
 *
 * Return:
 *	On success, 0. On failure, -errno.
 */
static int ftpm_tee_probe(struct device *dev)
{
	int rc;
	struct tpm_chip *chip;
	struct ftpm_tee_private *pvt_data = NULL;
	struct tee_ioctl_open_session_arg sess_arg;

	pvt_data = devm_kzalloc(dev, sizeof(struct ftpm_tee_private),
				GFP_KERNEL);
	if (!pvt_data)
		return -ENOMEM;

	dev_set_drvdata(dev, pvt_data);

	/* Open context with TEE driver */
	pvt_data->ctx = tee_client_open_context(NULL, ftpm_tee_match, NULL,
						NULL);
	if (IS_ERR(pvt_data->ctx)) {
		if (PTR_ERR(pvt_data->ctx) == -ENOENT)
			return -EPROBE_DEFER;
		dev_err(dev, "%s: tee_client_open_context failed\n", __func__);
		return PTR_ERR(pvt_data->ctx);
	}

	/* Open a session with fTPM TA */
	memset(&sess_arg, 0, sizeof(sess_arg));
	export_uuid(sess_arg.uuid, &ftpm_ta_uuid);
	sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC;
	sess_arg.num_params = 0;

	rc = tee_client_open_session(pvt_data->ctx, &sess_arg, NULL);
	if ((rc < 0) || (sess_arg.ret != 0)) {
		dev_err(dev, "%s: tee_client_open_session failed, err=%x\n",
			__func__, sess_arg.ret);
		rc = -EINVAL;
		goto out_tee_session;
	}
	pvt_data->session = sess_arg.session;

	/* Allocate dynamic shared memory with fTPM TA */
	pvt_data->shm = tee_shm_alloc_kernel_buf(pvt_data->ctx,
						 MAX_COMMAND_SIZE +
						 MAX_RESPONSE_SIZE);
	if (IS_ERR(pvt_data->shm)) {
		dev_err(dev, "%s: tee_shm_alloc_kernel_buf failed\n", __func__);
		rc = -ENOMEM;
		goto out_shm_alloc;
	}

	/* Allocate new struct tpm_chip instance */
	chip = tpm_chip_alloc(dev, &ftpm_tee_tpm_ops);
	if (IS_ERR(chip)) {
		dev_err(dev, "%s: tpm_chip_alloc failed\n", __func__);
		rc = PTR_ERR(chip);
		goto out_chip_alloc;
	}

	pvt_data->chip = chip;
	pvt_data->chip->flags |= TPM_CHIP_FLAG_TPM2;

	/* Create a character device for the fTPM */
	rc = tpm_chip_register(pvt_data->chip);
	if (rc) {
		dev_err(dev, "%s: tpm_chip_register failed with rc=%d\n",
			__func__, rc);
		goto out_chip;
	}

	return 0;

out_chip:
	put_device(&pvt_data->chip->dev);
out_chip_alloc:
	tee_shm_free(pvt_data->shm);
out_shm_alloc:
	tee_client_close_session(pvt_data->ctx, pvt_data->session);
out_tee_session:
	tee_client_close_context(pvt_data->ctx);

	return rc;
}

static int ftpm_plat_tee_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;

	return ftpm_tee_probe(dev);
}

/**
 * ftpm_tee_remove() - remove the TPM device
 * @dev: the device description.
 *
 * Return:
 *	0 always.
 */
static int ftpm_tee_remove(struct device *dev)
{
	struct ftpm_tee_private *pvt_data = dev_get_drvdata(dev);

	/* Release the chip */
	tpm_chip_unregister(pvt_data->chip);

	/* frees chip */
	put_device(&pvt_data->chip->dev);

	/* Free the shared memory pool */
	tee_shm_free(pvt_data->shm);

	/* close the existing session with fTPM TA*/
	tee_client_close_session(pvt_data->ctx, pvt_data->session);

	/* close the context with TEE driver */
	tee_client_close_context(pvt_data->ctx);

	/* memory allocated with devm_kzalloc() is freed automatically */

	return 0;
}

static void ftpm_plat_tee_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;

	ftpm_tee_remove(dev);
}

/**
 * ftpm_plat_tee_shutdown() - shutdown the TPM device
 * @pdev: the platform_device description.
 */
static void ftpm_plat_tee_shutdown(struct platform_device *pdev)
{
	struct ftpm_tee_private *pvt_data = dev_get_drvdata(&pdev->dev);

	tee_shm_free(pvt_data->shm);
	tee_client_close_session(pvt_data->ctx, pvt_data->session);
	tee_client_close_context(pvt_data->ctx);
}

static const struct of_device_id of_ftpm_tee_ids[] = {
	{ .compatible = "microsoft,ftpm" },
	{ }
};
MODULE_DEVICE_TABLE(of, of_ftpm_tee_ids);

static struct platform_driver ftpm_tee_plat_driver = {
	.driver = {
		.name = "ftpm-tee",
		.of_match_table = of_match_ptr(of_ftpm_tee_ids),
	},
	.shutdown = ftpm_plat_tee_shutdown,
	.probe = ftpm_plat_tee_probe,
	.remove_new = ftpm_plat_tee_remove,
};

/* UUID of the fTPM TA */
static const struct tee_client_device_id optee_ftpm_id_table[] = {
	{UUID_INIT(0xbc50d971, 0xd4c9, 0x42c4,
		   0x82, 0xcb, 0x34, 0x3f, 0xb7, 0xf3, 0x78, 0x96)},
	{}
};

MODULE_DEVICE_TABLE(tee, optee_ftpm_id_table);

static struct tee_client_driver ftpm_tee_driver = {
	.id_table	= optee_ftpm_id_table,
	.driver		= {
		.name		= "optee-ftpm",
		.bus		= &tee_bus_type,
		.probe		= ftpm_tee_probe,
		.remove		= ftpm_tee_remove,
	},
};

static int __init ftpm_mod_init(void)
{
	int rc;

	rc = platform_driver_register(&ftpm_tee_plat_driver);
	if (rc)
		return rc;

	rc = driver_register(&ftpm_tee_driver.driver);
	if (rc) {
		platform_driver_unregister(&ftpm_tee_plat_driver);
		return rc;
	}

	return 0;
}

static void __exit ftpm_mod_exit(void)
{
	platform_driver_unregister(&ftpm_tee_plat_driver);
	driver_unregister(&ftpm_tee_driver.driver);
}

module_init(ftpm_mod_init);
module_exit(ftpm_mod_exit);

MODULE_AUTHOR("Thirupathaiah Annapureddy <thiruan@microsoft.com>");
MODULE_DESCRIPTION("TPM Driver for fTPM TA in TEE");
MODULE_LICENSE("GPL v2");
