// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2016 Intel Corporation
 *
 * Authors:
 * Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
 *
 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
 *
 * This file contains TPM2 protocol implementations of the commands
 * used by the kernel internally.
 */

#include <linux/gfp.h>
#include <asm/unaligned.h>
#include "tpm.h"

enum tpm2_handle_types {
	TPM2_HT_HMAC_SESSION	= 0x02000000,
	TPM2_HT_POLICY_SESSION	= 0x03000000,
	TPM2_HT_TRANSIENT	= 0x80000000,
};

struct tpm2_context {
	__be64 sequence;
	__be32 saved_handle;
	__be32 hierarchy;
	__be16 blob_size;
} __packed;

static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
		if (space->session_tbl[i])
			tpm2_flush_context(chip, space->session_tbl[i]);
	}
}

int tpm2_init_space(struct tpm_space *space, unsigned int buf_size)
{
	space->context_buf = kzalloc(buf_size, GFP_KERNEL);
	if (!space->context_buf)
		return -ENOMEM;

	space->session_buf = kzalloc(buf_size, GFP_KERNEL);
	if (space->session_buf == NULL) {
		kfree(space->context_buf);
		/* Prevent caller getting a dangling pointer. */
		space->context_buf = NULL;
		return -ENOMEM;
	}

	space->buf_size = buf_size;
	return 0;
}

void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space)
{

	if (tpm_try_get_ops(chip) == 0) {
		tpm2_flush_sessions(chip, space);
		tpm_put_ops(chip);
	}

	kfree(space->context_buf);
	kfree(space->session_buf);
}

static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
			     unsigned int *offset, u32 *handle)
{
	struct tpm_buf tbuf;
	struct tpm2_context *ctx;
	unsigned int body_size;
	int rc;

	rc = tpm_buf_init(&tbuf, TPM2_ST_NO_SESSIONS, TPM2_CC_CONTEXT_LOAD);
	if (rc)
		return rc;

	ctx = (struct tpm2_context *)&buf[*offset];
	body_size = sizeof(*ctx) + be16_to_cpu(ctx->blob_size);
	tpm_buf_append(&tbuf, &buf[*offset], body_size);

	rc = tpm_transmit_cmd(chip, &tbuf, 4, NULL);
	if (rc < 0) {
		dev_warn(&chip->dev, "%s: failed with a system error %d\n",
			 __func__, rc);
		tpm_buf_destroy(&tbuf);
		return -EFAULT;
	} else if (tpm2_rc_value(rc) == TPM2_RC_HANDLE ||
		   rc == TPM2_RC_REFERENCE_H0) {
		/*
		 * TPM_RC_HANDLE means that the session context can't
		 * be loaded because of an internal counter mismatch
		 * that makes the TPM think there might have been a
		 * replay.  This might happen if the context was saved
		 * and loaded outside the space.
		 *
		 * TPM_RC_REFERENCE_H0 means the session has been
		 * flushed outside the space
		 */
		*handle = 0;
		tpm_buf_destroy(&tbuf);
		return -ENOENT;
	} else if (rc > 0) {
		dev_warn(&chip->dev, "%s: failed with a TPM error 0x%04X\n",
			 __func__, rc);
		tpm_buf_destroy(&tbuf);
		return -EFAULT;
	}

	*handle = be32_to_cpup((__be32 *)&tbuf.data[TPM_HEADER_SIZE]);
	*offset += body_size;

	tpm_buf_destroy(&tbuf);
	return 0;
}

static int tpm2_save_context(struct tpm_chip *chip, u32 handle, u8 *buf,
			     unsigned int buf_size, unsigned int *offset)
{
	struct tpm_buf tbuf;
	unsigned int body_size;
	int rc;

	rc = tpm_buf_init(&tbuf, TPM2_ST_NO_SESSIONS, TPM2_CC_CONTEXT_SAVE);
	if (rc)
		return rc;

	tpm_buf_append_u32(&tbuf, handle);

	rc = tpm_transmit_cmd(chip, &tbuf, 0, NULL);
	if (rc < 0) {
		dev_warn(&chip->dev, "%s: failed with a system error %d\n",
			 __func__, rc);
		tpm_buf_destroy(&tbuf);
		return -EFAULT;
	} else if (tpm2_rc_value(rc) == TPM2_RC_REFERENCE_H0) {
		tpm_buf_destroy(&tbuf);
		return -ENOENT;
	} else if (rc) {
		dev_warn(&chip->dev, "%s: failed with a TPM error 0x%04X\n",
			 __func__, rc);
		tpm_buf_destroy(&tbuf);
		return -EFAULT;
	}

	body_size = tpm_buf_length(&tbuf) - TPM_HEADER_SIZE;
	if ((*offset + body_size) > buf_size) {
		dev_warn(&chip->dev, "%s: out of backing storage\n", __func__);
		tpm_buf_destroy(&tbuf);
		return -ENOMEM;
	}

	memcpy(&buf[*offset], &tbuf.data[TPM_HEADER_SIZE], body_size);
	*offset += body_size;
	tpm_buf_destroy(&tbuf);
	return 0;
}

void tpm2_flush_space(struct tpm_chip *chip)
{
	struct tpm_space *space = &chip->work_space;
	int i;

	for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++)
		if (space->context_tbl[i] && ~space->context_tbl[i])
			tpm2_flush_context(chip, space->context_tbl[i]);

	tpm2_flush_sessions(chip, space);
}

static int tpm2_load_space(struct tpm_chip *chip)
{
	struct tpm_space *space = &chip->work_space;
	unsigned int offset;
	int i;
	int rc;

	for (i = 0, offset = 0; i < ARRAY_SIZE(space->context_tbl); i++) {
		if (!space->context_tbl[i])
			continue;

		/* sanity check, should never happen */
		if (~space->context_tbl[i]) {
			dev_err(&chip->dev, "context table is inconsistent");
			return -EFAULT;
		}

		rc = tpm2_load_context(chip, space->context_buf, &offset,
				       &space->context_tbl[i]);
		if (rc)
			return rc;
	}

	for (i = 0, offset = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
		u32 handle;

		if (!space->session_tbl[i])
			continue;

		rc = tpm2_load_context(chip, space->session_buf,
				       &offset, &handle);
		if (rc == -ENOENT) {
			/* load failed, just forget session */
			space->session_tbl[i] = 0;
		} else if (rc) {
			tpm2_flush_space(chip);
			return rc;
		}
		if (handle != space->session_tbl[i]) {
			dev_warn(&chip->dev, "session restored to wrong handle\n");
			tpm2_flush_space(chip);
			return -EFAULT;
		}
	}

	return 0;
}

static bool tpm2_map_to_phandle(struct tpm_space *space, void *handle)
{
	u32 vhandle = be32_to_cpup((__be32 *)handle);
	u32 phandle;
	int i;

	i = 0xFFFFFF - (vhandle & 0xFFFFFF);
	if (i >= ARRAY_SIZE(space->context_tbl) || !space->context_tbl[i])
		return false;

	phandle = space->context_tbl[i];
	*((__be32 *)handle) = cpu_to_be32(phandle);
	return true;
}

static int tpm2_map_command(struct tpm_chip *chip, u32 cc, u8 *cmd)
{
	struct tpm_space *space = &chip->work_space;
	unsigned int nr_handles;
	u32 attrs;
	__be32 *handle;
	int i;

	i = tpm2_find_cc(chip, cc);
	if (i < 0)
		return -EINVAL;

	attrs = chip->cc_attrs_tbl[i];
	nr_handles = (attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0);

	handle = (__be32 *)&cmd[TPM_HEADER_SIZE];
	for (i = 0; i < nr_handles; i++, handle++) {
		if ((be32_to_cpu(*handle) & 0xFF000000) == TPM2_HT_TRANSIENT) {
			if (!tpm2_map_to_phandle(space, handle))
				return -EINVAL;
		}
	}

	return 0;
}

static int tpm_find_and_validate_cc(struct tpm_chip *chip,
				    struct tpm_space *space,
				    const void *cmd, size_t len)
{
	const struct tpm_header *header = (const void *)cmd;
	int i;
	u32 cc;
	u32 attrs;
	unsigned int nr_handles;

	if (len < TPM_HEADER_SIZE || !chip->nr_commands)
		return -EINVAL;

	cc = be32_to_cpu(header->ordinal);

	i = tpm2_find_cc(chip, cc);
	if (i < 0) {
		dev_dbg(&chip->dev, "0x%04X is an invalid command\n",
			cc);
		return -EOPNOTSUPP;
	}

	attrs = chip->cc_attrs_tbl[i];
	nr_handles =
		4 * ((attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0));
	if (len < TPM_HEADER_SIZE + 4 * nr_handles)
		goto err_len;

	return cc;
err_len:
	dev_dbg(&chip->dev, "%s: insufficient command length %zu", __func__,
		len);
	return -EINVAL;
}

int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd,
		       size_t cmdsiz)
{
	int rc;
	int cc;

	if (!space)
		return 0;

	cc = tpm_find_and_validate_cc(chip, space, cmd, cmdsiz);
	if (cc < 0)
		return cc;

	memcpy(&chip->work_space.context_tbl, &space->context_tbl,
	       sizeof(space->context_tbl));
	memcpy(&chip->work_space.session_tbl, &space->session_tbl,
	       sizeof(space->session_tbl));
	memcpy(chip->work_space.context_buf, space->context_buf,
	       space->buf_size);
	memcpy(chip->work_space.session_buf, space->session_buf,
	       space->buf_size);

	rc = tpm2_load_space(chip);
	if (rc) {
		tpm2_flush_space(chip);
		return rc;
	}

	rc = tpm2_map_command(chip, cc, cmd);
	if (rc) {
		tpm2_flush_space(chip);
		return rc;
	}

	chip->last_cc = cc;
	return 0;
}

static bool tpm2_add_session(struct tpm_chip *chip, u32 handle)
{
	struct tpm_space *space = &chip->work_space;
	int i;

	for (i = 0; i < ARRAY_SIZE(space->session_tbl); i++)
		if (space->session_tbl[i] == 0)
			break;

	if (i == ARRAY_SIZE(space->session_tbl))
		return false;

	space->session_tbl[i] = handle;
	return true;
}

static u32 tpm2_map_to_vhandle(struct tpm_space *space, u32 phandle, bool alloc)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++) {
		if (alloc) {
			if (!space->context_tbl[i]) {
				space->context_tbl[i] = phandle;
				break;
			}
		} else if (space->context_tbl[i] == phandle)
			break;
	}

	if (i == ARRAY_SIZE(space->context_tbl))
		return 0;

	return TPM2_HT_TRANSIENT | (0xFFFFFF - i);
}

static int tpm2_map_response_header(struct tpm_chip *chip, u32 cc, u8 *rsp,
				    size_t len)
{
	struct tpm_space *space = &chip->work_space;
	struct tpm_header *header = (struct tpm_header *)rsp;
	u32 phandle;
	u32 phandle_type;
	u32 vhandle;
	u32 attrs;
	int i;

	if (be32_to_cpu(header->return_code) != TPM2_RC_SUCCESS)
		return 0;

	i = tpm2_find_cc(chip, cc);
	/* sanity check, should never happen */
	if (i < 0)
		return -EFAULT;

	attrs = chip->cc_attrs_tbl[i];
	if (!((attrs >> TPM2_CC_ATTR_RHANDLE) & 1))
		return 0;

	phandle = be32_to_cpup((__be32 *)&rsp[TPM_HEADER_SIZE]);
	phandle_type = phandle & 0xFF000000;

	switch (phandle_type) {
	case TPM2_HT_TRANSIENT:
		vhandle = tpm2_map_to_vhandle(space, phandle, true);
		if (!vhandle)
			goto out_no_slots;

		*(__be32 *)&rsp[TPM_HEADER_SIZE] = cpu_to_be32(vhandle);
		break;
	case TPM2_HT_HMAC_SESSION:
	case TPM2_HT_POLICY_SESSION:
		if (!tpm2_add_session(chip, phandle))
			goto out_no_slots;
		break;
	default:
		dev_err(&chip->dev, "%s: unknown handle 0x%08X\n",
			__func__, phandle);
		break;
	}

	return 0;
out_no_slots:
	tpm2_flush_context(chip, phandle);
	dev_warn(&chip->dev, "%s: out of slots for 0x%08X\n", __func__,
		 phandle);
	return -ENOMEM;
}

struct tpm2_cap_handles {
	u8 more_data;
	__be32 capability;
	__be32 count;
	__be32 handles[];
} __packed;

static int tpm2_map_response_body(struct tpm_chip *chip, u32 cc, u8 *rsp,
				  size_t len)
{
	struct tpm_space *space = &chip->work_space;
	struct tpm_header *header = (struct tpm_header *)rsp;
	struct tpm2_cap_handles *data;
	u32 phandle;
	u32 phandle_type;
	u32 vhandle;
	int i;
	int j;

	if (cc != TPM2_CC_GET_CAPABILITY ||
	    be32_to_cpu(header->return_code) != TPM2_RC_SUCCESS) {
		return 0;
	}

	if (len < TPM_HEADER_SIZE + 9)
		return -EFAULT;

	data = (void *)&rsp[TPM_HEADER_SIZE];
	if (be32_to_cpu(data->capability) != TPM2_CAP_HANDLES)
		return 0;

	if (be32_to_cpu(data->count) > (UINT_MAX - TPM_HEADER_SIZE - 9) / 4)
		return -EFAULT;

	if (len != TPM_HEADER_SIZE + 9 + 4 * be32_to_cpu(data->count))
		return -EFAULT;

	for (i = 0, j = 0; i < be32_to_cpu(data->count); i++) {
		phandle = be32_to_cpup((__be32 *)&data->handles[i]);
		phandle_type = phandle & 0xFF000000;

		switch (phandle_type) {
		case TPM2_HT_TRANSIENT:
			vhandle = tpm2_map_to_vhandle(space, phandle, false);
			if (!vhandle)
				break;

			data->handles[j] = cpu_to_be32(vhandle);
			j++;
			break;

		default:
			data->handles[j] = cpu_to_be32(phandle);
			j++;
			break;
		}

	}

	header->length = cpu_to_be32(TPM_HEADER_SIZE + 9 + 4 * j);
	data->count = cpu_to_be32(j);
	return 0;
}

static int tpm2_save_space(struct tpm_chip *chip)
{
	struct tpm_space *space = &chip->work_space;
	unsigned int offset;
	int i;
	int rc;

	for (i = 0, offset = 0; i < ARRAY_SIZE(space->context_tbl); i++) {
		if (!(space->context_tbl[i] && ~space->context_tbl[i]))
			continue;

		rc = tpm2_save_context(chip, space->context_tbl[i],
				       space->context_buf, space->buf_size,
				       &offset);
		if (rc == -ENOENT) {
			space->context_tbl[i] = 0;
			continue;
		} else if (rc)
			return rc;

		tpm2_flush_context(chip, space->context_tbl[i]);
		space->context_tbl[i] = ~0;
	}

	for (i = 0, offset = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
		if (!space->session_tbl[i])
			continue;

		rc = tpm2_save_context(chip, space->session_tbl[i],
				       space->session_buf, space->buf_size,
				       &offset);
		if (rc == -ENOENT) {
			/* handle error saving session, just forget it */
			space->session_tbl[i] = 0;
		} else if (rc < 0) {
			tpm2_flush_space(chip);
			return rc;
		}
	}

	return 0;
}

int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
		      void *buf, size_t *bufsiz)
{
	struct tpm_header *header = buf;
	int rc;

	if (!space)
		return 0;

	rc = tpm2_map_response_header(chip, chip->last_cc, buf, *bufsiz);
	if (rc) {
		tpm2_flush_space(chip);
		goto out;
	}

	rc = tpm2_map_response_body(chip, chip->last_cc, buf, *bufsiz);
	if (rc) {
		tpm2_flush_space(chip);
		goto out;
	}

	rc = tpm2_save_space(chip);
	if (rc) {
		tpm2_flush_space(chip);
		goto out;
	}

	*bufsiz = be32_to_cpu(header->length);

	memcpy(&space->context_tbl, &chip->work_space.context_tbl,
	       sizeof(space->context_tbl));
	memcpy(&space->session_tbl, &chip->work_space.session_tbl,
	       sizeof(space->session_tbl));
	memcpy(space->context_buf, chip->work_space.context_buf,
	       space->buf_size);
	memcpy(space->session_buf, chip->work_space.session_buf,
	       space->buf_size);

	return 0;
out:
	dev_err(&chip->dev, "%s: error %d\n", __func__, rc);
	return rc;
}

/*
 * Put the reference to the main device.
 */
static void tpm_devs_release(struct device *dev)
{
	struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs);

	/* release the master device reference */
	put_device(&chip->dev);
}

/*
 * Remove the device file for exposed TPM spaces and release the device
 * reference. This may also release the reference to the master device.
 */
void tpm_devs_remove(struct tpm_chip *chip)
{
	cdev_device_del(&chip->cdevs, &chip->devs);
	put_device(&chip->devs);
}

/*
 * Add a device file to expose TPM spaces. Also take a reference to the
 * main device.
 */
int tpm_devs_add(struct tpm_chip *chip)
{
	int rc;

	device_initialize(&chip->devs);
	chip->devs.parent = chip->dev.parent;
	chip->devs.class = &tpmrm_class;

	/*
	 * Get extra reference on main device to hold on behalf of devs.
	 * This holds the chip structure while cdevs is in use. The
	 * corresponding put is in the tpm_devs_release.
	 */
	get_device(&chip->dev);
	chip->devs.release = tpm_devs_release;
	chip->devs.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES);
	cdev_init(&chip->cdevs, &tpmrm_fops);
	chip->cdevs.owner = THIS_MODULE;

	rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num);
	if (rc)
		goto err_put_devs;

	rc = cdev_device_add(&chip->cdevs, &chip->devs);
	if (rc) {
		dev_err(&chip->devs,
			"unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
			dev_name(&chip->devs), MAJOR(chip->devs.devt),
			MINOR(chip->devs.devt), rc);
		goto err_put_devs;
	}

	return 0;

err_put_devs:
	put_device(&chip->devs);

	return rc;
}
