/*
 * (C) Copyright 2013
 * Reinhard Pfau, Guntermann & Drunck GmbH, reinhard.pfau@gdsys.cc
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 */

/* TODO: some more #ifdef's to avoid unneeded code for stage 1 / stage 2 */

#ifdef CCDM_ID_DEBUG
#define DEBUG
#endif

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

#undef CCDM_FIRST_STAGE
#undef CCDM_SECOND_STAGE
#undef CCDM_AUTO_FIRST_STAGE

#ifdef CONFIG_DEVELOP
#define CCDM_DEVELOP
#endif

#ifdef CONFIG_TRAILBLAZER
#define CCDM_FIRST_STAGE
#undef CCDM_SECOND_STAGE
#else
#undef CCDM_FIRST_STAGE
#define CCDM_SECOND_STAGE
#endif

#if defined(CCDM_DEVELOP) && defined(CCDM_SECOND_STAGE) && \
	!defined(CCCM_FIRST_STAGE)
#define CCDM_AUTO_FIRST_STAGE
#endif

/* enums from TCG specs */
enum {
	/* capability areas */
	TPM_CAP_NV_INDEX	= 0x00000011,
	TPM_CAP_HANDLE		= 0x00000014,
	/* resource types */
	TPM_RT_KEY	= 0x00000001,
};

/* CCDM specific contants */
enum {
	/* NV indices */
	NV_COMMON_DATA_INDEX	= 0x40000001,
	/* magics for key blob chains */
	MAGIC_KEY_PROGRAM	= 0x68726500,
	MAGIC_HMAC		= 0x68616300,
	MAGIC_END_OF_CHAIN	= 0x00000000,
	/* sizes */
	NV_COMMON_DATA_MIN_SIZE	= 3 * sizeof(uint64_t) + 2 * sizeof(uint16_t),
};

/* 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,
};

struct key_program {
	uint32_t magic;
	uint32_t code_crc;
	uint32_t code_size;
	uint8_t code[];
};

struct h_reg {
	bool valid;
	uint8_t digest[20];
};


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_SELF_HASH	= 1,
	FIX_HREG_STAGE2_HASH	= 2,
	FIX_HREG_VENDOR		= 3,
	COUNT_FIX_HREGS
};


/* 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 void(*bl2_entry)(void);

static struct h_reg pcr_hregs[24];
static struct h_reg fix_hregs[COUNT_FIX_HREGS];
static struct h_reg var_hregs[8];
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 prg_stage1_prepare[] = {
	0x00, 0x20, 0x00, 0x00, /* opcode: SYNC f0 */
	0x00, 0x24, 0x00, 0x00, /* opcode: SYNC f1 */
	0x01, 0x80, 0x00, 0x00, /* opcode: CHECK0 PCR0 */
	0x81, 0x22, 0x00, 0x00, /* opcode: LOAD PCR0, f0 */
	0x01, 0x84, 0x00, 0x00, /* opcode: CHECK0 PCR1 */
	0x81, 0x26, 0x10, 0x00, /* opcode: LOAD PCR1, f1 */
	0x01, 0x88, 0x00, 0x00, /* opcode: CHECK0 PCR2 */
	0x81, 0x2a, 0x20, 0x00, /* opcode: LOAD PCR2, f2 */
	0x01, 0x8c, 0x00, 0x00, /* opcode: CHECK0 PCR3 */
	0x81, 0x2e, 0x30, 0x00, /* opcode: LOAD PCR3, f3 */
};

static const uint8_t prg_stage2_prepare[] = {
	0x00, 0x80, 0x00, 0x00, /* opcode: SYNC PCR0 */
	0x00, 0x84, 0x00, 0x00, /* opcode: SYNC PCR1 */
	0x00, 0x88, 0x00, 0x00, /* opcode: SYNC PCR2 */
	0x00, 0x8c, 0x00, 0x00, /* opcode: SYNC PCR3 */
	0x00, 0x90, 0x00, 0x00, /* opcode: SYNC PCR4 */
};

static const uint8_t prg_stage2_success[] = {
	0x81, 0x02, 0x40, 0x14, /* opcode: LOAD PCR4, #<20B data> */
	0x48, 0xfd, 0x95, 0x17, 0xe7, 0x54, 0x6b, 0x68, /* data */
	0x92, 0x31, 0x18, 0x05, 0xf8, 0x58, 0x58, 0x3c, /* data */
	0xe4, 0xd2, 0x81, 0xe0, /* data */
};

static const uint8_t prg_stage_fail[] = {
	0x81, 0x01, 0x00, 0x14, /* opcode: LOAD v0, #<20B data> */
	0xc0, 0x32, 0xad, 0xc1, 0xff, 0x62, 0x9c, 0x9b, /* data */
	0x66, 0xf2, 0x27, 0x49, 0xad, 0x66, 0x7e, 0x6b, /* data */
	0xea, 0xdf, 0x14, 0x4b, /* data */
	0x81, 0x42, 0x30, 0x00, /* opcode: LOAD PCR3, v0 */
	0x81, 0x42, 0x40, 0x00, /* opcode: LOAD PCR4, v0 */
};

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


/**
 * @brief read a bunch of data from MMC into memory.
 *
 * @param mmc	pointer to the mmc structure to use.
 * @param src	offset where the data starts on MMC/SD device (in bytes).
 * @param dst	pointer to the location where the read data should be stored.
 * @param size	number of bytes to read from the MMC/SD device.
 * @return number of bytes read or -1 on error.
 */
static int ccdm_mmc_read(struct mmc *mmc, u64 src, u8 *dst, int size)
{
	int result = 0;
	u32 blk_len, ofs;
	ulong block_no, n, cnt;
	u8 *tmp_buf = NULL;

	if (size <= 0)
		goto end;

	blk_len = mmc->read_bl_len;
	tmp_buf = malloc(blk_len);
	if (!tmp_buf)
		goto failure;
	block_no = src / blk_len;
	ofs = src % blk_len;

	if (ofs) {
		n = mmc->block_dev.block_read(mmc->block_dev.dev, block_no++, 1,
			tmp_buf);
		if (!n)
			goto failure;
		result = min(size, blk_len - ofs);
		memcpy(dst, tmp_buf + ofs, result);
		dst += result;
		size -= result;
	}
	cnt = size / blk_len;
	if (cnt) {
		n = mmc->block_dev.block_read(mmc->block_dev.dev, block_no, cnt,
			dst);
		if (n != cnt)
			goto failure;
		size -= cnt * blk_len;
		result += cnt * blk_len;
		dst += cnt * blk_len;
		block_no += cnt;
	}
	if (size) {
		n = mmc->block_dev.block_read(mmc->block_dev.dev, block_no++, 1,
			tmp_buf);
		if (!n)
			goto failure;
		memcpy(dst, tmp_buf, size);
		result += size;
	}
	goto end;
failure:
	result = -1;
end:
	if (tmp_buf)
		free(tmp_buf);
	return result;
}

/**
 * @brief returns a location where the 2nd stage bootloader can be(/ is) placed.
 *
 * @return pointer to the location for/of the 2nd stage bootloader
 */
static u8 *get_2nd_stage_bl_location(ulong target_addr)
{
	ulong addr;
#ifdef CCDM_SECOND_STAGE
	addr = getenv_ulong("loadaddr", 16, CONFIG_LOADADDR);
#else
	addr = target_addr;
#endif
	return (u8 *)(addr);
}


#ifdef CCDM_SECOND_STAGE
/**
 * @brief returns a location where the image can be(/ is) placed.
 *
 * @return pointer to the location for/of the image
 */
static u8 *get_image_location(void)
{
	ulong addr;
	/* TODO use other area? */
	addr = getenv_ulong("loadaddr", 16, CONFIG_LOADADDR);
	return (u8 *)(addr);
}
#endif

/**
 * @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;
	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 compute hash of bootloader itself.
 * @param[out] dst	hash register where the hash should be stored
 * @return 0 on success, != 0 on failure.
 *
 * @note MUST be called at a time where the boot loader is accessible at the
 * configured location (; so take care when code is reallocated).
 */
static int compute_self_hash(struct h_reg *dst)
{
	sha1_csum((const uint8_t *)CONFIG_SYS_MONITOR_BASE,
		  CONFIG_SYS_MONITOR_LEN, dst->digest);
	dst->valid = true;
	return 0;
}

int ccdm_compute_self_hash(void)
{
	if (!fix_hregs[FIX_HREG_SELF_HASH].valid)
		compute_self_hash(&fix_hregs[FIX_HREG_SELF_HASH]);
	return 0;
}

/**
 * @brief compute the hash of the 2nd stage boot loader (on SD card)
 * @param[out] dst	hash register to store the computed hash
 * @return 0 on success, != 0 on failure
 *
 * Determines the size and location of the 2nd stage boot loader on SD card,
 * loads the 2nd stage boot loader and computes the (SHA1) hash value.
 * Within the 1st stage boot loader, the 2nd stage boot loader is loaded at
 * the desired memory location and the variable @a bl2_entry is set.
 *
 * @note This sets the variable @a bl2_entry to the entry point when the
 * 2nd stage boot loader is loaded at its configured memory location.
 */
static int compute_second_stage_hash(struct h_reg *dst)
{
	int result = 0;
	u32 code_len, code_offset, target_addr, exec_entry;
	struct mmc *mmc;
	u8 *load_addr = NULL;
	u8 buf[128];

	mmc = find_mmc_device(0);
	if (!mmc)
		goto failure;
	mmc_init(mmc);

	if (ccdm_mmc_read(mmc, 0, buf, sizeof(buf)) < 0)
		goto failure;

	code_offset = *(u32 *)(buf + ESDHC_BOOT_IMAGE_ADDR_OFS);
	code_len = *(u32 *)(buf + ESDHC_BOOT_IMAGE_SIZE_OFS);
	target_addr = *(u32 *)(buf + ESDHC_BOOT_IMAGE_TARGET_OFS);
	exec_entry =  *(u32 *)(buf + ESDHC_BOOT_IMAGE_ENTRY_OFS);

	load_addr = get_2nd_stage_bl_location(target_addr);
	if (load_addr == (u8 *)target_addr)
		bl2_entry = (void(*)(void))exec_entry;

	if (ccdm_mmc_read(mmc, code_offset, load_addr, code_len) < 0)
		goto failure;

	sha1_csum(load_addr, code_len, dst->digest);
	dst->valid = true;

	goto end;
failure:
	result = 1;
	bl2_entry = NULL;
end:
	return result;
}

/**
 * @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_SELF_HASH:
					ccdm_compute_self_hash();
					break;
				case FIX_HREG_STAGE2_HASH:
					compute_second_stage_hash(result);
					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;
	}
	/* TODO remember key handle somehow? */

	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(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.
 */
static 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;
}

static int check_hmac(struct key_program *hmac,
	const uint8_t *data, size_t data_size)
{
	uint8_t key[20], computed_hmac[20];
	uint32_t type;

	type = get_unaligned_be32(hmac->code);
	if (type != 0)
		return 1;
	memset(key, 0, sizeof(key));
	compute_extend(key, pcr_hregs[1].digest, 20);
	compute_extend(key, pcr_hregs[2].digest, 20);
	compute_extend(key, pcr_hregs[3].digest, 20);
	compute_extend(key, pcr_hregs[4].digest, 20);

	sha1_hmac(key, sizeof(key), data, data_size, computed_hmac);

	return memcmp(computed_hmac, hmac->code + 4, 20);
}

static int 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;
}

#if defined(CCDM_FIRST_STAGE) || (defined CCDM_AUTO_FIRST_STAGE)
static struct key_program *load_sd_key_program(void)
{
	u32 code_len, code_offset;
	struct mmc *mmc;
	u8 buf[128];
	struct key_program *result = NULL, *hmac = NULL;
	struct key_program header;

	mmc = find_mmc_device(0);
	if (!mmc)
		return NULL;
	mmc_init(mmc);

	if (ccdm_mmc_read(mmc, 0, buf, sizeof(buf)) <= 0)
		goto failure;

	code_offset = *(u32 *)(buf + ESDHC_BOOT_IMAGE_ADDR_OFS);
	code_len = *(u32 *)(buf + ESDHC_BOOT_IMAGE_SIZE_OFS);

	code_offset += code_len;
	/* TODO: the following needs to be the size of the 2nd stage env */
	code_offset += CONFIG_ENV_SIZE;

	if (ccdm_mmc_read(mmc, code_offset, buf, 4*3) < 0)
		goto failure;

	header.magic = get_unaligned_be32(buf);
	header.code_crc = get_unaligned_be32(buf + 4);
	header.code_size = get_unaligned_be32(buf + 8);

	if (header.magic != MAGIC_KEY_PROGRAM)
		goto failure;

	result = malloc(sizeof(struct key_program) + header.code_size);
	if (!result)
		goto failure;
	*result = header;

	printf("load key program chunk from SD card (%u bytes) ",
	       header.code_size);
	code_offset += 12;
	if (ccdm_mmc_read(mmc, code_offset, result->code, header.code_size)
		< 0)
		goto failure;
	code_offset += header.code_size;
	puts("\n");

	if (verify_program(result))
		goto failure;

	if (ccdm_mmc_read(mmc, code_offset, buf, 4*3) < 0)
		goto failure;

	header.magic = get_unaligned_be32(buf);
	header.code_crc = get_unaligned_be32(buf + 4);
	header.code_size = get_unaligned_be32(buf + 8);

	if (header.magic == MAGIC_HMAC) {
		puts("check integrity\n");
		hmac = malloc(sizeof(struct key_program) + header.code_size);
		if (!hmac)
			goto failure;
		*hmac = header;
		code_offset += 12;
		if (ccdm_mmc_read(mmc, code_offset, hmac->code,
				  hmac->code_size) < 0)
			goto failure;
		if (verify_program(hmac))
			goto failure;
		if (check_hmac(hmac, result->code, result->code_size)) {
			puts("key program integrity could not be verified\n");
			goto failure;
		}
		puts("key program verified\n");
	}

	goto end;
failure:
	if (result)
		free(result);
	result = NULL;
end:
	if (hmac)
		free(hmac);

	return result;
}
#endif

#ifdef CCDM_SECOND_STAGE
/**
 * @brief load a key program from file system.
 * @param ifname	interface of the file system
 * @param dev_part_str	device part of the file system
 * @param fs_type	tyep of the file system
 * @param path		path of the file to load.
 * @return the loaded structure or NULL on failure.
 */
static struct key_program *load_key_chunk(const char *ifname,
	const char *dev_part_str, int fs_type,
	const char *path)
{
	struct key_program *result = NULL;
	struct key_program header;
	uint32_t crc;
	uint8_t buf[12];
	int i;

	if (fs_set_blk_dev(ifname, dev_part_str, fs_type))
		goto failure;
	i = fs_read(path, (ulong)buf, 0, 12);
	if (i < 12)
		goto failure;
	header.magic = get_unaligned_be32(buf);
	header.code_crc = get_unaligned_be32(buf + 4);
	header.code_size = get_unaligned_be32(buf + 8);

	if (header.magic != MAGIC_HMAC && header.magic != MAGIC_KEY_PROGRAM)
		goto failure;

	result = malloc(sizeof(struct key_program) + header.code_size);
	if (!result)
		goto failure;
	if (fs_set_blk_dev(ifname, dev_part_str, fs_type))
		goto failure;
	i = fs_read(path, (ulong)result, 0,
		sizeof(struct key_program) + header.code_size);
	if (i <= 0)
		goto failure;
	*result = header;

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

	if (crc != result->code_crc) {
		printf("%s: HRC crc mismatch: %08x != %08x\n",
		       path, crc, result->code_crc);
		goto failure;
	}
	goto end;
failure:
	if (result) {
		free(result);
		result = NULL;
	}
end:
	return result;
}
#endif

#if defined(CCDM_FIRST_STAGE) || (defined CCDM_AUTO_FIRST_STAGE)
static int first_stage_actions(void)
{
	int result = 0;
	struct key_program *sd_prg = NULL;

	puts("CCDM S1: start actions\n");
#ifndef CCDM_SECOND_STAGE
	if (tpm_continue_self_test())
		goto failure;
#else
	tpm_continue_self_test();
#endif
	mdelay(37);

	if (hre_run_program(prg_stage1_prepare, sizeof(prg_stage1_prepare)))
		goto failure;

	sd_prg = load_sd_key_program();
	if (sd_prg) {
		if (hre_run_program(sd_prg->code, sd_prg->code_size))
			goto failure;
		puts("SD code run successfully\n");
	} else {
		puts("no key program found on SD\n");
		goto failure;
	}
	goto end;
failure:
	result = 1;
end:
	if (sd_prg)
		free(sd_prg);
	printf("CCDM S1: actions done (%d)\n", result);
	return result;
}
#endif

#ifdef CCDM_FIRST_STAGE
static int first_stage_init(void)
{
	int res = 0;
	puts("CCDM S1\n");
	if (tpm_init() || tpm_startup(TPM_ST_CLEAR))
		return 1;
	res = first_stage_actions();
#ifndef CCDM_SECOND_STAGE
	if (!res) {
		if (bl2_entry)
			(*bl2_entry)();
		res = 1;
	}
#endif
	return res;
}
#endif

#ifdef CCDM_SECOND_STAGE
static int second_stage_init(void)
{
	static const char mac_suffix[] = ".mac";
	bool did_first_stage_run = true;
	int result = 0;
	char *cptr, *mmcdev = NULL;
	struct key_program *hmac_blob = NULL;
	const char *image_path = "/ccdm.itb";
	char *mac_path = NULL;
	ulong image_addr;
	size_t image_size;
	uint32_t err;

	printf("CCDM S2\n");
	if (tpm_init())
		return 1;
	err = tpm_startup(TPM_ST_CLEAR);
	if (err != TPM_INVALID_POSTINIT)
		did_first_stage_run = false;

#ifdef CCDM_AUTO_FIRST_STAGE
	if (!did_first_stage_run && first_stage_actions())
		goto failure;
#else
	if (!did_first_stage_run)
		goto failure;
#endif

	if (hre_run_program(prg_stage2_prepare, sizeof(prg_stage2_prepare)))
		goto failure;

	/* run "prepboot" from env to get "mmcdev" set */
	cptr = getenv("prepboot");
	if (cptr && !run_command(cptr, 0))
		mmcdev = getenv("mmcdev");
	if (!mmcdev)
		goto failure;

	cptr = getenv("ramdiskimage");
	if (cptr)
		image_path = cptr;

	mac_path = malloc(strlen(image_path) + strlen(mac_suffix) + 1);
	if (mac_path == NULL)
		goto failure;
	strcpy(mac_path, image_path);
	strcat(mac_path, mac_suffix);

	/* read image from mmcdev (ccdm.itb) */
	image_addr = (ulong)get_image_location();
	if (fs_set_blk_dev("mmc", mmcdev, FS_TYPE_EXT))
		goto failure;
	image_size = fs_read(image_path, image_addr, 0, 0);
	if (image_size <= 0)
		goto failure;
	printf("CCDM image found on %s, %d bytes\n", mmcdev, image_size);

	hmac_blob = load_key_chunk("mmc", mmcdev, FS_TYPE_EXT, mac_path);
	if (!hmac_blob) {
		puts("failed to load mac file\n");
		goto failure;
	}
	if (verify_program(hmac_blob)) {
		puts("corrupted mac file\n");
		goto failure;
	}
	if (check_hmac(hmac_blob, (u8 *)image_addr, image_size)) {
		puts("image integrity could not be verified\n");
		goto failure;
	}
	puts("CCDM image OK\n");

	hre_run_program(prg_stage2_success, sizeof(prg_stage2_success));

	goto end;
failure:
	result = 1;
	hre_run_program(prg_stage_fail, sizeof(prg_stage_fail));
end:
	if (hmac_blob)
		free(hmac_blob);
	if (mac_path)
		free(mac_path);

	return result;
}
#endif

int show_self_hash(void)
{
	struct h_reg *hash_ptr;
#ifdef CCDM_SECOND_STAGE
	struct h_reg hash;

	hash_ptr = &hash;
	if (compute_self_hash(hash_ptr))
		return 1;
#else
	hash_ptr = &fix_hregs[FIX_HREG_SELF_HASH];
#endif
	puts("self hash: ");
	if (hash_ptr && hash_ptr->valid)
		print_buffer(0, hash_ptr->digest, 1, 20, 20);
	else
		puts("INVALID\n");

	return 0;
}

/**
 * @brief let the system hang.
 *
 * Called on error.
 * Will stop the boot process; display a message and signal the error condition
 * by blinking the "status" and the "finder" LED of the controller board.
 *
 * @note the develop version runs the blink cycle 2 times and then returns.
 * The release version never returns.
 */
static void ccdm_hang(void)
{
	static const u64 f0 = 0x0ba3bb8ba2e880; /* blink code "finder" LED */
	static const u64 s0 = 0x00f0f0f0f0f0f0; /* blink code "status" LED */
	u64 f, s;
	int i;
#ifdef CCDM_DEVELOP
	int j;
#endif

	I2C_SET_BUS(0);
	pca9698_direction_output(0x22, 0, 0); /* Finder */
	pca9698_direction_output(0x22, 4, 0); /* Status */

	puts("### ERROR ### Please RESET the board ###\n");
	bootstage_error(BOOTSTAGE_ID_NEED_RESET);
#ifdef CCDM_DEVELOP
	puts("*** ERROR ******** THIS WOULD HANG ******** ERROR ***\n");
	puts("** but we continue since this is a DEVELOP version **\n");
	puts("*** ERROR ******** THIS WOULD HANG ******** ERROR ***\n");
	for (j = 2; j-- > 0;) {
		putc('#');
#else
	for (;;) {
#endif
		f = f0;
		s = s0;
		for (i = 54; i-- > 0;) {
			pca9698_set_value(0x22, 0, !(f & 1));
			pca9698_set_value(0x22, 4, (s & 1));
			f >>= 1;
			s >>= 1;
			mdelay(120);
		}
	}
	puts("\ncontinue...\n");
}

int startup_ccdm_id_module(void)
{
	int result = 0;
	unsigned int orig_i2c_bus;

	orig_i2c_bus = I2C_GET_BUS();
	I2C_SET_BUS(1);

	/* goto end; */

#ifdef CCDM_DEVELOP
	show_self_hash();
#endif
#ifdef CCDM_FIRST_STAGE
	result = first_stage_init();
	if (result) {
		puts("1st stage init failed\n");
		goto failure;
	}
#endif
#ifdef CCDM_SECOND_STAGE
	result = second_stage_init();
	if (result) {
		puts("2nd stage init failed\n");
		goto failure;
	}
#endif

	goto end;
failure:
	result = 1;
end:
	I2C_SET_BUS(orig_i2c_bus);
	if (result)
		ccdm_hang();

	return result;
}
