/*
 * Freescale i.MX23/i.MX28 SB image generator
 *
 * Copyright (C) 2012-2013 Marek Vasut <marex@denx.de>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#ifdef CONFIG_MXS

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>

#include <openssl/evp.h>

#include "imagetool.h"
#include "mxsimage.h"
#include <image.h>


/*
 * DCD block
 * |-Write to address command block
 * |  0xf00 == 0xf33d
 * |  0xba2 == 0xb33f
 * |-ORR address with mask command block
 * |  0xf00 |= 0x1337
 * |-Write to address command block
 * |  0xba2 == 0xd00d
 * :
 */
#define SB_HAB_DCD_WRITE	0xccUL
#define SB_HAB_DCD_CHECK	0xcfUL
#define SB_HAB_DCD_NOOP		0xc0UL
#define SB_HAB_DCD_MASK_BIT	(1 << 3)
#define SB_HAB_DCD_SET_BIT	(1 << 4)

/* Addr.n = Value.n */
#define	SB_DCD_WRITE	\
	(SB_HAB_DCD_WRITE << 24)
/* Addr.n &= ~Value.n */
#define	SB_DCD_ANDC	\
	((SB_HAB_DCD_WRITE << 24) | SB_HAB_DCD_SET_BIT)
/* Addr.n |= Value.n */
#define	SB_DCD_ORR	\
	((SB_HAB_DCD_WRITE << 24) | SB_HAB_DCD_SET_BIT | SB_HAB_DCD_MASK_BIT)
/* (Addr.n & Value.n) == 0 */
#define	SB_DCD_CHK_EQZ	\
	(SB_HAB_DCD_CHECK << 24)
/* (Addr.n & Value.n) == Value.n */
#define	SB_DCD_CHK_EQ	\
	((SB_HAB_DCD_CHECK << 24) | SB_HAB_DCD_SET_BIT)
/* (Addr.n & Value.n) != Value.n */
#define	SB_DCD_CHK_NEQ	\
	((SB_HAB_DCD_CHECK << 24) | SB_HAB_DCD_MASK_BIT)
/* (Addr.n & Value.n) != 0 */
#define	SB_DCD_CHK_NEZ	\
	((SB_HAB_DCD_CHECK << 24) | SB_HAB_DCD_SET_BIT | SB_HAB_DCD_MASK_BIT)
/* NOP */
#define	SB_DCD_NOOP	\
	(SB_HAB_DCD_NOOP << 24)

struct sb_dcd_ctx {
	struct sb_dcd_ctx		*dcd;

	uint32_t			id;

	/* The DCD block. */
	uint32_t			*payload;
	/* Size of the whole DCD block. */
	uint32_t			size;

	/* Pointer to previous DCD command block. */
	uint32_t			*prev_dcd_head;
};

/*
 * IMAGE
 *   |-SECTION
 *   |    |-CMD
 *   |    |-CMD
 *   |    `-CMD
 *   |-SECTION
 *   |    |-CMD
 *   :    :
 */
struct sb_cmd_list {
	char				*cmd;
	size_t				len;
	unsigned int			lineno;
};

struct sb_cmd_ctx {
	uint32_t			size;

	struct sb_cmd_ctx		*cmd;

	uint8_t				*data;
	uint32_t			length;

	struct sb_command		payload;
	struct sb_command		c_payload;
};

struct sb_section_ctx {
	uint32_t			size;

	/* Section flags */
	unsigned int			boot:1;

	struct sb_section_ctx		*sect;

	struct sb_cmd_ctx		*cmd_head;
	struct sb_cmd_ctx		*cmd_tail;

	struct sb_sections_header	payload;
};

struct sb_image_ctx {
	unsigned int			in_section:1;
	unsigned int			in_dcd:1;
	/* Image configuration */
	unsigned int			verbose_boot:1;
	unsigned int			silent_dump:1;
	char				*input_filename;
	char				*output_filename;
	char				*cfg_filename;
	uint8_t				image_key[16];

	/* Number of section in the image */
	unsigned int			sect_count;
	/* Bootable section */
	unsigned int			sect_boot;
	unsigned int			sect_boot_found:1;

	struct sb_section_ctx		*sect_head;
	struct sb_section_ctx		*sect_tail;

	struct sb_dcd_ctx		*dcd_head;
	struct sb_dcd_ctx		*dcd_tail;

	EVP_CIPHER_CTX			cipher_ctx;
	EVP_MD_CTX			md_ctx;
	uint8_t				digest[32];
	struct sb_key_dictionary_key	sb_dict_key;

	struct sb_boot_image_header	payload;
};

/*
 * Instruction semantics:
 * NOOP
 * TAG [LAST]
 * LOAD       address file
 * LOAD  IVT  address IVT_entry_point
 * FILL address pattern length
 * JUMP [HAB] address [r0_arg]
 * CALL [HAB] address [r0_arg]
 * MODE mode
 *      For i.MX23, mode = USB/I2C/SPI1_FLASH/SPI2_FLASH/NAND_BCH
 *                         JTAG/SPI3_EEPROM/SD_SSP0/SD_SSP1
 *      For i.MX28, mode = USB/I2C/SPI2_FLASH/SPI3_FLASH/NAND_BCH
 *                         JTAG/SPI2_EEPROM/SD_SSP0/SD_SSP1
 */

/*
 * AES libcrypto
 */
static int sb_aes_init(struct sb_image_ctx *ictx, uint8_t *iv, int enc)
{
	EVP_CIPHER_CTX *ctx = &ictx->cipher_ctx;
	int ret;

	/* If there is no init vector, init vector is all zeroes. */
	if (!iv)
		iv = ictx->image_key;

	EVP_CIPHER_CTX_init(ctx);
	ret = EVP_CipherInit(ctx, EVP_aes_128_cbc(), ictx->image_key, iv, enc);
	if (ret == 1)
		EVP_CIPHER_CTX_set_padding(ctx, 0);
	return ret;
}

static int sb_aes_crypt(struct sb_image_ctx *ictx, uint8_t *in_data,
			uint8_t *out_data, int in_len)
{
	EVP_CIPHER_CTX *ctx = &ictx->cipher_ctx;
	int ret, outlen;
	uint8_t *outbuf;

	outbuf = malloc(in_len);
	if (!outbuf)
		return -ENOMEM;
	memset(outbuf, 0, sizeof(in_len));

	ret = EVP_CipherUpdate(ctx, outbuf, &outlen, in_data, in_len);
	if (!ret) {
		ret = -EINVAL;
		goto err;
	}

	if (out_data)
		memcpy(out_data, outbuf, outlen);

err:
	free(outbuf);
	return ret;
}

static int sb_aes_deinit(EVP_CIPHER_CTX *ctx)
{
	return EVP_CIPHER_CTX_cleanup(ctx);
}

static int sb_aes_reinit(struct sb_image_ctx *ictx, int enc)
{
	int ret;
	EVP_CIPHER_CTX *ctx = &ictx->cipher_ctx;
	struct sb_boot_image_header *sb_header = &ictx->payload;
	uint8_t *iv = sb_header->iv;

	ret = sb_aes_deinit(ctx);
	if (!ret)
		return ret;
	return sb_aes_init(ictx, iv, enc);
}

/*
 * CRC32
 */
static uint32_t crc32(uint8_t *data, uint32_t len)
{
	const uint32_t poly = 0x04c11db7;
	uint32_t crc32 = 0xffffffff;
	unsigned int byte, bit;

	for (byte = 0; byte < len; byte++) {
		crc32 ^= data[byte] << 24;

		for (bit = 8; bit > 0; bit--) {
			if (crc32 & (1UL << 31))
				crc32 = (crc32 << 1) ^ poly;
			else
				crc32 = (crc32 << 1);
		}
	}

	return crc32;
}

/*
 * Debug
 */
static void soprintf(struct sb_image_ctx *ictx, const char *fmt, ...)
{
	va_list ap;

	if (ictx->silent_dump)
		return;

	va_start(ap, fmt);
	vfprintf(stdout, fmt, ap);
	va_end(ap);
}

/*
 * Code
 */
static time_t sb_get_timestamp(void)
{
	struct tm time_2000 = {
		.tm_yday	= 1,	/* Jan. 1st */
		.tm_year	= 100,	/* 2000 */
	};
	time_t seconds_to_2000 = mktime(&time_2000);
	time_t seconds_to_now = time(NULL);

	return seconds_to_now - seconds_to_2000;
}

static int sb_get_time(time_t time, struct tm *tm)
{
	struct tm time_2000 = {
		.tm_yday	= 1,	/* Jan. 1st */
		.tm_year	= 0,	/* 1900 */
	};
	const time_t seconds_to_2000 = mktime(&time_2000);
	const time_t seconds_to_now = seconds_to_2000 + time;
	struct tm *ret;
	ret = gmtime_r(&seconds_to_now, tm);
	return ret ? 0 : -EINVAL;
}

static void sb_encrypt_sb_header(struct sb_image_ctx *ictx)
{
	EVP_MD_CTX *md_ctx = &ictx->md_ctx;
	struct sb_boot_image_header *sb_header = &ictx->payload;
	uint8_t *sb_header_ptr = (uint8_t *)sb_header;

	/* Encrypt the header, compute the digest. */
	sb_aes_crypt(ictx, sb_header_ptr, NULL, sizeof(*sb_header));
	EVP_DigestUpdate(md_ctx, sb_header_ptr, sizeof(*sb_header));
}

static void sb_encrypt_sb_sections_header(struct sb_image_ctx *ictx)
{
	EVP_MD_CTX *md_ctx = &ictx->md_ctx;
	struct sb_section_ctx *sctx = ictx->sect_head;
	struct sb_sections_header *shdr;
	uint8_t *sb_sections_header_ptr;
	const int size = sizeof(*shdr);

	while (sctx) {
		shdr = &sctx->payload;
		sb_sections_header_ptr = (uint8_t *)shdr;

		sb_aes_crypt(ictx, sb_sections_header_ptr,
			     ictx->sb_dict_key.cbc_mac, size);
		EVP_DigestUpdate(md_ctx, sb_sections_header_ptr, size);

		sctx = sctx->sect;
	};
}

static void sb_encrypt_key_dictionary_key(struct sb_image_ctx *ictx)
{
	EVP_MD_CTX *md_ctx = &ictx->md_ctx;

	sb_aes_crypt(ictx, ictx->image_key, ictx->sb_dict_key.key,
		     sizeof(ictx->sb_dict_key.key));
	EVP_DigestUpdate(md_ctx, &ictx->sb_dict_key, sizeof(ictx->sb_dict_key));
}

static void sb_decrypt_key_dictionary_key(struct sb_image_ctx *ictx)
{
	EVP_MD_CTX *md_ctx = &ictx->md_ctx;

	EVP_DigestUpdate(md_ctx, &ictx->sb_dict_key, sizeof(ictx->sb_dict_key));
	sb_aes_crypt(ictx, ictx->sb_dict_key.key, ictx->image_key,
		     sizeof(ictx->sb_dict_key.key));
}

static void sb_encrypt_tag(struct sb_image_ctx *ictx,
		struct sb_cmd_ctx *cctx)
{
	EVP_MD_CTX *md_ctx = &ictx->md_ctx;
	struct sb_command *cmd = &cctx->payload;

	sb_aes_crypt(ictx, (uint8_t *)cmd,
		     (uint8_t *)&cctx->c_payload, sizeof(*cmd));
	EVP_DigestUpdate(md_ctx, &cctx->c_payload, sizeof(*cmd));
}

static int sb_encrypt_image(struct sb_image_ctx *ictx)
{
	/* Start image-wide crypto. */
	EVP_MD_CTX_init(&ictx->md_ctx);
	EVP_DigestInit(&ictx->md_ctx, EVP_sha1());

	/*
	 * SB image header.
	 */
	sb_aes_init(ictx, NULL, 1);
	sb_encrypt_sb_header(ictx);

	/*
	 * SB sections header.
	 */
	sb_encrypt_sb_sections_header(ictx);

	/*
	 * Key dictionary.
	 */
	sb_aes_reinit(ictx, 1);
	sb_encrypt_key_dictionary_key(ictx);

	/*
	 * Section tags.
	 */
	struct sb_cmd_ctx *cctx;
	struct sb_command *ccmd;
	struct sb_section_ctx *sctx = ictx->sect_head;

	while (sctx) {
		cctx = sctx->cmd_head;

		sb_aes_reinit(ictx, 1);

		while (cctx) {
			ccmd = &cctx->payload;

			sb_encrypt_tag(ictx, cctx);

			if (ccmd->header.tag == ROM_TAG_CMD) {
				sb_aes_reinit(ictx, 1);
			} else if (ccmd->header.tag == ROM_LOAD_CMD) {
				sb_aes_crypt(ictx, cctx->data, cctx->data,
					     cctx->length);
				EVP_DigestUpdate(&ictx->md_ctx, cctx->data,
						 cctx->length);
			}

			cctx = cctx->cmd;
		}

		sctx = sctx->sect;
	};

	/*
	 * Dump the SHA1 of the whole image.
	 */
	sb_aes_reinit(ictx, 1);

	EVP_DigestFinal(&ictx->md_ctx, ictx->digest, NULL);
	sb_aes_crypt(ictx, ictx->digest, ictx->digest, sizeof(ictx->digest));

	/* Stop the encryption session. */
	sb_aes_deinit(&ictx->cipher_ctx);

	return 0;
}

static int sb_load_file(struct sb_cmd_ctx *cctx, char *filename)
{
	long real_size, roundup_size;
	uint8_t *data;
	long ret;
	unsigned long size;
	FILE *fp;

	if (!filename) {
		fprintf(stderr, "ERR: Missing filename!\n");
		return -EINVAL;
	}

	fp = fopen(filename, "r");
	if (!fp)
		goto err_open;

	ret = fseek(fp, 0, SEEK_END);
	if (ret < 0)
		goto err_file;

	real_size = ftell(fp);
	if (real_size < 0)
		goto err_file;

	ret = fseek(fp, 0, SEEK_SET);
	if (ret < 0)
		goto err_file;

	roundup_size = roundup(real_size, SB_BLOCK_SIZE);
	data = calloc(1, roundup_size);
	if (!data)
		goto err_file;

	size = fread(data, 1, real_size, fp);
	if (size != (unsigned long)real_size)
		goto err_alloc;

	cctx->data = data;
	cctx->length = roundup_size;

	fclose(fp);
	return 0;

err_alloc:
	free(data);
err_file:
	fclose(fp);
err_open:
	fprintf(stderr, "ERR: Failed to load file \"%s\"\n", filename);
	return -EINVAL;
}

static uint8_t sb_command_checksum(struct sb_command *inst)
{
	uint8_t *inst_ptr = (uint8_t *)inst;
	uint8_t csum = 0;
	unsigned int i;

	for (i = 0; i < sizeof(struct sb_command); i++)
		csum += inst_ptr[i];

	return csum;
}

static int sb_token_to_long(char *tok, uint32_t *rid)
{
	char *endptr;
	unsigned long id;

	if (tok[0] != '0' || tok[1] != 'x') {
		fprintf(stderr, "ERR: Invalid hexadecimal number!\n");
		return -EINVAL;
	}

	tok += 2;

	errno = 0;
	id = strtoul(tok, &endptr, 16);
	if ((errno == ERANGE && id == ULONG_MAX) || (errno != 0 && id == 0)) {
		fprintf(stderr, "ERR: Value can't be decoded!\n");
		return -EINVAL;
	}

	/* Check for 32-bit overflow. */
	if (id > 0xffffffff) {
		fprintf(stderr, "ERR: Value too big!\n");
		return -EINVAL;
	}

	if (endptr == tok) {
		fprintf(stderr, "ERR: Deformed value!\n");
		return -EINVAL;
	}

	*rid = (uint32_t)id;
	return 0;
}

static int sb_grow_dcd(struct sb_dcd_ctx *dctx, unsigned int inc_size)
{
	uint32_t *tmp;

	if (!inc_size)
		return 0;

	dctx->size += inc_size;
	tmp = realloc(dctx->payload, dctx->size);
	if (!tmp)
		return -ENOMEM;

	dctx->payload = tmp;

	/* Assemble and update the HAB DCD header. */
	dctx->payload[0] = htonl((SB_HAB_DCD_TAG << 24) |
				 (dctx->size << 8) |
				 SB_HAB_VERSION);

	return 0;
}

static int sb_build_dcd(struct sb_image_ctx *ictx, struct sb_cmd_list *cmd)
{
	struct sb_dcd_ctx *dctx;

	char *tok;
	uint32_t id;
	int ret;

	dctx = calloc(1, sizeof(*dctx));
	if (!dctx)
		return -ENOMEM;

	ret = sb_grow_dcd(dctx, 4);
	if (ret)
		goto err_dcd;

	/* Read DCD block number. */
	tok = strtok(cmd->cmd, " ");
	if (!tok) {
		fprintf(stderr, "#%i ERR: DCD block without number!\n",
			cmd->lineno);
		ret = -EINVAL;
		goto err_dcd;
	}

	/* Parse the DCD block number. */
	ret = sb_token_to_long(tok, &id);
	if (ret) {
		fprintf(stderr, "#%i ERR: Malformed DCD block number!\n",
			cmd->lineno);
		goto err_dcd;
	}

	dctx->id = id;

	/*
	 * The DCD block is now constructed. Append it to the list.
	 * WARNING: The DCD size is still not computed and will be
	 * updated while parsing it's commands.
	 */
	if (!ictx->dcd_head) {
		ictx->dcd_head = dctx;
		ictx->dcd_tail = dctx;
	} else {
		ictx->dcd_tail->dcd = dctx;
		ictx->dcd_tail = dctx;
	}

	return 0;

err_dcd:
	free(dctx->payload);
	free(dctx);
	return ret;
}

static int sb_build_dcd_block(struct sb_image_ctx *ictx,
			      struct sb_cmd_list *cmd,
			      uint32_t type)
{
	char *tok;
	uint32_t address, value, length;
	int ret;

	struct sb_dcd_ctx *dctx = ictx->dcd_tail;
	uint32_t *dcd;

	if (dctx->prev_dcd_head && (type != SB_DCD_NOOP) &&
	    ((dctx->prev_dcd_head[0] & 0xff0000ff) == type)) {
		/* Same instruction as before, just append it. */
		ret = sb_grow_dcd(dctx, 8);
		if (ret)
			return ret;
	} else if (type == SB_DCD_NOOP) {
		ret = sb_grow_dcd(dctx, 4);
		if (ret)
			return ret;

		/* Update DCD command block pointer. */
		dctx->prev_dcd_head = dctx->payload +
				dctx->size / sizeof(*dctx->payload) - 1;

		/* NOOP has only 4 bytes and no payload. */
		goto noop;
	} else {
		/*
		 * Either a different instruction block started now
		 * or this is the first instruction block.
		 */
		ret = sb_grow_dcd(dctx, 12);
		if (ret)
			return ret;

		/* Update DCD command block pointer. */
		dctx->prev_dcd_head = dctx->payload +
				dctx->size / sizeof(*dctx->payload) - 3;
	}

	dcd = dctx->payload + dctx->size / sizeof(*dctx->payload) - 2;

	/*
	 * Prepare the command.
	 */
	tok = strtok(cmd->cmd, " ");
	if (!tok) {
		fprintf(stderr, "#%i ERR: Missing DCD address!\n",
			cmd->lineno);
		ret = -EINVAL;
		goto err;
	}

	/* Read DCD destination address. */
	ret = sb_token_to_long(tok, &address);
	if (ret) {
		fprintf(stderr, "#%i ERR: Incorrect DCD address!\n",
			cmd->lineno);
		goto err;
	}

	tok = strtok(NULL, " ");
	if (!tok) {
		fprintf(stderr, "#%i ERR: Missing DCD value!\n",
			cmd->lineno);
		ret = -EINVAL;
		goto err;
	}

	/* Read DCD operation value. */
	ret = sb_token_to_long(tok, &value);
	if (ret) {
		fprintf(stderr, "#%i ERR: Incorrect DCD value!\n",
			cmd->lineno);
		goto err;
	}

	/* Fill in the new DCD entry. */
	dcd[0] = htonl(address);
	dcd[1] = htonl(value);

noop:
	/* Update the DCD command block. */
	length = dctx->size -
		 ((dctx->prev_dcd_head - dctx->payload) *
		 sizeof(*dctx->payload));
	dctx->prev_dcd_head[0] = htonl(type | (length << 8));

err:
	return ret;
}

static int sb_build_section(struct sb_image_ctx *ictx, struct sb_cmd_list *cmd)
{
	struct sb_section_ctx *sctx;
	struct sb_sections_header *shdr;
	char *tok;
	uint32_t bootable = 0;
	uint32_t id;
	int ret;

	sctx = calloc(1, sizeof(*sctx));
	if (!sctx)
		return -ENOMEM;

	/* Read section number. */
	tok = strtok(cmd->cmd, " ");
	if (!tok) {
		fprintf(stderr, "#%i ERR: Section without number!\n",
			cmd->lineno);
		ret = -EINVAL;
		goto err_sect;
	}

	/* Parse the section number. */
	ret = sb_token_to_long(tok, &id);
	if (ret) {
		fprintf(stderr, "#%i ERR: Malformed section number!\n",
			cmd->lineno);
		goto err_sect;
	}

	/* Read section's BOOTABLE flag. */
	tok = strtok(NULL, " ");
	if (tok && (strlen(tok) == 8) && !strncmp(tok, "BOOTABLE", 8))
		bootable = SB_SECTION_FLAG_BOOTABLE;

	sctx->boot = bootable;

	shdr = &sctx->payload;
	shdr->section_number = id;
	shdr->section_flags = bootable;

	/*
	 * The section is now constructed. Append it to the list.
	 * WARNING: The section size is still not computed and will
	 * be updated while parsing it's commands.
	 */
	ictx->sect_count++;

	/* Mark that this section is bootable one. */
	if (bootable) {
		if (ictx->sect_boot_found) {
			fprintf(stderr,
				"#%i WARN: Multiple bootable section!\n",
				cmd->lineno);
		} else {
			ictx->sect_boot = id;
			ictx->sect_boot_found = 1;
		}
	}

	if (!ictx->sect_head) {
		ictx->sect_head = sctx;
		ictx->sect_tail = sctx;
	} else {
		ictx->sect_tail->sect = sctx;
		ictx->sect_tail = sctx;
	}

	return 0;

err_sect:
	free(sctx);
	return ret;
}

static int sb_build_command_nop(struct sb_image_ctx *ictx)
{
	struct sb_section_ctx *sctx = ictx->sect_tail;
	struct sb_cmd_ctx *cctx;
	struct sb_command *ccmd;

	cctx = calloc(1, sizeof(*cctx));
	if (!cctx)
		return -ENOMEM;

	ccmd = &cctx->payload;

	/*
	 * Construct the command.
	 */
	ccmd->header.checksum	= 0x5a;
	ccmd->header.tag	= ROM_NOP_CMD;

	cctx->size = sizeof(*ccmd);

	/*
	 * Append the command to the last section.
	 */
	if (!sctx->cmd_head) {
		sctx->cmd_head = cctx;
		sctx->cmd_tail = cctx;
	} else {
		sctx->cmd_tail->cmd = cctx;
		sctx->cmd_tail = cctx;
	}

	return 0;
}

static int sb_build_command_tag(struct sb_image_ctx *ictx,
				struct sb_cmd_list *cmd)
{
	struct sb_section_ctx *sctx = ictx->sect_tail;
	struct sb_cmd_ctx *cctx;
	struct sb_command *ccmd;
	char *tok;

	cctx = calloc(1, sizeof(*cctx));
	if (!cctx)
		return -ENOMEM;

	ccmd = &cctx->payload;

	/*
	 * Prepare the command.
	 */
	/* Check for the LAST keyword. */
	tok = strtok(cmd->cmd, " ");
	if (tok && !strcmp(tok, "LAST"))
		ccmd->header.flags = ROM_TAG_CMD_FLAG_ROM_LAST_TAG;

	/*
	 * Construct the command.
	 */
	ccmd->header.checksum	= 0x5a;
	ccmd->header.tag	= ROM_TAG_CMD;

	cctx->size = sizeof(*ccmd);

	/*
	 * Append the command to the last section.
	 */
	if (!sctx->cmd_head) {
		sctx->cmd_head = cctx;
		sctx->cmd_tail = cctx;
	} else {
		sctx->cmd_tail->cmd = cctx;
		sctx->cmd_tail = cctx;
	}

	return 0;
}

static int sb_build_command_load(struct sb_image_ctx *ictx,
				 struct sb_cmd_list *cmd)
{
	struct sb_section_ctx *sctx = ictx->sect_tail;
	struct sb_cmd_ctx *cctx;
	struct sb_command *ccmd;
	char *tok;
	int ret, is_ivt = 0, is_dcd = 0;
	uint32_t dest, dcd = 0;

	cctx = calloc(1, sizeof(*cctx));
	if (!cctx)
		return -ENOMEM;

	ccmd = &cctx->payload;

	/*
	 * Prepare the command.
	 */
	tok = strtok(cmd->cmd, " ");
	if (!tok) {
		fprintf(stderr, "#%i ERR: Missing LOAD address or 'IVT'!\n",
			cmd->lineno);
		ret = -EINVAL;
		goto err;
	}

	/* Check for "IVT" flag. */
	if (!strcmp(tok, "IVT"))
		is_ivt = 1;
	if (!strcmp(tok, "DCD"))
		is_dcd = 1;
	if (is_ivt || is_dcd) {
		tok = strtok(NULL, " ");
		if (!tok) {
			fprintf(stderr, "#%i ERR: Missing LOAD address!\n",
				cmd->lineno);
			ret = -EINVAL;
			goto err;
		}
	}

	/* Read load destination address. */
	ret = sb_token_to_long(tok, &dest);
	if (ret) {
		fprintf(stderr, "#%i ERR: Incorrect LOAD address!\n",
			cmd->lineno);
		goto err;
	}

	/* Read filename or IVT entrypoint or DCD block ID. */
	tok = strtok(NULL, " ");
	if (!tok) {
		fprintf(stderr,
			"#%i ERR: Missing LOAD filename or IVT ep or DCD block ID!\n",
			cmd->lineno);
		ret = -EINVAL;
		goto err;
	}

	if (is_ivt) {
		/* Handle IVT. */
		struct sb_ivt_header *ivt;
		uint32_t ivtep;
		ret = sb_token_to_long(tok, &ivtep);

		if (ret) {
			fprintf(stderr,
				"#%i ERR: Incorrect IVT entry point!\n",
				cmd->lineno);
			goto err;
		}

		ivt = calloc(1, sizeof(*ivt));
		if (!ivt) {
			ret = -ENOMEM;
			goto err;
		}

		ivt->header = sb_hab_ivt_header();
		ivt->entry = ivtep;
		ivt->self = dest;

		cctx->data = (uint8_t *)ivt;
		cctx->length = sizeof(*ivt);
	} else if (is_dcd) {
		struct sb_dcd_ctx *dctx = ictx->dcd_head;
		uint32_t dcdid;
		uint8_t *payload;
		uint32_t asize;
		ret = sb_token_to_long(tok, &dcdid);

		if (ret) {
			fprintf(stderr,
				"#%i ERR: Incorrect DCD block ID!\n",
				cmd->lineno);
			goto err;
		}

		while (dctx) {
			if (dctx->id == dcdid)
				break;
			dctx = dctx->dcd;
		}

		if (!dctx) {
			fprintf(stderr, "#%i ERR: DCD block %08x not found!\n",
				cmd->lineno, dcdid);
			goto err;
		}

		asize = roundup(dctx->size, SB_BLOCK_SIZE);
		payload = calloc(1, asize);
		if (!payload) {
			ret = -ENOMEM;
			goto err;
		}

		memcpy(payload, dctx->payload, dctx->size);

		cctx->data = payload;
		cctx->length = asize;

		/* Set the Load DCD flag. */
		dcd = ROM_LOAD_CMD_FLAG_DCD_LOAD;
	} else {
		/* Regular LOAD of a file. */
		ret = sb_load_file(cctx, tok);
		if (ret) {
			fprintf(stderr, "#%i ERR: Cannot load '%s'!\n",
				cmd->lineno, tok);
			goto err;
		}
	}

	if (cctx->length & (SB_BLOCK_SIZE - 1)) {
		fprintf(stderr, "#%i ERR: Unaligned payload!\n",
			cmd->lineno);
	}

	/*
	 * Construct the command.
	 */
	ccmd->header.checksum	= 0x5a;
	ccmd->header.tag	= ROM_LOAD_CMD;
	ccmd->header.flags	= dcd;

	ccmd->load.address	= dest;
	ccmd->load.count	= cctx->length;
	ccmd->load.crc32	= crc32(cctx->data, cctx->length);

	cctx->size = sizeof(*ccmd) + cctx->length;

	/*
	 * Append the command to the last section.
	 */
	if (!sctx->cmd_head) {
		sctx->cmd_head = cctx;
		sctx->cmd_tail = cctx;
	} else {
		sctx->cmd_tail->cmd = cctx;
		sctx->cmd_tail = cctx;
	}

	return 0;

err:
	free(cctx);
	return ret;
}

static int sb_build_command_fill(struct sb_image_ctx *ictx,
				 struct sb_cmd_list *cmd)
{
	struct sb_section_ctx *sctx = ictx->sect_tail;
	struct sb_cmd_ctx *cctx;
	struct sb_command *ccmd;
	char *tok;
	uint32_t address, pattern, length;
	int ret;

	cctx = calloc(1, sizeof(*cctx));
	if (!cctx)
		return -ENOMEM;

	ccmd = &cctx->payload;

	/*
	 * Prepare the command.
	 */
	tok = strtok(cmd->cmd, " ");
	if (!tok) {
		fprintf(stderr, "#%i ERR: Missing FILL address!\n",
			cmd->lineno);
		ret = -EINVAL;
		goto err;
	}

	/* Read fill destination address. */
	ret = sb_token_to_long(tok, &address);
	if (ret) {
		fprintf(stderr, "#%i ERR: Incorrect FILL address!\n",
			cmd->lineno);
		goto err;
	}

	tok = strtok(NULL, " ");
	if (!tok) {
		fprintf(stderr, "#%i ERR: Missing FILL pattern!\n",
			cmd->lineno);
		ret = -EINVAL;
		goto err;
	}

	/* Read fill pattern address. */
	ret = sb_token_to_long(tok, &pattern);
	if (ret) {
		fprintf(stderr, "#%i ERR: Incorrect FILL pattern!\n",
			cmd->lineno);
		goto err;
	}

	tok = strtok(NULL, " ");
	if (!tok) {
		fprintf(stderr, "#%i ERR: Missing FILL length!\n",
			cmd->lineno);
		ret = -EINVAL;
		goto err;
	}

	/* Read fill pattern address. */
	ret = sb_token_to_long(tok, &length);
	if (ret) {
		fprintf(stderr, "#%i ERR: Incorrect FILL length!\n",
			cmd->lineno);
		goto err;
	}

	/*
	 * Construct the command.
	 */
	ccmd->header.checksum	= 0x5a;
	ccmd->header.tag	= ROM_FILL_CMD;

	ccmd->fill.address	= address;
	ccmd->fill.count	= length;
	ccmd->fill.pattern	= pattern;

	cctx->size = sizeof(*ccmd);

	/*
	 * Append the command to the last section.
	 */
	if (!sctx->cmd_head) {
		sctx->cmd_head = cctx;
		sctx->cmd_tail = cctx;
	} else {
		sctx->cmd_tail->cmd = cctx;
		sctx->cmd_tail = cctx;
	}

	return 0;

err:
	free(cctx);
	return ret;
}

static int sb_build_command_jump_call(struct sb_image_ctx *ictx,
				      struct sb_cmd_list *cmd,
				      unsigned int is_call)
{
	struct sb_section_ctx *sctx = ictx->sect_tail;
	struct sb_cmd_ctx *cctx;
	struct sb_command *ccmd;
	char *tok;
	uint32_t dest, arg = 0x0;
	uint32_t hab = 0;
	int ret;
	const char *cmdname = is_call ? "CALL" : "JUMP";

	cctx = calloc(1, sizeof(*cctx));
	if (!cctx)
		return -ENOMEM;

	ccmd = &cctx->payload;

	/*
	 * Prepare the command.
	 */
	tok = strtok(cmd->cmd, " ");
	if (!tok) {
		fprintf(stderr,
			"#%i ERR: Missing %s address or 'HAB'!\n",
			cmd->lineno, cmdname);
		ret = -EINVAL;
		goto err;
	}

	/* Check for "HAB" flag. */
	if (!strcmp(tok, "HAB")) {
		hab = is_call ? ROM_CALL_CMD_FLAG_HAB : ROM_JUMP_CMD_FLAG_HAB;
		tok = strtok(NULL, " ");
		if (!tok) {
			fprintf(stderr, "#%i ERR: Missing %s address!\n",
				cmd->lineno, cmdname);
			ret = -EINVAL;
			goto err;
		}
	}
	/* Read load destination address. */
	ret = sb_token_to_long(tok, &dest);
	if (ret) {
		fprintf(stderr, "#%i ERR: Incorrect %s address!\n",
			cmd->lineno, cmdname);
		goto err;
	}

	tok = strtok(NULL, " ");
	if (tok) {
		ret = sb_token_to_long(tok, &arg);
		if (ret) {
			fprintf(stderr,
				"#%i ERR: Incorrect %s argument!\n",
				cmd->lineno, cmdname);
			goto err;
		}
	}

	/*
	 * Construct the command.
	 */
	ccmd->header.checksum	= 0x5a;
	ccmd->header.tag	= is_call ? ROM_CALL_CMD : ROM_JUMP_CMD;
	ccmd->header.flags	= hab;

	ccmd->call.address	= dest;
	ccmd->call.argument	= arg;

	cctx->size = sizeof(*ccmd);

	/*
	 * Append the command to the last section.
	 */
	if (!sctx->cmd_head) {
		sctx->cmd_head = cctx;
		sctx->cmd_tail = cctx;
	} else {
		sctx->cmd_tail->cmd = cctx;
		sctx->cmd_tail = cctx;
	}

	return 0;

err:
	free(cctx);
	return ret;
}

static int sb_build_command_jump(struct sb_image_ctx *ictx,
				 struct sb_cmd_list *cmd)
{
	return sb_build_command_jump_call(ictx, cmd, 0);
}

static int sb_build_command_call(struct sb_image_ctx *ictx,
				 struct sb_cmd_list *cmd)
{
	return sb_build_command_jump_call(ictx, cmd, 1);
}

static int sb_build_command_mode(struct sb_image_ctx *ictx,
				 struct sb_cmd_list *cmd)
{
	struct sb_section_ctx *sctx = ictx->sect_tail;
	struct sb_cmd_ctx *cctx;
	struct sb_command *ccmd;
	char *tok;
	int ret;
	unsigned int i;
	uint32_t mode = 0xffffffff;

	cctx = calloc(1, sizeof(*cctx));
	if (!cctx)
		return -ENOMEM;

	ccmd = &cctx->payload;

	/*
	 * Prepare the command.
	 */
	tok = strtok(cmd->cmd, " ");
	if (!tok) {
		fprintf(stderr, "#%i ERR: Missing MODE boot mode argument!\n",
			cmd->lineno);
		ret = -EINVAL;
		goto err;
	}

	for (i = 0; i < ARRAY_SIZE(modetable); i++) {
		if (!strcmp(tok, modetable[i].name)) {
			mode = modetable[i].mode;
			break;
		}

		if (!modetable[i].altname)
			continue;

		if (!strcmp(tok, modetable[i].altname)) {
			mode = modetable[i].mode;
			break;
		}
	}

	if (mode == 0xffffffff) {
		fprintf(stderr, "#%i ERR: Invalid MODE boot mode argument!\n",
			cmd->lineno);
		ret = -EINVAL;
		goto err;
	}

	/*
	 * Construct the command.
	 */
	ccmd->header.checksum	= 0x5a;
	ccmd->header.tag	= ROM_MODE_CMD;

	ccmd->mode.mode		= mode;

	cctx->size = sizeof(*ccmd);

	/*
	 * Append the command to the last section.
	 */
	if (!sctx->cmd_head) {
		sctx->cmd_head = cctx;
		sctx->cmd_tail = cctx;
	} else {
		sctx->cmd_tail->cmd = cctx;
		sctx->cmd_tail = cctx;
	}

	return 0;

err:
	free(cctx);
	return ret;
}

static int sb_prefill_image_header(struct sb_image_ctx *ictx)
{
	struct sb_boot_image_header *hdr = &ictx->payload;

	/* Fill signatures */
	memcpy(hdr->signature1, "STMP", 4);
	memcpy(hdr->signature2, "sgtl", 4);

	/* SB Image version 1.1 */
	hdr->major_version = SB_VERSION_MAJOR;
	hdr->minor_version = SB_VERSION_MINOR;

	/* Boot image major version */
	hdr->product_version.major = htons(0x999);
	hdr->product_version.minor = htons(0x999);
	hdr->product_version.revision = htons(0x999);
	/* Boot image major version */
	hdr->component_version.major = htons(0x999);
	hdr->component_version.minor = htons(0x999);
	hdr->component_version.revision = htons(0x999);

	/* Drive tag must be 0x0 for i.MX23 */
	hdr->drive_tag = 0;

	hdr->header_blocks =
		sizeof(struct sb_boot_image_header) / SB_BLOCK_SIZE;
	hdr->section_header_size =
		sizeof(struct sb_sections_header) / SB_BLOCK_SIZE;
	hdr->timestamp_us = sb_get_timestamp() * 1000000;

	/* FIXME -- add proper config option */
	hdr->flags = ictx->verbose_boot ? SB_IMAGE_FLAG_VERBOSE : 0,

	/* FIXME -- We support only default key */
	hdr->key_count = 1;

	return 0;
}

static int sb_postfill_image_header(struct sb_image_ctx *ictx)
{
	struct sb_boot_image_header *hdr = &ictx->payload;
	struct sb_section_ctx *sctx = ictx->sect_head;
	uint32_t kd_size, sections_blocks;
	EVP_MD_CTX md_ctx;

	/* The main SB header size in blocks. */
	hdr->image_blocks = hdr->header_blocks;

	/* Size of the key dictionary, which has single zero entry. */
	kd_size = hdr->key_count * sizeof(struct sb_key_dictionary_key);
	hdr->image_blocks += kd_size / SB_BLOCK_SIZE;

	/* Now count the payloads. */
	hdr->section_count = ictx->sect_count;
	while (sctx) {
		hdr->image_blocks += sctx->size / SB_BLOCK_SIZE;
		sctx = sctx->sect;
	}

	if (!ictx->sect_boot_found) {
		fprintf(stderr, "ERR: No bootable section selected!\n");
		return -EINVAL;
	}
	hdr->first_boot_section_id = ictx->sect_boot;

	/* The n * SB section size in blocks. */
	sections_blocks = hdr->section_count * hdr->section_header_size;
	hdr->image_blocks += sections_blocks;

	/* Key dictionary offset. */
	hdr->key_dictionary_block = hdr->header_blocks + sections_blocks;

	/* Digest of the whole image. */
	hdr->image_blocks += 2;

	/* Pointer past the dictionary. */
	hdr->first_boot_tag_block =
		hdr->key_dictionary_block + kd_size / SB_BLOCK_SIZE;

	/* Compute header digest. */
	EVP_MD_CTX_init(&md_ctx);

	EVP_DigestInit(&md_ctx, EVP_sha1());
	EVP_DigestUpdate(&md_ctx, hdr->signature1,
			 sizeof(struct sb_boot_image_header) -
			 sizeof(hdr->digest));
	EVP_DigestFinal(&md_ctx, hdr->digest, NULL);

	return 0;
}

static int sb_fixup_sections_and_tags(struct sb_image_ctx *ictx)
{
	/* Fixup the placement of sections. */
	struct sb_boot_image_header *ihdr = &ictx->payload;
	struct sb_section_ctx *sctx = ictx->sect_head;
	struct sb_sections_header *shdr;
	struct sb_cmd_ctx *cctx;
	struct sb_command *ccmd;
	uint32_t offset = ihdr->first_boot_tag_block;

	while (sctx) {
		shdr = &sctx->payload;

		/* Fill in the section TAG offset. */
		shdr->section_offset = offset + 1;
		offset += shdr->section_size;

		/* Section length is measured from the TAG block. */
		shdr->section_size--;

		/* Fixup the TAG command. */
		cctx = sctx->cmd_head;
		while (cctx) {
			ccmd = &cctx->payload;
			if (ccmd->header.tag == ROM_TAG_CMD) {
				ccmd->tag.section_number = shdr->section_number;
				ccmd->tag.section_length = shdr->section_size;
				ccmd->tag.section_flags = shdr->section_flags;
			}

			/* Update the command checksum. */
			ccmd->header.checksum = sb_command_checksum(ccmd);

			cctx = cctx->cmd;
		}

		sctx = sctx->sect;
	}

	return 0;
}

static int sb_parse_line(struct sb_image_ctx *ictx, struct sb_cmd_list *cmd)
{
	char *tok;
	char *line = cmd->cmd;
	char *rptr;
	int ret;

	/* Analyze the identifier on this line first. */
	tok = strtok_r(line, " ", &rptr);
	if (!tok || (strlen(tok) == 0)) {
		fprintf(stderr, "#%i ERR: Invalid line!\n", cmd->lineno);
		return -EINVAL;
	}

	cmd->cmd = rptr;

	/* DCD */
	if (!strcmp(tok, "DCD")) {
		ictx->in_section = 0;
		ictx->in_dcd = 1;
		sb_build_dcd(ictx, cmd);
		return 0;
	}

	/* Section */
	if (!strcmp(tok, "SECTION")) {
		ictx->in_section = 1;
		ictx->in_dcd = 0;
		sb_build_section(ictx, cmd);
		return 0;
	}

	if (!ictx->in_section && !ictx->in_dcd) {
		fprintf(stderr, "#%i ERR: Data outside of a section!\n",
			cmd->lineno);
		return -EINVAL;
	}

	if (ictx->in_section) {
		/* Section commands */
		if (!strcmp(tok, "NOP")) {
			ret = sb_build_command_nop(ictx);
		} else if (!strcmp(tok, "TAG")) {
			ret = sb_build_command_tag(ictx, cmd);
		} else if (!strcmp(tok, "LOAD")) {
			ret = sb_build_command_load(ictx, cmd);
		} else if (!strcmp(tok, "FILL")) {
			ret = sb_build_command_fill(ictx, cmd);
		} else if (!strcmp(tok, "JUMP")) {
			ret = sb_build_command_jump(ictx, cmd);
		} else if (!strcmp(tok, "CALL")) {
			ret = sb_build_command_call(ictx, cmd);
		} else if (!strcmp(tok, "MODE")) {
			ret = sb_build_command_mode(ictx, cmd);
		} else {
			fprintf(stderr,
				"#%i ERR: Unsupported instruction '%s'!\n",
				cmd->lineno, tok);
			return -ENOTSUP;
		}
	} else if (ictx->in_dcd) {
		char *lptr;
		uint32_t ilen = '1';

		tok = strtok_r(tok, ".", &lptr);
		if (!tok || (strlen(tok) == 0) || (lptr && strlen(lptr) != 1)) {
			fprintf(stderr, "#%i ERR: Invalid line!\n",
				cmd->lineno);
			return -EINVAL;
		}

		if (lptr &&
		    (lptr[0] != '1' && lptr[0] != '2' && lptr[0] != '4')) {
			fprintf(stderr, "#%i ERR: Invalid instruction width!\n",
				cmd->lineno);
			return -EINVAL;
		}

		if (lptr)
			ilen = lptr[0] - '1';

		/* DCD commands */
		if (!strcmp(tok, "WRITE")) {
			ret = sb_build_dcd_block(ictx, cmd,
						 SB_DCD_WRITE | ilen);
		} else if (!strcmp(tok, "ANDC")) {
			ret = sb_build_dcd_block(ictx, cmd,
						 SB_DCD_ANDC | ilen);
		} else if (!strcmp(tok, "ORR")) {
			ret = sb_build_dcd_block(ictx, cmd,
						 SB_DCD_ORR | ilen);
		} else if (!strcmp(tok, "EQZ")) {
			ret = sb_build_dcd_block(ictx, cmd,
						 SB_DCD_CHK_EQZ | ilen);
		} else if (!strcmp(tok, "EQ")) {
			ret = sb_build_dcd_block(ictx, cmd,
						 SB_DCD_CHK_EQ | ilen);
		} else if (!strcmp(tok, "NEQ")) {
			ret = sb_build_dcd_block(ictx, cmd,
						 SB_DCD_CHK_NEQ | ilen);
		} else if (!strcmp(tok, "NEZ")) {
			ret = sb_build_dcd_block(ictx, cmd,
						 SB_DCD_CHK_NEZ | ilen);
		} else if (!strcmp(tok, "NOOP")) {
			ret = sb_build_dcd_block(ictx, cmd, SB_DCD_NOOP);
		} else {
			fprintf(stderr,
				"#%i ERR: Unsupported instruction '%s'!\n",
				cmd->lineno, tok);
			return -ENOTSUP;
		}
	} else {
		fprintf(stderr, "#%i ERR: Unsupported instruction '%s'!\n",
			cmd->lineno, tok);
		return -ENOTSUP;
	}

	/*
	 * Here we have at least one section with one command, otherwise we
	 * would have failed already higher above.
	 *
	 * FIXME -- should the updating happen here ?
	 */
	if (ictx->in_section && !ret) {
		ictx->sect_tail->size += ictx->sect_tail->cmd_tail->size;
		ictx->sect_tail->payload.section_size =
			ictx->sect_tail->size / SB_BLOCK_SIZE;
	}

	return ret;
}

static int sb_load_cmdfile(struct sb_image_ctx *ictx)
{
	struct sb_cmd_list cmd;
	int lineno = 1;
	FILE *fp;
	char *line = NULL;
	ssize_t rlen;
	size_t len;

	fp = fopen(ictx->cfg_filename, "r");
	if (!fp)
		goto err_file;

	while ((rlen = getline(&line, &len, fp)) > 0) {
		memset(&cmd, 0, sizeof(cmd));

		/* Strip the trailing newline. */
		line[rlen - 1] = '\0';

		cmd.cmd = line;
		cmd.len = rlen;
		cmd.lineno = lineno++;

		sb_parse_line(ictx, &cmd);
	}

	free(line);

	fclose(fp);

	return 0;

err_file:
	fclose(fp);
	fprintf(stderr, "ERR: Failed to load file \"%s\"\n",
		ictx->cfg_filename);
	return -EINVAL;
}

static int sb_build_tree_from_cfg(struct sb_image_ctx *ictx)
{
	int ret;

	ret = sb_load_cmdfile(ictx);
	if (ret)
		return ret;

	ret = sb_prefill_image_header(ictx);
	if (ret)
		return ret;

	ret = sb_postfill_image_header(ictx);
	if (ret)
		return ret;

	ret = sb_fixup_sections_and_tags(ictx);
	if (ret)
		return ret;

	return 0;
}

static int sb_verify_image_header(struct sb_image_ctx *ictx,
				  FILE *fp, long fsize)
{
	/* Verify static fields in the image header. */
	struct sb_boot_image_header *hdr = &ictx->payload;
	const char *stat[2] = { "[PASS]", "[FAIL]" };
	struct tm tm;
	int sz, ret = 0;
	unsigned char digest[20];
	EVP_MD_CTX md_ctx;
	unsigned long size;

	/* Start image-wide crypto. */
	EVP_MD_CTX_init(&ictx->md_ctx);
	EVP_DigestInit(&ictx->md_ctx, EVP_sha1());

	soprintf(ictx, "---------- Verifying SB Image Header ----------\n");

	size = fread(&ictx->payload, 1, sizeof(ictx->payload), fp);
	if (size != sizeof(ictx->payload)) {
		fprintf(stderr, "ERR: SB image header too short!\n");
		return -EINVAL;
	}

	/* Compute header digest. */
	EVP_MD_CTX_init(&md_ctx);
	EVP_DigestInit(&md_ctx, EVP_sha1());
	EVP_DigestUpdate(&md_ctx, hdr->signature1,
			 sizeof(struct sb_boot_image_header) -
			 sizeof(hdr->digest));
	EVP_DigestFinal(&md_ctx, digest, NULL);

	sb_aes_init(ictx, NULL, 1);
	sb_encrypt_sb_header(ictx);

	if (memcmp(digest, hdr->digest, 20))
		ret = -EINVAL;
	soprintf(ictx, "%s Image header checksum:        %s\n", stat[!!ret],
		 ret ? "BAD" : "OK");
	if (ret)
		return ret;

	if (memcmp(hdr->signature1, "STMP", 4) ||
	    memcmp(hdr->signature2, "sgtl", 4))
		ret = -EINVAL;
	soprintf(ictx, "%s Signatures:                   '%.4s' '%.4s'\n",
		 stat[!!ret], hdr->signature1, hdr->signature2);
	if (ret)
		return ret;

	if ((hdr->major_version != SB_VERSION_MAJOR) ||
	    ((hdr->minor_version != 1) && (hdr->minor_version != 2)))
		ret = -EINVAL;
	soprintf(ictx, "%s Image version:                v%i.%i\n", stat[!!ret],
		 hdr->major_version, hdr->minor_version);
	if (ret)
		return ret;

	ret = sb_get_time(hdr->timestamp_us / 1000000, &tm);
	soprintf(ictx,
		 "%s Creation time:                %02i:%02i:%02i %02i/%02i/%04i\n",
		 stat[!!ret], tm.tm_hour, tm.tm_min, tm.tm_sec,
		 tm.tm_mday, tm.tm_mon, tm.tm_year + 2000);
	if (ret)
		return ret;

	soprintf(ictx, "%s Product version:              %x.%x.%x\n", stat[0],
		 ntohs(hdr->product_version.major),
		 ntohs(hdr->product_version.minor),
		 ntohs(hdr->product_version.revision));
	soprintf(ictx, "%s Component version:            %x.%x.%x\n", stat[0],
		 ntohs(hdr->component_version.major),
		 ntohs(hdr->component_version.minor),
		 ntohs(hdr->component_version.revision));

	if (hdr->flags & ~SB_IMAGE_FLAG_VERBOSE)
		ret = -EINVAL;
	soprintf(ictx, "%s Image flags:                  %s\n", stat[!!ret],
		 hdr->flags & SB_IMAGE_FLAG_VERBOSE ? "Verbose_boot" : "");
	if (ret)
		return ret;

	if (hdr->drive_tag != 0)
		ret = -EINVAL;
	soprintf(ictx, "%s Drive tag:                    %i\n", stat[!!ret],
		 hdr->drive_tag);
	if (ret)
		return ret;

	sz = sizeof(struct sb_boot_image_header) / SB_BLOCK_SIZE;
	if (hdr->header_blocks != sz)
		ret = -EINVAL;
	soprintf(ictx, "%s Image header size (blocks):   %i\n", stat[!!ret],
		 hdr->header_blocks);
	if (ret)
		return ret;

	sz = sizeof(struct sb_sections_header) / SB_BLOCK_SIZE;
	if (hdr->section_header_size != sz)
		ret = -EINVAL;
	soprintf(ictx, "%s Section header size (blocks): %i\n", stat[!!ret],
		 hdr->section_header_size);
	if (ret)
		return ret;

	soprintf(ictx, "%s Sections count:               %i\n", stat[!!ret],
		 hdr->section_count);
	soprintf(ictx, "%s First bootable section        %i\n", stat[!!ret],
		 hdr->first_boot_section_id);

	if (hdr->image_blocks != fsize / SB_BLOCK_SIZE)
		ret = -EINVAL;
	soprintf(ictx, "%s Image size (blocks):          %i\n", stat[!!ret],
		 hdr->image_blocks);
	if (ret)
		return ret;

	sz = hdr->header_blocks + hdr->section_header_size * hdr->section_count;
	if (hdr->key_dictionary_block != sz)
		ret = -EINVAL;
	soprintf(ictx, "%s Key dict offset (blocks):     %i\n", stat[!!ret],
		 hdr->key_dictionary_block);
	if (ret)
		return ret;

	if (hdr->key_count != 1)
		ret = -EINVAL;
	soprintf(ictx, "%s Number of encryption keys:    %i\n", stat[!!ret],
		 hdr->key_count);
	if (ret)
		return ret;

	sz = hdr->header_blocks + hdr->section_header_size * hdr->section_count;
	sz += hdr->key_count *
		sizeof(struct sb_key_dictionary_key) / SB_BLOCK_SIZE;
	if (hdr->first_boot_tag_block != (unsigned)sz)
		ret = -EINVAL;
	soprintf(ictx, "%s First TAG block (blocks):     %i\n", stat[!!ret],
		 hdr->first_boot_tag_block);
	if (ret)
		return ret;

	return 0;
}

static void sb_decrypt_tag(struct sb_image_ctx *ictx,
		struct sb_cmd_ctx *cctx)
{
	EVP_MD_CTX *md_ctx = &ictx->md_ctx;
	struct sb_command *cmd = &cctx->payload;

	sb_aes_crypt(ictx, (uint8_t *)&cctx->c_payload,
		     (uint8_t *)&cctx->payload, sizeof(*cmd));
	EVP_DigestUpdate(md_ctx, &cctx->c_payload, sizeof(*cmd));
}

static int sb_verify_command(struct sb_image_ctx *ictx,
			     struct sb_cmd_ctx *cctx, FILE *fp,
			     unsigned long *tsize)
{
	struct sb_command *ccmd = &cctx->payload;
	unsigned long size, asize;
	char *csum, *flag = "";
	int ret;
	unsigned int i;
	uint8_t csn, csc = ccmd->header.checksum;
	ccmd->header.checksum = 0x5a;
	csn = sb_command_checksum(ccmd);
	ccmd->header.checksum = csc;

	if (csc == csn)
		ret = 0;
	else
		ret = -EINVAL;
	csum = ret ? "checksum BAD" : "checksum OK";

	switch (ccmd->header.tag) {
	case ROM_NOP_CMD:
		soprintf(ictx, " NOOP # %s\n", csum);
		return ret;
	case ROM_TAG_CMD:
		if (ccmd->header.flags & ROM_TAG_CMD_FLAG_ROM_LAST_TAG)
			flag = "LAST";
		soprintf(ictx, " TAG %s # %s\n", flag, csum);
		sb_aes_reinit(ictx, 0);
		return ret;
	case ROM_LOAD_CMD:
		soprintf(ictx, " LOAD addr=0x%08x length=0x%08x # %s\n",
			 ccmd->load.address, ccmd->load.count, csum);

		cctx->length = ccmd->load.count;
		asize = roundup(cctx->length, SB_BLOCK_SIZE);
		cctx->data = malloc(asize);
		if (!cctx->data)
			return -ENOMEM;

		size = fread(cctx->data, 1, asize, fp);
		if (size != asize) {
			fprintf(stderr,
				"ERR: SB LOAD command payload too short!\n");
			return -EINVAL;
		}

		*tsize += size;

		EVP_DigestUpdate(&ictx->md_ctx, cctx->data, asize);
		sb_aes_crypt(ictx, cctx->data, cctx->data, asize);

		if (ccmd->load.crc32 != crc32(cctx->data, asize)) {
			fprintf(stderr,
				"ERR: SB LOAD command payload CRC32 invalid!\n");
			return -EINVAL;
		}
		return 0;
	case ROM_FILL_CMD:
		soprintf(ictx,
			 " FILL addr=0x%08x length=0x%08x pattern=0x%08x # %s\n",
			 ccmd->fill.address, ccmd->fill.count,
			 ccmd->fill.pattern, csum);
		return 0;
	case ROM_JUMP_CMD:
		if (ccmd->header.flags & ROM_JUMP_CMD_FLAG_HAB)
			flag = " HAB";
		soprintf(ictx,
			 " JUMP%s addr=0x%08x r0_arg=0x%08x # %s\n",
			 flag, ccmd->fill.address, ccmd->jump.argument, csum);
		return 0;
	case ROM_CALL_CMD:
		if (ccmd->header.flags & ROM_CALL_CMD_FLAG_HAB)
			flag = " HAB";
		soprintf(ictx,
			 " CALL%s addr=0x%08x r0_arg=0x%08x # %s\n",
			 flag, ccmd->fill.address, ccmd->jump.argument, csum);
		return 0;
	case ROM_MODE_CMD:
		for (i = 0; i < ARRAY_SIZE(modetable); i++) {
			if (ccmd->mode.mode == modetable[i].mode) {
				soprintf(ictx, " MODE %s # %s\n",
					 modetable[i].name, csum);
				break;
			}
		}
		fprintf(stderr, " MODE !INVALID! # %s\n", csum);
		return 0;
	}

	return ret;
}

static int sb_verify_commands(struct sb_image_ctx *ictx,
			      struct sb_section_ctx *sctx, FILE *fp)
{
	unsigned long size, tsize = 0;
	struct sb_cmd_ctx *cctx;
	int ret;

	sb_aes_reinit(ictx, 0);

	while (tsize < sctx->size) {
		cctx = calloc(1, sizeof(*cctx));
		if (!cctx)
			return -ENOMEM;
		if (!sctx->cmd_head) {
			sctx->cmd_head = cctx;
			sctx->cmd_tail = cctx;
		} else {
			sctx->cmd_tail->cmd = cctx;
			sctx->cmd_tail = cctx;
		}

		size = fread(&cctx->c_payload, 1, sizeof(cctx->c_payload), fp);
		if (size != sizeof(cctx->c_payload)) {
			fprintf(stderr, "ERR: SB command header too short!\n");
			return -EINVAL;
		}

		tsize += size;

		sb_decrypt_tag(ictx, cctx);

		ret = sb_verify_command(ictx, cctx, fp, &tsize);
		if (ret)
			return -EINVAL;
	}

	return 0;
}

static int sb_verify_sections_cmds(struct sb_image_ctx *ictx, FILE *fp)
{
	struct sb_boot_image_header *hdr = &ictx->payload;
	struct sb_sections_header *shdr;
	unsigned int i;
	int ret;
	struct sb_section_ctx *sctx;
	unsigned long size;
	char *bootable = "";

	soprintf(ictx, "----- Verifying  SB Sections and Commands -----\n");

	for (i = 0; i < hdr->section_count; i++) {
		sctx = calloc(1, sizeof(*sctx));
		if (!sctx)
			return -ENOMEM;
		if (!ictx->sect_head) {
			ictx->sect_head = sctx;
			ictx->sect_tail = sctx;
		} else {
			ictx->sect_tail->sect = sctx;
			ictx->sect_tail = sctx;
		}

		size = fread(&sctx->payload, 1, sizeof(sctx->payload), fp);
		if (size != sizeof(sctx->payload)) {
			fprintf(stderr, "ERR: SB section header too short!\n");
			return -EINVAL;
		}
	}

	size = fread(&ictx->sb_dict_key, 1, sizeof(ictx->sb_dict_key), fp);
	if (size != sizeof(ictx->sb_dict_key)) {
		fprintf(stderr, "ERR: SB key dictionary too short!\n");
		return -EINVAL;
	}

	sb_encrypt_sb_sections_header(ictx);
	sb_aes_reinit(ictx, 0);
	sb_decrypt_key_dictionary_key(ictx);

	sb_aes_reinit(ictx, 0);

	sctx = ictx->sect_head;
	while (sctx) {
		shdr = &sctx->payload;

		if (shdr->section_flags & SB_SECTION_FLAG_BOOTABLE) {
			sctx->boot = 1;
			bootable = " BOOTABLE";
		}

		sctx->size = (shdr->section_size * SB_BLOCK_SIZE) +
			     sizeof(struct sb_command);
		soprintf(ictx, "SECTION 0x%x%s # size = %i bytes\n",
			 shdr->section_number, bootable, sctx->size);

		if (shdr->section_flags & ~SB_SECTION_FLAG_BOOTABLE)
			fprintf(stderr, " WARN: Unknown section flag(s) %08x\n",
				shdr->section_flags);

		if ((shdr->section_flags & SB_SECTION_FLAG_BOOTABLE) &&
		    (hdr->first_boot_section_id != shdr->section_number)) {
			fprintf(stderr,
				" WARN: Bootable section does ID not match image header ID!\n");
		}

		ret = sb_verify_commands(ictx, sctx, fp);
		if (ret)
			return ret;

		sctx = sctx->sect;
	}

	/*
	 * FIXME IDEA:
	 * check if the first TAG command is at sctx->section_offset
	 */
	return 0;
}

static int sb_verify_image_end(struct sb_image_ctx *ictx,
			       FILE *fp, off_t filesz)
{
	uint8_t digest[32];
	unsigned long size;
	off_t pos;
	int ret;

	soprintf(ictx, "------------- Verifying image end -------------\n");

	size = fread(digest, 1, sizeof(digest), fp);
	if (size != sizeof(digest)) {
		fprintf(stderr, "ERR: SB key dictionary too short!\n");
		return -EINVAL;
	}

	pos = ftell(fp);
	if (pos != filesz) {
		fprintf(stderr, "ERR: Trailing data past the image!\n");
		return -EINVAL;
	}

	/* Check the image digest. */
	EVP_DigestFinal(&ictx->md_ctx, ictx->digest, NULL);

	/* Decrypt the image digest from the input image. */
	sb_aes_reinit(ictx, 0);
	sb_aes_crypt(ictx, digest, digest, sizeof(digest));

	/* Check all of 20 bytes of the SHA1 hash. */
	ret = memcmp(digest, ictx->digest, 20) ? -EINVAL : 0;

	if (ret)
		soprintf(ictx, "[FAIL] Full-image checksum:          BAD\n");
	else
		soprintf(ictx, "[PASS] Full-image checksum:          OK\n");

	return ret;
}


static int sb_build_tree_from_img(struct sb_image_ctx *ictx)
{
	long filesize;
	int ret;
	FILE *fp;

	if (!ictx->input_filename) {
		fprintf(stderr, "ERR: Missing filename!\n");
		return -EINVAL;
	}

	fp = fopen(ictx->input_filename, "r");
	if (!fp)
		goto err_open;

	ret = fseek(fp, 0, SEEK_END);
	if (ret < 0)
		goto err_file;

	filesize = ftell(fp);
	if (filesize < 0)
		goto err_file;

	ret = fseek(fp, 0, SEEK_SET);
	if (ret < 0)
		goto err_file;

	if (filesize < (signed)sizeof(ictx->payload)) {
		fprintf(stderr, "ERR: File too short!\n");
		goto err_file;
	}

	if (filesize & (SB_BLOCK_SIZE - 1)) {
		fprintf(stderr, "ERR: The file is not aligned!\n");
		goto err_file;
	}

	/* Load and verify image header */
	ret = sb_verify_image_header(ictx, fp, filesize);
	if (ret)
		goto err_verify;

	/* Load and verify sections and commands */
	ret = sb_verify_sections_cmds(ictx, fp);
	if (ret)
		goto err_verify;

	ret = sb_verify_image_end(ictx, fp, filesize);
	if (ret)
		goto err_verify;

	ret = 0;

err_verify:
	soprintf(ictx, "-------------------- Result -------------------\n");
	soprintf(ictx, "Verification %s\n", ret ? "FAILED" : "PASSED");

	/* Stop the encryption session. */
	sb_aes_deinit(&ictx->cipher_ctx);

	fclose(fp);
	return ret;

err_file:
	fclose(fp);
err_open:
	fprintf(stderr, "ERR: Failed to load file \"%s\"\n",
		ictx->input_filename);
	return -EINVAL;
}

static void sb_free_image(struct sb_image_ctx *ictx)
{
	struct sb_section_ctx *sctx = ictx->sect_head, *s_head;
	struct sb_dcd_ctx *dctx = ictx->dcd_head, *d_head;
	struct sb_cmd_ctx *cctx, *c_head;

	while (sctx) {
		s_head = sctx;
		c_head = sctx->cmd_head;

		while (c_head) {
			cctx = c_head;
			c_head = c_head->cmd;
			if (cctx->data)
				free(cctx->data);
			free(cctx);
		}

		sctx = sctx->sect;
		free(s_head);
	}

	while (dctx) {
		d_head = dctx;
		dctx = dctx->dcd;
		free(d_head->payload);
		free(d_head);
	}
}

/*
 * MXSSB-MKIMAGE glue code.
 */
static int mxsimage_check_image_types(uint8_t type)
{
	if (type == IH_TYPE_MXSIMAGE)
		return EXIT_SUCCESS;
	else
		return EXIT_FAILURE;
}

static void mxsimage_set_header(void *ptr, struct stat *sbuf, int ifd,
				struct image_tool_params *params)
{
}

int mxsimage_check_params(struct image_tool_params *params)
{
	if (!params)
		return -1;
	if (!strlen(params->imagename)) {
		fprintf(stderr,
			"Error: %s - Configuration file not specified, it is needed for mxsimage generation\n",
			params->cmdname);
		return -1;
	}

	/*
	 * Check parameters:
	 * XIP is not allowed and verify that incompatible
	 * parameters are not sent at the same time
	 * For example, if list is required a data image must not be provided
	 */
	return	(params->dflag && (params->fflag || params->lflag)) ||
		(params->fflag && (params->dflag || params->lflag)) ||
		(params->lflag && (params->dflag || params->fflag)) ||
		(params->xflag) || !(strlen(params->imagename));
}

static int mxsimage_verify_print_header(char *file, int silent)
{
	int ret;
	struct sb_image_ctx ctx;

	memset(&ctx, 0, sizeof(ctx));

	ctx.input_filename = file;
	ctx.silent_dump = silent;

	ret = sb_build_tree_from_img(&ctx);
	sb_free_image(&ctx);

	return ret;
}

char *imagefile;
static int mxsimage_verify_header(unsigned char *ptr, int image_size,
			struct image_tool_params *params)
{
	struct sb_boot_image_header *hdr;

	if (!ptr)
		return -EINVAL;

	hdr = (struct sb_boot_image_header *)ptr;

	/*
	 * Check if the header contains the MXS image signatures,
	 * if so, do a full-image verification.
	 */
	if (memcmp(hdr->signature1, "STMP", 4) ||
	    memcmp(hdr->signature2, "sgtl", 4))
		return -EINVAL;

	imagefile = params->imagefile;

	return mxsimage_verify_print_header(params->imagefile, 1);
}

static void mxsimage_print_header(const void *hdr)
{
	if (imagefile)
		mxsimage_verify_print_header(imagefile, 0);
}

static int sb_build_image(struct sb_image_ctx *ictx,
			  struct image_type_params *tparams)
{
	struct sb_boot_image_header *sb_header = &ictx->payload;
	struct sb_section_ctx *sctx;
	struct sb_cmd_ctx *cctx;
	struct sb_command *ccmd;
	struct sb_key_dictionary_key *sb_dict_key = &ictx->sb_dict_key;

	uint8_t *image, *iptr;

	/* Calculate image size. */
	uint32_t size = sizeof(*sb_header) +
		ictx->sect_count * sizeof(struct sb_sections_header) +
		sizeof(*sb_dict_key) + sizeof(ictx->digest);

	sctx = ictx->sect_head;
	while (sctx) {
		size += sctx->size;
		sctx = sctx->sect;
	};

	image = malloc(size);
	if (!image)
		return -ENOMEM;
	iptr = image;

	memcpy(iptr, sb_header, sizeof(*sb_header));
	iptr += sizeof(*sb_header);

	sctx = ictx->sect_head;
	while (sctx) {
		memcpy(iptr, &sctx->payload, sizeof(struct sb_sections_header));
		iptr += sizeof(struct sb_sections_header);
		sctx = sctx->sect;
	};

	memcpy(iptr, sb_dict_key, sizeof(*sb_dict_key));
	iptr += sizeof(*sb_dict_key);

	sctx = ictx->sect_head;
	while (sctx) {
		cctx = sctx->cmd_head;
		while (cctx) {
			ccmd = &cctx->payload;

			memcpy(iptr, &cctx->c_payload, sizeof(cctx->payload));
			iptr += sizeof(cctx->payload);

			if (ccmd->header.tag == ROM_LOAD_CMD) {
				memcpy(iptr, cctx->data, cctx->length);
				iptr += cctx->length;
			}

			cctx = cctx->cmd;
		}

		sctx = sctx->sect;
	};

	memcpy(iptr, ictx->digest, sizeof(ictx->digest));
	iptr += sizeof(ictx->digest);

	/* Configure the mkimage */
	tparams->hdr = image;
	tparams->header_size = size;

	return 0;
}

static int mxsimage_generate(struct image_tool_params *params,
	struct image_type_params *tparams)
{
	int ret;
	struct sb_image_ctx ctx;

	/* Do not copy the U-Boot image! */
	params->skipcpy = 1;

	memset(&ctx, 0, sizeof(ctx));

	ctx.cfg_filename = params->imagename;
	ctx.output_filename = params->imagefile;
	ctx.verbose_boot = 1;

	ret = sb_build_tree_from_cfg(&ctx);
	if (ret)
		goto fail;

	ret = sb_encrypt_image(&ctx);
	if (!ret)
		ret = sb_build_image(&ctx, tparams);

fail:
	sb_free_image(&ctx);

	return ret;
}

/*
 * mxsimage parameters
 */
static struct image_type_params mxsimage_params = {
	.name		= "Freescale MXS Boot Image support",
	.header_size	= 0,
	.hdr		= NULL,
	.check_image_type = mxsimage_check_image_types,
	.verify_header	= mxsimage_verify_header,
	.print_header	= mxsimage_print_header,
	.set_header	= mxsimage_set_header,
	.check_params	= mxsimage_check_params,
	.vrec_header	= mxsimage_generate,
};

void init_mxs_image_type(void)
{
	register_image_type(&mxsimage_params);
}

#else
void init_mxs_image_type(void)
{
}
#endif
