/*
 * (C) Copyright 2013
 * Reinhard Pfau, Guntermann & Drunck GmbH, reinhard.pfau@gdsys.cc
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <malloc.h>
#include <fs.h>
#include <i2c.h>
#include <mmc.h>
#include <tpm.h>
#include <u-boot/sha1.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
#include <pca9698.h>

#include "hre.h"

/* other constants */
enum {
	ESDHC_BOOT_IMAGE_SIG_OFS	= 0x40,
	ESDHC_BOOT_IMAGE_SIZE_OFS	= 0x48,
	ESDHC_BOOT_IMAGE_ADDR_OFS	= 0x50,
	ESDHC_BOOT_IMAGE_TARGET_OFS	= 0x58,
	ESDHC_BOOT_IMAGE_ENTRY_OFS	= 0x60,
};

enum {
	I2C_SOC_0 = 0,
	I2C_SOC_1 = 1,
};

enum access_mode {
	HREG_NONE	= 0,
	HREG_RD		= 1,
	HREG_WR		= 2,
	HREG_RDWR	= 3,
};

/* register constants */
enum {
	FIX_HREG_DEVICE_ID_HASH	= 0,
	FIX_HREG_UNUSED1	= 1,
	FIX_HREG_UNUSED2	= 2,
	FIX_HREG_VENDOR		= 3,
	COUNT_FIX_HREGS
};

static struct h_reg pcr_hregs[24];
static struct h_reg fix_hregs[COUNT_FIX_HREGS];
static struct h_reg var_hregs[8];

/* hre opcodes */
enum {
	/* opcodes w/o data */
	HRE_NOP		= 0x00,
	HRE_SYNC	= HRE_NOP,
	HRE_CHECK0	= 0x01,
	/* opcodes w/o data, w/ sync dst */
	/* opcodes w/ data */
	HRE_LOAD	= 0x81,
	/* opcodes w/data, w/sync dst */
	HRE_XOR		= 0xC1,
	HRE_AND		= 0xC2,
	HRE_OR		= 0xC3,
	HRE_EXTEND	= 0xC4,
	HRE_LOADKEY	= 0xC5,
};

/* hre errors */
enum {
	HRE_E_OK	= 0,
	HRE_E_TPM_FAILURE,
	HRE_E_INVALID_HREG,
};

static uint64_t device_id;
static uint64_t device_cl;
static uint64_t device_type;

static uint32_t platform_key_handle;

static uint32_t hre_tpm_err;
static int hre_err = HRE_E_OK;

#define IS_PCR_HREG(spec) ((spec) & 0x20)
#define IS_FIX_HREG(spec) (((spec) & 0x38) == 0x08)
#define IS_VAR_HREG(spec) (((spec) & 0x38) == 0x10)
#define HREG_IDX(spec) ((spec) & (IS_PCR_HREG(spec) ? 0x1f : 0x7))

static const uint8_t vendor[] = "Guntermann & Drunck";

/**
 * @brief get the size of a given (TPM) NV area
 * @param index	NV index of the area to get size for
 * @param size	pointer to the size
 * @return 0 on success, != 0 on error
 */
static int get_tpm_nv_size(uint32_t index, uint32_t *size)
{
	uint32_t err;
	uint8_t info[72];
	uint8_t *ptr;
	uint16_t v16;

	err = tpm_get_capability(TPM_CAP_NV_INDEX, index,
		info, sizeof(info));
	if (err) {
		printf("tpm_get_capability(CAP_NV_INDEX, %08x) failed: %u\n",
		       index, err);
		return 1;
	}

	/* skip tag and nvIndex */
	ptr = info + 6;
	/* skip 2 pcr info fields */
	v16 = get_unaligned_be16(ptr);
	ptr += 2 + v16 + 1 + 20;
	v16 = get_unaligned_be16(ptr);
	ptr += 2 + v16 + 1 + 20;
	/* skip permission and flags */
	ptr += 6 + 3;

	*size = get_unaligned_be32(ptr);
	return 0;
}

/**
 * @brief search for a key by usage auth and pub key hash.
 * @param auth	usage auth of the key to search for
 * @param pubkey_digest	(SHA1) hash of the pub key structure of the key
 * @param[out] handle	the handle of the key iff found
 * @return 0 if key was found in TPM; != 0 if not.
 */
static int find_key(const uint8_t auth[20], const uint8_t pubkey_digest[20],
		uint32_t *handle)
{
	uint16_t key_count;
	uint32_t key_handles[10];
	uint8_t buf[288];
	uint8_t *ptr;
	uint32_t err;
	uint8_t digest[20];
	size_t buf_len;
	unsigned int i;

	/* fetch list of already loaded keys in the TPM */
	err = tpm_get_capability(TPM_CAP_HANDLE, TPM_RT_KEY, buf, sizeof(buf));
	if (err)
		return -1;
	key_count = get_unaligned_be16(buf);
	ptr = buf + 2;
	for (i = 0; i < key_count; ++i, ptr += 4)
		key_handles[i] = get_unaligned_be32(ptr);

	/* now search a(/ the) key which we can access with the given auth */
	for (i = 0; i < key_count; ++i) {
		buf_len = sizeof(buf);
		err = tpm_get_pub_key_oiap(key_handles[i], auth, buf, &buf_len);
		if (err && err != TPM_AUTHFAIL)
			return -1;
		if (err)
			continue;
		sha1_csum(buf, buf_len, digest);
		if (!memcmp(digest, pubkey_digest, 20)) {
			*handle = key_handles[i];
			return 0;
		}
	}
	return 1;
}

/**
 * @brief read CCDM common data from TPM NV
 * @return 0 if CCDM common data was found and read, !=0 if something failed.
 */
static int read_common_data(void)
{
	uint32_t size = 0;
	uint32_t err;
	uint8_t buf[256];
	sha1_context ctx;

	if (get_tpm_nv_size(NV_COMMON_DATA_INDEX, &size) ||
	    size < NV_COMMON_DATA_MIN_SIZE)
		return 1;
	err = tpm_nv_read_value(NV_COMMON_DATA_INDEX,
		buf, min(sizeof(buf), size));
	if (err) {
		printf("tpm_nv_read_value() failed: %u\n", err);
		return 1;
	}

	device_id = get_unaligned_be64(buf);
	device_cl = get_unaligned_be64(buf + 8);
	device_type = get_unaligned_be64(buf + 16);

	sha1_starts(&ctx);
	sha1_update(&ctx, buf, 24);
	sha1_finish(&ctx, fix_hregs[FIX_HREG_DEVICE_ID_HASH].digest);
	fix_hregs[FIX_HREG_DEVICE_ID_HASH].valid = true;

	platform_key_handle = get_unaligned_be32(buf + 24);

	return 0;
}

/**
 * @brief get pointer to  hash register by specification
 * @param spec	specification of a hash register
 * @return pointer to hash register or NULL if @a spec does not qualify a
 * valid hash register; NULL else.
 */
static struct h_reg *get_hreg(uint8_t spec)
{
	uint8_t idx;

	idx = HREG_IDX(spec);
	if (IS_FIX_HREG(spec)) {
		if (idx < ARRAY_SIZE(fix_hregs))
			return fix_hregs + idx;
		hre_err = HRE_E_INVALID_HREG;
	} else if (IS_PCR_HREG(spec)) {
		if (idx < ARRAY_SIZE(pcr_hregs))
			return pcr_hregs + idx;
		hre_err = HRE_E_INVALID_HREG;
	} else if (IS_VAR_HREG(spec)) {
		if (idx < ARRAY_SIZE(var_hregs))
			return var_hregs + idx;
		hre_err = HRE_E_INVALID_HREG;
	}
	return NULL;
}

/**
 * @brief get pointer of a hash register by specification and usage.
 * @param spec	specification of a hash register
 * @param mode	access mode (read or write or read/write)
 * @return pointer to hash register if found and valid; NULL else.
 *
 * This func uses @a get_reg() to determine the hash register for a given spec.
 * If a register is found it is validated according to the desired access mode.
 * The value of automatic registers (PCR register and fixed registers) is
 * loaded or computed on read access.
 */
static struct h_reg *access_hreg(uint8_t spec, enum access_mode mode)
{
	struct h_reg *result;

	result = get_hreg(spec);
	if (!result)
		return NULL;

	if (mode & HREG_WR) {
		if (IS_FIX_HREG(spec)) {
			hre_err = HRE_E_INVALID_HREG;
			return NULL;
		}
	}
	if (mode & HREG_RD) {
		if (!result->valid) {
			if (IS_PCR_HREG(spec)) {
				hre_tpm_err = tpm_pcr_read(HREG_IDX(spec),
					result->digest, 20);
				result->valid = (hre_tpm_err == TPM_SUCCESS);
			} else if (IS_FIX_HREG(spec)) {
				switch (HREG_IDX(spec)) {
				case FIX_HREG_DEVICE_ID_HASH:
					read_common_data();
					break;
				case FIX_HREG_VENDOR:
					memcpy(result->digest, vendor, 20);
					result->valid = true;
					break;
				}
			} else {
				result->valid = true;
			}
		}
		if (!result->valid) {
			hre_err = HRE_E_INVALID_HREG;
			return NULL;
		}
	}

	return result;
}

static void *compute_and(void *_dst, const void *_src, size_t n)
{
	uint8_t *dst = _dst;
	const uint8_t *src = _src;
	size_t i;

	for (i = n; i-- > 0; )
		*dst++ &= *src++;

	return _dst;
}

static void *compute_or(void *_dst, const void *_src, size_t n)
{
	uint8_t *dst = _dst;
	const uint8_t *src = _src;
	size_t i;

	for (i = n; i-- > 0; )
		*dst++ |= *src++;

	return _dst;
}

static void *compute_xor(void *_dst, const void *_src, size_t n)
{
	uint8_t *dst = _dst;
	const uint8_t *src = _src;
	size_t i;

	for (i = n; i-- > 0; )
		*dst++ ^= *src++;

	return _dst;
}

static void *compute_extend(void *_dst, const void *_src, size_t n)
{
	uint8_t digest[20];
	sha1_context ctx;

	sha1_starts(&ctx);
	sha1_update(&ctx, _dst, n);
	sha1_update(&ctx, _src, n);
	sha1_finish(&ctx, digest);
	memcpy(_dst, digest, min(n, sizeof(digest)));

	return _dst;
}

static int hre_op_loadkey(struct h_reg *src_reg, struct h_reg *dst_reg,
		const void *key, size_t key_size)
{
	uint32_t parent_handle;
	uint32_t key_handle;

	if (!src_reg || !dst_reg || !src_reg->valid || !dst_reg->valid)
		return -1;
	if (find_key(src_reg->digest, dst_reg->digest, &parent_handle))
		return -1;
	hre_tpm_err = tpm_load_key2_oiap(parent_handle, key, key_size,
		src_reg->digest, &key_handle);
	if (hre_tpm_err) {
		hre_err = HRE_E_TPM_FAILURE;
		return -1;
	}

	return 0;
}

/**
 * @brief executes the next opcode on the hash register engine.
 * @param[in,out] ip	pointer to the opcode (instruction pointer)
 * @param[in,out] code_size	(remaining) size of the code
 * @return new instruction pointer on success, NULL on error.
 */
static const uint8_t *hre_execute_op(const uint8_t **ip, size_t *code_size)
{
	bool dst_modified = false;
	uint32_t ins;
	uint8_t opcode;
	uint8_t src_spec;
	uint8_t dst_spec;
	uint16_t data_size;
	struct h_reg *src_reg, *dst_reg;
	uint8_t buf[20];
	const uint8_t *src_buf, *data;
	uint8_t *ptr;
	int i;
	void * (*bin_func)(void *, const void *, size_t);

	if (*code_size < 4)
		return NULL;

	ins = get_unaligned_be32(*ip);
	opcode = **ip;
	data = *ip + 4;
	src_spec = (ins >> 18) & 0x3f;
	dst_spec = (ins >> 12) & 0x3f;
	data_size = (ins & 0x7ff);

	debug("HRE: ins=%08x (op=%02x, s=%02x, d=%02x, L=%d)\n", ins,
	      opcode, src_spec, dst_spec, data_size);

	if ((opcode & 0x80) && (data_size + 4) > *code_size)
		return NULL;

	src_reg = access_hreg(src_spec, HREG_RD);
	if (hre_err || hre_tpm_err)
		return NULL;
	dst_reg = access_hreg(dst_spec, (opcode & 0x40) ? HREG_RDWR : HREG_WR);
	if (hre_err || hre_tpm_err)
		return NULL;

	switch (opcode) {
	case HRE_NOP:
		goto end;
	case HRE_CHECK0:
		if (src_reg) {
			for (i = 0; i < 20; ++i) {
				if (src_reg->digest[i])
					return NULL;
			}
		}
		break;
	case HRE_LOAD:
		bin_func = memcpy;
		goto do_bin_func;
	case HRE_XOR:
		bin_func = compute_xor;
		goto do_bin_func;
	case HRE_AND:
		bin_func = compute_and;
		goto do_bin_func;
	case HRE_OR:
		bin_func = compute_or;
		goto do_bin_func;
	case HRE_EXTEND:
		bin_func = compute_extend;
do_bin_func:
		if (!dst_reg)
			return NULL;
		if (src_reg) {
			src_buf = src_reg->digest;
		} else {
			if (!data_size) {
				memset(buf, 0, 20);
				src_buf = buf;
			} else if (data_size == 1) {
				memset(buf, *data, 20);
				src_buf = buf;
			} else if (data_size >= 20) {
				src_buf = data;
			} else {
				src_buf = buf;
				for (ptr = (uint8_t *)src_buf, i = 20; i > 0;
					i -= data_size, ptr += data_size)
					memcpy(ptr, data,
					       min_t(size_t, i, data_size));
			}
		}
		bin_func(dst_reg->digest, src_buf, 20);
		dst_reg->valid = true;
		dst_modified = true;
		break;
	case HRE_LOADKEY:
		if (hre_op_loadkey(src_reg, dst_reg, data, data_size))
			return NULL;
		break;
	default:
		return NULL;
	}

	if (dst_reg && dst_modified && IS_PCR_HREG(dst_spec)) {
		hre_tpm_err = tpm_extend(HREG_IDX(dst_spec), dst_reg->digest,
			dst_reg->digest);
		if (hre_tpm_err) {
			hre_err = HRE_E_TPM_FAILURE;
			return NULL;
		}
	}
end:
	*ip += 4;
	*code_size -= 4;
	if (opcode & 0x80) {
		*ip += data_size;
		*code_size -= data_size;
	}

	return *ip;
}

/**
 * @brief runs a program on the hash register engine.
 * @param code		pointer to the (HRE) code.
 * @param code_size	size of the code (in bytes).
 * @return 0 on success, != 0 on failure.
 */
int hre_run_program(const uint8_t *code, size_t code_size)
{
	size_t code_left;
	const uint8_t *ip = code;

	code_left = code_size;
	hre_tpm_err = 0;
	hre_err = HRE_E_OK;
	while (code_left > 0)
		if (!hre_execute_op(&ip, &code_left))
			return -1;

	return hre_err;
}

int hre_verify_program(struct key_program *prg)
{
	uint32_t crc;

	crc = crc32(0, prg->code, prg->code_size);

	if (crc != prg->code_crc) {
		printf("HRC crc mismatch: %08x != %08x\n",
		       crc, prg->code_crc);
		return 1;
	}
	return 0;
}
