// SPDX-License-Identifier: GPL-2.0+
/*
 * Image manipulator for Marvell SoCs
 *  supports Kirkwood, Dove, Armada 370, Armada XP, Armada 375, Armada 38x and
 *  Armada 39x
 *
 * (C) Copyright 2013 Thomas Petazzoni
 * <thomas.petazzoni@free-electrons.com>
 *
 * (C) Copyright 2022 Pali Rohár <pali@kernel.org>
 */

#define OPENSSL_API_COMPAT 0x10101000L

#include "imagetool.h"
#include <limits.h>
#include <image.h>
#include <stdarg.h>
#include <stdint.h>
#include "kwbimage.h"

#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/evp.h>

#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
    (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
static void RSA_get0_key(const RSA *r,
                 const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
{
   if (n != NULL)
       *n = r->n;
   if (e != NULL)
       *e = r->e;
   if (d != NULL)
       *d = r->d;
}

#elif !defined(LIBRESSL_VERSION_NUMBER)
void EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
{
	EVP_MD_CTX_reset(ctx);
}
#endif

/* fls - find last (most-significant) bit set in 4-bit integer */
static inline int fls4(int num)
{
	if (num & 0x8)
		return 4;
	else if (num & 0x4)
		return 3;
	else if (num & 0x2)
		return 2;
	else if (num & 0x1)
		return 1;
	else
		return 0;
}

static struct image_cfg_element *image_cfg;
static int cfgn;
static int verbose_mode;

struct boot_mode {
	unsigned int id;
	const char *name;
};

/*
 * SHA2-256 hash
 */
struct hash_v1 {
	uint8_t hash[32];
};

struct boot_mode boot_modes[] = {
	{ IBR_HDR_I2C_ID, "i2c"  },
	{ IBR_HDR_SPI_ID, "spi"  },
	{ IBR_HDR_NAND_ID, "nand" },
	{ IBR_HDR_SATA_ID, "sata" },
	{ IBR_HDR_PEX_ID, "pex"  },
	{ IBR_HDR_UART_ID, "uart" },
	{ IBR_HDR_SDIO_ID, "sdio" },
	{},
};

struct nand_ecc_mode {
	unsigned int id;
	const char *name;
};

struct nand_ecc_mode nand_ecc_modes[] = {
	{ IBR_HDR_ECC_DEFAULT, "default" },
	{ IBR_HDR_ECC_FORCED_HAMMING, "hamming" },
	{ IBR_HDR_ECC_FORCED_RS, "rs" },
	{ IBR_HDR_ECC_DISABLED, "disabled" },
	{},
};

/* Used to identify an undefined execution or destination address */
#define ADDR_INVALID ((uint32_t)-1)

#define BINARY_MAX_ARGS 255

/* In-memory representation of a line of the configuration file */

enum image_cfg_type {
	IMAGE_CFG_VERSION = 0x1,
	IMAGE_CFG_BOOT_FROM,
	IMAGE_CFG_DEST_ADDR,
	IMAGE_CFG_EXEC_ADDR,
	IMAGE_CFG_NAND_BLKSZ,
	IMAGE_CFG_NAND_BADBLK_LOCATION,
	IMAGE_CFG_NAND_ECC_MODE,
	IMAGE_CFG_NAND_PAGESZ,
	IMAGE_CFG_CPU,
	IMAGE_CFG_BINARY,
	IMAGE_CFG_DATA,
	IMAGE_CFG_DATA_DELAY,
	IMAGE_CFG_BAUDRATE,
	IMAGE_CFG_UART_PORT,
	IMAGE_CFG_UART_MPP,
	IMAGE_CFG_DEBUG,
	IMAGE_CFG_KAK,
	IMAGE_CFG_CSK,
	IMAGE_CFG_CSK_INDEX,
	IMAGE_CFG_JTAG_DELAY,
	IMAGE_CFG_BOX_ID,
	IMAGE_CFG_FLASH_ID,
	IMAGE_CFG_SEC_COMMON_IMG,
	IMAGE_CFG_SEC_SPECIALIZED_IMG,
	IMAGE_CFG_SEC_BOOT_DEV,
	IMAGE_CFG_SEC_FUSE_DUMP,

	IMAGE_CFG_COUNT
} type;

static const char * const id_strs[] = {
	[IMAGE_CFG_VERSION] = "VERSION",
	[IMAGE_CFG_BOOT_FROM] = "BOOT_FROM",
	[IMAGE_CFG_DEST_ADDR] = "DEST_ADDR",
	[IMAGE_CFG_EXEC_ADDR] = "EXEC_ADDR",
	[IMAGE_CFG_NAND_BLKSZ] = "NAND_BLKSZ",
	[IMAGE_CFG_NAND_BADBLK_LOCATION] = "NAND_BADBLK_LOCATION",
	[IMAGE_CFG_NAND_ECC_MODE] = "NAND_ECC_MODE",
	[IMAGE_CFG_NAND_PAGESZ] = "NAND_PAGE_SIZE",
	[IMAGE_CFG_CPU] = "CPU",
	[IMAGE_CFG_BINARY] = "BINARY",
	[IMAGE_CFG_DATA] = "DATA",
	[IMAGE_CFG_DATA_DELAY] = "DATA_DELAY",
	[IMAGE_CFG_BAUDRATE] = "BAUDRATE",
	[IMAGE_CFG_UART_PORT] = "UART_PORT",
	[IMAGE_CFG_UART_MPP] = "UART_MPP",
	[IMAGE_CFG_DEBUG] = "DEBUG",
	[IMAGE_CFG_KAK] = "KAK",
	[IMAGE_CFG_CSK] = "CSK",
	[IMAGE_CFG_CSK_INDEX] = "CSK_INDEX",
	[IMAGE_CFG_JTAG_DELAY] = "JTAG_DELAY",
	[IMAGE_CFG_BOX_ID] = "BOX_ID",
	[IMAGE_CFG_FLASH_ID] = "FLASH_ID",
	[IMAGE_CFG_SEC_COMMON_IMG] = "SEC_COMMON_IMG",
	[IMAGE_CFG_SEC_SPECIALIZED_IMG] = "SEC_SPECIALIZED_IMG",
	[IMAGE_CFG_SEC_BOOT_DEV] = "SEC_BOOT_DEV",
	[IMAGE_CFG_SEC_FUSE_DUMP] = "SEC_FUSE_DUMP"
};

struct image_cfg_element {
	enum image_cfg_type type;
	union {
		unsigned int version;
		unsigned int cpu_sheeva;
		unsigned int bootfrom;
		struct {
			const char *file;
			unsigned int loadaddr;
			unsigned int args[BINARY_MAX_ARGS];
			unsigned int nargs;
		} binary;
		unsigned int dstaddr;
		unsigned int execaddr;
		unsigned int nandblksz;
		unsigned int nandbadblklocation;
		unsigned int nandeccmode;
		unsigned int nandpagesz;
		struct ext_hdr_v0_reg regdata;
		unsigned int regdata_delay;
		unsigned int baudrate;
		unsigned int uart_port;
		unsigned int uart_mpp;
		unsigned int debug;
		const char *key_name;
		int csk_idx;
		uint8_t jtag_delay;
		uint32_t boxid;
		uint32_t flashid;
		bool sec_specialized_img;
		unsigned int sec_boot_dev;
		const char *name;
	};
};

#define IMAGE_CFG_ELEMENT_MAX 256

/*
 * Utility functions to manipulate boot mode and ecc modes (convert
 * them back and forth between description strings and the
 * corresponding numerical identifiers).
 */

static const char *image_boot_mode_name(unsigned int id)
{
	int i;

	for (i = 0; boot_modes[i].name; i++)
		if (boot_modes[i].id == id)
			return boot_modes[i].name;
	return NULL;
}

static int image_boot_mode_id(const char *boot_mode_name)
{
	int i;

	for (i = 0; boot_modes[i].name; i++)
		if (!strcmp(boot_modes[i].name, boot_mode_name))
			return boot_modes[i].id;

	return -1;
}

static const char *image_nand_ecc_mode_name(unsigned int id)
{
	int i;

	for (i = 0; nand_ecc_modes[i].name; i++)
		if (nand_ecc_modes[i].id == id)
			return nand_ecc_modes[i].name;

	return NULL;
}

static int image_nand_ecc_mode_id(const char *nand_ecc_mode_name)
{
	int i;

	for (i = 0; nand_ecc_modes[i].name; i++)
		if (!strcmp(nand_ecc_modes[i].name, nand_ecc_mode_name))
			return nand_ecc_modes[i].id;
	return -1;
}

static struct image_cfg_element *
image_find_option(unsigned int optiontype)
{
	int i;

	for (i = 0; i < cfgn; i++) {
		if (image_cfg[i].type == optiontype)
			return &image_cfg[i];
	}

	return NULL;
}

static unsigned int
image_count_options(unsigned int optiontype)
{
	int i;
	unsigned int count = 0;

	for (i = 0; i < cfgn; i++)
		if (image_cfg[i].type == optiontype)
			count++;

	return count;
}

static int image_get_csk_index(void)
{
	struct image_cfg_element *e;

	e = image_find_option(IMAGE_CFG_CSK_INDEX);
	if (!e)
		return -1;

	return e->csk_idx;
}

static bool image_get_spezialized_img(void)
{
	struct image_cfg_element *e;

	e = image_find_option(IMAGE_CFG_SEC_SPECIALIZED_IMG);
	if (!e)
		return false;

	return e->sec_specialized_img;
}

static int image_get_bootfrom(void)
{
	struct image_cfg_element *e;

	e = image_find_option(IMAGE_CFG_BOOT_FROM);
	if (!e)
		/* fallback to SPI if no BOOT_FROM is not provided */
		return IBR_HDR_SPI_ID;

	return e->bootfrom;
}

static int image_is_cpu_sheeva(void)
{
	struct image_cfg_element *e;

	e = image_find_option(IMAGE_CFG_CPU);
	if (!e)
		return 0;

	return e->cpu_sheeva;
}

/*
 * Compute a 8-bit checksum of a memory area. This algorithm follows
 * the requirements of the Marvell SoC BootROM specifications.
 */
static uint8_t image_checksum8(void *start, uint32_t len)
{
	uint8_t csum = 0;
	uint8_t *p = start;

	/* check len and return zero checksum if invalid */
	if (!len)
		return 0;

	do {
		csum += *p;
		p++;
	} while (--len);

	return csum;
}

/*
 * Verify checksum over a complete header that includes the checksum field.
 * Return 1 when OK, otherwise 0.
 */
static int main_hdr_checksum_ok(void *hdr)
{
	/* Offsets of checksum in v0 and v1 headers are the same */
	struct main_hdr_v0 *main_hdr = (struct main_hdr_v0 *)hdr;
	uint8_t checksum;

	checksum = image_checksum8(hdr, kwbheader_size_for_csum(hdr));
	/* Calculated checksum includes the header checksum field. Compensate
	 * for that.
	 */
	checksum -= main_hdr->checksum;

	return checksum == main_hdr->checksum;
}

static uint32_t image_checksum32(void *start, uint32_t len)
{
	uint32_t csum = 0;
	uint32_t *p = start;

	/* check len and return zero checksum if invalid */
	if (!len)
		return 0;

	if (len % sizeof(uint32_t)) {
		fprintf(stderr, "Length %d is not in multiple of %zu\n",
			len, sizeof(uint32_t));
		return 0;
	}

	do {
		csum += *p;
		p++;
		len -= sizeof(uint32_t);
	} while (len > 0);

	return csum;
}

static unsigned int options_to_baudrate(uint8_t options)
{
	switch (options & 0x7) {
	case MAIN_HDR_V1_OPT_BAUD_2400:
		return 2400;
	case MAIN_HDR_V1_OPT_BAUD_4800:
		return 4800;
	case MAIN_HDR_V1_OPT_BAUD_9600:
		return 9600;
	case MAIN_HDR_V1_OPT_BAUD_19200:
		return 19200;
	case MAIN_HDR_V1_OPT_BAUD_38400:
		return 38400;
	case MAIN_HDR_V1_OPT_BAUD_57600:
		return 57600;
	case MAIN_HDR_V1_OPT_BAUD_115200:
		return 115200;
	case MAIN_HDR_V1_OPT_BAUD_DEFAULT:
	default:
		return 0;
	}
}

static uint8_t baudrate_to_option(unsigned int baudrate)
{
	switch (baudrate) {
	case 2400:
		return MAIN_HDR_V1_OPT_BAUD_2400;
	case 4800:
		return MAIN_HDR_V1_OPT_BAUD_4800;
	case 9600:
		return MAIN_HDR_V1_OPT_BAUD_9600;
	case 19200:
		return MAIN_HDR_V1_OPT_BAUD_19200;
	case 38400:
		return MAIN_HDR_V1_OPT_BAUD_38400;
	case 57600:
		return MAIN_HDR_V1_OPT_BAUD_57600;
	case 115200:
		return MAIN_HDR_V1_OPT_BAUD_115200;
	default:
		return MAIN_HDR_V1_OPT_BAUD_DEFAULT;
	}
}

static void kwb_msg(const char *fmt, ...)
{
	if (verbose_mode) {
		va_list ap;

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

static int openssl_err(const char *msg)
{
	unsigned long ssl_err = ERR_get_error();

	fprintf(stderr, "%s", msg);
	fprintf(stderr, ": %s\n",
		ERR_error_string(ssl_err, 0));

	return -1;
}

static int kwb_load_rsa_key(const char *keydir, const char *name, RSA **p_rsa)
{
	char path[PATH_MAX];
	RSA *rsa;
	FILE *f;

	if (!keydir)
		keydir = ".";

	snprintf(path, sizeof(path), "%s/%s.key", keydir, name);
	f = fopen(path, "r");
	if (!f) {
		fprintf(stderr, "Couldn't open RSA private key: '%s': %s\n",
			path, strerror(errno));
		return -ENOENT;
	}

	rsa = PEM_read_RSAPrivateKey(f, 0, NULL, "");
	if (!rsa) {
		openssl_err("Failure reading private key");
		fclose(f);
		return -EPROTO;
	}
	fclose(f);
	*p_rsa = rsa;

	return 0;
}

static int kwb_load_cfg_key(struct image_tool_params *params,
			    unsigned int cfg_option, const char *key_name,
			    RSA **p_key)
{
	struct image_cfg_element *e_key;
	RSA *key;
	int res;

	*p_key = NULL;

	e_key = image_find_option(cfg_option);
	if (!e_key) {
		fprintf(stderr, "%s not configured\n", key_name);
		return -ENOENT;
	}

	res = kwb_load_rsa_key(params->keydir, e_key->key_name, &key);
	if (res < 0) {
		fprintf(stderr, "Failed to load %s\n", key_name);
		return -ENOENT;
	}

	*p_key = key;

	return 0;
}

static int kwb_load_kak(struct image_tool_params *params, RSA **p_kak)
{
	return kwb_load_cfg_key(params, IMAGE_CFG_KAK, "KAK", p_kak);
}

static int kwb_load_csk(struct image_tool_params *params, RSA **p_csk)
{
	return kwb_load_cfg_key(params, IMAGE_CFG_CSK, "CSK", p_csk);
}

static int kwb_compute_pubkey_hash(struct pubkey_der_v1 *pk,
				   struct hash_v1 *hash)
{
	EVP_MD_CTX *ctx;
	unsigned int key_size;
	unsigned int hash_size;
	int ret = 0;

	if (!pk || !hash || pk->key[0] != 0x30 || pk->key[1] != 0x82)
		return -EINVAL;

	key_size = (pk->key[2] << 8) + pk->key[3] + 4;

	ctx = EVP_MD_CTX_create();
	if (!ctx)
		return openssl_err("EVP context creation failed");

	EVP_MD_CTX_init(ctx);
	if (!EVP_DigestInit(ctx, EVP_sha256())) {
		ret = openssl_err("Digest setup failed");
		goto hash_err_ctx;
	}

	if (!EVP_DigestUpdate(ctx, pk->key, key_size)) {
		ret = openssl_err("Hashing data failed");
		goto hash_err_ctx;
	}

	if (!EVP_DigestFinal(ctx, hash->hash, &hash_size)) {
		ret = openssl_err("Could not obtain hash");
		goto hash_err_ctx;
	}

	EVP_MD_CTX_cleanup(ctx);

hash_err_ctx:
	EVP_MD_CTX_destroy(ctx);
	return ret;
}

static int kwb_import_pubkey(RSA **key, struct pubkey_der_v1 *src, char *keyname)
{
	RSA *rsa;
	const unsigned char *ptr;

	if (!key || !src)
		goto fail;

	ptr = src->key;
	rsa = d2i_RSAPublicKey(key, &ptr, sizeof(src->key));
	if (!rsa) {
		openssl_err("error decoding public key");
		goto fail;
	}

	return 0;
fail:
	fprintf(stderr, "Failed to decode %s pubkey\n", keyname);
	return -EINVAL;
}

static int kwb_export_pubkey(RSA *key, struct pubkey_der_v1 *dst, FILE *hashf,
			     char *keyname)
{
	int size_exp, size_mod, size_seq;
	const BIGNUM *key_e, *key_n;
	uint8_t *cur;
	char *errmsg = "Failed to encode %s\n";

	RSA_get0_key(key, NULL, &key_e, NULL);
	RSA_get0_key(key, &key_n, NULL, NULL);

	if (!key || !key_e || !key_n || !dst) {
		fprintf(stderr, "export pk failed: (%p, %p, %p, %p)",
			key, key_e, key_n, dst);
		fprintf(stderr, errmsg, keyname);
		return -EINVAL;
	}

	/*
	 * According to the specs, the key should be PKCS#1 DER encoded.
	 * But unfortunately the really required encoding seems to be different;
	 * it violates DER...! (But it still conformes to BER.)
	 * (Length always in long form w/ 2 byte length code; no leading zero
	 * when MSB of first byte is set...)
	 * So we cannot use the encoding func provided by OpenSSL and have to
	 * do the encoding manually.
	 */

	size_exp = BN_num_bytes(key_e);
	size_mod = BN_num_bytes(key_n);
	size_seq = 4 + size_mod + 4 + size_exp;

	if (size_mod > 256) {
		fprintf(stderr, "export pk failed: wrong mod size: %d\n",
			size_mod);
		fprintf(stderr, errmsg, keyname);
		return -EINVAL;
	}

	if (4 + size_seq > sizeof(dst->key)) {
		fprintf(stderr, "export pk failed: seq too large (%d, %zu)\n",
			4 + size_seq, sizeof(dst->key));
		fprintf(stderr, errmsg, keyname);
		return -ENOBUFS;
	}

	cur = dst->key;

	/* PKCS#1 (RFC3447) RSAPublicKey structure */
	*cur++ = 0x30;		/* SEQUENCE */
	*cur++ = 0x82;
	*cur++ = (size_seq >> 8) & 0xFF;
	*cur++ = size_seq & 0xFF;
	/* Modulus */
	*cur++ = 0x02;		/* INTEGER */
	*cur++ = 0x82;
	*cur++ = (size_mod >> 8) & 0xFF;
	*cur++ = size_mod & 0xFF;
	BN_bn2bin(key_n, cur);
	cur += size_mod;
	/* Exponent */
	*cur++ = 0x02;		/* INTEGER */
	*cur++ = 0x82;
	*cur++ = (size_exp >> 8) & 0xFF;
	*cur++ = size_exp & 0xFF;
	BN_bn2bin(key_e, cur);

	if (hashf) {
		struct hash_v1 pk_hash;
		int i;
		int ret = 0;

		ret = kwb_compute_pubkey_hash(dst, &pk_hash);
		if (ret < 0) {
			fprintf(stderr, errmsg, keyname);
			return ret;
		}

		fprintf(hashf, "SHA256 = ");
		for (i = 0 ; i < sizeof(pk_hash.hash); ++i)
			fprintf(hashf, "%02X", pk_hash.hash[i]);
		fprintf(hashf, "\n");
	}

	return 0;
}

static int kwb_sign(RSA *key, void *data, int datasz, struct sig_v1 *sig,
		    char *signame)
{
	EVP_PKEY *evp_key;
	EVP_MD_CTX *ctx;
	unsigned int sig_size;
	int size;
	int ret = 0;

	evp_key = EVP_PKEY_new();
	if (!evp_key)
		return openssl_err("EVP_PKEY object creation failed");

	if (!EVP_PKEY_set1_RSA(evp_key, key)) {
		ret = openssl_err("EVP key setup failed");
		goto err_key;
	}

	size = EVP_PKEY_size(evp_key);
	if (size > sizeof(sig->sig)) {
		fprintf(stderr, "Buffer to small for signature (%d bytes)\n",
			size);
		ret = -ENOBUFS;
		goto err_key;
	}

	ctx = EVP_MD_CTX_create();
	if (!ctx) {
		ret = openssl_err("EVP context creation failed");
		goto err_key;
	}
	EVP_MD_CTX_init(ctx);
	if (!EVP_SignInit(ctx, EVP_sha256())) {
		ret = openssl_err("Signer setup failed");
		goto err_ctx;
	}

	if (!EVP_SignUpdate(ctx, data, datasz)) {
		ret = openssl_err("Signing data failed");
		goto err_ctx;
	}

	if (!EVP_SignFinal(ctx, sig->sig, &sig_size, evp_key)) {
		ret = openssl_err("Could not obtain signature");
		goto err_ctx;
	}

	EVP_MD_CTX_cleanup(ctx);
	EVP_MD_CTX_destroy(ctx);
	EVP_PKEY_free(evp_key);

	return 0;

err_ctx:
	EVP_MD_CTX_destroy(ctx);
err_key:
	EVP_PKEY_free(evp_key);
	fprintf(stderr, "Failed to create %s signature\n", signame);
	return ret;
}

static int kwb_verify(RSA *key, void *data, int datasz, struct sig_v1 *sig,
		      char *signame)
{
	EVP_PKEY *evp_key;
	EVP_MD_CTX *ctx;
	int size;
	int ret = 0;

	evp_key = EVP_PKEY_new();
	if (!evp_key)
		return openssl_err("EVP_PKEY object creation failed");

	if (!EVP_PKEY_set1_RSA(evp_key, key)) {
		ret = openssl_err("EVP key setup failed");
		goto err_key;
	}

	size = EVP_PKEY_size(evp_key);
	if (size > sizeof(sig->sig)) {
		fprintf(stderr, "Invalid signature size (%d bytes)\n",
			size);
		ret = -EINVAL;
		goto err_key;
	}

	ctx = EVP_MD_CTX_create();
	if (!ctx) {
		ret = openssl_err("EVP context creation failed");
		goto err_key;
	}
	EVP_MD_CTX_init(ctx);
	if (!EVP_VerifyInit(ctx, EVP_sha256())) {
		ret = openssl_err("Verifier setup failed");
		goto err_ctx;
	}

	if (!EVP_VerifyUpdate(ctx, data, datasz)) {
		ret = openssl_err("Hashing data failed");
		goto err_ctx;
	}

	if (EVP_VerifyFinal(ctx, sig->sig, sizeof(sig->sig), evp_key) != 1) {
		ret = openssl_err("Could not verify signature");
		goto err_ctx;
	}

	EVP_MD_CTX_cleanup(ctx);
	EVP_MD_CTX_destroy(ctx);
	EVP_PKEY_free(evp_key);

	return 0;

err_ctx:
	EVP_MD_CTX_destroy(ctx);
err_key:
	EVP_PKEY_free(evp_key);
	fprintf(stderr, "Failed to verify %s signature\n", signame);
	return ret;
}

static int kwb_sign_and_verify(RSA *key, void *data, int datasz,
			       struct sig_v1 *sig, char *signame)
{
	if (kwb_sign(key, data, datasz, sig, signame) < 0)
		return -1;

	if (kwb_verify(key, data, datasz, sig, signame) < 0)
		return -1;

	return 0;
}


static int kwb_dump_fuse_cmds_38x(FILE *out, struct secure_hdr_v1 *sec_hdr)
{
	struct hash_v1 kak_pub_hash;
	struct image_cfg_element *e;
	unsigned int fuse_line;
	int i, idx;
	uint8_t *ptr;
	uint32_t val;
	int ret = 0;

	if (!out || !sec_hdr)
		return -EINVAL;

	ret = kwb_compute_pubkey_hash(&sec_hdr->kak, &kak_pub_hash);
	if (ret < 0)
		goto done;

	fprintf(out, "# burn KAK pub key hash\n");
	ptr = kak_pub_hash.hash;
	for (fuse_line = 26; fuse_line <= 30; ++fuse_line) {
		fprintf(out, "fuse prog -y %u 0 ", fuse_line);

		for (i = 4; i-- > 0;)
			fprintf(out, "%02hx", (ushort)ptr[i]);
		ptr += 4;
		fprintf(out, " 00");

		if (fuse_line < 30) {
			for (i = 3; i-- > 0;)
				fprintf(out, "%02hx", (ushort)ptr[i]);
			ptr += 3;
		} else {
			fprintf(out, "000000");
		}

		fprintf(out, " 1\n");
	}

	fprintf(out, "# burn CSK selection\n");

	idx = image_get_csk_index();
	if (idx < 0 || idx > 15) {
		ret = -EINVAL;
		goto done;
	}
	if (idx > 0) {
		for (fuse_line = 31; fuse_line < 31 + idx; ++fuse_line)
			fprintf(out, "fuse prog -y %u 0 00000001 00000000 1\n",
				fuse_line);
	} else {
		fprintf(out, "# CSK index is 0; no mods needed\n");
	}

	e = image_find_option(IMAGE_CFG_BOX_ID);
	if (e) {
		fprintf(out, "# set box ID\n");
		fprintf(out, "fuse prog -y 48 0 %08x 00000000 1\n", e->boxid);
	}

	e = image_find_option(IMAGE_CFG_FLASH_ID);
	if (e) {
		fprintf(out, "# set flash ID\n");
		fprintf(out, "fuse prog -y 47 0 %08x 00000000 1\n", e->flashid);
	}

	fprintf(out, "# enable secure mode ");
	fprintf(out, "(must be the last fuse line written)\n");

	val = 1;
	e = image_find_option(IMAGE_CFG_SEC_BOOT_DEV);
	if (!e) {
		fprintf(stderr, "ERROR: secured mode boot device not given\n");
		ret = -EINVAL;
		goto done;
	}

	if (e->sec_boot_dev > 0xff) {
		fprintf(stderr, "ERROR: secured mode boot device invalid\n");
		ret = -EINVAL;
		goto done;
	}

	val |= (e->sec_boot_dev << 8);

	fprintf(out, "fuse prog -y 24 0 %08x 0103e0a9 1\n", val);

	fprintf(out, "# lock (unused) fuse lines (0-23)s\n");
	for (fuse_line = 0; fuse_line < 24; ++fuse_line)
		fprintf(out, "fuse prog -y %u 2 1\n", fuse_line);

	fprintf(out, "# OK, that's all :-)\n");

done:
	return ret;
}

static int kwb_dump_fuse_cmds(struct secure_hdr_v1 *sec_hdr)
{
	int ret = 0;
	struct image_cfg_element *e;

	e = image_find_option(IMAGE_CFG_SEC_FUSE_DUMP);
	if (!e)
		return 0;

	if (!strcmp(e->name, "a38x")) {
		FILE *out = fopen("kwb_fuses_a38x.txt", "w+");

		if (!out) {
			fprintf(stderr, "Couldn't open eFuse settings: '%s': %s\n",
				"kwb_fuses_a38x.txt", strerror(errno));
			return -ENOENT;
		}

		kwb_dump_fuse_cmds_38x(out, sec_hdr);
		fclose(out);
		goto done;
	}

	ret = -ENOSYS;

done:
	return ret;
}

static int image_fill_xip_header(void *image, struct image_tool_params *params)
{
	struct main_hdr_v1 *main_hdr = image; /* kwbimage v0 and v1 have same XIP members */
	int version = kwbimage_version(image);
	uint32_t srcaddr = le32_to_cpu(main_hdr->srcaddr);
	uint32_t startaddr = 0;

	if (main_hdr->blockid != IBR_HDR_SPI_ID) {
		fprintf(stderr, "XIP is supported only for SPI images\n");
		return 0;
	}

	if (version == 0 &&
		   params->addr >= 0xE8000000 && params->addr < 0xEFFFFFFF &&
		   params->ep >= 0xE8000000 && params->ep < 0xEFFFFFFF) {
		/* Load and Execute address is in SPI address space (kwbimage v0) */
		startaddr = 0xE8000000;
	} else if (version != 0 &&
		   params->addr >= 0xD4000000 && params->addr < 0xD7FFFFFF &&
		   params->ep >= 0xD4000000 && params->ep < 0xD7FFFFFF) {
		/* Load and Execute address is in SPI address space (kwbimage v1) */
		startaddr = 0xD4000000;
	} else if (version != 0 &&
		   params->addr >= 0xD8000000 && params->addr < 0xDFFFFFFF &&
		   params->ep >= 0xD8000000 && params->ep < 0xDFFFFFFF) {
		/* Load and Execute address is in Device bus space (kwbimage v1) */
		startaddr = 0xD8000000;
	} else if (params->addr != 0x0) {
		/* Load address is non-zero */
		if (version == 0)
			fprintf(stderr, "XIP Load Address or XIP Entry Point is not in SPI address space\n");
		else
			fprintf(stderr, "XIP Load Address or XIP Entry Point is not in SPI nor in Device bus address space\n");
		return 0;
	}

	/*
	 * For XIP destaddr must be set to 0xFFFFFFFF and
	 * execaddr relative to the start of XIP memory address space.
	 */
	main_hdr->destaddr = cpu_to_le32(0xFFFFFFFF);

	if (startaddr == 0) {
		/*
		 * mkimage's --load-address 0x0 means that binary is Position
		 * Independent and in this case mkimage's --entry-point address
		 * is relative offset from beginning of the data part of image.
		 */
		main_hdr->execaddr = cpu_to_le32(srcaddr + params->ep);
	} else {
		/* The lowest possible load address is after the header at srcaddr. */
		if (params->addr - startaddr < srcaddr) {
			fprintf(stderr,
				"Invalid XIP Load Address 0x%08x.\n"
				"The lowest address for this configuration is 0x%08x.\n",
				params->addr, (unsigned)(startaddr + srcaddr));
			return 0;
		}
		main_hdr->srcaddr = cpu_to_le32(params->addr - startaddr);
		main_hdr->execaddr = cpu_to_le32(params->ep - startaddr);
	}

	return 1;
}

static size_t image_headersz_align(size_t headersz, uint8_t blockid)
{
	/*
	 * Header needs to be 4-byte aligned, which is already ensured by code
	 * above. Moreover UART images must have header aligned to 128 bytes
	 * (xmodem block size), NAND images to 256 bytes (ECC calculation),
	 * and SATA and SDIO images to 512 bytes (storage block size).
	 * Note that SPI images do not have to have header size aligned
	 * to 256 bytes because it is possible to read from SPI storage from
	 * any offset (read offset does not have to be aligned to block size).
	 */
	if (blockid == IBR_HDR_UART_ID)
		return ALIGN(headersz, 128);
	else if (blockid == IBR_HDR_NAND_ID)
		return ALIGN(headersz, 256);
	else if (blockid == IBR_HDR_SATA_ID || blockid == IBR_HDR_SDIO_ID)
		return ALIGN(headersz, 512);
	else
		return headersz;
}

static size_t image_headersz_v0(int *hasext)
{
	size_t headersz;

	headersz = sizeof(struct main_hdr_v0);
	if (image_count_options(IMAGE_CFG_DATA) > 0) {
		headersz += sizeof(struct ext_hdr_v0);
		if (hasext)
			*hasext = 1;
	}

	return headersz;
}

static void *image_create_v0(size_t *dataoff, struct image_tool_params *params,
			     int payloadsz)
{
	struct image_cfg_element *e;
	size_t headersz;
	struct main_hdr_v0 *main_hdr;
	uint8_t *image;
	int has_ext = 0;

	/*
	 * Calculate the size of the header and the offset of the
	 * payload
	 */
	headersz = image_headersz_v0(&has_ext);
	*dataoff = image_headersz_align(headersz, image_get_bootfrom());

	image = malloc(headersz);
	if (!image) {
		fprintf(stderr, "Cannot allocate memory for image\n");
		return NULL;
	}

	memset(image, 0, headersz);

	main_hdr = (struct main_hdr_v0 *)image;

	/* Fill in the main header */
	main_hdr->blocksize =
		cpu_to_le32(payloadsz);
	main_hdr->srcaddr   = cpu_to_le32(*dataoff);
	main_hdr->ext       = has_ext;
	main_hdr->version   = 0;
	main_hdr->destaddr  = cpu_to_le32(params->addr);
	main_hdr->execaddr  = cpu_to_le32(params->ep);
	main_hdr->blockid   = image_get_bootfrom();

	e = image_find_option(IMAGE_CFG_NAND_ECC_MODE);
	if (e)
		main_hdr->nandeccmode = e->nandeccmode;
	e = image_find_option(IMAGE_CFG_NAND_BLKSZ);
	if (e)
		main_hdr->nandblocksize = e->nandblksz / (64 * 1024);
	e = image_find_option(IMAGE_CFG_NAND_PAGESZ);
	if (e)
		main_hdr->nandpagesize = cpu_to_le16(e->nandpagesz);
	e = image_find_option(IMAGE_CFG_NAND_BADBLK_LOCATION);
	if (e)
		main_hdr->nandbadblklocation = e->nandbadblklocation;

	/*
	 * For SATA srcaddr is specified in number of sectors.
	 * This expects the sector size to be 512 bytes.
	 */
	if (main_hdr->blockid == IBR_HDR_SATA_ID)
		main_hdr->srcaddr = cpu_to_le32(le32_to_cpu(main_hdr->srcaddr) / 512);

	/* For PCIe srcaddr is not used and must be set to 0xFFFFFFFF. */
	if (main_hdr->blockid == IBR_HDR_PEX_ID)
		main_hdr->srcaddr = cpu_to_le32(0xFFFFFFFF);

	if (params->xflag) {
		if (!image_fill_xip_header(main_hdr, params)) {
			free(image);
			return NULL;
		}
		*dataoff = le32_to_cpu(main_hdr->srcaddr);
	}

	/* Generate the ext header */
	if (has_ext) {
		struct ext_hdr_v0 *ext_hdr;
		int cfgi, datai;

		ext_hdr = (struct ext_hdr_v0 *)
				(image + sizeof(struct main_hdr_v0));
		ext_hdr->offset = cpu_to_le32(0x40);

		for (cfgi = 0, datai = 0; cfgi < cfgn; cfgi++) {
			e = &image_cfg[cfgi];
			if (e->type != IMAGE_CFG_DATA)
				continue;

			ext_hdr->rcfg[datai].raddr =
				cpu_to_le32(e->regdata.raddr);
			ext_hdr->rcfg[datai].rdata =
				cpu_to_le32(e->regdata.rdata);
			datai++;
		}

		ext_hdr->checksum = image_checksum8(ext_hdr,
						    sizeof(struct ext_hdr_v0));
	}

	main_hdr->checksum = image_checksum8(image,
					     sizeof(struct main_hdr_v0));

	return image;
}

static size_t image_headersz_v1(int *hasext)
{
	struct image_cfg_element *e;
	unsigned int count;
	size_t headersz;
	int cpu_sheeva;
	struct stat s;
	int cfgi;
	int ret;

	headersz = sizeof(struct main_hdr_v1);

	if (image_get_csk_index() >= 0) {
		headersz += sizeof(struct secure_hdr_v1);
		if (hasext)
			*hasext = 1;
	}

	cpu_sheeva = image_is_cpu_sheeva();

	count = 0;
	for (cfgi = 0; cfgi < cfgn; cfgi++) {
		e = &image_cfg[cfgi];

		if (e->type == IMAGE_CFG_DATA)
			count++;

		if (e->type == IMAGE_CFG_DATA_DELAY ||
		    (e->type == IMAGE_CFG_BINARY && count > 0)) {
			headersz += sizeof(struct register_set_hdr_v1) + 8 * count + 4;
			count = 0;
		}

		if (e->type != IMAGE_CFG_BINARY)
			continue;

		ret = stat(e->binary.file, &s);
		if (ret < 0) {
			char cwd[PATH_MAX];
			char *dir = cwd;

			memset(cwd, 0, sizeof(cwd));
			if (!getcwd(cwd, sizeof(cwd))) {
				dir = "current working directory";
				perror("getcwd() failed");
			}

			fprintf(stderr,
				"Didn't find the file '%s' in '%s' which is mandatory to generate the image\n"
				"This file generally contains the DDR3 training code, and should be extracted from an existing bootable\n"
				"image for your board. Use 'dumpimage -T kwbimage -p 1' to extract it from an existing image.\n",
				e->binary.file, dir);
			return 0;
		}

		headersz += sizeof(struct opt_hdr_v1) + sizeof(uint32_t) +
			(e->binary.nargs) * sizeof(uint32_t);

		if (e->binary.loadaddr) {
			/*
			 * BootROM loads kwbimage header (in which the
			 * executable code is also stored) to address
			 * 0x40004000 or 0x40000000. Thus there is
			 * restriction for the load address of the N-th
			 * BINARY image.
			 */
			unsigned int base_addr, low_addr, high_addr;

			base_addr = cpu_sheeva ? 0x40004000 : 0x40000000;
			low_addr = base_addr + headersz;
			high_addr = low_addr +
				    (BINARY_MAX_ARGS - e->binary.nargs) * sizeof(uint32_t);

			if (cpu_sheeva && e->binary.loadaddr % 16) {
				fprintf(stderr,
					"Invalid LOAD_ADDRESS 0x%08x for BINARY %s with %d args.\n"
					"Address for CPU SHEEVA must be 16-byte aligned.\n",
					e->binary.loadaddr, e->binary.file, e->binary.nargs);
				return 0;
			}

			if (e->binary.loadaddr % 4 || e->binary.loadaddr < low_addr ||
			    e->binary.loadaddr > high_addr) {
				fprintf(stderr,
					"Invalid LOAD_ADDRESS 0x%08x for BINARY %s with %d args.\n"
					"Address must be 4-byte aligned and in range 0x%08x-0x%08x.\n",
					e->binary.loadaddr, e->binary.file,
					e->binary.nargs, low_addr, high_addr);
				return 0;
			}
			headersz = e->binary.loadaddr - base_addr;
		} else if (cpu_sheeva) {
			headersz = ALIGN(headersz, 16);
		} else {
			headersz = ALIGN(headersz, 4);
		}

		headersz += ALIGN(s.st_size, 4) + sizeof(uint32_t);
		if (hasext)
			*hasext = 1;
	}

	if (count > 0)
		headersz += sizeof(struct register_set_hdr_v1) + 8 * count + 4;

	/*
	 * For all images except UART, headersz stored in header itself should
	 * contains header size without padding. For UART image BootROM rounds
	 * down headersz to multiply of 128 bytes. Therefore align UART headersz
	 * to multiply of 128 bytes to ensure that remaining UART header bytes
	 * are not ignored by BootROM.
	 */
	if (image_get_bootfrom() == IBR_HDR_UART_ID)
		headersz = ALIGN(headersz, 128);

	return headersz;
}

static int add_binary_header_v1(uint8_t **cur, uint8_t **next_ext,
				struct image_cfg_element *binarye,
				struct main_hdr_v1 *main_hdr)
{
	struct opt_hdr_v1 *hdr = (struct opt_hdr_v1 *)*cur;
	uint32_t base_addr;
	uint32_t add_args;
	uint32_t offset;
	uint32_t *args;
	size_t binhdrsz;
	int cpu_sheeva;
	struct stat s;
	int argi;
	FILE *bin;
	int ret;

	hdr->headertype = OPT_HDR_V1_BINARY_TYPE;

	bin = fopen(binarye->binary.file, "r");
	if (!bin) {
		fprintf(stderr, "Cannot open binary file %s\n",
			binarye->binary.file);
		return -1;
	}

	if (fstat(fileno(bin), &s)) {
		fprintf(stderr, "Cannot stat binary file %s\n",
			binarye->binary.file);
		goto err_close;
	}

	*cur += sizeof(struct opt_hdr_v1);

	args = (uint32_t *)*cur;
	*args = cpu_to_le32(binarye->binary.nargs);
	args++;
	for (argi = 0; argi < binarye->binary.nargs; argi++)
		args[argi] = cpu_to_le32(binarye->binary.args[argi]);

	*cur += (binarye->binary.nargs + 1) * sizeof(uint32_t);

	/*
	 * ARM executable code inside the BIN header on platforms with Sheeva
	 * CPU (A370 and AXP) must always be aligned with the 128-bit boundary.
	 * In the case when this code is not position independent (e.g. ARM
	 * SPL), it must be placed at fixed load and execute address.
	 * This requirement can be met by inserting dummy arguments into
	 * BIN header, if needed.
	 */
	cpu_sheeva = image_is_cpu_sheeva();
	base_addr = cpu_sheeva ? 0x40004000 : 0x40000000;
	offset = *cur - (uint8_t *)main_hdr;
	if (binarye->binary.loadaddr)
		add_args = (binarye->binary.loadaddr - base_addr - offset) / sizeof(uint32_t);
	else if (cpu_sheeva)
		add_args = ((16 - offset % 16) % 16) / sizeof(uint32_t);
	else
		add_args = 0;
	if (add_args) {
		*(args - 1) = cpu_to_le32(binarye->binary.nargs + add_args);
		*cur += add_args * sizeof(uint32_t);
	}

	ret = fread(*cur, s.st_size, 1, bin);
	if (ret != 1) {
		fprintf(stderr,
			"Could not read binary image %s\n",
			binarye->binary.file);
		goto err_close;
	}

	fclose(bin);

	*cur += ALIGN(s.st_size, 4);

	*((uint32_t *)*cur) = 0x00000000;
	**next_ext = 1;
	*next_ext = *cur;

	*cur += sizeof(uint32_t);

	binhdrsz = sizeof(struct opt_hdr_v1) +
		(binarye->binary.nargs + add_args + 2) * sizeof(uint32_t) +
		ALIGN(s.st_size, 4);
	hdr->headersz_lsb = cpu_to_le16(binhdrsz & 0xFFFF);
	hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16;

	return 0;

err_close:
	fclose(bin);

	return -1;
}

static int export_pub_kak_hash(RSA *kak, struct secure_hdr_v1 *secure_hdr)
{
	FILE *hashf;
	int res;

	hashf = fopen("pub_kak_hash.txt", "w");
	if (!hashf) {
		fprintf(stderr, "Couldn't open hash file: '%s': %s\n",
			"pub_kak_hash.txt", strerror(errno));
		return 1;
	}

	res = kwb_export_pubkey(kak, &secure_hdr->kak, hashf, "KAK");

	fclose(hashf);

	return res < 0 ? 1 : 0;
}

static int kwb_sign_csk_with_kak(struct image_tool_params *params,
				 struct secure_hdr_v1 *secure_hdr, RSA *csk)
{
	RSA *kak = NULL;
	RSA *kak_pub = NULL;
	int csk_idx = image_get_csk_index();
	struct sig_v1 tmp_sig;

	if (csk_idx < 0 || csk_idx > 15) {
		fprintf(stderr, "Invalid CSK index %d\n", csk_idx);
		return 1;
	}

	if (kwb_load_kak(params, &kak) < 0)
		return 1;

	if (export_pub_kak_hash(kak, secure_hdr))
		return 1;

	if (kwb_import_pubkey(&kak_pub, &secure_hdr->kak, "KAK") < 0)
		return 1;

	if (kwb_export_pubkey(csk, &secure_hdr->csk[csk_idx], NULL, "CSK") < 0)
		return 1;

	if (kwb_sign_and_verify(kak, &secure_hdr->csk,
				sizeof(secure_hdr->csk) +
				sizeof(secure_hdr->csksig),
				&tmp_sig, "CSK") < 0)
		return 1;

	if (kwb_verify(kak_pub, &secure_hdr->csk,
		       sizeof(secure_hdr->csk) +
		       sizeof(secure_hdr->csksig),
		       &tmp_sig, "CSK (2)") < 0)
		return 1;

	secure_hdr->csksig = tmp_sig;

	return 0;
}

static int add_secure_header_v1(struct image_tool_params *params, uint8_t *image_ptr,
				size_t image_size, uint8_t *header_ptr, size_t headersz,
				struct secure_hdr_v1 *secure_hdr)
{
	struct image_cfg_element *e_jtagdelay;
	struct image_cfg_element *e_boxid;
	struct image_cfg_element *e_flashid;
	RSA *csk = NULL;
	struct sig_v1 tmp_sig;
	bool specialized_img = image_get_spezialized_img();

	kwb_msg("Create secure header content\n");

	e_jtagdelay = image_find_option(IMAGE_CFG_JTAG_DELAY);
	e_boxid = image_find_option(IMAGE_CFG_BOX_ID);
	e_flashid = image_find_option(IMAGE_CFG_FLASH_ID);

	if (kwb_load_csk(params, &csk) < 0)
		return 1;

	secure_hdr->headertype = OPT_HDR_V1_SECURE_TYPE;
	secure_hdr->headersz_msb = 0;
	secure_hdr->headersz_lsb = cpu_to_le16(sizeof(struct secure_hdr_v1));
	if (e_jtagdelay)
		secure_hdr->jtag_delay = e_jtagdelay->jtag_delay;
	if (e_boxid && specialized_img)
		secure_hdr->boxid = cpu_to_le32(e_boxid->boxid);
	if (e_flashid && specialized_img)
		secure_hdr->flashid = cpu_to_le32(e_flashid->flashid);

	if (kwb_sign_csk_with_kak(params, secure_hdr, csk))
		return 1;

	if (kwb_sign_and_verify(csk, image_ptr, image_size - 4,
				&secure_hdr->imgsig, "image") < 0)
		return 1;

	if (kwb_sign_and_verify(csk, header_ptr, headersz, &tmp_sig, "header") < 0)
		return 1;

	secure_hdr->hdrsig = tmp_sig;

	kwb_dump_fuse_cmds(secure_hdr);

	return 0;
}

static void finish_register_set_header_v1(uint8_t **cur, uint8_t **next_ext,
					  struct register_set_hdr_v1 *register_set_hdr,
					  int *datai, uint8_t delay)
{
	int size = sizeof(struct register_set_hdr_v1) + 8 * (*datai) + 4;

	register_set_hdr->headertype = OPT_HDR_V1_REGISTER_TYPE;
	register_set_hdr->headersz_lsb = cpu_to_le16(size & 0xFFFF);
	register_set_hdr->headersz_msb = size >> 16;
	register_set_hdr->data[*datai].last_entry.delay = delay;
	*cur += size;
	**next_ext = 1;
	*next_ext = &register_set_hdr->data[*datai].last_entry.next;
	*datai = 0;
}

static void *image_create_v1(size_t *dataoff, struct image_tool_params *params,
			     uint8_t *ptr, int payloadsz)
{
	struct image_cfg_element *e;
	struct main_hdr_v1 *main_hdr;
	struct register_set_hdr_v1 *register_set_hdr;
	struct secure_hdr_v1 *secure_hdr = NULL;
	size_t headersz;
	uint8_t *image, *cur;
	int hasext = 0;
	uint8_t *next_ext = NULL;
	int cfgi, datai;
	uint8_t delay;

	/*
	 * Calculate the size of the header and the offset of the
	 * payload
	 */
	headersz = image_headersz_v1(&hasext);
	if (headersz == 0)
		return NULL;
	*dataoff = image_headersz_align(headersz, image_get_bootfrom());

	image = malloc(headersz);
	if (!image) {
		fprintf(stderr, "Cannot allocate memory for image\n");
		return NULL;
	}

	memset(image, 0, headersz);

	main_hdr = (struct main_hdr_v1 *)image;
	cur = image;
	cur += sizeof(struct main_hdr_v1);
	next_ext = &main_hdr->ext;

	/* Fill the main header */
	main_hdr->blocksize    =
		cpu_to_le32(payloadsz);
	main_hdr->headersz_lsb = cpu_to_le16(headersz & 0xFFFF);
	main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16;
	main_hdr->destaddr     = cpu_to_le32(params->addr);
	main_hdr->execaddr     = cpu_to_le32(params->ep);
	main_hdr->srcaddr      = cpu_to_le32(*dataoff);
	main_hdr->ext          = hasext;
	main_hdr->version      = 1;
	main_hdr->blockid      = image_get_bootfrom();

	e = image_find_option(IMAGE_CFG_NAND_BLKSZ);
	if (e)
		main_hdr->nandblocksize = e->nandblksz / (64 * 1024);
	e = image_find_option(IMAGE_CFG_NAND_PAGESZ);
	if (e)
		main_hdr->nandpagesize = cpu_to_le16(e->nandpagesz);
	e = image_find_option(IMAGE_CFG_NAND_BADBLK_LOCATION);
	if (e)
		main_hdr->nandbadblklocation = e->nandbadblklocation;
	e = image_find_option(IMAGE_CFG_BAUDRATE);
	if (e)
		main_hdr->options |= baudrate_to_option(e->baudrate);
	e = image_find_option(IMAGE_CFG_UART_PORT);
	if (e)
		main_hdr->options |= (e->uart_port & 3) << 3;
	e = image_find_option(IMAGE_CFG_UART_MPP);
	if (e)
		main_hdr->options |= (e->uart_mpp & 7) << 5;
	e = image_find_option(IMAGE_CFG_DEBUG);
	if (e)
		main_hdr->flags = e->debug ? 0x1 : 0;

	/*
	 * For SATA srcaddr is specified in number of sectors.
	 * This expects the sector size to be 512 bytes.
	 */
	if (main_hdr->blockid == IBR_HDR_SATA_ID)
		main_hdr->srcaddr = cpu_to_le32(le32_to_cpu(main_hdr->srcaddr) / 512);

	/* For PCIe srcaddr is not used and must be set to 0xFFFFFFFF. */
	if (main_hdr->blockid == IBR_HDR_PEX_ID)
		main_hdr->srcaddr = cpu_to_le32(0xFFFFFFFF);

	if (params->xflag) {
		if (!image_fill_xip_header(main_hdr, params)) {
			free(image);
			return NULL;
		}
		*dataoff = le32_to_cpu(main_hdr->srcaddr);
	}

	if (image_get_csk_index() >= 0) {
		/*
		 * only reserve the space here; we fill the header later since
		 * we need the header to be complete to compute the signatures
		 */
		secure_hdr = (struct secure_hdr_v1 *)cur;
		cur += sizeof(struct secure_hdr_v1);
		*next_ext = 1;
		next_ext = &secure_hdr->next;
	}

	datai = 0;
	for (cfgi = 0; cfgi < cfgn; cfgi++) {
		e = &image_cfg[cfgi];
		if (e->type != IMAGE_CFG_DATA &&
		    e->type != IMAGE_CFG_DATA_DELAY &&
		    e->type != IMAGE_CFG_BINARY)
			continue;

		if (datai == 0)
			register_set_hdr = (struct register_set_hdr_v1 *)cur;

		/* If delay is not specified, use the smallest possible value. */
		if (e->type == IMAGE_CFG_DATA_DELAY)
			delay = e->regdata_delay;
		else
			delay = REGISTER_SET_HDR_OPT_DELAY_MS(0);

		/*
		 * DATA_DELAY command is the last entry in the register set
		 * header and BINARY command inserts new binary header.
		 * Therefore BINARY command requires to finish register set
		 * header if some DATA command was specified. And DATA_DELAY
		 * command automatically finish register set header even when
		 * there was no DATA command.
		 */
		if (e->type == IMAGE_CFG_DATA_DELAY ||
		    (e->type == IMAGE_CFG_BINARY && datai != 0))
			finish_register_set_header_v1(&cur, &next_ext, register_set_hdr,
						      &datai, delay);

		if (e->type == IMAGE_CFG_DATA) {
			register_set_hdr->data[datai].entry.address =
				cpu_to_le32(e->regdata.raddr);
			register_set_hdr->data[datai].entry.value =
				cpu_to_le32(e->regdata.rdata);
			datai++;
		}

		if (e->type == IMAGE_CFG_BINARY) {
			if (add_binary_header_v1(&cur, &next_ext, e, main_hdr))
				return NULL;
		}
	}
	if (datai != 0) {
		/* Set delay to the smallest possible value. */
		delay = REGISTER_SET_HDR_OPT_DELAY_MS(0);
		finish_register_set_header_v1(&cur, &next_ext, register_set_hdr,
					      &datai, delay);
	}

	if (secure_hdr && add_secure_header_v1(params, ptr + *dataoff, payloadsz,
					       image, headersz, secure_hdr))
		return NULL;

	/* Calculate and set the header checksum */
	main_hdr->checksum = image_checksum8(main_hdr, headersz);

	return image;
}

static int recognize_keyword(char *keyword)
{
	int kw_id;

	for (kw_id = 1; kw_id < IMAGE_CFG_COUNT; ++kw_id)
		if (!strcmp(keyword, id_strs[kw_id]))
			return kw_id;

	return 0;
}

static int image_create_config_parse_oneline(char *line,
					     struct image_cfg_element *el)
{
	char *keyword, *saveptr, *value1, *value2;
	char delimiters[] = " \t";
	int keyword_id, ret, argi;
	char *unknown_msg = "Ignoring unknown line '%s'\n";

	keyword = strtok_r(line, delimiters, &saveptr);
	keyword_id = recognize_keyword(keyword);

	if (!keyword_id) {
		fprintf(stderr, unknown_msg, line);
		return 0;
	}

	el->type = keyword_id;

	value1 = strtok_r(NULL, delimiters, &saveptr);

	if (!value1) {
		fprintf(stderr, "Parameter missing in line '%s'\n", line);
		return -1;
	}

	switch (keyword_id) {
	case IMAGE_CFG_VERSION:
		el->version = atoi(value1);
		break;
	case IMAGE_CFG_CPU:
		if (strcmp(value1, "FEROCEON") == 0)
			el->cpu_sheeva = 0;
		else if (strcmp(value1, "SHEEVA") == 0)
			el->cpu_sheeva = 1;
		else if (strcmp(value1, "A9") == 0)
			el->cpu_sheeva = 0;
		else {
			fprintf(stderr, "Invalid CPU %s\n", value1);
			return -1;
		}
		break;
	case IMAGE_CFG_BOOT_FROM:
		ret = image_boot_mode_id(value1);

		if (ret < 0) {
			fprintf(stderr, "Invalid boot media '%s'\n", value1);
			return -1;
		}
		el->bootfrom = ret;
		break;
	case IMAGE_CFG_NAND_BLKSZ:
		el->nandblksz = strtoul(value1, NULL, 16);
		break;
	case IMAGE_CFG_NAND_BADBLK_LOCATION:
		el->nandbadblklocation = strtoul(value1, NULL, 16);
		break;
	case IMAGE_CFG_NAND_ECC_MODE:
		ret = image_nand_ecc_mode_id(value1);

		if (ret < 0) {
			fprintf(stderr, "Invalid NAND ECC mode '%s'\n", value1);
			return -1;
		}
		el->nandeccmode = ret;
		break;
	case IMAGE_CFG_NAND_PAGESZ:
		el->nandpagesz = strtoul(value1, NULL, 16);
		break;
	case IMAGE_CFG_BINARY:
		argi = 0;

		el->binary.file = strdup(value1);
		while (1) {
			char *value = strtok_r(NULL, delimiters, &saveptr);
			char *endptr;

			if (!value)
				break;

			if (!strcmp(value, "LOAD_ADDRESS")) {
				value = strtok_r(NULL, delimiters, &saveptr);
				if (!value) {
					fprintf(stderr,
						"Missing address argument for BINARY LOAD_ADDRESS\n");
					return -1;
				}
				el->binary.loadaddr = strtoul(value, &endptr, 16);
				if (*endptr) {
					fprintf(stderr,
						"Invalid argument '%s' for BINARY LOAD_ADDRESS\n",
						value);
					return -1;
				}
				value = strtok_r(NULL, delimiters, &saveptr);
				if (value) {
					fprintf(stderr,
						"Unexpected argument '%s' after BINARY LOAD_ADDRESS\n",
						value);
					return -1;
				}
				break;
			}

			el->binary.args[argi] = strtoul(value, &endptr, 16);
			if (*endptr) {
				fprintf(stderr, "Invalid argument '%s' for BINARY\n", value);
				return -1;
			}
			argi++;
			if (argi >= BINARY_MAX_ARGS) {
				fprintf(stderr,
					"Too many arguments for BINARY\n");
				return -1;
			}
		}
		el->binary.nargs = argi;
		break;
	case IMAGE_CFG_DATA:
		value2 = strtok_r(NULL, delimiters, &saveptr);

		if (!value1 || !value2) {
			fprintf(stderr,
				"Invalid number of arguments for DATA\n");
			return -1;
		}

		el->regdata.raddr = strtoul(value1, NULL, 16);
		el->regdata.rdata = strtoul(value2, NULL, 16);
		break;
	case IMAGE_CFG_DATA_DELAY:
		if (!strcmp(value1, "SDRAM_SETUP"))
			el->regdata_delay = REGISTER_SET_HDR_OPT_DELAY_SDRAM_SETUP;
		else
			el->regdata_delay = REGISTER_SET_HDR_OPT_DELAY_MS(strtoul(value1, NULL, 10));
		if (el->regdata_delay > 255) {
			fprintf(stderr, "Maximal DATA_DELAY is 255\n");
			return -1;
		}
		break;
	case IMAGE_CFG_BAUDRATE:
		el->baudrate = strtoul(value1, NULL, 10);
		break;
	case IMAGE_CFG_UART_PORT:
		el->uart_port = strtoul(value1, NULL, 16);
		break;
	case IMAGE_CFG_UART_MPP:
		el->uart_mpp = strtoul(value1, NULL, 16);
		break;
	case IMAGE_CFG_DEBUG:
		el->debug = strtoul(value1, NULL, 10);
		break;
	case IMAGE_CFG_KAK:
		el->key_name = strdup(value1);
		break;
	case IMAGE_CFG_CSK:
		el->key_name = strdup(value1);
		break;
	case IMAGE_CFG_CSK_INDEX:
		el->csk_idx = strtol(value1, NULL, 0);
		break;
	case IMAGE_CFG_JTAG_DELAY:
		el->jtag_delay = strtoul(value1, NULL, 0);
		break;
	case IMAGE_CFG_BOX_ID:
		el->boxid = strtoul(value1, NULL, 0);
		break;
	case IMAGE_CFG_FLASH_ID:
		el->flashid = strtoul(value1, NULL, 0);
		break;
	case IMAGE_CFG_SEC_SPECIALIZED_IMG:
		el->sec_specialized_img = true;
		break;
	case IMAGE_CFG_SEC_COMMON_IMG:
		el->sec_specialized_img = false;
		break;
	case IMAGE_CFG_SEC_BOOT_DEV:
		el->sec_boot_dev = strtoul(value1, NULL, 0);
		break;
	case IMAGE_CFG_SEC_FUSE_DUMP:
		el->name = strdup(value1);
		break;
	default:
		fprintf(stderr, unknown_msg, line);
	}

	return 0;
}

/*
 * Parse the configuration file 'fcfg' into the array of configuration
 * elements 'image_cfg', and return the number of configuration
 * elements in 'cfgn'.
 */
static int image_create_config_parse(FILE *fcfg)
{
	int ret;
	int cfgi = 0;

	/* Parse the configuration file */
	while (!feof(fcfg)) {
		char *line;
		char buf[256];

		/* Read the current line */
		memset(buf, 0, sizeof(buf));
		line = fgets(buf, sizeof(buf), fcfg);
		if (!line)
			break;

		/* Ignore useless lines */
		if (line[0] == '\n' || line[0] == '#')
			continue;

		/* Strip final newline */
		if (line[strlen(line) - 1] == '\n')
			line[strlen(line) - 1] = 0;

		/* Parse the current line */
		ret = image_create_config_parse_oneline(line,
							&image_cfg[cfgi]);
		if (ret)
			return ret;

		cfgi++;

		if (cfgi >= IMAGE_CFG_ELEMENT_MAX) {
			fprintf(stderr,
				"Too many configuration elements in .cfg file\n");
			return -1;
		}
	}

	cfgn = cfgi;
	return 0;
}

static int image_get_version(void)
{
	struct image_cfg_element *e;

	e = image_find_option(IMAGE_CFG_VERSION);
	if (!e)
		return -1;

	return e->version;
}

static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
				struct image_tool_params *params)
{
	FILE *fcfg;
	void *image = NULL;
	int version;
	size_t dataoff = 0;
	size_t datasz;
	uint32_t checksum;
	struct stat s;
	int ret;

	/*
	 * Do not use sbuf->st_size as it contains size with padding.
	 * We need original image data size, so stat original file.
	 */
	if (params->skipcpy) {
		s.st_size = 0;
	} else if (stat(params->datafile, &s)) {
		fprintf(stderr, "Could not stat data file %s: %s\n",
			params->datafile, strerror(errno));
		exit(EXIT_FAILURE);
	}
	datasz = ALIGN(s.st_size, 4);

	fcfg = fopen(params->imagename, "r");
	if (!fcfg) {
		fprintf(stderr, "Could not open input file %s\n",
			params->imagename);
		exit(EXIT_FAILURE);
	}

	image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX *
			   sizeof(struct image_cfg_element));
	if (!image_cfg) {
		fprintf(stderr, "Cannot allocate memory\n");
		fclose(fcfg);
		exit(EXIT_FAILURE);
	}

	memset(image_cfg, 0,
	       IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element));
	rewind(fcfg);

	ret = image_create_config_parse(fcfg);
	fclose(fcfg);
	if (ret) {
		free(image_cfg);
		exit(EXIT_FAILURE);
	}

	version = image_get_version();
	switch (version) {
		/*
		 * Fallback to version 0 if no version is provided in the
		 * cfg file
		 */
	case -1:
	case 0:
		image = image_create_v0(&dataoff, params, datasz + 4);
		break;

	case 1:
		image = image_create_v1(&dataoff, params, ptr, datasz + 4);
		break;

	default:
		fprintf(stderr, "Unsupported version %d\n", version);
		free(image_cfg);
		exit(EXIT_FAILURE);
	}

	if (!image) {
		fprintf(stderr, "Could not create image\n");
		free(image_cfg);
		exit(EXIT_FAILURE);
	}

	free(image_cfg);

	/* Build and add image data checksum */
	checksum = cpu_to_le32(image_checksum32((uint8_t *)ptr + dataoff,
						datasz));
	memcpy((uint8_t *)ptr + dataoff + datasz, &checksum, sizeof(uint32_t));

	/* Finally copy the header into the image area */
	memcpy(ptr, image, kwbheader_size(image));

	free(image);
}

static void kwbimage_print_header(const void *ptr, struct image_tool_params *params)
{
	struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
	struct bin_hdr_v0 *bhdr;
	struct opt_hdr_v1 *ohdr;

	printf("Image Type:   MVEBU Boot from %s Image\n",
	       image_boot_mode_name(mhdr->blockid));
	printf("Image version:%d\n", kwbimage_version(ptr));

	for_each_opt_hdr_v1 (ohdr, mhdr) {
		if (ohdr->headertype == OPT_HDR_V1_BINARY_TYPE) {
			printf("BIN Img Size: ");
			genimg_print_size(opt_hdr_v1_size(ohdr) - 12 -
					  4 * ohdr->data[0]);
			printf("BIN Img Offs: ");
			genimg_print_size(((uint8_t *)ohdr - (uint8_t *)mhdr) +
					  8 + 4 * ohdr->data[0]);
		}
	}

	for_each_bin_hdr_v0(bhdr, mhdr) {
		printf("BIN Img Size: ");
		genimg_print_size(le32_to_cpu(bhdr->size));
		printf("BIN Img Addr: %08x\n", le32_to_cpu(bhdr->destaddr));
		printf("BIN Img Entr: %08x\n", le32_to_cpu(bhdr->execaddr));
	}

	printf("Data Size:    ");
	genimg_print_size(le32_to_cpu(mhdr->blocksize) - sizeof(uint32_t));
	printf("Data Offset:  ");
	if (mhdr->blockid == IBR_HDR_SATA_ID)
		printf("%u Sector%s (LBA)\n", le32_to_cpu(mhdr->srcaddr),
		       le32_to_cpu(mhdr->srcaddr) != 1 ? "s" : "");
	else
		genimg_print_size(le32_to_cpu(mhdr->srcaddr));
	if (mhdr->blockid == IBR_HDR_SPI_ID && le32_to_cpu(mhdr->destaddr) == 0xFFFFFFFF) {
		printf("Load Address: XIP\n");
		printf("Execute Offs: %08x\n", le32_to_cpu(mhdr->execaddr));
	} else {
		printf("Load Address: %08x\n", le32_to_cpu(mhdr->destaddr));
		printf("Entry Point:  %08x\n", le32_to_cpu(mhdr->execaddr));
	}
}

static int kwbimage_check_image_types(uint8_t type)
{
	if (type == IH_TYPE_KWBIMAGE)
		return EXIT_SUCCESS;

	return EXIT_FAILURE;
}

static int kwbimage_verify_header(unsigned char *ptr, int image_size,
				  struct image_tool_params *params)
{
	size_t header_size = kwbheader_size(ptr);
	uint8_t blockid;
	uint32_t offset;
	uint32_t size;
	uint8_t csum;

	if (header_size > 192*1024)
		return -FDT_ERR_BADSTRUCTURE;

	if (header_size > image_size)
		return -FDT_ERR_BADSTRUCTURE;

	if (!main_hdr_checksum_ok(ptr))
		return -FDT_ERR_BADSTRUCTURE;

	/* Only version 0 extended header has checksum */
	if (kwbimage_version(ptr) == 0) {
		struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
		struct ext_hdr_v0 *ext_hdr;
		struct bin_hdr_v0 *bhdr;

		for_each_ext_hdr_v0(ext_hdr, ptr) {
			csum = image_checksum8(ext_hdr, sizeof(*ext_hdr) - 1);
			if (csum != ext_hdr->checksum)
				return -FDT_ERR_BADSTRUCTURE;
		}

		for_each_bin_hdr_v0(bhdr, ptr) {
			csum = image_checksum8(bhdr, (uint8_t *)&bhdr->checksum - (uint8_t *)bhdr - 1);
			if (csum != bhdr->checksum)
				return -FDT_ERR_BADSTRUCTURE;

			if (bhdr->offset > sizeof(*bhdr) || bhdr->offset % 4 != 0)
				return -FDT_ERR_BADSTRUCTURE;

			if (bhdr->offset + bhdr->size + 4 > sizeof(*bhdr) || bhdr->size % 4 != 0)
				return -FDT_ERR_BADSTRUCTURE;

			if (image_checksum32((uint8_t *)bhdr + bhdr->offset, bhdr->size) !=
			    *(uint32_t *)((uint8_t *)bhdr + bhdr->offset + bhdr->size))
				return -FDT_ERR_BADSTRUCTURE;
		}

		blockid = mhdr->blockid;
		offset = le32_to_cpu(mhdr->srcaddr);
		size = le32_to_cpu(mhdr->blocksize);
	} else if (kwbimage_version(ptr) == 1) {
		struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
		const uint8_t *mhdr_end;
		struct opt_hdr_v1 *ohdr;

		mhdr_end = (uint8_t *)mhdr + header_size;
		for_each_opt_hdr_v1 (ohdr, ptr)
			if (!opt_hdr_v1_valid_size(ohdr, mhdr_end))
				return -FDT_ERR_BADSTRUCTURE;

		blockid = mhdr->blockid;
		offset = le32_to_cpu(mhdr->srcaddr);
		size = le32_to_cpu(mhdr->blocksize);
	} else {
		return -FDT_ERR_BADSTRUCTURE;
	}

	/*
	 * For SATA srcaddr is specified in number of sectors.
	 * This expects that sector size is 512 bytes.
	 */
	if (blockid == IBR_HDR_SATA_ID)
		offset *= 512;

	/*
	 * For PCIe srcaddr is always set to 0xFFFFFFFF.
	 * This expects that data starts after all headers.
	 */
	if (blockid == IBR_HDR_PEX_ID && offset == 0xFFFFFFFF)
		offset = header_size;

	if (offset > image_size || offset % 4 != 0)
		return -FDT_ERR_BADSTRUCTURE;

	if (size < 4 || offset + size > image_size || size % 4 != 0)
		return -FDT_ERR_BADSTRUCTURE;

	if (image_checksum32(ptr + offset, size - 4) !=
	    *(uint32_t *)(ptr + offset + size - 4))
		return -FDT_ERR_BADSTRUCTURE;

	return 0;
}

static int kwbimage_generate(struct image_tool_params *params,
			     struct image_type_params *tparams)
{
	FILE *fcfg;
	struct stat s;
	int alloc_len;
	int bootfrom;
	int version;
	void *hdr;
	int ret;
	int align, size;

	fcfg = fopen(params->imagename, "r");
	if (!fcfg) {
		fprintf(stderr, "Could not open input file %s\n",
			params->imagename);
		exit(EXIT_FAILURE);
	}

	if (params->skipcpy) {
		s.st_size = 0;
	} else if (stat(params->datafile, &s)) {
		fprintf(stderr, "Could not stat data file %s: %s\n",
			params->datafile, strerror(errno));
		exit(EXIT_FAILURE);
	}

	image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX *
			   sizeof(struct image_cfg_element));
	if (!image_cfg) {
		fprintf(stderr, "Cannot allocate memory\n");
		fclose(fcfg);
		exit(EXIT_FAILURE);
	}

	memset(image_cfg, 0,
	       IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element));
	rewind(fcfg);

	ret = image_create_config_parse(fcfg);
	fclose(fcfg);
	if (ret) {
		free(image_cfg);
		exit(EXIT_FAILURE);
	}

	bootfrom = image_get_bootfrom();
	version = image_get_version();
	switch (version) {
		/*
		 * Fallback to version 0 if no version is provided in the
		 * cfg file
		 */
	case -1:
	case 0:
		alloc_len = image_headersz_v0(NULL);
		break;

	case 1:
		alloc_len = image_headersz_v1(NULL);
		if (!alloc_len) {
			free(image_cfg);
			exit(EXIT_FAILURE);
		}
		if (alloc_len > 192*1024) {
			fprintf(stderr, "Header is too big (%u bytes), maximal kwbimage header size is %u bytes\n", alloc_len, 192*1024);
			free(image_cfg);
			exit(EXIT_FAILURE);
		}
		break;

	default:
		fprintf(stderr, "Unsupported version %d\n", version);
		free(image_cfg);
		exit(EXIT_FAILURE);
	}

	alloc_len = image_headersz_align(alloc_len, image_get_bootfrom());

	free(image_cfg);

	hdr = malloc(alloc_len);
	if (!hdr) {
		fprintf(stderr, "%s: malloc return failure: %s\n",
			params->cmdname, strerror(errno));
		exit(EXIT_FAILURE);
	}

	memset(hdr, 0, alloc_len);
	tparams->header_size = alloc_len;
	tparams->hdr = hdr;

	/*
	 * Final SATA and SDIO images must be aligned to 512 bytes.
	 * Final SPI and NAND images must be aligned to 256 bytes.
	 * Final UART image must be aligned to 128 bytes.
	 */
	if (bootfrom == IBR_HDR_SATA_ID || bootfrom == IBR_HDR_SDIO_ID)
		align = 512;
	else if (bootfrom == IBR_HDR_SPI_ID || bootfrom == IBR_HDR_NAND_ID)
		align = 256;
	else if (bootfrom == IBR_HDR_UART_ID)
		align = 128;
	else
		align = 4;

	/*
	 * The resulting image needs to be 4-byte aligned. At least
	 * the Marvell hdrparser tool complains if its unaligned.
	 * After the image data is stored 4-byte checksum.
	 */
	size = 4 + (align - (alloc_len + s.st_size + 4) % align) % align;

	/*
	 * This function should return aligned size of the datafile.
	 * When skipcpy is set (datafile is skipped) then return value of this
	 * function is ignored, so we have to put required kwbimage aligning
	 * into the preallocated header size.
	 */
	if (params->skipcpy) {
		tparams->header_size += size;
		return 0;
	} else {
		return size;
	}
}

static int kwbimage_generate_config(void *ptr, struct image_tool_params *params)
{
	struct main_hdr_v0 *mhdr0 = (struct main_hdr_v0 *)ptr;
	struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
	size_t header_size = kwbheader_size(ptr);
	struct register_set_hdr_v1 *regset_hdr;
	struct ext_hdr_v0_reg *regdata;
	struct ext_hdr_v0 *ehdr0;
	struct bin_hdr_v0 *bhdr0;
	struct opt_hdr_v1 *ohdr;
	int regset_count;
	int params_count;
	unsigned offset;
	int is_v0_ext;
	int cur_idx;
	int version;
	FILE *f;
	int i;

	f = fopen(params->outfile, "w");
	if (!f) {
		fprintf(stderr, "Can't open \"%s\": %s\n", params->outfile, strerror(errno));
		return -1;
	}

	version = kwbimage_version(ptr);

	is_v0_ext = 0;
	if (version == 0) {
		if (mhdr0->ext > 1 || mhdr0->bin ||
		    ((ehdr0 = ext_hdr_v0_first(ptr)) &&
		     (ehdr0->match_addr || ehdr0->match_mask || ehdr0->match_value)))
			is_v0_ext = 1;
	}

	if (version != 0)
		fprintf(f, "VERSION %d\n", version);

	fprintf(f, "BOOT_FROM %s\n", image_boot_mode_name(mhdr->blockid) ?: "<unknown>");

	if (version == 0 && mhdr->blockid == IBR_HDR_NAND_ID)
		fprintf(f, "NAND_ECC_MODE %s\n", image_nand_ecc_mode_name(mhdr0->nandeccmode));

	if (mhdr->blockid == IBR_HDR_NAND_ID)
		fprintf(f, "NAND_PAGE_SIZE 0x%x\n", (unsigned)le16_to_cpu(mhdr->nandpagesize));

	if (mhdr->blockid == IBR_HDR_NAND_ID && (version != 0 || is_v0_ext || mhdr->nandblocksize != 0)) {
		if (mhdr->nandblocksize != 0) /* block size explicitly set in 64 kB unit */
			fprintf(f, "NAND_BLKSZ 0x%x\n", (unsigned)mhdr->nandblocksize * 64*1024);
		else if (le16_to_cpu(mhdr->nandpagesize) > 512)
			fprintf(f, "NAND_BLKSZ 0x10000\n"); /* large page NAND flash = 64 kB block size */
		else
			fprintf(f, "NAND_BLKSZ 0x4000\n"); /* small page NAND flash = 16 kB block size */
	}

	if (mhdr->blockid == IBR_HDR_NAND_ID && (version != 0 || is_v0_ext))
		fprintf(f, "NAND_BADBLK_LOCATION 0x%x\n", (unsigned)mhdr->nandbadblklocation);

	if (version == 0 && mhdr->blockid == IBR_HDR_SATA_ID)
		fprintf(f, "SATA_PIO_MODE %u\n", (unsigned)mhdr0->satapiomode);

	/*
	 * Addresses and sizes which are specified by mkimage command line
	 * arguments and not in kwbimage config file
	 */

	if (version != 0)
		fprintf(f, "#HEADER_SIZE 0x%x\n",
			((unsigned)mhdr->headersz_msb << 8) | le16_to_cpu(mhdr->headersz_lsb));

	fprintf(f, "#SRC_ADDRESS 0x%x\n", le32_to_cpu(mhdr->srcaddr));
	fprintf(f, "#BLOCK_SIZE 0x%x\n", le32_to_cpu(mhdr->blocksize));
	fprintf(f, "#DEST_ADDRESS 0x%08x\n", le32_to_cpu(mhdr->destaddr));
	fprintf(f, "#EXEC_ADDRESS 0x%08x\n", le32_to_cpu(mhdr->execaddr));

	if (version != 0) {
		if (options_to_baudrate(mhdr->options))
			fprintf(f, "BAUDRATE %u\n", options_to_baudrate(mhdr->options));
		if (options_to_baudrate(mhdr->options) ||
		    ((mhdr->options >> 3) & 0x3) || ((mhdr->options >> 5) & 0x7)) {
			fprintf(f, "UART_PORT %u\n", (unsigned)((mhdr->options >> 3) & 0x3));
			fprintf(f, "UART_MPP 0x%x\n", (unsigned)((mhdr->options >> 5) & 0x7));
		}
		if (mhdr->flags & 0x1)
			fprintf(f, "DEBUG 1\n");
	}

	cur_idx = 1;
	for_each_opt_hdr_v1(ohdr, ptr) {
		if (ohdr->headertype == OPT_HDR_V1_SECURE_TYPE) {
			fprintf(f, "#SECURE_HEADER\n");
		} else if (ohdr->headertype == OPT_HDR_V1_BINARY_TYPE) {
			fprintf(f, "BINARY binary%d.bin", cur_idx);
			for (i = 0; i < ohdr->data[0]; i++)
				fprintf(f, " 0x%x", le32_to_cpu(((uint32_t *)ohdr->data)[i + 1]));
			offset = (unsigned)((uint8_t *)ohdr - (uint8_t *)mhdr) + 8 + 4 * ohdr->data[0];
			fprintf(f, " LOAD_ADDRESS 0x%08x\n", 0x40000000 + offset);
			fprintf(f, " # for CPU SHEEVA: LOAD_ADDRESS 0x%08x\n", 0x40004000 + offset);
			cur_idx++;
		} else if (ohdr->headertype == OPT_HDR_V1_REGISTER_TYPE) {
			regset_hdr = (struct register_set_hdr_v1 *)ohdr;
			if (opt_hdr_v1_size(ohdr) > sizeof(*ohdr))
				regset_count = (opt_hdr_v1_size(ohdr) - sizeof(*ohdr)) /
					       sizeof(regset_hdr->data[0].entry);
			else
				regset_count = 0;
			for (i = 0; i < regset_count; i++)
				fprintf(f, "DATA 0x%08x 0x%08x\n",
					le32_to_cpu(regset_hdr->data[i].entry.address),
					le32_to_cpu(regset_hdr->data[i].entry.value));
			if (regset_count > 0) {
				if (regset_hdr->data[regset_count-1].last_entry.delay !=
				    REGISTER_SET_HDR_OPT_DELAY_SDRAM_SETUP)
					fprintf(f, "DATA_DELAY %u\n",
						(unsigned)regset_hdr->data[regset_count-1].last_entry.delay);
				else
					fprintf(f, "DATA_DELAY SDRAM_SETUP\n");
			}
		}
	}

	if (version == 0 && !is_v0_ext && le16_to_cpu(mhdr0->ddrinitdelay))
		fprintf(f, "DDR_INIT_DELAY %u\n", (unsigned)le16_to_cpu(mhdr0->ddrinitdelay));

	for_each_ext_hdr_v0(ehdr0, ptr) {
		if (is_v0_ext) {
			fprintf(f, "\nMATCH ADDRESS 0x%08x MASK 0x%08x VALUE 0x%08x\n",
				le32_to_cpu(ehdr0->match_addr),
				le32_to_cpu(ehdr0->match_mask),
				le32_to_cpu(ehdr0->match_value));
			if (ehdr0->rsvd1[0] || ehdr0->rsvd1[1] || ehdr0->rsvd1[2] ||
			    ehdr0->rsvd1[3] || ehdr0->rsvd1[4] || ehdr0->rsvd1[5] ||
			    ehdr0->rsvd1[6] || ehdr0->rsvd1[7])
				fprintf(f, "#DDR_RSVD1 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
					ehdr0->rsvd1[0], ehdr0->rsvd1[1], ehdr0->rsvd1[2],
					ehdr0->rsvd1[3], ehdr0->rsvd1[4], ehdr0->rsvd1[5],
					ehdr0->rsvd1[6], ehdr0->rsvd1[7]);
			if (ehdr0->rsvd2[0] || ehdr0->rsvd2[1] || ehdr0->rsvd2[2] ||
			    ehdr0->rsvd2[3] || ehdr0->rsvd2[4] || ehdr0->rsvd2[5] ||
			    ehdr0->rsvd2[6])
				fprintf(f, "#DDR_RSVD2 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
					ehdr0->rsvd2[0], ehdr0->rsvd2[1], ehdr0->rsvd2[2],
					ehdr0->rsvd2[3], ehdr0->rsvd2[4], ehdr0->rsvd2[5],
					ehdr0->rsvd2[6]);
			if (ehdr0->ddrwritetype)
				fprintf(f, "DDR_WRITE_TYPE %u\n", (unsigned)ehdr0->ddrwritetype);
			if (ehdr0->ddrresetmpp)
				fprintf(f, "DDR_RESET_MPP 0x%x\n", (unsigned)ehdr0->ddrresetmpp);
			if (ehdr0->ddrclkenmpp)
				fprintf(f, "DDR_CLKEN_MPP 0x%x\n", (unsigned)ehdr0->ddrclkenmpp);
			if (ehdr0->ddrinitdelay)
				fprintf(f, "DDR_INIT_DELAY %u\n", (unsigned)ehdr0->ddrinitdelay);
		}

		if (ehdr0->offset) {
			for (regdata = (struct ext_hdr_v0_reg *)((uint8_t *)ptr + ehdr0->offset);
			     (uint8_t *)regdata < (uint8_t *)ptr + header_size &&
			     (regdata->raddr || regdata->rdata);
			     regdata++)
				fprintf(f, "DATA 0x%08x 0x%08x\n", le32_to_cpu(regdata->raddr),
					le32_to_cpu(regdata->rdata));
			if ((uint8_t *)regdata != (uint8_t *)ptr + ehdr0->offset)
				fprintf(f, "DATA 0x0 0x0\n");
		}

		if (le32_to_cpu(ehdr0->enddelay))
			fprintf(f, "DATA_DELAY %u\n", le32_to_cpu(ehdr0->enddelay));
		else if (is_v0_ext)
			fprintf(f, "DATA_DELAY SDRAM_SETUP\n");
	}

	cur_idx = 1;
	for_each_bin_hdr_v0(bhdr0, ptr) {
		fprintf(f, "\nMATCH ADDRESS 0x%08x MASK 0x%08x VALUE 0x%08x\n",
			le32_to_cpu(bhdr0->match_addr),
			le32_to_cpu(bhdr0->match_mask),
			le32_to_cpu(bhdr0->match_value));

		fprintf(f, "BINARY binary%d.bin", cur_idx);
		params_count = fls4(bhdr0->params_flags & 0xF);
		for (i = 0; i < params_count; i++)
			fprintf(f, " 0x%x", (bhdr0->params[i] & (1 << i)) ? bhdr0->params[i] : 0);
		fprintf(f, " LOAD_ADDRESS 0x%08x", le32_to_cpu(bhdr0->destaddr));
		fprintf(f, " EXEC_ADDRESS 0x%08x", le32_to_cpu(bhdr0->execaddr));
		fprintf(f, "\n");

		fprintf(f, "#BINARY_OFFSET 0x%x\n", le32_to_cpu(bhdr0->offset));
		fprintf(f, "#BINARY_SIZE 0x%x\n", le32_to_cpu(bhdr0->size));

		if (bhdr0->rsvd1)
			fprintf(f, "#BINARY_RSVD1 0x%x\n", (unsigned)bhdr0->rsvd1);
		if (bhdr0->rsvd2)
			fprintf(f, "#BINARY_RSVD2 0x%x\n", (unsigned)bhdr0->rsvd2);

		cur_idx++;
	}

	/* Undocumented reserved fields */

	if (version == 0 && (mhdr0->rsvd1[0] || mhdr0->rsvd1[1] || mhdr0->rsvd1[2]))
		fprintf(f, "#RSVD1 0x%x 0x%x 0x%x\n", (unsigned)mhdr0->rsvd1[0],
			(unsigned)mhdr0->rsvd1[1], (unsigned)mhdr0->rsvd1[2]);

	if (version == 0 && le16_to_cpu(mhdr0->rsvd2))
		fprintf(f, "#RSVD2 0x%x\n", (unsigned)le16_to_cpu(mhdr0->rsvd2));

	if (version != 0 && mhdr->reserved4)
		fprintf(f, "#RESERVED4 0x%x\n", (unsigned)mhdr->reserved4);

	if (version != 0 && mhdr->reserved5)
		fprintf(f, "#RESERVED5 0x%x\n", (unsigned)le16_to_cpu(mhdr->reserved5));

	fclose(f);

	return 0;
}

static int kwbimage_extract_subimage(void *ptr, struct image_tool_params *params)
{
	struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
	size_t header_size = kwbheader_size(ptr);
	struct bin_hdr_v0 *bhdr;
	struct opt_hdr_v1 *ohdr;
	int idx = params->pflag;
	int cur_idx;
	uint32_t offset;
	ulong image;
	ulong size;

	/* Generate kwbimage config file when '-p -1' is specified */
	if (idx == -1)
		return kwbimage_generate_config(ptr, params);

	image = 0;
	size = 0;

	if (idx == 0) {
		/* Extract data image when -p is not specified or when '-p 0' is specified */
		offset = le32_to_cpu(mhdr->srcaddr);

		if (mhdr->blockid == IBR_HDR_SATA_ID)
			offset *= 512;

		if (mhdr->blockid == IBR_HDR_PEX_ID && offset == 0xFFFFFFFF)
			offset = header_size;

		image = (ulong)((uint8_t *)ptr + offset);
		size = le32_to_cpu(mhdr->blocksize) - 4;
	} else {
		/* Extract N-th binary header executabe image when other '-p N' is specified */
		cur_idx = 1;
		for_each_opt_hdr_v1(ohdr, ptr) {
			if (ohdr->headertype != OPT_HDR_V1_BINARY_TYPE)
				continue;

			if (idx == cur_idx) {
				image = (ulong)&ohdr->data[4 + 4 * ohdr->data[0]];
				size = opt_hdr_v1_size(ohdr) - 12 - 4 * ohdr->data[0];
				break;
			}

			++cur_idx;
		}
		for_each_bin_hdr_v0(bhdr, ptr) {
			if (idx == cur_idx) {
				image = (ulong)bhdr + bhdr->offset;
				size = bhdr->size;
				break;
			}
			++cur_idx;
		}

		if (!image) {
			fprintf(stderr, "Argument -p %d is invalid\n", idx);
			fprintf(stderr, "Available subimages:\n");
			fprintf(stderr, " -p -1  - kwbimage config file\n");
			fprintf(stderr, " -p 0   - data image\n");
			if (cur_idx - 1 > 0)
				fprintf(stderr, " -p N   - Nth binary header image (totally: %d)\n",
					cur_idx - 1);
			return -1;
		}
	}

	return imagetool_save_subimage(params->outfile, image, size);
}

static int kwbimage_check_params(struct image_tool_params *params)
{
	if (!params->lflag && !params->iflag && !params->pflag &&
	    (!params->imagename || !strlen(params->imagename))) {
		char *msg = "Configuration file for kwbimage creation omitted";

		fprintf(stderr, "Error:%s - %s\n", params->cmdname, msg);
		return 1;
	}

	return (params->dflag && (params->fflag || params->lflag || params->skipcpy)) ||
		(params->fflag) ||
		(params->lflag && (params->dflag || params->fflag));
}

/*
 * kwbimage type parameters definition
 */
U_BOOT_IMAGE_TYPE(
	kwbimage,
	"Marvell MVEBU Boot Image support",
	0,
	NULL,
	kwbimage_check_params,
	kwbimage_verify_header,
	kwbimage_print_header,
	kwbimage_set_header,
	kwbimage_extract_subimage,
	kwbimage_check_image_types,
	NULL,
	kwbimage_generate
);
