/* ifwitool, CLI utility for IFWI manipulation */
/* SPDX-License-Identifier: GPL-2.0-only */

#include <commonlib/bsd/helpers.h>
#include <commonlib/endian.h>
#include <getopt.h>
#include <stdlib.h>
#include <time.h>

#include "common.h"

/*
 * BPDT is Boot Partition Descriptor Table. It is located at the start of a
 * logical boot partition(LBP). It stores information about the critical
 * sub-partitions present within the LBP.
 *
 * S-BPDT is Secondary Boot Partition Descriptor Table. It is located after the
 * critical sub-partitions and contains information about the non-critical
 * sub-partitions present within the LBP.
 *
 * Both tables are identified by BPDT_SIGNATURE stored at the start of the
 * table.
 */
#define BPDT_SIGNATURE				(0x000055AA)

#define LBP1					(0)
#define LBP2					(1)

/* Parameters passed in by caller. */
static struct param {
	const char *file_name;
	size_t logical_boot_partition;
	const char *subpart_name;
	const char *image_name;
	bool dir_ops;
	const char *dentry_name;
} param;

struct bpdt_header {
	/*
	 * This is used to identify start of BPDT. It should always be
	 * BPDT_SIGNATURE.
	 */
	uint32_t signature;
	/* Count of BPDT entries present. */
	uint16_t descriptor_count;
	/* Version - Currently supported = 1. */
	uint16_t bpdt_version;
	/* Unused - Should be 0. */
	uint32_t xor_redundant_block;
	/* Version of IFWI build. */
	uint32_t ifwi_version;
	/* Version of FIT tool used to create IFWI. */
	uint64_t fit_tool_version;
} __packed;
#define BPDT_HEADER_SIZE			(sizeof(struct bpdt_header))

struct bpdt_entry {
	/* Type of sub-partition. */
	uint16_t type;
	/* Attributes of sub-partition. */
	uint16_t flags;
	/* Offset of sub-partition from beginning of LBP. */
	uint32_t offset;
	/* Size in bytes of sub-partition. */
	uint32_t size;
} __packed;
#define BPDT_ENTRY_SIZE			(sizeof(struct bpdt_entry))

struct bpdt {
	struct bpdt_header h;
	/* In practice, this could be an array of 0 to n entries. */
	struct bpdt_entry e[0];
} __packed;

static inline size_t get_bpdt_size(struct bpdt_header *h)
{
	return (sizeof(*h) + BPDT_ENTRY_SIZE * h->descriptor_count);
}

/* Minimum size in bytes allocated to BPDT in IFWI. */
#define BPDT_MIN_SIZE				(512)

/* Header to define directory header for sub-partition. */
struct subpart_dir_header {
	/* Should be SUBPART_DIR_MARKER. */
	uint32_t marker;
	/* Number of directory entries in the sub-partition. */
	uint32_t num_entries;
	/* Currenty supported - 1. */
	uint8_t header_version;
	/* Currenty supported - 1. */
	uint8_t entry_version;
	/* Length of directory header in bytes. */
	uint8_t header_length;
	/*
	 * 2s complement of 8-bit sum from first byte of header to last byte of
	 * last directory entry.
	 */
	uint8_t checksum;
	/* ASCII short name of sub-partition. */
	uint8_t name[4];
} __packed;
#define SUBPART_DIR_HEADER_SIZE			\
					(sizeof(struct subpart_dir_header))
#define SUBPART_DIR_MARKER				0x44504324
#define SUBPART_DIR_HEADER_VERSION_SUPPORTED	1
#define SUBPART_DIR_ENTRY_VERSION_SUPPORTED	1

/* Structure for each directory entry for sub-partition. */
struct subpart_dir_entry {
	/* Name of directory entry - Not guaranteed to be NULL-terminated. */
	uint8_t name[12];
	/* Offset of entry from beginning of sub-partition. */
	uint32_t offset;
	/* Length in bytes of sub-directory entry. */
	uint32_t length;
	/* Must be zero. */
	uint32_t rsvd;
} __packed;
#define SUBPART_DIR_ENTRY_SIZE			\
					(sizeof(struct subpart_dir_entry))

struct subpart_dir {
	struct subpart_dir_header h;
	/* In practice, this could be an array of 0 to n entries. */
	struct subpart_dir_entry e[0];
} __packed;

static inline size_t subpart_dir_size(struct subpart_dir_header *h)
{
	return (sizeof(*h) + SUBPART_DIR_ENTRY_SIZE * h->num_entries);
}

struct manifest_header {
	uint32_t header_type;
	uint32_t header_length;
	uint32_t header_version;
	uint32_t flags;
	uint32_t vendor;
	uint32_t date;
	uint32_t size;
	uint32_t id;
	uint32_t rsvd;
	uint64_t version;
	uint32_t svn;
	uint64_t rsvd1;
	uint8_t rsvd2[64];
	uint32_t modulus_size;
	uint32_t exponent_size;
	uint8_t public_key[256];
	uint32_t exponent;
	uint8_t signature[256];
} __packed;

#define DWORD_SIZE				4
#define MANIFEST_HDR_SIZE			(sizeof(struct manifest_header))
#define MANIFEST_ID_MAGIC			(0x324e4d24)

struct module {
	uint8_t name[12];
	uint8_t type;
	uint8_t hash_alg;
	uint16_t hash_size;
	uint32_t metadata_size;
	uint8_t metadata_hash[32];
} __packed;

#define MODULE_SIZE				(sizeof(struct module))

struct signed_pkg_info_ext {
	uint32_t ext_type;
	uint32_t ext_length;
	uint8_t name[4];
	uint32_t vcn;
	uint8_t bitmap[16];
	uint32_t svn;
	uint8_t rsvd[16];
} __packed;

#define SIGNED_PKG_INFO_EXT_TYPE		0x15
#define SIGNED_PKG_INFO_EXT_SIZE		\
	(sizeof(struct signed_pkg_info_ext))

/*
 * Attributes for various IFWI sub-partitions.
 * LIES_WITHIN_BPDT_4K = Sub-Partition should lie within the same 4K block as
 * BPDT.
 * NON_CRITICAL_SUBPART = Sub-Partition entry should be present in S-BPDT.
 * CONTAINS_DIR = Sub-Partition contains directory.
 * AUTO_GENERATED = Sub-Partition is generated by the tool.
 * MANDATORY_BPDT_ENTRY = Even if sub-partition is deleted, BPDT should contain
 * an entry for it with size 0 and offset 0.
 */
enum subpart_attributes {
	LIES_WITHIN_BPDT_4K = (1 << 0),
	NON_CRITICAL_SUBPART = (1 << 1),
	CONTAINS_DIR = (1 << 2),
	AUTO_GENERATED = (1 << 3),
	MANDATORY_BPDT_ENTRY = (1 << 4),
};

/* Type value for various IFWI sub-partitions. */
enum bpdt_entry_type {
	SMIP_TYPE		= 0,
	CSE_RBE_TYPE		= 1,
	CSE_BUP_TYPE		= 2,
	UCODE_TYPE		= 3,
	IBB_TYPE		= 4,
	S_BPDT_TYPE		= 5,
	OBB_TYPE		= 6,
	CSE_MAIN_TYPE		= 7,
	ISH_TYPE		= 8,
	CSE_IDLM_TYPE		= 9,
	IFP_OVERRIDE_TYPE	= 10,
	DEBUG_TOKENS_TYPE	= 11,
	UFS_PHY_TYPE		= 12,
	UFS_GPP_TYPE		= 13,
	PMC_TYPE		= 14,
	IUNIT_TYPE		= 15,
	NVM_CONFIG_TYPE	= 16,
	UEP_TYPE		= 17,
	UFS_RATE_B_TYPE	= 18,
	MAX_SUBPARTS		= 19,
};

/*
 * There are two order requirements for an IFWI image:
 * 1. Order in which the sub-partitions lie within the BPDT entries.
 * 2. Order in which the sub-partitions lie within the image.
 *
 * header_order defines #1 i.e. the order in which the sub-partitions should
 * appear in the BPDT entries. pack_order defines #2 i.e. the order in which
 * sub-partitions appear in the IFWI image. pack_order controls the offset and
 * thus sub-partitions would have increasing offsets as we loop over pack_order.
 */
const enum bpdt_entry_type bpdt_header_order[MAX_SUBPARTS] = {
	/* Order of the following entries is mandatory. */
	CSE_IDLM_TYPE,
	IFP_OVERRIDE_TYPE,
	S_BPDT_TYPE,
	CSE_RBE_TYPE,
	UFS_PHY_TYPE,
	UFS_GPP_TYPE,
	/* Order of the following entries is recommended. */
	UEP_TYPE,
	NVM_CONFIG_TYPE,
	UFS_RATE_B_TYPE,
	IBB_TYPE,
	SMIP_TYPE,
	PMC_TYPE,
	CSE_BUP_TYPE,
	UCODE_TYPE,
	DEBUG_TOKENS_TYPE,
	IUNIT_TYPE,
	CSE_MAIN_TYPE,
	ISH_TYPE,
	OBB_TYPE,
};

const enum bpdt_entry_type bpdt_pack_order[MAX_SUBPARTS] = {
	/* Order of the following entries is mandatory. */
	UFS_GPP_TYPE,
	UFS_PHY_TYPE,
	IFP_OVERRIDE_TYPE,
	UEP_TYPE,
	NVM_CONFIG_TYPE,
	UFS_RATE_B_TYPE,
	/* Order of the following entries is recommended. */
	IBB_TYPE,
	SMIP_TYPE,
	CSE_RBE_TYPE,
	PMC_TYPE,
	CSE_BUP_TYPE,
	UCODE_TYPE,
	CSE_IDLM_TYPE,
	DEBUG_TOKENS_TYPE,
	S_BPDT_TYPE,
	IUNIT_TYPE,
	CSE_MAIN_TYPE,
	ISH_TYPE,
	OBB_TYPE,
};

/* Utility functions. */
enum ifwi_ret {
	COMMAND_ERR = -1,
	NO_ACTION_REQUIRED = 0,
	REPACK_REQUIRED = 1,
};

struct dir_ops {
	enum ifwi_ret (*dir_add)(int);
};

static enum ifwi_ret ibbp_dir_add(int);

const struct subpart_info {
	const char *name;
	const char *readable_name;
	uint32_t attr;
	struct dir_ops dir_ops;
} subparts[MAX_SUBPARTS] = {
	/* OEM SMIP */
	[SMIP_TYPE] = {"SMIP", "SMIP", CONTAINS_DIR, {NULL} },
	/* CSE RBE */
	[CSE_RBE_TYPE] = {"RBEP", "CSE_RBE", CONTAINS_DIR |
			  MANDATORY_BPDT_ENTRY, {NULL} },
	/* CSE BUP */
	[CSE_BUP_TYPE] = {"FTPR", "CSE_BUP", CONTAINS_DIR |
			  MANDATORY_BPDT_ENTRY, {NULL} },
	/* uCode */
	[UCODE_TYPE] = {"UCOD", "Microcode", CONTAINS_DIR, {NULL} },
	/* IBB */
	[IBB_TYPE] = {"IBBP", "Bootblock", CONTAINS_DIR, {ibbp_dir_add} },
	/* S-BPDT */
	[S_BPDT_TYPE] = {"S_BPDT", "S-BPDT", AUTO_GENERATED |
			 MANDATORY_BPDT_ENTRY, {NULL} },
	/* OBB */
	[OBB_TYPE] = {"OBBP", "OEM boot block", CONTAINS_DIR |
		      NON_CRITICAL_SUBPART, {NULL} },
	/* CSE Main */
	[CSE_MAIN_TYPE] = {"NFTP", "CSE_MAIN", CONTAINS_DIR |
			   NON_CRITICAL_SUBPART, {NULL} },
	/* ISH */
	[ISH_TYPE] = {"ISHP", "ISH", NON_CRITICAL_SUBPART, {NULL} },
	/* CSE IDLM */
	[CSE_IDLM_TYPE] = {"DLMP", "CSE_IDLM", CONTAINS_DIR |
			   MANDATORY_BPDT_ENTRY, {NULL} },
	/* IFP Override */
	[IFP_OVERRIDE_TYPE] = {"IFP_OVERRIDE", "IFP_OVERRIDE",
			       LIES_WITHIN_BPDT_4K | MANDATORY_BPDT_ENTRY,
			       {NULL} },
	/* Debug Tokens */
	[DEBUG_TOKENS_TYPE] = {"DEBUG_TOKENS", "Debug Tokens", 0, {NULL} },
	/* UFS Phy Configuration */
	[UFS_PHY_TYPE] = {"UFS_PHY", "UFS Phy", LIES_WITHIN_BPDT_4K |
			  MANDATORY_BPDT_ENTRY, {NULL} },
	/* UFS GPP LUN ID */
	[UFS_GPP_TYPE] = {"UFS_GPP", "UFS GPP", LIES_WITHIN_BPDT_4K |
			  MANDATORY_BPDT_ENTRY, {NULL} },
	/* PMC */
	[PMC_TYPE] = {"PMCP", "PMC firmware", CONTAINS_DIR, {NULL} },
	/* IUNIT */
	[IUNIT_TYPE] = {"IUNP", "IUNIT", NON_CRITICAL_SUBPART, {NULL} },
	/* NVM Config */
	[NVM_CONFIG_TYPE] = {"NVM_CONFIG", "NVM Config", 0, {NULL} },
	/* UEP */
	[UEP_TYPE] = {"UEP", "UEP", LIES_WITHIN_BPDT_4K | MANDATORY_BPDT_ENTRY,
		      {NULL} },
	/* UFS Rate B Config */
	[UFS_RATE_B_TYPE] = {"UFS_RATE_B", "UFS Rate B Config", 0, {NULL} },
};

struct ifwi_image {
	/* Data read from input file. */
	struct buffer input_buff;

	/* BPDT header and entries. */
	struct buffer bpdt;
	size_t input_ifwi_start_offset;
	size_t input_ifwi_end_offset;

	/* Subpartition content. */
	struct buffer subpart_buf[MAX_SUBPARTS];
} ifwi_image;

static void alloc_buffer(struct buffer *b, size_t s, const char *n)
{
	if (buffer_create(b, s, n) == 0)
		return;

	ERROR("Buffer allocation failure for %s (size = %zx).\n", n, s);
	exit(-1);
}

/*
 * Read header/entry members in little-endian format.
 * Returns the offset up to which the read was performed.
*/
static size_t read_member(void *src, size_t offset, size_t size_bytes,
			  void *dst)
{
	switch (size_bytes) {
	case 1:
		*(uint8_t *)dst = read_at_le8(src, offset);
		break;
	case 2:
		*(uint16_t *)dst = read_at_le16(src, offset);
		break;
	case 4:
		*(uint32_t *)dst = read_at_le32(src, offset);
		break;
	case 8:
		*(uint64_t *)dst = read_at_le64(src, offset);
		break;
	default:
		ERROR("Read size not supported %zd\n", size_bytes);
		exit(-1);
	}

	return (offset + size_bytes);
}

/*
 * Convert to little endian format.
 * Returns the offset up to which the fixup was performed.
 */
static size_t fix_member(void *data, size_t offset, size_t size_bytes)
{
	uint8_t *src = (uint8_t *)data + offset;

	switch (size_bytes) {
	case 1:
		write_at_le8(data, *(uint8_t *)src, offset);
		break;
	case 2:
		write_at_le16(data, *(uint16_t *)src, offset);
		break;
	case 4:
		write_at_le32(data, *(uint32_t *)src, offset);
		break;
	case 8:
		write_at_le64(data, *(uint64_t *)src, offset);
		break;
	default:
		ERROR("Write size not supported %zd\n", size_bytes);
		exit(-1);
	}
	return (offset + size_bytes);
}


static void print_subpart_dir(struct subpart_dir *s)
{
	if (verbose == 0)
		return;

	size_t i;

	printf("%-25s 0x%-23.8x\n", "Marker", s->h.marker);
	printf("%-25s %-25d\n", "Num entries", s->h.num_entries);
	printf("%-25s %-25d\n", "Header Version", s->h.header_version);
	printf("%-25s %-25d\n", "Entry Version", s->h.entry_version);
	printf("%-25s 0x%-23x\n", "Header Length", s->h.header_length);
	printf("%-25s 0x%-23x\n", "Checksum", s->h.checksum);
	printf("%-25s ", "Name");
	for (i = 0; i < sizeof(s->h.name); i++)
		printf("%c", s->h.name[i]);

	printf("\n");

	printf("%-25s%-25s%-25s%-25s%-25s\n", "Entry #", "Name", "Offset",
	       "Length", "Rsvd");

	printf("=============================================================="
	       "===========================================================\n");

	for (i = 0; i < s->h.num_entries; i++) {
		printf("%-25zd%-25.12s0x%-23x0x%-23x0x%-23x\n", i+1,
		       s->e[i].name, s->e[i].offset, s->e[i].length,
		       s->e[i].rsvd);
	}

	printf("=============================================================="
	       "===========================================================\n");
}

static void bpdt_print_header(struct bpdt_header *h, const char *name)
{
	if (verbose == 0)
		return;

	printf("%-25s %-25s\n", "Header", name);
	printf("%-25s 0x%-23.8x\n", "Signature", h->signature);
	printf("%-25s %-25d\n", "Descriptor count", h->descriptor_count);
	printf("%-25s %-25d\n", "BPDT Version", h->bpdt_version);
	printf("%-25s 0x%-23x\n", "XOR checksum", h->xor_redundant_block);
	printf("%-25s 0x%-23x\n", "IFWI Version", h->ifwi_version);
	printf("%-25s 0x%-23llx\n", "FIT Tool Version",
	       (long long)h->fit_tool_version);
}

static void bpdt_print_entries(struct bpdt_entry *e, size_t count,
			       const char *name)
{
	if (verbose == 0)
		return;

	printf("%s entries\n", name);

	printf("%-25s%-25s%-25s%-25s%-25s%-25s%-25s%-25s\n", "Entry #",
	       "Sub-Partition", "Name", "Type", "Flags", "Offset", "Size",
	       "File Offset");

	printf("=============================================================="
	       "=============================================================="
	       "=============================================================="
	       "===============\n");


	size_t i;
	for (i = 0; i < count; i++) {
		printf("%-25zd%-25s%-25s%-25d0x%-23.08x0x%-23x0x%-23x0x%-23zx"
		       "\n", i+1, subparts[e[i].type].name,
		       subparts[e[i].type].readable_name, e[i].type, e[i].flags,
		       e[i].offset, e[i].size,
		       e[i].offset + ifwi_image.input_ifwi_start_offset);
	}

	printf("=============================================================="
	       "=============================================================="
	       "=============================================================="
	       "===============\n");

}

static void bpdt_validate_header(struct bpdt_header *h, const char *name)
{
	assert(h->signature == BPDT_SIGNATURE);

	if (h->bpdt_version != 1) {
		ERROR("Invalid header : %s\n", name);
		exit(-1);
	}

	DEBUG("Validated header : %s\n", name);
}

static void bpdt_read_header(void *data, struct bpdt_header *h,
			     const char *name)
{
	size_t offset = 0;

	offset = read_member(data, offset, sizeof(h->signature), &h->signature);
	offset = read_member(data, offset, sizeof(h->descriptor_count),
			     &h->descriptor_count);
	offset = read_member(data, offset, sizeof(h->bpdt_version),
			     &h->bpdt_version);
	offset = read_member(data, offset, sizeof(h->xor_redundant_block),
			     &h->xor_redundant_block);
	offset = read_member(data, offset, sizeof(h->ifwi_version),
			     &h->ifwi_version);
	read_member(data, offset, sizeof(h->fit_tool_version),
		    &h->fit_tool_version);

	bpdt_validate_header(h, name);
	bpdt_print_header(h, name);
}

static void bpdt_read_entries(void *data, struct bpdt *bpdt, const char *name)
{
	size_t i, offset = 0;
	struct bpdt_entry *e = &bpdt->e[0];
	size_t count = bpdt->h.descriptor_count;

	for (i = 0; i < count; i++) {
		offset = read_member(data, offset, sizeof(e[i].type),
				     &e[i].type);
		offset = read_member(data, offset, sizeof(e[i].flags),
				     &e[i].flags);
		offset = read_member(data, offset, sizeof(e[i].offset),
				     &e[i].offset);
		offset = read_member(data, offset, sizeof(e[i].size),
				     &e[i].size);
	}

	bpdt_print_entries(e, count, name);
}

/*
 * Given type of sub-partition, identify BPDT entry for it.
 * Sub-Partition could lie either within BPDT or S-BPDT.
 */
static struct bpdt_entry *__find_entry_by_type(struct bpdt_entry *e,
					       size_t count, int type)
{
	size_t i;
	for (i = 0; i < count; i++) {
		if (e[i].type == type)
			break;
	}

	if (i == count)
		return NULL;

	return &e[i];
}

static struct bpdt_entry *find_entry_by_type(int type)
{
	struct bpdt *b = buffer_get(&ifwi_image.bpdt);
	if (b == NULL)
		return NULL;

	struct bpdt_entry *curr = __find_entry_by_type(&b->e[0],
						       b->h.descriptor_count,
						       type);

	if (curr)
		return curr;

	b = buffer_get(&ifwi_image.subpart_buf[S_BPDT_TYPE]);
	if (b == NULL)
		return NULL;

	return __find_entry_by_type(&b->e[0], b->h.descriptor_count, type);
}

/*
 * Find sub-partition type given its name. If the name does not exist, returns
 * -1.
 */
static int find_type_by_name(const char *name)
{
	int i;

	for (i = 0; i < MAX_SUBPARTS; i++) {
		if ((strlen(subparts[i].name) == strlen(name)) &&
		    (!strcmp(subparts[i].name, name)))
			break;
	}

	if (i == MAX_SUBPARTS) {
		ERROR("Invalid sub-partition name %s.\n", name);
		return -1;
	}

	return i;
}

/*
 * Read the content of a sub-partition from input file and store it in
 * ifwi_image.subpart_buf[SUB-PARTITION_TYPE].
 *
 * Returns the maximum offset occupied by the sub-partitions.
 */
static size_t read_subpart_buf(void *data, size_t size, struct bpdt_entry *e,
			       size_t count)
{
	size_t i, type;
	struct buffer *buf;
	size_t max_offset = 0;

	for (i = 0; i < count; i++) {
		type = e[i].type;

		if (type >= MAX_SUBPARTS) {
			ERROR("Invalid sub-partition type %zd.\n", type);
			exit(-1);
		}

		if (buffer_size(&ifwi_image.subpart_buf[type])) {
			ERROR("Multiple sub-partitions of type %zd(%s).\n",
			      type, subparts[type].name);
			exit(-1);
		}

		if (e[i].size == 0) {
			INFO("Dummy sub-partition %zd(%s). Skipping.\n", type,
			     subparts[type].name);
			continue;
		}

		assert((e[i].offset + e[i].size) <= size);

		/*
		 * Sub-partitions in IFWI image are not in the same order as
		 * in BPDT entries. BPDT entries are in header_order whereas
		 * sub-partition offsets in the image are in pack_order.
		 */
		if ((e[i].offset + e[i].size) > max_offset)
			max_offset = e[i].offset + e[i].size;

		/*
		 * S-BPDT sub-partition contains information about all the
		 * non-critical sub-partitions. Thus, size of S-BPDT
		 * sub-partition equals size of S-BPDT plus size of all the
		 * non-critical sub-partitions. Thus, reading whole of S-BPDT
		 * here would be redundant as the non-critical partitions are
		 * read and allocated buffers separately. Also, S-BPDT requires
		 * special handling for reading header and entries.
		 */
		if (type == S_BPDT_TYPE)
			continue;

		buf = &ifwi_image.subpart_buf[type];

		alloc_buffer(buf, e[i].size, subparts[type].name);
		memcpy(buffer_get(buf), (uint8_t *)data + e[i].offset,
		       e[i].size);
	}

	assert(max_offset);
	return max_offset;
}

/*
 * Allocate buffer for bpdt header, entries and all sub-partition content.
 * Returns offset in data where BPDT ends.
 */
static size_t alloc_bpdt_buffer(void *data, size_t size, size_t offset,
				struct buffer *b, const char *name)
{
	struct bpdt_header bpdt_header;
	assert((offset + BPDT_HEADER_SIZE) < size);
	bpdt_read_header((uint8_t *)data + offset, &bpdt_header, name);

	/* Buffer to read BPDT header and entries. */
	alloc_buffer(b, get_bpdt_size(&bpdt_header), name);

	struct bpdt *bpdt = buffer_get(b);
	memcpy(&bpdt->h, &bpdt_header, BPDT_HEADER_SIZE);

	/*
	 * If no entries are present, maximum offset occupied is (offset +
	 * BPDT_HEADER_SIZE).
	 */
	if (bpdt->h.descriptor_count == 0)
		return (offset + BPDT_HEADER_SIZE);

	/* Read all entries. */
	assert((offset + get_bpdt_size(&bpdt->h)) < size);
	bpdt_read_entries((uint8_t *)data + offset + BPDT_HEADER_SIZE, bpdt,
			  name);

	/* Read all sub-partition content in subpart_buf. */
	return read_subpart_buf(data, size, &bpdt->e[0],
				bpdt->h.descriptor_count);
}

static void parse_sbpdt(void *data, size_t size)
{
	struct bpdt_entry *s;
	s  = find_entry_by_type(S_BPDT_TYPE);
	if (!s)
		return;

	assert(size > s->offset);

	alloc_bpdt_buffer(data, size, s->offset,
			  &ifwi_image.subpart_buf[S_BPDT_TYPE],
			  "S-BPDT");
}

static uint8_t calc_checksum(struct subpart_dir *s)
{
	size_t size = subpart_dir_size(&s->h);
	uint8_t *data = (uint8_t *)s;
	uint8_t checksum = 0;
	size_t i;

	uint8_t old_checksum = s->h.checksum;
	s->h.checksum = 0;

	for (i = 0; i < size; i++)
		checksum += data[i];

	s->h.checksum = old_checksum;

	/* 2s complement */
	return -checksum;
}

static void validate_subpart_dir(struct subpart_dir *s, const char *name,
				 bool checksum_check)
{
	if ((s->h.marker != SUBPART_DIR_MARKER) ||
	    (s->h.header_version != SUBPART_DIR_HEADER_VERSION_SUPPORTED) ||
	    (s->h.entry_version != SUBPART_DIR_ENTRY_VERSION_SUPPORTED) ||
	    (s->h.header_length != SUBPART_DIR_HEADER_SIZE)) {
		ERROR("Invalid subpart_dir for %s.\n", name);
		exit(-1);
	}

	if (checksum_check == false)
		return;

	uint8_t checksum = calc_checksum(s);

	if (checksum != s->h.checksum)
		ERROR("Invalid checksum for %s (Expected=0x%x, Actual=0x%x).\n",
		      name, checksum, s->h.checksum);
}

static void validate_subpart_dir_without_checksum(struct subpart_dir *s,
						  const char *name)
{
	validate_subpart_dir(s, name, 0);
}

static void validate_subpart_dir_with_checksum(struct subpart_dir *s,
					       const char *name)
{
	validate_subpart_dir(s, name, 1);
}

static void parse_subpart_dir(struct buffer *subpart_dir_buf,
			      struct buffer *input_buf, const char *name)
{
	struct subpart_dir_header hdr;
	size_t offset = 0;
	uint8_t *data = buffer_get(input_buf);
	size_t size = buffer_size(input_buf);

	/* Read Subpart_Dir header. */
	assert(size >= SUBPART_DIR_HEADER_SIZE);
	offset = read_member(data, offset, sizeof(hdr.marker), &hdr.marker);
	offset = read_member(data, offset, sizeof(hdr.num_entries),
			     &hdr.num_entries);
	offset = read_member(data, offset, sizeof(hdr.header_version),
			     &hdr.header_version);
	offset = read_member(data, offset, sizeof(hdr.entry_version),
			     &hdr.entry_version);
	offset = read_member(data, offset, sizeof(hdr.header_length),
			     &hdr.header_length);
	offset = read_member(data, offset, sizeof(hdr.checksum), &hdr.checksum);
	memcpy(hdr.name, data + offset, sizeof(hdr.name));
	offset += sizeof(hdr.name);

	validate_subpart_dir_without_checksum((struct subpart_dir *)&hdr, name);

	assert(size > subpart_dir_size(&hdr));
	alloc_buffer(subpart_dir_buf, subpart_dir_size(&hdr), "Subpart Dir");
	memcpy(buffer_get(subpart_dir_buf), &hdr, SUBPART_DIR_HEADER_SIZE);

	/* Read Subpart Dir entries. */
	struct subpart_dir *subpart_dir = buffer_get(subpart_dir_buf);
	struct subpart_dir_entry *e = &subpart_dir->e[0];
	uint32_t i;
	for (i = 0; i < hdr.num_entries; i++) {
		memcpy(e[i].name, data + offset, sizeof(e[i].name));
		offset += sizeof(e[i].name);
		offset = read_member(data, offset, sizeof(e[i].offset),
				     &e[i].offset);
		offset = read_member(data, offset, sizeof(e[i].length),
				     &e[i].length);
		offset = read_member(data, offset, sizeof(e[i].rsvd),
				     &e[i].rsvd);
	}

	validate_subpart_dir_with_checksum(subpart_dir, name);

	print_subpart_dir(subpart_dir);
}

/* Parse the bpdt entries to compute the size of the BPDT */
static size_t bpdt_size(void *data)
{
	struct bpdt *b = (struct bpdt *)data;
	size_t i, size = 0;

	for (i = 0; i < b->h.descriptor_count; i++)
		size = MAX(size, b->e[i].offset + b->e[i].size);

	return size;
}

/* Parse input image file to identify different sub-partitions. */
static int ifwi_parse(void)
{
	DEBUG("Parsing IFWI image...\n");
	const char *image_name = param.image_name;

	/* Read input file. */
	struct buffer *buff = &ifwi_image.input_buff;
	if (buffer_from_file(buff, image_name)) {
		ERROR("Failed to read input file %s.\n", image_name);
		return -1;
	}

	INFO("Buffer %p size 0x%zx\n", buff->data, buff->size);

	/* Look for BPDT signature at 4K intervals. */
	size_t offset = 0, lbp = LBP1;
	void *data = buffer_get(buff);

	while (offset < buffer_size(buff)) {
		if (read_at_le32(data, offset) == BPDT_SIGNATURE) {
			if (lbp == param.logical_boot_partition)
				break;
			offset += bpdt_size((uint8_t *)data + offset);
			lbp++;
		} else
			offset += 4 * KiB;
	}

	if (offset >= buffer_size(buff)) {
		ERROR("Image does not contain BPDT for LBP=%zd!!\n",
		      param.logical_boot_partition);
		return -1;
	}

	ifwi_image.input_ifwi_start_offset = offset;
	INFO("BPDT starts at offset 0x%zx.\n", offset);

	data = (uint8_t *)data + offset;
	size_t ifwi_size = buffer_size(buff) - offset;

	/* Read BPDT and sub-partitions. */
	uintptr_t end_offset;
	end_offset = ifwi_image.input_ifwi_start_offset +
		alloc_bpdt_buffer(data, ifwi_size, 0, &ifwi_image.bpdt, "BPDT");

	/* Parse S-BPDT, if any. */
	parse_sbpdt(data, ifwi_size);

	/*
	 * Store end offset of IFWI. Required for copying any trailing non-IFWI
	 * part of the image.
	 * ASSUMPTION: IFWI image always ends on a 4K boundary.
	 */
	ifwi_image.input_ifwi_end_offset = ALIGN_UP(end_offset, 4 * KiB);
	DEBUG("Parsing done.\n");

	return 0;
}

/*
 * This function is used by repack to count the number of BPDT and S-BPDT
 * entries that are present. It frees the current buffers used by the entries
 * and allocates fresh buffers that can be used for repacking. Returns BPDT
 * entries which are empty and need to be filled in.
 */
static void __bpdt_reset(struct buffer *b, size_t count, size_t size)
{
	size_t bpdt_size = BPDT_HEADER_SIZE + count * BPDT_ENTRY_SIZE;
	assert(size >= bpdt_size);

	/*
	 * If buffer does not have the required size, allocate a fresh buffer.
	 */
	if (buffer_size(b) != size) {
		struct buffer temp;
		alloc_buffer(&temp, size, b->name);
		memcpy(buffer_get(&temp), buffer_get(b), buffer_size(b));
		buffer_delete(b);
		*b = temp;
	}

	struct bpdt *bpdt = buffer_get(b);
	uint8_t *ptr = (uint8_t *)&bpdt->e[0];
	size_t entries_size = BPDT_ENTRY_SIZE * count;

	/* Zero out BPDT entries. */
	memset(ptr, 0, entries_size);
	/* Fill any pad-space with FF. */
	memset(ptr + entries_size, 0xFF, size - bpdt_size);

	bpdt->h.descriptor_count = count;
}

static void bpdt_reset(void)
{
	size_t i;
	size_t bpdt_count = 0, sbpdt_count = 0, dummy_bpdt_count = 0;

	/* Count number of BPDT and S-BPDT entries. */
	for (i = 0; i < MAX_SUBPARTS; i++) {
		if (buffer_size(&ifwi_image.subpart_buf[i]) == 0) {
			if (subparts[i].attr & MANDATORY_BPDT_ENTRY) {
				bpdt_count++;
				dummy_bpdt_count++;
			}
			continue;
		}

		if (subparts[i].attr & NON_CRITICAL_SUBPART)
			sbpdt_count++;
		else
			bpdt_count++;
	}

	DEBUG("Count: BPDT = %zd, Dummy BPDT = %zd, S-BPDT = %zd\n", bpdt_count,
	      dummy_bpdt_count, sbpdt_count);

	/* Update BPDT if required. */
	size_t bpdt_size = MAX(BPDT_MIN_SIZE,
			       BPDT_HEADER_SIZE + bpdt_count * BPDT_ENTRY_SIZE);
	__bpdt_reset(&ifwi_image.bpdt, bpdt_count, bpdt_size);

	/* Update S-BPDT if required. */
	bpdt_size = ALIGN_UP(BPDT_HEADER_SIZE + sbpdt_count * BPDT_ENTRY_SIZE,
			  4 * KiB);
	__bpdt_reset(&ifwi_image.subpart_buf[S_BPDT_TYPE], sbpdt_count,
		     bpdt_size);
}

/* Initialize BPDT entries in header order. */
static void bpdt_entries_init_header_order(void)
{
	int i, type;
	size_t size;

	struct bpdt *bpdt, *sbpdt, *curr;
	size_t bpdt_curr = 0, sbpdt_curr = 0, *count_ptr;

	bpdt = buffer_get(&ifwi_image.bpdt);
	sbpdt = buffer_get(&ifwi_image.subpart_buf[S_BPDT_TYPE]);

	for (i = 0; i < MAX_SUBPARTS; i++) {
		type = bpdt_header_order[i];
		size = buffer_size(&ifwi_image.subpart_buf[type]);

		if ((size == 0) && !(subparts[type].attr &
				     MANDATORY_BPDT_ENTRY))
			continue;

		if (subparts[type].attr & NON_CRITICAL_SUBPART) {
			curr = sbpdt;
			count_ptr = &sbpdt_curr;
		} else {
			curr = bpdt;
			count_ptr = &bpdt_curr;
		}

		assert(*count_ptr < curr->h.descriptor_count);
		curr->e[*count_ptr].type = type;
		curr->e[*count_ptr].flags = 0;
		curr->e[*count_ptr].offset = 0;
		curr->e[*count_ptr].size = size;

		(*count_ptr)++;
	}
}

static void pad_buffer(struct buffer *b, size_t size)
{
	size_t buff_size = buffer_size(b);

	assert(buff_size <= size);

	if (buff_size == size)
		return;

	struct buffer temp;
	alloc_buffer(&temp, size, b->name);
	uint8_t *data = buffer_get(&temp);

	memcpy(data, buffer_get(b), buff_size);
	memset(data + buff_size, 0xFF, size - buff_size);

	*b = temp;
}

/* Initialize offsets of entries using pack order. */
static void bpdt_entries_init_pack_order(void)
{
	int i, type;
	struct bpdt_entry *curr;
	size_t curr_offset, curr_end;

	curr_offset = MAX(BPDT_MIN_SIZE, buffer_size(&ifwi_image.bpdt));

	/*
	 * There are two types of sub-partitions that need to be handled here:
	 *   1. Sub-partitions that lie within the same 4K as BPDT
	 *   2. Sub-partitions that lie outside the 4K of BPDT
	 *
	 * For sub-partitions of type # 1, there is no requirement on the start
	 * or end of the sub-partition. They need to be packed in without any
	 * holes left in between. If there is any empty space left after the end
	 * of the last sub-partition in 4K of BPDT, then that space needs to be
	 * padded with FF bytes, but the size of the last sub-partition remains
	 * unchanged.
	 *
	 * For sub-partitions of type # 2, both the start and end should be a
	 * multiple of 4K. If not, then it needs to be padded with FF bytes and
	 * size adjusted such that the sub-partition ends on 4K boundary.
	 */

	/* #1 Sub-partitions that lie within same 4K as BPDT. */
	struct buffer *last_bpdt_buff = &ifwi_image.bpdt;

	for (i = 0; i < MAX_SUBPARTS; i++) {
		type = bpdt_pack_order[i];
		curr = find_entry_by_type(type);

		if ((curr == NULL) || (curr->size == 0))
			continue;

		if (!(subparts[type].attr & LIES_WITHIN_BPDT_4K))
			continue;

		curr->offset = curr_offset;
		curr_offset = curr->offset + curr->size;
		last_bpdt_buff = &ifwi_image.subpart_buf[type];
		DEBUG("type=%d, curr_offset=0x%zx, curr->offset=0x%x, "
		      "curr->size=0x%x, buff_size=0x%zx\n", type, curr_offset,
		      curr->offset, curr->size,
		      buffer_size(&ifwi_image.subpart_buf[type]));
	}

	/* Pad ff bytes if there is any empty space left in BPDT 4K. */
	curr_end = ALIGN_UP(curr_offset, 4 * KiB);
	pad_buffer(last_bpdt_buff,
		   buffer_size(last_bpdt_buff) + (curr_end - curr_offset));
	curr_offset = curr_end;

	/* #2 Sub-partitions that lie outside of BPDT 4K. */
	for (i = 0; i < MAX_SUBPARTS; i++) {
		type = bpdt_pack_order[i];
		curr = find_entry_by_type(type);

		if ((curr == NULL) || (curr->size == 0))
			continue;

		if (subparts[type].attr & LIES_WITHIN_BPDT_4K)
			continue;

		assert(curr_offset == ALIGN_UP(curr_offset, 4 * KiB));
		curr->offset = curr_offset;
		curr_end = ALIGN_UP(curr->offset + curr->size, 4 * KiB);
		curr->size = curr_end - curr->offset;

		pad_buffer(&ifwi_image.subpart_buf[type], curr->size);

		curr_offset = curr_end;
		DEBUG("type=%d, curr_offset=0x%zx, curr->offset=0x%x, "
		      "curr->size=0x%x, buff_size=0x%zx\n", type, curr_offset,
		      curr->offset, curr->size,
		      buffer_size(&ifwi_image.subpart_buf[type]));
	}

	/*
	 * Update size of S-BPDT to include size of all non-critical
	 * sub-partitions.
	 *
	 * Assumption: S-BPDT always lies at the end of IFWI image.
	 */
	curr = find_entry_by_type(S_BPDT_TYPE);
	assert(curr);

	assert(curr_offset == ALIGN_UP(curr_offset, 4 * KiB));
	curr->size = curr_offset - curr->offset;
}

/* Convert all members of BPDT to little-endian format. */
static void bpdt_fixup_write_buffer(struct buffer *buf)
{
	struct bpdt *s = buffer_get(buf);

	struct bpdt_header *h = &s->h;
	struct bpdt_entry *e = &s->e[0];

	size_t count = h->descriptor_count;

	size_t offset = 0;

	offset = fix_member(&h->signature, offset, sizeof(h->signature));
	offset = fix_member(&h->descriptor_count, offset,
			    sizeof(h->descriptor_count));
	offset = fix_member(&h->bpdt_version, offset, sizeof(h->bpdt_version));
	offset = fix_member(&h->xor_redundant_block, offset,
			    sizeof(h->xor_redundant_block));
	offset = fix_member(&h->ifwi_version, offset, sizeof(h->ifwi_version));
	offset = fix_member(&h->fit_tool_version, offset,
			    sizeof(h->fit_tool_version));

	uint32_t i;
	for (i = 0; i < count; i++) {
		offset = fix_member(&e[i].type, offset, sizeof(e[i].type));
		offset = fix_member(&e[i].flags, offset, sizeof(e[i].flags));
		offset = fix_member(&e[i].offset, offset, sizeof(e[i].offset));
		offset = fix_member(&e[i].size, offset, sizeof(e[i].size));
	}
}

/* Write BPDT to output buffer after fixup. */
static void bpdt_write(struct buffer *dst, size_t offset, struct buffer *src)
{
	bpdt_fixup_write_buffer(src);
	memcpy(buffer_get(dst) + offset, buffer_get(src), buffer_size(src));
}

/*
 * Follows these steps to re-create image:
 * 1. Write any non-IFWI prefix.
 * 2. Write out BPDT header and entries.
 * 3. Write sub-partition buffers to respective offsets.
 * 4. Write any non-IFWI suffix.
 *
 * While performing the above steps, make sure that any empty holes are filled
 * with FF.
 */
static void ifwi_write(const char *image_name)
{
	struct bpdt_entry *s = find_entry_by_type(S_BPDT_TYPE);
	assert(s);

	size_t ifwi_start, ifwi_end, file_end;

	ifwi_start = ifwi_image.input_ifwi_start_offset;
	ifwi_end = ifwi_start + ALIGN_UP(s->offset + s->size, 4 * KiB);
	file_end = ifwi_end + (buffer_size(&ifwi_image.input_buff) -
			       ifwi_image.input_ifwi_end_offset);

	struct buffer b;

	alloc_buffer(&b, file_end, "Final-IFWI");

	uint8_t *input_data = buffer_get(&ifwi_image.input_buff);
	uint8_t *output_data = buffer_get(&b);

	DEBUG("ifwi_start:0x%zx, ifwi_end:0x%zx, file_end:0x%zx\n", ifwi_start,
	      ifwi_end, file_end);

	/* Copy non-IFWI prefix, if any. */
	memcpy(output_data, input_data, ifwi_start);

	DEBUG("Copied non-IFWI prefix (offset=0x0, size=0x%zx).\n", ifwi_start);

	struct buffer ifwi;
	buffer_splice(&ifwi, &b, ifwi_start, ifwi_end - ifwi_start);
	uint8_t *ifwi_data = buffer_get(&ifwi);

	/* Copy sub-partitions using pack_order. */
	struct bpdt_entry *curr;
	struct buffer *subpart_buf;
	int i, type;
	for (i = 0; i < MAX_SUBPARTS; i++) {
		type = bpdt_pack_order[i];

		if (type == S_BPDT_TYPE)
			continue;

		curr = find_entry_by_type(type);

		if ((curr == NULL) || (curr->size == 0))
			continue;

		subpart_buf = &ifwi_image.subpart_buf[type];

		DEBUG("curr->offset=0x%x, curr->size=0x%x, type=%d, "
		      "write_size=0x%zx\n", curr->offset, curr->size, type,
		      buffer_size(subpart_buf));

		assert((curr->offset + buffer_size(subpart_buf)) <=
		       buffer_size(&ifwi));

		memcpy(ifwi_data + curr->offset, buffer_get(subpart_buf),
		       buffer_size(subpart_buf));
	}

	/* Copy non-IFWI suffix, if any. */
	if (ifwi_end != file_end) {
		memcpy(output_data + ifwi_end,
		       input_data + ifwi_image.input_ifwi_end_offset,
		       file_end - ifwi_end);
		DEBUG("Copied non-IFWI suffix (offset=0x%zx,size=0x%zx).\n",
		      ifwi_end, file_end - ifwi_end);
	}

	/*
	 * Convert BPDT to little-endian format and write it to output buffer.
	 * S-BPDT is written first and then BPDT.
	 */
	bpdt_write(&ifwi, s->offset, &ifwi_image.subpart_buf[S_BPDT_TYPE]);
	bpdt_write(&ifwi, 0, &ifwi_image.bpdt);

	if (buffer_write_file(&b, image_name)) {
		ERROR("File write error\n");
		exit(-1);
	}

	buffer_delete(&b);
	printf("Image written successfully to %s.\n", image_name);
}

/*
 * Calculate size and offset of each sub-partition again since it might have
 * changed because of add/delete operation. Also, re-create BPDT and S-BPDT
 * entries and write back the new IFWI image to file.
 */
static void ifwi_repack(void)
{
	bpdt_reset();
	bpdt_entries_init_header_order();
	bpdt_entries_init_pack_order();

	struct bpdt *b = buffer_get(&ifwi_image.bpdt);
	bpdt_print_entries(&b->e[0], b->h.descriptor_count, "BPDT");

	b = buffer_get(&ifwi_image.subpart_buf[S_BPDT_TYPE]);
	bpdt_print_entries(&b->e[0], b->h.descriptor_count, "S-BPDT");

	DEBUG("Repack done.. writing image.\n");
	ifwi_write(param.image_name);
}

static void init_subpart_dir_header(struct subpart_dir_header *hdr,
				    size_t count, const char *name)
{
	memset(hdr, 0, sizeof(*hdr));

	hdr->marker = SUBPART_DIR_MARKER;
	hdr->num_entries = count;
	hdr->header_version = SUBPART_DIR_HEADER_VERSION_SUPPORTED;
	hdr->entry_version = SUBPART_DIR_ENTRY_VERSION_SUPPORTED;
	hdr->header_length = SUBPART_DIR_HEADER_SIZE;
	memcpy(hdr->name, name, sizeof(hdr->name));
}

static size_t init_subpart_dir_entry(struct subpart_dir_entry *e,
				     struct buffer *b, size_t offset)
{
	memset(e, 0, sizeof(*e));

	assert(strlen(b->name) <= sizeof(e->name));
	strncpy((char *)e->name, (char *)b->name, sizeof(e->name));
	e->offset = offset;
	e->length = buffer_size(b);

	return (offset + buffer_size(b));
}

static void init_manifest_header(struct manifest_header *hdr, size_t size)
{
	memset(hdr, 0, sizeof(*hdr));

	hdr->header_type = 0x4;
	assert((MANIFEST_HDR_SIZE % DWORD_SIZE) == 0);
	hdr->header_length = MANIFEST_HDR_SIZE / DWORD_SIZE;
	hdr->header_version = 0x10000;
	hdr->vendor = 0x8086;

	struct tm *local_time;
	time_t curr_time;
	char buffer[11];

	curr_time = time(NULL);
	local_time = localtime(&curr_time);
	strftime(buffer, sizeof(buffer), "0x%Y%m%d", local_time);
	hdr->date = strtoul(buffer, NULL, 16);

	assert((size % DWORD_SIZE) == 0);
	hdr->size = size / DWORD_SIZE;
	hdr->id = MANIFEST_ID_MAGIC;
}

static void init_signed_pkg_info_ext(struct signed_pkg_info_ext *ext,
				     size_t count, const char *name)
{
	memset(ext, 0, sizeof(*ext));

	ext->ext_type = SIGNED_PKG_INFO_EXT_TYPE;
	ext->ext_length = SIGNED_PKG_INFO_EXT_SIZE + count * MODULE_SIZE;
	memcpy(ext->name, name, sizeof(ext->name));
}

static void subpart_dir_fixup_write_buffer(struct buffer *buf)
{
	struct subpart_dir *s = buffer_get(buf);
	struct subpart_dir_header *h = &s->h;
	struct subpart_dir_entry *e = &s->e[0];

	size_t count = h->num_entries;
	size_t offset = 0;

	offset = fix_member(&h->marker, offset, sizeof(h->marker));
	offset = fix_member(&h->num_entries, offset, sizeof(h->num_entries));
	offset = fix_member(&h->header_version, offset,
			    sizeof(h->header_version));
	offset = fix_member(&h->entry_version, offset,
			    sizeof(h->entry_version));
	offset = fix_member(&h->header_length, offset,
			    sizeof(h->header_length));
	offset = fix_member(&h->checksum, offset, sizeof(h->checksum));
	offset += sizeof(h->name);

	uint32_t i;
	for (i = 0; i < count; i++) {
		offset += sizeof(e[i].name);
		offset = fix_member(&e[i].offset, offset, sizeof(e[i].offset));
		offset = fix_member(&e[i].length, offset, sizeof(e[i].length));
		offset = fix_member(&e[i].rsvd, offset, sizeof(e[i].rsvd));
	}
}

static void create_subpart(struct buffer *dst, struct buffer *info[],
			   size_t count, const char *name)
{
	struct buffer subpart_dir_buff;
	size_t size = SUBPART_DIR_HEADER_SIZE + count * SUBPART_DIR_ENTRY_SIZE;

	alloc_buffer(&subpart_dir_buff, size, "subpart-dir");

	struct subpart_dir_header *h = buffer_get(&subpart_dir_buff);
	struct subpart_dir_entry *e = (struct subpart_dir_entry *)(h + 1);

	init_subpart_dir_header(h, count, name);

	size_t curr_offset = size;
	size_t i;

	for (i = 0; i < count; i++) {
		curr_offset = init_subpart_dir_entry(&e[i], info[i],
						     curr_offset);
	}

	alloc_buffer(dst, curr_offset, name);
	uint8_t *data = buffer_get(dst);

	for (i = 0; i < count; i++) {
		memcpy(data + e[i].offset, buffer_get(info[i]),
		       buffer_size(info[i]));
	}

	h->checksum = calc_checksum(buffer_get(&subpart_dir_buff));

	struct subpart_dir *dir = buffer_get(&subpart_dir_buff);

	print_subpart_dir(dir);

	subpart_dir_fixup_write_buffer(&subpart_dir_buff);
	memcpy(data, dir, buffer_size(&subpart_dir_buff));

	buffer_delete(&subpart_dir_buff);
}

static enum ifwi_ret ibbp_dir_add(int type)
{
#define DUMMY_IBB_SIZE			(4 * KiB)

	assert(type == IBB_TYPE);

	/*
	 * Entry # 1 - IBBP.man
	 * Contains manifest header and signed pkg info extension.
	 */
	struct buffer manifest;
	size_t size = MANIFEST_HDR_SIZE + SIGNED_PKG_INFO_EXT_SIZE;
	alloc_buffer(&manifest, size, "IBBP.man");

	struct manifest_header *man_hdr = buffer_get(&manifest);
	init_manifest_header(man_hdr, size);

	struct signed_pkg_info_ext *ext;
	ext = (struct signed_pkg_info_ext *)(man_hdr + 1);

	init_signed_pkg_info_ext(ext, 0, subparts[type].name);

	/* Entry # 2 - IBBL */
	struct buffer ibbl;
	if (buffer_from_file(&ibbl, param.file_name))
		return COMMAND_ERR;

	/* Entry # 3 - IBB */
	struct buffer ibb;
	alloc_buffer(&ibb, DUMMY_IBB_SIZE, "IBB");
	memset(buffer_get(&ibb), 0xFF, DUMMY_IBB_SIZE);

	/* Create subpartition. */
	struct buffer *info[] = {
		&manifest, &ibbl, &ibb,
	};
	create_subpart(&ifwi_image.subpart_buf[type], &info[0],
		       ARRAY_SIZE(info), subparts[type].name);

	return REPACK_REQUIRED;
}

static enum ifwi_ret ifwi_raw_add(int type)
{
	if (buffer_from_file(&ifwi_image.subpart_buf[type], param.file_name))
		return COMMAND_ERR;

	printf("Sub-partition %s(%d) added from file %s.\n", param.subpart_name,
	       type, param.file_name);
	return REPACK_REQUIRED;
}

static enum ifwi_ret ifwi_dir_add(int type)
{
	if (!(subparts[type].attr & CONTAINS_DIR) ||
	    (subparts[type].dir_ops.dir_add == NULL)) {
		ERROR("Sub-Partition %s(%d) does not support dir ops.\n",
		      subparts[type].name, type);
		return COMMAND_ERR;
	}

	if (!param.dentry_name) {
		ERROR("%s: -e option required\n", __func__);
		return COMMAND_ERR;
	}

	enum ifwi_ret ret = subparts[type].dir_ops.dir_add(type);
	if (ret != COMMAND_ERR)
		printf("Sub-partition %s(%d) entry %s added from file %s.\n",
		       param.subpart_name, type, param.dentry_name,
		       param.file_name);
	else
		ERROR("Sub-partition dir operation failed.\n");

	return ret;
}

static enum ifwi_ret ifwi_add(void)
{
	if (!param.file_name) {
		ERROR("%s: -f option required\n", __func__);
		return COMMAND_ERR;
	}

	if (!param.subpart_name) {
		ERROR("%s: -n option required\n", __func__);
		return COMMAND_ERR;
	}

	int type = find_type_by_name(param.subpart_name);
	if (type == -1)
		return COMMAND_ERR;

	const struct subpart_info *curr_subpart = &subparts[type];

	if (curr_subpart->attr & AUTO_GENERATED) {
		ERROR("Cannot add auto-generated sub-partitions.\n");
		return COMMAND_ERR;
	}

	if (buffer_size(&ifwi_image.subpart_buf[type])) {
		ERROR("Image already contains sub-partition %s(%d).\n",
		      param.subpart_name, type);
		return COMMAND_ERR;
	}

	if (param.dir_ops)
		return ifwi_dir_add(type);

	return ifwi_raw_add(type);
}

static enum ifwi_ret ifwi_delete(void)
{
	if (!param.subpart_name) {
		ERROR("%s: -n option required\n", __func__);
		return COMMAND_ERR;
	}

	int type = find_type_by_name(param.subpart_name);
	if (type == -1)
		return COMMAND_ERR;

	const struct subpart_info *curr_subpart = &subparts[type];

	if (curr_subpart->attr & AUTO_GENERATED) {
		ERROR("Cannot delete auto-generated sub-partitions.\n");
		return COMMAND_ERR;
	}

	if (buffer_size(&ifwi_image.subpart_buf[type]) == 0) {
		printf("Image does not contain sub-partition %s(%d).\n",
		       param.subpart_name, type);
		return NO_ACTION_REQUIRED;
	}

	buffer_delete(&ifwi_image.subpart_buf[type]);
	printf("Sub-Partition %s(%d) deleted.\n", subparts[type].name, type);
	return REPACK_REQUIRED;
}

static enum ifwi_ret ifwi_dir_extract(int type)
{
	if (!(subparts[type].attr & CONTAINS_DIR)) {
		ERROR("Sub-Partition %s(%d) does not support dir ops.\n",
		      subparts[type].name, type);
		return COMMAND_ERR;
	}

	if (!param.dentry_name) {
		ERROR("%s: -e option required.\n", __func__);
		return COMMAND_ERR;
	}

	struct buffer subpart_dir_buff;
	parse_subpart_dir(&subpart_dir_buff, &ifwi_image.subpart_buf[type],
			  subparts[type].name);

	uint32_t i;
	struct subpart_dir *s = buffer_get(&subpart_dir_buff);

	for (i = 0; i < s->h.num_entries; i++) {
		if (!strncmp((char *)s->e[i].name, param.dentry_name,
			     sizeof(s->e[i].name)))
			break;
	}

	if (i == s->h.num_entries) {
		ERROR("Entry %s not found in subpartition for %s.\n",
		      param.dentry_name, param.subpart_name);
		exit(-1);
	}

	struct buffer dst;

	DEBUG("Splicing buffer at 0x%x size 0x%x\n", s->e[i].offset,
	      s->e[i].length);
	buffer_splice(&dst, &ifwi_image.subpart_buf[type], s->e[i].offset,
		      s->e[i].length);

	if (buffer_write_file(&dst, param.file_name))
		return COMMAND_ERR;

	printf("Sub-Partition %s(%d), entry(%s) stored in %s.\n",
	       param.subpart_name, type, param.dentry_name, param.file_name);

	return NO_ACTION_REQUIRED;
}

static enum ifwi_ret ifwi_raw_extract(int type)
{
	if (buffer_write_file(&ifwi_image.subpart_buf[type], param.file_name))
		return COMMAND_ERR;

	printf("Sub-Partition %s(%d) stored in %s.\n", param.subpart_name, type,
	       param.file_name);

	return NO_ACTION_REQUIRED;
}

static enum ifwi_ret ifwi_extract(void)
{
	if (!param.file_name) {
		ERROR("%s: -f option required\n", __func__);
		return COMMAND_ERR;
	}

	if (!param.subpart_name) {
		ERROR("%s: -n option required\n", __func__);
		return COMMAND_ERR;
	}

	int type = find_type_by_name(param.subpart_name);
	if (type == -1)
		return COMMAND_ERR;

	if (type == S_BPDT_TYPE) {
		INFO("Tool does not support raw extract for %s\n",
		     param.subpart_name);
		return NO_ACTION_REQUIRED;
	}

	if (buffer_size(&ifwi_image.subpart_buf[type]) == 0) {
		ERROR("Image does not contain sub-partition %s(%d).\n",
		      param.subpart_name, type);
		return COMMAND_ERR;
	}

	INFO("Extracting sub-partition %s(%d).\n", param.subpart_name, type);
	if (param.dir_ops)
		return ifwi_dir_extract(type);

	return ifwi_raw_extract(type);
}

static enum ifwi_ret ifwi_print(void)
{
	verbose += 2;

	struct bpdt *b = buffer_get(&ifwi_image.bpdt);

	bpdt_print_header(&b->h, "BPDT");
	bpdt_print_entries(&b->e[0], b->h.descriptor_count, "BPDT");

	b = buffer_get(&ifwi_image.subpart_buf[S_BPDT_TYPE]);
	bpdt_print_header(&b->h, "S-BPDT");
	bpdt_print_entries(&b->e[0], b->h.descriptor_count, "S-BPDT");

	if (param.dir_ops == 0) {
		verbose -= 2;
		return NO_ACTION_REQUIRED;
	}

	int i;
	struct buffer subpart_dir_buf;
	for (i = 0; i < MAX_SUBPARTS ; i++) {
		if (!(subparts[i].attr & CONTAINS_DIR) ||
		    (buffer_size(&ifwi_image.subpart_buf[i]) == 0))
			continue;

		parse_subpart_dir(&subpart_dir_buf, &ifwi_image.subpart_buf[i],
				  subparts[i].name);
		buffer_delete(&subpart_dir_buf);
	}

	verbose -= 2;

	return NO_ACTION_REQUIRED;
}

static enum ifwi_ret ifwi_raw_replace(int type)
{
	buffer_delete(&ifwi_image.subpart_buf[type]);
	return ifwi_raw_add(type);
}

static enum ifwi_ret ifwi_dir_replace(int type)
{
	if (!(subparts[type].attr & CONTAINS_DIR)) {
		ERROR("Sub-Partition %s(%d) does not support dir ops.\n",
		      subparts[type].name, type);
		return COMMAND_ERR;
	}

	if (!param.dentry_name) {
		ERROR("%s: -e option required.\n", __func__);
		return COMMAND_ERR;
	}

	struct buffer subpart_dir_buf;
	parse_subpart_dir(&subpart_dir_buf, &ifwi_image.subpart_buf[type],
			  subparts[type].name);

	uint32_t i;
	struct subpart_dir *s = buffer_get(&subpart_dir_buf);

	for (i = 0; i < s->h.num_entries; i++) {
		if (!strcmp((char *)s->e[i].name, param.dentry_name))
			break;
	}

	if (i == s->h.num_entries) {
		ERROR("Entry %s not found in subpartition for %s.\n",
		      param.dentry_name, param.subpart_name);
		exit(-1);
	}

	struct buffer b;
	if (buffer_from_file(&b, param.file_name)) {
		ERROR("Failed to read %s\n", param.file_name);
		exit(-1);
	}

	struct buffer dst;
	size_t dst_size = buffer_size(&ifwi_image.subpart_buf[type]) +
				      buffer_size(&b) - s->e[i].length;
	size_t subpart_start = s->e[i].offset;
	size_t subpart_end = s->e[i].offset + s->e[i].length;

	alloc_buffer(&dst, dst_size, ifwi_image.subpart_buf[type].name);

	uint8_t *src_data = buffer_get(&ifwi_image.subpart_buf[type]);
	uint8_t *dst_data = buffer_get(&dst);
	size_t curr_offset = 0;

	/* Copy data before the sub-partition entry. */
	memcpy(dst_data + curr_offset, src_data, subpart_start);
	curr_offset += subpart_start;

	/* Copy sub-partition entry. */
	memcpy(dst_data + curr_offset, buffer_get(&b), buffer_size(&b));
	curr_offset += buffer_size(&b);

	/* Copy remaining data. */
	memcpy(dst_data + curr_offset, src_data + subpart_end,
	       buffer_size(&ifwi_image.subpart_buf[type]) - subpart_end);

	/* Update sub-partition buffer. */
	int offset = s->e[i].offset;
	buffer_delete(&ifwi_image.subpart_buf[type]);
	ifwi_image.subpart_buf[type] = dst;

	/* Update length of entry in the subpartition. */
	s->e[i].length = buffer_size(&b);
	buffer_delete(&b);

	/* Adjust offsets of affected entries in subpartition. */
	offset = s->e[i].offset - offset;
	for (; i < s->h.num_entries; i++) {
		s->e[i].offset += offset;
	}

	/* Re-calculate checksum. */
	s->h.checksum = calc_checksum(s);

	/* Convert members to litte-endian. */
	subpart_dir_fixup_write_buffer(&subpart_dir_buf);

	memcpy(dst_data, buffer_get(&subpart_dir_buf),
	       buffer_size(&subpart_dir_buf));

	buffer_delete(&subpart_dir_buf);

	printf("Sub-partition %s(%d) entry %s replaced from file %s.\n",
	       param.subpart_name, type, param.dentry_name, param.file_name);

	return REPACK_REQUIRED;
}

static enum ifwi_ret ifwi_replace(void)
{
	if (!param.file_name) {
		ERROR("%s: -f option required\n", __func__);
		return COMMAND_ERR;
	}

	if (!param.subpart_name) {
		ERROR("%s: -n option required\n", __func__);
		return COMMAND_ERR;
	}

	int type = find_type_by_name(param.subpart_name);
	if (type == -1)
		return COMMAND_ERR;

	const struct subpart_info *curr_subpart = &subparts[type];

	if (curr_subpart->attr & AUTO_GENERATED) {
		ERROR("Cannot replace auto-generated sub-partitions.\n");
		return COMMAND_ERR;
	}

	if (buffer_size(&ifwi_image.subpart_buf[type]) == 0) {
		ERROR("Image does not contain sub-partition %s(%d).\n",
		      param.subpart_name, type);
		return COMMAND_ERR;
	}

	if (param.dir_ops)
		return ifwi_dir_replace(type);

	return ifwi_raw_replace(type);
}

static enum ifwi_ret ifwi_create(void)
{
	/*
	 * Create peels off any non-IFWI content present in the input buffer and
	 * creates output file with only the IFWI present.
	 */

	if (!param.file_name) {
		ERROR("%s: -f option required\n", __func__);
		return COMMAND_ERR;
	}

	/* Peel off any non-IFWI prefix. */
	buffer_seek(&ifwi_image.input_buff,
		    ifwi_image.input_ifwi_start_offset);
	/* Peel off any non-IFWI suffix. */
	buffer_set_size(&ifwi_image.input_buff,
			ifwi_image.input_ifwi_end_offset -
			ifwi_image.input_ifwi_start_offset);

	/*
	 * Adjust start and end offset of IFWI now that non-IFWI prefix is gone.
	 */
	ifwi_image.input_ifwi_end_offset -= ifwi_image.input_ifwi_start_offset;
	ifwi_image.input_ifwi_start_offset = 0;

	param.image_name = param.file_name;

	return REPACK_REQUIRED;
}

struct command {
	const char *name;
	const char *optstring;
	enum ifwi_ret (*function)(void);
};

static const struct command commands[] = {
	{"add", "f:n:e:dsvh?", ifwi_add},
	{"create", "f:svh?", ifwi_create},
	{"delete", "f:n:svh?", ifwi_delete},
	{"extract", "f:n:e:dsvh?", ifwi_extract},
	{"print", "dsh?", ifwi_print},
	{"replace", "f:n:e:dsvh?", ifwi_replace},
};

static struct option long_options[] = {
	{"subpart_dentry",  required_argument, 0, 'e'},
	{"file",	    required_argument, 0, 'f'},
	{"help",	    required_argument, 0, 'h'},
	{"name",	    required_argument, 0, 'n'},
	{"dir_ops",         no_argument,       0, 'd'},
	{"verbose",	    no_argument,       0, 'v'},
	{"second_lbp",	    no_argument,       0, 's'},
	{NULL,		    0,                 0,  0 }
};

static void usage(const char *name)
{
	printf("ifwitool: Utility for IFWI manipulation\n\n"
	       "USAGE:\n"
	       " %s [-h]\n"
	       " %s FILE COMMAND [PARAMETERS]\n\n"
	       "COMMANDs:\n"
	       " add -f FILE -n NAME [-d -e ENTRY] [-s]\n"
	       " create -f FILE [-s]\n"
	       " delete -n NAME [-s]\n"
	       " extract -f FILE -n NAME [-d -e ENTRY] [-s]\n"
	       " print [-d] [-s]\n"
	       " replace -f FILE -n NAME [-d -e ENTRY] [-s]\n"
	       "OPTIONs:\n"
	       " -f FILE : File to read/write/create/extract\n"
	       " -s      : Use the second Logical Boot Partition\n"
	       " -d      : Perform directory operation\n"
	       " -e ENTRY: Name of directory entry to operate on\n"
	       " -v      : Verbose level\n"
	       " -h      : Help message\n"
	       " -n NAME : Name of sub-partition to operate on\n",
	       name, name
	       );

	printf("\nNAME should be one of:\n");
	int i;
	for (i = 0; i < MAX_SUBPARTS; i++)
		printf("%s(%s)\n", subparts[i].name, subparts[i].readable_name);
	printf("\n");
}

int main(int argc, char **argv)
{
	if (argc < 3) {
		usage(argv[0]);
		return 1;
	}

	param.image_name = argv[1];
	param.logical_boot_partition = LBP1;
	char *cmd = argv[2];
	optind += 2;

	uint32_t i;

	for (i = 0; i < ARRAY_SIZE(commands); i++) {
		if (strcmp(cmd, commands[i].name) != 0)
			continue;

		int c;

		while (1) {
			int option_index;

			c = getopt_long(argc, argv, commands[i].optstring,
					long_options, &option_index);

			if (c == -1)
				break;

			/* Filter out illegal long options. */
			if (strchr(commands[i].optstring, c) == NULL) {
				ERROR("%s: invalid option -- '%c'\n", argv[0],
				      c);
				c = '?';
			}

			switch (c) {
			case 'n':
				param.subpart_name = optarg;
				break;
			case 's':
				param.logical_boot_partition = LBP2;
				break;
			case 'f':
				param.file_name = optarg;
				break;
			case 'd':
				param.dir_ops = 1;
				break;
			case 'e':
				param.dentry_name = optarg;
				break;
			case 'v':
				verbose++;
				break;
			case 'h':
			case '?':
				usage(argv[0]);
				return 1;
			default:
				break;
			}
		}

		if (ifwi_parse()) {
			ERROR("%s: ifwi parsing failed\n", argv[0]);
			return 1;
		}

		enum ifwi_ret ret = commands[i].function();

		if (ret == COMMAND_ERR) {
			ERROR("%s: failed execution\n", argv[0]);
			return 1;
		}

		if (ret == REPACK_REQUIRED)
			ifwi_repack();

		return 0;
	}

	ERROR("%s: invalid command\n", argv[0]);
	return 1;
}
