// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2018 Arm Ltd.
 * (C) Copyright 2020-2021 Samuel Holland <samuel@sholland.org>
 */

#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <openssl/asn1t.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>

#include <image.h>
#include <sunxi_image.h>

#include "imagetool.h"
#include "mkimage.h"

/*
 * NAND requires 8K padding. For other devices, BROM requires only
 * 512B padding, but let's use the larger padding to cover everything.
 */
#define PAD_SIZE		8192

#define pr_fmt(fmt)		"mkimage (TOC0): %s: " fmt
#define pr_err(fmt, args...)	fprintf(stderr, pr_fmt(fmt), "error", ##args)
#define pr_warn(fmt, args...)	fprintf(stderr, pr_fmt(fmt), "warning", ##args)
#define pr_info(fmt, args...)	fprintf(stderr, pr_fmt(fmt), "info", ##args)

struct __packed toc0_key_item {
	__le32  vendor_id;
	__le32  key0_n_len;
	__le32  key0_e_len;
	__le32  key1_n_len;
	__le32  key1_e_len;
	__le32  sig_len;
	uint8_t key0[512];
	uint8_t key1[512];
	uint8_t reserved[32];
	uint8_t sig[256];
};

/*
 * This looks somewhat like an X.509 certificate, but it is not valid BER.
 *
 * Some differences:
 *  - Some X.509 certificate fields are missing or rearranged.
 *  - Some sequences have the wrong tag.
 *  - Zero-length sequences are accepted.
 *  - Large strings and integers must be an even number of bytes long.
 *  - Positive integers are not zero-extended to maintain their sign.
 *
 * See https://linux-sunxi.org/TOC0 for more information.
 */
struct __packed toc0_small_tag {
	uint8_t tag;
	uint8_t length;
};

typedef struct toc0_small_tag toc0_small_int;
typedef struct toc0_small_tag toc0_small_oct;
typedef struct toc0_small_tag toc0_small_seq;
typedef struct toc0_small_tag toc0_small_exp;

#define TOC0_SMALL_INT(len) { 0x02, (len) }
#define TOC0_SMALL_SEQ(len) { 0x30, (len) }
#define TOC0_SMALL_EXP(tag, len) { 0xa0 | (tag), len }

struct __packed toc0_large_tag {
	uint8_t tag;
	uint8_t prefix;
	uint8_t length_hi;
	uint8_t length_lo;
};

typedef struct toc0_large_tag toc0_large_int;
typedef struct toc0_large_tag toc0_large_bit;
typedef struct toc0_large_tag toc0_large_seq;

#define TOC0_LARGE_INT(len) { 0x02, 0x82, (len) >> 8, (len) & 0xff }
#define TOC0_LARGE_BIT(len) { 0x03, 0x82, (len) >> 8, (len) & 0xff }
#define TOC0_LARGE_SEQ(len) { 0x30, 0x82, (len) >> 8, (len) & 0xff }

struct __packed toc0_cert_item {
	toc0_large_seq tag_totalSequence;
	struct __packed toc0_totalSequence {
		toc0_large_seq tag_mainSequence;
		struct __packed toc0_mainSequence {
			toc0_small_exp tag_explicit0;
			struct __packed toc0_explicit0 {
				toc0_small_int tag_version;
				uint8_t version;
			} explicit0;
			toc0_small_int tag_serialNumber;
			uint8_t serialNumber;
			toc0_small_seq tag_signature;
			toc0_small_seq tag_issuer;
			toc0_small_seq tag_validity;
			toc0_small_seq tag_subject;
			toc0_large_seq tag_subjectPublicKeyInfo;
			struct __packed toc0_subjectPublicKeyInfo {
				toc0_small_seq tag_algorithm;
				toc0_large_seq tag_publicKey;
				struct __packed toc0_publicKey {
					toc0_large_int tag_n;
					uint8_t n[256];
					toc0_small_int tag_e;
					uint8_t e[3];
				} publicKey;
			} subjectPublicKeyInfo;
			toc0_small_exp tag_explicit3;
			struct __packed toc0_explicit3 {
				toc0_small_seq tag_extension;
				struct __packed toc0_extension {
					toc0_small_int tag_digest;
					uint8_t digest[32];
				} extension;
			} explicit3;
		} mainSequence;
		toc0_large_bit tag_sigSequence;
		struct __packed toc0_sigSequence {
			toc0_small_seq tag_algorithm;
			toc0_large_bit tag_signature;
			uint8_t signature[256];
		} sigSequence;
	} totalSequence;
};

#define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER))

static const struct toc0_cert_item cert_item_template = {
	TOC0_LARGE_SEQ(sizeof(struct toc0_totalSequence)),
	{
		TOC0_LARGE_SEQ(sizeof(struct toc0_mainSequence)),
		{
			TOC0_SMALL_EXP(0, sizeof(struct toc0_explicit0)),
			{
				TOC0_SMALL_INT(sizeof_field(struct toc0_explicit0, version)),
				0,
			},
			TOC0_SMALL_INT(sizeof_field(struct toc0_mainSequence, serialNumber)),
			0,
			TOC0_SMALL_SEQ(0),
			TOC0_SMALL_SEQ(0),
			TOC0_SMALL_SEQ(0),
			TOC0_SMALL_SEQ(0),
			TOC0_LARGE_SEQ(sizeof(struct toc0_subjectPublicKeyInfo)),
			{
				TOC0_SMALL_SEQ(0),
				TOC0_LARGE_SEQ(sizeof(struct toc0_publicKey)),
				{
					TOC0_LARGE_INT(sizeof_field(struct toc0_publicKey, n)),
					{},
					TOC0_SMALL_INT(sizeof_field(struct toc0_publicKey, e)),
					{},
				},
			},
			TOC0_SMALL_EXP(3, sizeof(struct toc0_explicit3)),
			{
				TOC0_SMALL_SEQ(sizeof(struct toc0_extension)),
				{
					TOC0_SMALL_INT(sizeof_field(struct toc0_extension, digest)),
					{},
				},
			},
		},
		TOC0_LARGE_BIT(sizeof(struct toc0_sigSequence)),
		{
			TOC0_SMALL_SEQ(0),
			TOC0_LARGE_BIT(sizeof_field(struct toc0_sigSequence, signature)),
			{},
		},
	},
};

#define TOC0_DEFAULT_NUM_ITEMS		3
#define TOC0_DEFAULT_HEADER_LEN						  \
	ALIGN(								  \
		sizeof(struct toc0_main_info)				+ \
		sizeof(struct toc0_item_info) *	TOC0_DEFAULT_NUM_ITEMS	+ \
		sizeof(struct toc0_cert_item)				+ \
		sizeof(struct toc0_key_item),				  \
	32)

static char *fw_key_file   = "fw_key.pem";
static char *key_item_file = "key_item.bin";
static char *root_key_file = "root_key.pem";

/*
 * Create a key item in @buf, containing the public keys @root_key and @fw_key,
 * and signed by the RSA key @root_key.
 */
static int toc0_create_key_item(uint8_t *buf, uint32_t *len,
				RSA *root_key, RSA *fw_key)
{
	struct toc0_key_item *key_item = (void *)buf;
	uint8_t digest[SHA256_DIGEST_LENGTH];
	int ret = EXIT_FAILURE;
	unsigned int sig_len;
	int n_len, e_len;

	/* Store key 0. */
	n_len = BN_bn2bin(RSA_get0_n(root_key), key_item->key0);
	e_len = BN_bn2bin(RSA_get0_e(root_key), key_item->key0 + n_len);
	if (n_len + e_len > sizeof(key_item->key0)) {
		pr_err("Root key is too big for key item\n");
		goto err;
	}
	key_item->key0_n_len = cpu_to_le32(n_len);
	key_item->key0_e_len = cpu_to_le32(e_len);

	/* Store key 1. */
	n_len = BN_bn2bin(RSA_get0_n(fw_key), key_item->key1);
	e_len = BN_bn2bin(RSA_get0_e(fw_key), key_item->key1 + n_len);
	if (n_len + e_len > sizeof(key_item->key1)) {
		pr_err("Firmware key is too big for key item\n");
		goto err;
	}
	key_item->key1_n_len = cpu_to_le32(n_len);
	key_item->key1_e_len = cpu_to_le32(e_len);

	/* Sign the key item. */
	key_item->sig_len = cpu_to_le32(RSA_size(root_key));
	SHA256(buf, key_item->sig - buf, digest);
	if (!RSA_sign(NID_sha256, digest, sizeof(digest),
		      key_item->sig, &sig_len, root_key)) {
		pr_err("Failed to sign key item\n");
		goto err;
	}
	if (sig_len != sizeof(key_item->sig)) {
		pr_err("Bad key item signature length\n");
		goto err;
	}

	*len = sizeof(*key_item);
	ret = EXIT_SUCCESS;

err:
	return ret;
}

/*
 * Verify the key item in @buf, containing two public keys @key0 and @key1,
 * and signed by the RSA key @key0. If @root_key is provided, only signatures
 * by that key will be accepted. @key1 is returned in @key.
 */
static int toc0_verify_key_item(const uint8_t *buf, uint32_t len,
				RSA *root_key, RSA **fw_key)
{
	struct toc0_key_item *key_item = (void *)buf;
	uint8_t digest[SHA256_DIGEST_LENGTH];
	int ret = EXIT_FAILURE;
	int n_len, e_len;
	RSA *key0 = NULL;
	RSA *key1 = NULL;
	BIGNUM *n, *e;

	if (len < sizeof(*key_item))
		goto err;

	/* Load key 0. */
	n_len = le32_to_cpu(key_item->key0_n_len);
	e_len = le32_to_cpu(key_item->key0_e_len);
	if (n_len + e_len > sizeof(key_item->key0)) {
		pr_err("Bad root key size in key item\n");
		goto err;
	}
	n = BN_bin2bn(key_item->key0, n_len, NULL);
	e = BN_bin2bn(key_item->key0 + n_len, e_len, NULL);
	key0 = RSA_new();
	if (!key0)
		goto err;
	if (!RSA_set0_key(key0, n, e, NULL))
		goto err;

	/* If a root key was provided, compare it to key 0. */
	if (root_key && (BN_cmp(n, RSA_get0_n(root_key)) ||
			 BN_cmp(e, RSA_get0_e(root_key)))) {
		pr_err("Wrong root key in key item\n");
		goto err;
	}

	/* Verify the key item signature. */
	SHA256(buf, key_item->sig - buf, digest);
	if (!RSA_verify(NID_sha256, digest, sizeof(digest),
			key_item->sig, le32_to_cpu(key_item->sig_len), key0)) {
		pr_err("Bad key item signature\n");
		goto err;
	}

	if (fw_key) {
		/* Load key 1. */
		n_len = le32_to_cpu(key_item->key1_n_len);
		e_len = le32_to_cpu(key_item->key1_e_len);
		if (n_len + e_len > sizeof(key_item->key1)) {
			pr_err("Bad firmware key size in key item\n");
			goto err;
		}
		n = BN_bin2bn(key_item->key1, n_len, NULL);
		e = BN_bin2bn(key_item->key1 + n_len, e_len, NULL);
		key1 = RSA_new();
		if (!key1)
			goto err;
		if (!RSA_set0_key(key1, n, e, NULL))
			goto err;

		if (*fw_key) {
			/* If a FW key was provided, compare it to key 1. */
			if (BN_cmp(n, RSA_get0_n(*fw_key)) ||
			    BN_cmp(e, RSA_get0_e(*fw_key))) {
				pr_err("Wrong firmware key in key item\n");
				goto err;
			}
		} else {
			/* Otherwise, send key1 back to the caller. */
			*fw_key = key1;
			key1 = NULL;
		}
	}

	ret = EXIT_SUCCESS;

err:
	RSA_free(key0);
	RSA_free(key1);

	return ret;
}

/*
 * Create a certificate in @buf, describing the firmware with SHA256 digest
 * @digest, and signed by the RSA key @fw_key.
 */
static int toc0_create_cert_item(uint8_t *buf, uint32_t *len, RSA *fw_key,
				 uint8_t digest[static SHA256_DIGEST_LENGTH])
{
	struct toc0_cert_item *cert_item = (void *)buf;
	uint8_t cert_digest[SHA256_DIGEST_LENGTH];
	struct toc0_totalSequence *totalSequence;
	struct toc0_sigSequence *sigSequence;
	struct toc0_extension *extension;
	struct toc0_publicKey *publicKey;
	int ret = EXIT_FAILURE;
	unsigned int sig_len;

	memcpy(cert_item, &cert_item_template, sizeof(*cert_item));
	*len = sizeof(*cert_item);

	/*
	 * Fill in the public key.
	 *
	 * Only 2048-bit RSA keys are supported. Since this uses a fixed-size
	 * structure, it may fail for non-standard exponents.
	 */
	totalSequence = &cert_item->totalSequence;
	publicKey = &totalSequence->mainSequence.subjectPublicKeyInfo.publicKey;
	if (BN_bn2binpad(RSA_get0_n(fw_key), publicKey->n, sizeof(publicKey->n)) < 0 ||
	    BN_bn2binpad(RSA_get0_e(fw_key), publicKey->e, sizeof(publicKey->e)) < 0) {
		pr_err("Firmware key is too big for certificate\n");
		goto err;
	}

	/* Fill in the firmware digest. */
	extension = &totalSequence->mainSequence.explicit3.extension;
	memcpy(&extension->digest, digest, SHA256_DIGEST_LENGTH);

	/*
	 * Sign the certificate.
	 *
	 * In older SBROM versions (and by default in newer versions),
	 * the last 4 bytes of the certificate are not signed.
	 *
	 * (The buffer passed to SHA256 starts at tag_mainSequence, but
	 *  the buffer size does not include the length of that tag.)
	 */
	SHA256((uint8_t *)totalSequence, sizeof(struct toc0_mainSequence), cert_digest);
	sigSequence = &totalSequence->sigSequence;
	if (!RSA_sign(NID_sha256, cert_digest, SHA256_DIGEST_LENGTH,
		      sigSequence->signature, &sig_len, fw_key)) {
		pr_err("Failed to sign certificate\n");
		goto err;
	}
	if (sig_len != sizeof(sigSequence->signature)) {
		pr_err("Bad certificate signature length\n");
		goto err;
	}

	ret = EXIT_SUCCESS;

err:
	return ret;
}

/*
 * Verify the certificate in @buf, describing the firmware with SHA256 digest
 * @digest, and signed by the RSA key contained within. If @fw_key is provided,
 * only that key will be accepted.
 *
 * This function is only expected to work with images created by mkimage.
 */
static int toc0_verify_cert_item(const uint8_t *buf, uint32_t len, RSA *fw_key,
				 uint8_t digest[static SHA256_DIGEST_LENGTH])
{
	const struct toc0_cert_item *cert_item = (const void *)buf;
	uint8_t cert_digest[SHA256_DIGEST_LENGTH];
	const struct toc0_totalSequence *totalSequence;
	const struct toc0_sigSequence *sigSequence;
	const struct toc0_extension *extension;
	const struct toc0_publicKey *publicKey;
	int ret = EXIT_FAILURE;
	RSA *key = NULL;
	BIGNUM *n, *e;

	/* Extract the public key from the certificate. */
	totalSequence = &cert_item->totalSequence;
	publicKey = &totalSequence->mainSequence.subjectPublicKeyInfo.publicKey;
	n = BN_bin2bn(publicKey->n, sizeof(publicKey->n), NULL);
	e = BN_bin2bn(publicKey->e, sizeof(publicKey->e), NULL);
	key = RSA_new();
	if (!key)
		goto err;
	if (!RSA_set0_key(key, n, e, NULL))
		goto err;

	/* If a key was provided, compare it to the embedded key. */
	if (fw_key && (BN_cmp(RSA_get0_n(key), RSA_get0_n(fw_key)) ||
		       BN_cmp(RSA_get0_e(key), RSA_get0_e(fw_key)))) {
		pr_err("Wrong firmware key in certificate\n");
		goto err;
	}

	/* If a digest was provided, compare it to the embedded digest. */
	extension = &totalSequence->mainSequence.explicit3.extension;
	if (digest && memcmp(&extension->digest, digest, SHA256_DIGEST_LENGTH)) {
		pr_err("Wrong firmware digest in certificate\n");
		goto err;
	}

	/* Verify the certificate's signature. See the comment above. */
	SHA256((uint8_t *)totalSequence, sizeof(struct toc0_mainSequence), cert_digest);
	sigSequence = &totalSequence->sigSequence;
	if (!RSA_verify(NID_sha256, cert_digest, SHA256_DIGEST_LENGTH,
			sigSequence->signature,
			sizeof(sigSequence->signature), key)) {
		pr_err("Bad certificate signature\n");
		goto err;
	}

	ret = EXIT_SUCCESS;

err:
	RSA_free(key);

	return ret;
}

/*
 * Always create a TOC0 containing 3 items. The extra item will be ignored on
 * SoCs which do not support it.
 */
static int toc0_create(uint8_t *buf, uint32_t len, RSA *root_key, RSA *fw_key,
		       uint8_t *key_item, uint32_t key_item_len,
		       uint8_t *fw_item, uint32_t fw_item_len, uint32_t fw_addr)
{
	struct toc0_main_info *main_info = (void *)buf;
	struct toc0_item_info *item_info = (void *)(main_info + 1);
	uint8_t digest[SHA256_DIGEST_LENGTH];
	uint32_t *buf32 = (void *)buf;
	RSA *orig_fw_key = fw_key;
	int ret = EXIT_FAILURE;
	uint32_t checksum = 0;
	uint32_t item_offset;
	uint32_t item_length;
	int i;

	/* Hash the firmware for inclusion in the certificate. */
	SHA256(fw_item, fw_item_len, digest);

	/* Create the main TOC0 header, containing three items. */
	memcpy(main_info->name, TOC0_MAIN_INFO_NAME, sizeof(main_info->name));
	main_info->magic	= cpu_to_le32(TOC0_MAIN_INFO_MAGIC);
	main_info->checksum	= cpu_to_le32(BROM_STAMP_VALUE);
	main_info->num_items	= cpu_to_le32(TOC0_DEFAULT_NUM_ITEMS);
	memcpy(main_info->end, TOC0_MAIN_INFO_END, sizeof(main_info->end));

	/* The first item links the ROTPK to the signing key. */
	item_offset = sizeof(*main_info) +
		      sizeof(*item_info) * TOC0_DEFAULT_NUM_ITEMS;
	/* Using an existing key item avoids needing the root private key. */
	if (key_item) {
		item_length = sizeof(*key_item);
		if (toc0_verify_key_item(key_item, item_length,
					 root_key, &fw_key))
			goto err;
		memcpy(buf + item_offset, key_item, item_length);
	} else if (toc0_create_key_item(buf + item_offset, &item_length,
					root_key, fw_key)) {
		goto err;
	}

	item_info->name		= cpu_to_le32(TOC0_ITEM_INFO_NAME_KEY);
	item_info->offset	= cpu_to_le32(item_offset);
	item_info->length	= cpu_to_le32(item_length);
	memcpy(item_info->end, TOC0_ITEM_INFO_END, sizeof(item_info->end));

	/* The second item contains a certificate signed by the firmware key. */
	item_offset = item_offset + item_length;
	if (toc0_create_cert_item(buf + item_offset, &item_length,
				  fw_key, digest))
		goto err;

	item_info++;
	item_info->name		= cpu_to_le32(TOC0_ITEM_INFO_NAME_CERT);
	item_info->offset	= cpu_to_le32(item_offset);
	item_info->length	= cpu_to_le32(item_length);
	memcpy(item_info->end, TOC0_ITEM_INFO_END, sizeof(item_info->end));

	/* The third item contains the actual boot code. */
	item_offset = ALIGN(item_offset + item_length, 32);
	item_length = fw_item_len;
	if (buf + item_offset != fw_item)
		memmove(buf + item_offset, fw_item, item_length);

	item_info++;
	item_info->name		= cpu_to_le32(TOC0_ITEM_INFO_NAME_FIRMWARE);
	item_info->offset	= cpu_to_le32(item_offset);
	item_info->length	= cpu_to_le32(item_length);
	item_info->load_addr	= cpu_to_le32(fw_addr);
	memcpy(item_info->end, TOC0_ITEM_INFO_END, sizeof(item_info->end));

	/* Pad to the required block size with 0xff to be flash-friendly. */
	item_offset = item_offset + item_length;
	item_length = ALIGN(item_offset, PAD_SIZE) - item_offset;
	memset(buf + item_offset, 0xff, item_length);

	/* Fill in the total padded file length. */
	item_offset = item_offset + item_length;
	main_info->length = cpu_to_le32(item_offset);

	/* Verify enough space was provided when creating the image. */
	assert(len >= item_offset);

	/* Calculate the checksum. Yes, it's that simple. */
	for (i = 0; i < item_offset / 4; ++i)
		checksum += le32_to_cpu(buf32[i]);
	main_info->checksum = cpu_to_le32(checksum);

	ret = EXIT_SUCCESS;

err:
	if (fw_key != orig_fw_key)
		RSA_free(fw_key);

	return ret;
}

static const struct toc0_item_info *
toc0_find_item(const struct toc0_main_info *main_info, uint32_t name,
	       uint32_t *offset, uint32_t *length)
{
	const struct toc0_item_info *item_info = (void *)(main_info + 1);
	uint32_t item_offset, item_length;
	uint32_t num_items, main_length;
	int i;

	num_items   = le32_to_cpu(main_info->num_items);
	main_length = le32_to_cpu(main_info->length);

	for (i = 0; i < num_items; ++i, ++item_info) {
		if (le32_to_cpu(item_info->name) != name)
			continue;

		item_offset = le32_to_cpu(item_info->offset);
		item_length = le32_to_cpu(item_info->length);

		if (item_offset > main_length ||
		    item_length > main_length - item_offset)
			continue;

		*offset = item_offset;
		*length = item_length;

		return item_info;
	}

	return NULL;
}

static int toc0_verify(const uint8_t *buf, uint32_t len, RSA *root_key)
{
	const struct toc0_main_info *main_info = (void *)buf;
	const struct toc0_item_info *item_info;
	uint8_t digest[SHA256_DIGEST_LENGTH];
	uint32_t main_length = le32_to_cpu(main_info->length);
	uint32_t checksum = BROM_STAMP_VALUE;
	uint32_t *buf32 = (void *)buf;
	uint32_t length, offset;
	int ret = EXIT_FAILURE;
	RSA *fw_key = NULL;
	int i;

	if (len < main_length)
		goto err;

	/* Verify the main header. */
	if (memcmp(main_info->name, TOC0_MAIN_INFO_NAME, sizeof(main_info->name)))
		goto err;
	if (le32_to_cpu(main_info->magic) != TOC0_MAIN_INFO_MAGIC)
		goto err;
	/* Verify the checksum without modifying the buffer. */
	for (i = 0; i < main_length / 4; ++i)
		checksum += le32_to_cpu(buf32[i]);
	if (checksum != 2 * le32_to_cpu(main_info->checksum))
		goto err;
	/* The length must be at least 512 byte aligned. */
	if (main_length % 512)
		goto err;
	if (memcmp(main_info->end, TOC0_MAIN_INFO_END, sizeof(main_info->end)))
		goto err;

	/* Verify the key item if present (it is optional). */
	item_info = toc0_find_item(main_info, TOC0_ITEM_INFO_NAME_KEY,
				   &offset, &length);
	if (!item_info)
		fw_key = root_key;
	else if (toc0_verify_key_item(buf + offset, length, root_key, &fw_key))
		goto err;

	/* Hash the firmware to compare with the certificate. */
	item_info = toc0_find_item(main_info, TOC0_ITEM_INFO_NAME_FIRMWARE,
				   &offset, &length);
	if (!item_info) {
		pr_err("Missing firmware item\n");
		goto err;
	}
	SHA256(buf + offset, length, digest);

	/* Verify the certificate item. */
	item_info = toc0_find_item(main_info, TOC0_ITEM_INFO_NAME_CERT,
				   &offset, &length);
	if (!item_info) {
		pr_err("Missing certificate item\n");
		goto err;
	}
	if (toc0_verify_cert_item(buf + offset, length, fw_key, digest))
		goto err;

	ret = EXIT_SUCCESS;

err:
	if (fw_key != root_key)
		RSA_free(fw_key);

	return ret;
}

static int toc0_check_params(struct image_tool_params *params)
{
	if (!params->dflag)
		return -EINVAL;

	/*
	 * If a key directory was provided, look for key files there.
	 * Otherwise, look for them in the current directory. The key files are
	 * the "quoted" terms in the description below.
	 *
	 * A summary of the chain of trust on most SoCs:
	 *  1) eFuse contains a SHA256 digest of the public "root key".
	 *  2) Private "root key" signs the certificate item (generated here).
	 *  3) Certificate item contains a SHA256 digest of the firmware item.
	 *
	 * A summary of the chain of trust on the H6 (by default; a bit in the
	 * BROM_CONFIG eFuse makes it work like above):
	 *  1) eFuse contains a SHA256 digest of the public "root key".
	 *  2) Private "root key" signs the "key item" (generated here).
	 *  3) "Key item" contains the public "root key" and public "fw key".
	 *  4) Private "fw key" signs the certificate item (generated here).
	 *  5) Certificate item contains a SHA256 digest of the firmware item.
	 *
	 * This means there are three valid ways to generate a TOC0:
	 *  1) Provide the private "root key" only. This works everywhere.
	 *     For H6, the "root key" will also be used as the "fw key".
	 *  2) FOR H6 ONLY: Provide the private "root key" and a separate
	 *     private "fw key".
	 *  3) FOR H6 ONLY: Provide the private "fw key" and a pre-existing
	 *     "key item" containing the corresponding  public "fw key".
	 *     In this case, the private "root key" can be kept offline. The
	 *     "key item" can be extracted from a TOC0 image generated using
	 *     method #2 above.
	 *
	 *  Note that until the ROTPK_HASH eFuse is programmed, any "root key"
	 *  will be accepted by the BROM.
	 */
	if (params->keydir) {
		if (asprintf(&fw_key_file, "%s/%s", params->keydir, fw_key_file) < 0)
			return -ENOMEM;
		if (asprintf(&key_item_file, "%s/%s", params->keydir, key_item_file) < 0)
			return -ENOMEM;
		if (asprintf(&root_key_file, "%s/%s", params->keydir, root_key_file) < 0)
			return -ENOMEM;
	}

	return 0;
}

static int toc0_verify_header(unsigned char *buf, int image_size,
			      struct image_tool_params *params)
{
	int ret = EXIT_FAILURE;
	RSA *root_key = NULL;
	FILE *fp;

	/* A root public key is optional. */
	fp = fopen(root_key_file, "rb");
	if (fp) {
		pr_info("Verifying image with existing root key\n");
		root_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
		if (!root_key)
			root_key = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL);
		fclose(fp);
		if (!root_key) {
			pr_err("Failed to read public key from '%s'\n",
			       root_key_file);
			goto err;
		}
	}

	ret = toc0_verify(buf, image_size, root_key);

err:
	RSA_free(root_key);

	return ret;
}

static const char *toc0_item_name(uint32_t name)
{
	if (name == TOC0_ITEM_INFO_NAME_CERT)
		return "Certificate";
	if (name == TOC0_ITEM_INFO_NAME_FIRMWARE)
		return "Firmware";
	if (name == TOC0_ITEM_INFO_NAME_KEY)
		return "Key";
	return "(unknown)";
}

static void toc0_print_header(const void *buf)
{
	const struct toc0_main_info *main_info = buf;
	const struct toc0_item_info *item_info = (void *)(main_info + 1);
	uint32_t head_length, main_length, num_items;
	uint32_t item_offset, item_length, item_name;
	int load_addr = -1;
	int i;

	num_items   = le32_to_cpu(main_info->num_items);
	head_length = sizeof(*main_info) + num_items * sizeof(*item_info);
	main_length = le32_to_cpu(main_info->length);

	printf("Allwinner TOC0 Image\n"
	       "Size: %d bytes\n"
	       "Contents: %d items\n"
	       " 00000000:%08x Headers\n",
	       main_length, num_items, head_length);

	for (i = 0; i < num_items; ++i, ++item_info) {
		item_offset = le32_to_cpu(item_info->offset);
		item_length = le32_to_cpu(item_info->length);
		item_name   = le32_to_cpu(item_info->name);

		if (item_name == TOC0_ITEM_INFO_NAME_FIRMWARE)
			load_addr = le32_to_cpu(item_info->load_addr);

		printf(" %08x:%08x %s\n",
		       item_offset, item_length,
		       toc0_item_name(item_name));
	}

	if (num_items && item_offset + item_length < main_length) {
		item_offset = item_offset + item_length;
		item_length = main_length - item_offset;

		printf(" %08x:%08x Padding\n",
		       item_offset, item_length);
	}

	if (load_addr != -1)
		printf("Load address: 0x%08x\n", load_addr);
}

static void toc0_set_header(void *buf, struct stat *sbuf, int ifd,
			    struct image_tool_params *params)
{
	uint32_t key_item_len = 0;
	uint8_t *key_item = NULL;
	int ret = EXIT_FAILURE;
	RSA *root_key = NULL;
	RSA *fw_key = NULL;
	FILE *fp;

	/* Either a key item or the root private key is required. */
	fp = fopen(key_item_file, "rb");
	if (fp) {
		pr_info("Creating image using existing key item\n");
		key_item_len = sizeof(struct toc0_key_item);
		key_item = OPENSSL_malloc(key_item_len);
		if (!key_item || fread(key_item, key_item_len, 1, fp) != 1) {
			pr_err("Failed to read key item from '%s'\n",
			       root_key_file);
			goto err;
		}
		fclose(fp);
		fp = NULL;
	}

	fp = fopen(root_key_file, "rb");
	if (fp) {
		root_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
		if (!root_key)
			root_key = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL);
		fclose(fp);
		fp = NULL;
	}

	/* When using an existing key item, the root key is optional. */
	if (!key_item && (!root_key || !RSA_get0_d(root_key))) {
		pr_err("Failed to read private key from '%s'\n",
		       root_key_file);
		pr_info("Try 'openssl genrsa -out root_key.pem'\n");
		goto err;
	}

	/* The certificate/firmware private key is always required. */
	fp = fopen(fw_key_file, "rb");
	if (fp) {
		fw_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
		fclose(fp);
		fp = NULL;
	}
	if (!fw_key) {
		/* If the root key is a private key, it can be used instead. */
		if (root_key && RSA_get0_d(root_key)) {
			pr_info("Using root key as firmware key\n");
			fw_key = root_key;
		} else {
			pr_err("Failed to read private key from '%s'\n",
			       fw_key_file);
			goto err;
		}
	}

	/* Warn about potential compatibility issues. */
	if (key_item || fw_key != root_key)
		pr_warn("Only H6 supports separate root and firmware keys\n");

	ret = toc0_create(buf, params->file_size, root_key, fw_key,
			  key_item, key_item_len,
			  buf + TOC0_DEFAULT_HEADER_LEN,
			  params->orig_file_size, params->addr);

err:
	OPENSSL_free(key_item);
	OPENSSL_free(root_key);
	if (fw_key != root_key)
		OPENSSL_free(fw_key);
	if (fp)
		fclose(fp);

	if (ret != EXIT_SUCCESS)
		exit(ret);
}

static int toc0_check_image_type(uint8_t type)
{
	return type == IH_TYPE_SUNXI_TOC0 ? 0 : 1;
}

static int toc0_vrec_header(struct image_tool_params *params,
			    struct image_type_params *tparams)
{
	tparams->hdr = calloc(tparams->header_size, 1);

	/* Save off the unpadded data size for SHA256 calculation. */
	params->orig_file_size = params->file_size - TOC0_DEFAULT_HEADER_LEN;

	/* Return padding to 8K blocks. */
	return ALIGN(params->file_size, PAD_SIZE) - params->file_size;
}

U_BOOT_IMAGE_TYPE(
	sunxi_toc0,
	"Allwinner TOC0 Boot Image support",
	TOC0_DEFAULT_HEADER_LEN,
	NULL,
	toc0_check_params,
	toc0_verify_header,
	toc0_print_header,
	toc0_set_header,
	NULL,
	toc0_check_image_type,
	NULL,
	toc0_vrec_header
);
