// 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
 * @pdev: the platform_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
 * @pdev: the platform_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_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");
