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

/* 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 <u-boot/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

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

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

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 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, block_no++, 1,
			tmp_buf);
		if (!n)
			goto failure;
		result = min(size, (int)(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, 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, 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_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.
 */
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];
	loff_t i;

	if (fs_set_blk_dev(ifname, dev_part_str, fs_type))
		goto failure;
	if (fs_read(path, (ulong)buf, 0, 12, &i) < 0)
		goto failure;
	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;
	if (fs_read(path, (ulong)result, 0,
		    sizeof(struct key_program) + header.code_size, &i) < 0)
		goto failure;
	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 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 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 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 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;
	loff_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;
	if (fs_read(image_path, image_addr, 0, 0, &image_size) < 0)
		goto failure;
	if (image_size <= 0)
		goto failure;
	printf("CCDM image found on %s, %lld 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(I2C_SOC_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_num();
	i2c_set_bus_num(I2C_SOC_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_num(orig_i2c_bus);
	if (result)
		ccdm_hang();

	return result;
}
