/* Copyright 2017 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <config.h>

#include <alloca.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
#include <openssl/opensslv.h>
#include <openssl/ossl_typ.h>
#include <openssl/sha.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sysexits.h>
#include <unistd.h>

#include "ccan/endian/endian.h"
#include "ccan/short_types/short_types.h"
#include "container-utils.h"
#include "container.h"

#define PASSED 1
#define FAILED 0
#define UNATTEMPTED -1

char *progname;

bool print_stats;
bool verbose, debug;
int wrap = 100;

ecc_key_t ECDSA_KEY_NULL;

typedef struct keyprops {
	char index;
	const char *name;
	const ecc_key_t *key;
	const ecc_signature_t *sig;
} Keyprops;

static void usage(int status);

static bool getPayloadHash(int fdin, unsigned char *md);
static bool getVerificationHash(char *input, unsigned char *md, int len);
static bool verify_signature(const char *moniker, const unsigned char *dgst,
		int dgst_len, const ecc_signature_t sig_raw, const ecc_key_t key_raw);

static void print_bytes(char *lead, uint8_t *buffer, size_t buflen)
{
	unsigned int i;
	unsigned int width;
	unsigned int leadbytes = strlen(lead);
	leadbytes = leadbytes > 30 ? 30 : leadbytes;
	width = (wrap - leadbytes) / 2;
	width = (width < 1) ? INT_MAX : width;

	fprintf(stdout, "%s", lead);
	for (i = 1; i < buflen + 1; i++) {
		fprintf(stdout, "%02x", buffer[i - 1]);
		if (((i % width) == 0) && (i < buflen))
			fprintf(stdout, "\n%*c", leadbytes, ' ');
	}
	fprintf(stdout, "\n");
}

bool stb_is_container(const void *buf, size_t size)
{
	ROM_container_raw *c;

	c = (ROM_container_raw*) buf;
	if (!buf || size < SECURE_BOOT_HEADERS_SIZE)
		return false;
	if (be32_to_cpu(c->magic_number) != ROM_MAGIC_NUMBER)
		return false;
	return true;
}

int parse_stb_container(const void* data, size_t len,
		struct parsed_stb_container *c)
{
	const size_t prefix_data_min_size = 3 * (EC_COORDBYTES * 2);
	c->buf = data;
	c->bufsz = len;
	c->c = data;
	c->ph = data += sizeof(ROM_container_raw);
	c->pd = data += sizeof(ROM_prefix_header_raw)
			+ (c->ph->ecid_count * ECID_SIZE);
	c->sh = data += prefix_data_min_size
			+ c->ph->sw_key_count * (EC_COORDBYTES * 2);
	c->ssig = data += sizeof(ROM_sw_header_raw) + c->sh->ecid_count * ECID_SIZE;

	return 0;
}

static void display_version_raw(const ROM_version_raw v)
{
	printf("ver_alg:\n");
	printf("  version:  %04x\n", be16_to_cpu(v.version));
	printf("  hash_alg: %02x (%s)\n", v.hash_alg,
			(v.hash_alg == 1) ? "SHA512" : "UNKNOWN");
	printf("  sig_alg:  %02x (%s)\n", v.sig_alg,
			(v.sig_alg == 1) ? "SHA512/ECDSA-521" : "UNKNOWN");
}

static void display_container_stats(const struct parsed_stb_container *c)
{
	unsigned int size, offset;

	printf("Container stats:\n");
	size = (uint8_t*) c->ph - (uint8_t *) c->c;
	offset = (uint8_t*) c->c - (uint8_t *) c->buf;
	printf("  HW header size        = %4u (%#06x) at offset %4u (%#06x)\n",
			size, size, offset, offset);
	size = (uint8_t*) c->pd - (uint8_t *) c->ph;
	offset = (uint8_t*) c->ph - (uint8_t *) c->buf;
	printf("  Prefix header size    = %4u (%#06x) at offset %4u (%#06x)\n",
			size, size, offset, offset);
	size = (uint8_t*) c->sh - (uint8_t *) c->pd;
	offset = (uint8_t*) c->pd - (uint8_t *) c->buf;
	printf("  Prefix data size      = %4u (%#06x) at offset %4u (%#06x)\n",
			size, size, offset, offset);
	size = (uint8_t*) c->ssig - (uint8_t *) c->sh;
	offset = (uint8_t*) c->sh - (uint8_t *) c->buf;
	printf("  SW header size        = %4u (%#06x) at offset %4u (%#06x)\n",
			size, size, offset, offset);
	size = sizeof(ecc_key_t) * c->ph->sw_key_count;
	offset = (uint8_t*) c->ssig - (uint8_t *) c->buf;
	printf("  SW signature size     = %4u (%#06x) at offset %4u (%#06x)\n",
			size, size, offset, offset);

	printf("  TOTAL HEADER SIZE     = %4lu (%#0lx)\n", c->bufsz, c->bufsz);
	printf("  PAYLOAD SIZE          = %4lu (%#0lx)\n",
			be64_to_cpu(c->sh->payload_size), be64_to_cpu(c->sh->payload_size));
	printf("  TOTAL CONTAINER SIZE  = %4lu (%#0lx)\n",
			be64_to_cpu(c->c->container_size),
			be64_to_cpu(c->c->container_size));
	printf("\n");
}

static void display_container(struct parsed_stb_container c)
{
	unsigned char md[SHA512_DIGEST_LENGTH];
	void *p;

	printf("Container:\n");
	printf("magic:          0x%04x\n", be32_to_cpu(c.c->magic_number));
	printf("version:        0x%02x\n", be16_to_cpu(c.c->version));
	printf("container_size: 0x%08lx (%lu)\n", be64_to_cpu(c.c->container_size),
			be64_to_cpu(c.c->container_size));
	printf("target_hrmor:   0x%08lx\n", be64_to_cpu(c.c->target_hrmor));
	printf("stack_pointer:  0x%08lx\n", be64_to_cpu(c.c->stack_pointer));
	print_bytes((char *) "hw_pkey_a: ", (uint8_t *) c.c->hw_pkey_a,
			sizeof(c.c->hw_pkey_a));
	print_bytes((char *) "hw_pkey_b: ", (uint8_t *) c.c->hw_pkey_b,
			sizeof(c.c->hw_pkey_b));
	print_bytes((char *) "hw_pkey_c: ", (uint8_t *) c.c->hw_pkey_c,
			sizeof(c.c->hw_pkey_c));

	p = SHA512(c.c->hw_pkey_a, sizeof(ecc_key_t) * 3, md);
	if (!p)
		die(EX_SOFTWARE, "%s", "Cannot get SHA512");
	printf("HW keys hash (calculated):\n");
	print_bytes((char *) "           ", (uint8_t *) md, sizeof(md));
	printf("\n");

	printf("Prefix Header:\n");
	display_version_raw(c.ph->ver_alg);
	printf("code_start_offset: %08lx\n", be64_to_cpu(c.ph->code_start_offset));
	printf("reserved:          %08lx\n", be64_to_cpu(c.ph->reserved));
	printf("flags:             %08x\n", be32_to_cpu(c.ph->flags));
	printf("sw_key_count:      %02x\n", c.ph->sw_key_count);
	printf("payload_size:      %08lx\n", be64_to_cpu(c.ph->payload_size));
	print_bytes((char *) "payload_hash:      ", (uint8_t *) c.ph->payload_hash,
			sizeof(c.ph->payload_hash));
	printf("ecid_count:        %02x\n", c.ph->ecid_count);

	for (int i = 0; i < c.ph->ecid_count; i++) {
		printf("ecid:              ");
		print_bytes((char *) "ecid:              ",
				(uint8_t *) c.ph->ecid[i].ecid, sizeof(c.ph->ecid[i].ecid));
		printf("\n");
	}
	printf("\n");

	printf("Prefix Data:\n");
	print_bytes((char *) "hw_sig_a:  ", (uint8_t *) c.pd->hw_sig_a, sizeof(c.pd->hw_sig_a));
	print_bytes((char *) "hw_sig_b:  ", (uint8_t *) c.pd->hw_sig_b, sizeof(c.pd->hw_sig_b));
	print_bytes((char *) "hw_sig_c:  ", (uint8_t *) c.pd->hw_sig_c, sizeof(c.pd->hw_sig_c));

	if (c.ph->sw_key_count >=1)
		print_bytes((char *) "sw_pkey_p: ", (uint8_t *) c.pd->sw_pkey_p, sizeof(c.pd->sw_pkey_p));
	if (c.ph->sw_key_count >=2)
		print_bytes((char *) "sw_pkey_q: ", (uint8_t *) c.pd->sw_pkey_q, sizeof(c.pd->sw_pkey_q));
	if (c.ph->sw_key_count >=3)
		print_bytes((char *) "sw_pkey_r: ", (uint8_t *) c.pd->sw_pkey_r, sizeof(c.pd->sw_pkey_r));

	printf("\n");

	printf("Software Header:\n");
	display_version_raw(c.sh->ver_alg);
	printf("code_start_offset: %08lx\n", be64_to_cpu(c.sh->code_start_offset));
	printf("reserved:          %08lx\n", be64_to_cpu(c.sh->reserved));
	printf("reserved (ASCII):  %.8s\n", (char *) &(c.sh->reserved));
	printf("flags:             %08x\n", be32_to_cpu(c.sh->flags));
	printf("reserved_0:        %02x\n", c.sh->reserved_0);
	printf("payload_size:      %08lx (%lu)\n", be64_to_cpu(c.sh->payload_size),
			be64_to_cpu(c.sh->payload_size));
	print_bytes((char *) "payload_hash:      ", (uint8_t *) c.sh->payload_hash,
			sizeof(c.sh->payload_hash));
	printf("ecid_count:        %02x\n", c.sh->ecid_count);

	for (int i = 0; i < c.sh->ecid_count; i++) {
		printf("ecid:              ");
		print_bytes((char *) "ecid:              ",
				(uint8_t *) c.sh->ecid[i].ecid, sizeof(c.sh->ecid[i].ecid));
		printf("\n");
	}
	printf("\n");

	printf("Software Signatures:\n");
	print_bytes((char *) "sw_sig_p:  ", (uint8_t *) c.ssig->sw_sig_p,
			sizeof(c.ssig->sw_sig_p));
	print_bytes((char *) "sw_sig_q:  ", (uint8_t *) c.ssig->sw_sig_q,
			sizeof(c.ssig->sw_sig_q));
	print_bytes((char *) "sw_sig_r:  ", (uint8_t *) c.ssig->sw_sig_r,
			sizeof(c.ssig->sw_sig_r));
	printf("\n");

	if (print_stats)
	display_container_stats(&c);
}

static bool validate_container(struct parsed_stb_container c, int fdin)
{
	static int n;
	static int status = true;

	Keyprops *k;

	Keyprops hwKeylist[] = {
		{ 'a', "HW_key_A", &(c.c->hw_pkey_a), &(c.pd->hw_sig_a) },
		{ 'b', "HW_key_B", &(c.c->hw_pkey_b), &(c.pd->hw_sig_b) },
		{ 'c', "HW_key_C", &(c.c->hw_pkey_c), &(c.pd->hw_sig_c) },
		{ 0, NULL, NULL, NULL },
	};
	Keyprops swKeylist[] = {
		{ 'p', "SW_key_P", &(c.pd->sw_pkey_p), &(c.ssig->sw_sig_p) },
		{ 'q', "SW_key_Q", &(c.pd->sw_pkey_q), &(c.ssig->sw_sig_q) },
		{ 'r', "SW_key_R", &(c.pd->sw_pkey_r), &(c.ssig->sw_sig_r) },
		{ 0, NULL, NULL, NULL },
	};

	void *md = alloca(SHA512_DIGEST_LENGTH);
	void *p;

	// Get Prefix header hash.
	p = SHA512((uint8_t *) c.ph, sizeof(ROM_prefix_header_raw), md);
	if (!p)
		die(EX_SOFTWARE, "%s", "Cannot get SHA512");
	if (verbose) print_bytes((char *) "PR header hash = ", (uint8_t *) md,
			SHA512_DIGEST_LENGTH);

	// Verify HW key sigs.
	for (k = hwKeylist; k->index; k++) {

		if (memcmp(k->key, &ECDSA_KEY_NULL, sizeof(ecc_key_t)))
			status = verify_signature(k->name, md, SHA512_DIGEST_LENGTH,
					*(k->sig), *(k->key)) && status;
		else
			if (verbose) printf("%s is NULL, skipping signature check.\n", k->name);
	}
	if (verbose) printf("\n");

	// Get SW header hash.
	p = SHA512((uint8_t *) c.sh, sizeof(ROM_sw_header_raw), md);
	if (!p)
		die(EX_SOFTWARE, "%s", "Cannot get SHA512");
	if (verbose) print_bytes((char *) "SW header hash = ", (uint8_t *) md,
			SHA512_DIGEST_LENGTH);

	// Verify SW key sigs.
	for (k = swKeylist, n = 1; k->index && n <= c.ph->sw_key_count; k++, n++) {

		if (memcmp(k->key, &ECDSA_KEY_NULL, sizeof(ecc_key_t)))
			status = verify_signature(k->name, md, SHA512_DIGEST_LENGTH,
					*(k->sig), *(k->key)) && status;
		else
			if (verbose) printf("%s is NULL, skipping\n", k->name);
	}
	if (verbose) printf("\n");

	// Verify Payload hash.
	status = getPayloadHash(fdin, md) && status;
	if (verbose) print_bytes((char *) "Payload hash = ", (uint8_t *) md,
			SHA512_DIGEST_LENGTH);

	if (memcmp((uint8_t *) c.sh->payload_hash, md, SHA512_DIGEST_LENGTH)) {
		if (verbose)
			printf("Payload hash does not agree with value in SW header: MISMATCH\n");
		status = false;
	} else {
		if (verbose)
			printf("Payload hash agrees with value in SW header: VERIFIED ./\n");
		status = status && true;
	}
	if (verbose) printf("\n");

	// Verify SW keys hash.
	p = SHA512(c.pd->sw_pkey_p, sizeof(ecc_key_t) * c.ph->sw_key_count, md);
	if (!p)
		die(EX_SOFTWARE, "%s", "Cannot get SHA512");
	if (verbose) print_bytes((char *) "SW keys hash = ", (uint8_t *) md,
			SHA512_DIGEST_LENGTH);

	if (memcmp((uint8_t *) c.ph->payload_hash, md, SHA512_DIGEST_LENGTH)) {
		if (verbose)
			printf("SW keys hash does not agree with value in Prefix header: MISMATCH\n");
		status = false;
	} else {
		if (verbose)
			printf("SW keys hash agrees with value in Prefix header: VERIFIED ./\n");
		status = status && true;
	}
	if (verbose) printf("\n");
	return status;
}

static bool verify_container(struct parsed_stb_container c, char * verify)
{
	static int status = false;

	void *md = alloca(SHA512_DIGEST_LENGTH);
	void *p;
	void *md_verify;

	p = SHA512(c.c->hw_pkey_a, sizeof(ecc_key_t) * 3, md);
	if (!p)
		die(EX_SOFTWARE, "%s", "Cannot get SHA512");
	if (verbose) print_bytes((char *) "HW keys hash = ", (uint8_t *) md,
			SHA512_DIGEST_LENGTH);

	md_verify = alloca(SHA512_DIGEST_LENGTH);
	getVerificationHash(verify, md_verify, SHA512_DIGEST_LENGTH);

	if (memcmp((uint8_t *) md_verify, md, SHA512_DIGEST_LENGTH )) {
		if (verbose)
			printf("HW keys hash does not agree with provided value: MISMATCH\n");
	} else {
		if (verbose)
			printf("HW keys hash agrees with provided value: VERIFIED ./\n");
		status = true;
	}
	if (verbose) printf("\n");
	return status;
}

static bool verify_signature(const char *moniker, const unsigned char *dgst,
		int dgst_len, const ecc_signature_t sig_raw, const ecc_key_t key_raw)
{
	int r;
	bool status = false;
	BIGNUM *r_bn, *s_bn;
	ECDSA_SIG* ecdsa_sig;
	EC_KEY *ec_key;
	const EC_GROUP *ec_group;
	unsigned char *buffer;
	BIGNUM *key_bn;
	EC_POINT *ec_point;

	// Convert the raw sig to a structure that can be handled by openssl.
	debug_print((char *) "Raw sig = ", (uint8_t *) sig_raw,
			sizeof(ecc_signature_t));

	r_bn = BN_new();
	s_bn = BN_new();

	BN_bin2bn((const unsigned char*) &sig_raw[0], 66, r_bn);
	BN_bin2bn((const unsigned char*) &sig_raw[66], 66, s_bn);

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
	ecdsa_sig = ECDSA_SIG_new();
	ECDSA_SIG_set0(ecdsa_sig, r_bn, s_bn);
#else
	ecdsa_sig = malloc(sizeof(ECDSA_SIG));
	ecdsa_sig->r = r_bn;
	ecdsa_sig->s = s_bn;
#endif

	// Convert the raw key to a structure that can be handled by openssl.
	debug_print((char *) "Raw key = ", (uint8_t *) key_raw,
			sizeof(ecc_key_t));

	ec_key = EC_KEY_new();
	if (!ec_key)
		die(EX_SOFTWARE, "%s", "Cannot EC_KEY_new");

	ec_group = EC_GROUP_new_by_curve_name(NID_secp521r1);
	if (!ec_group)
		die(EX_SOFTWARE, "%s", "Cannot EC_GROUP_new_by_curve_name");

	r = EC_KEY_set_group(ec_key, ec_group);
	if (r == 0)
		die(EX_SOFTWARE, "%s", "Cannot EC_KEY_set_group");

	// Add prefix 0x04, for uncompressed key.
	buffer = alloca(sizeof(ecc_key_t) + 1);
	*buffer = 0x04;
	memcpy(buffer + 1, key_raw, sizeof(ecc_key_t));

	key_bn = BN_new();
	BN_bin2bn((const unsigned char*) buffer, EC_COORDBYTES * 2 + 1, key_bn);

	ec_point = EC_POINT_bn2point(ec_group, key_bn, NULL, NULL);
	if (!ec_point)
		die(EX_SOFTWARE, "%s", "Cannot EC_POINT_bn2point");

	r = EC_KEY_set_public_key(ec_key, (const EC_POINT*) ec_point);
	if (r == 0)
		die(EX_SOFTWARE, "%s", "Cannot EC_KEY_set_public_key");

	// Verify the signature.
	r = ECDSA_do_verify(dgst, dgst_len, ecdsa_sig, ec_key);
	if (r == 1) {
		if (verbose) printf("%s signature is good: VERIFIED ./\n", moniker);
		status = true;
	} else if (r == 0) {
		if (verbose) printf("%s signature FAILED to verify.\n", moniker);
		status = false;
	} else {
		die(EX_SOFTWARE, "%s", "Cannot ECDSA_do_verify");
	}

	BN_free(r_bn);
	BN_free(s_bn);
	BN_free(key_bn);

	EC_KEY_free(ec_key);

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
	ECDSA_SIG_free(ecdsa_sig);
#else
	free(ecdsa_sig);
#endif
	return status;
}

static bool getPayloadHash(int fdin, unsigned char *md)
{
	struct stat payload_st;
	void *payload;
	int r;
	void *p;

	r = fstat(fdin, &payload_st);
	if (r != 0)
		die(EX_NOINPUT, "Cannot stat payload file at descriptor: %d (%s)", fdin,
				strerror(errno));

	payload = mmap(NULL, payload_st.st_size - SECURE_BOOT_HEADERS_SIZE,
			PROT_READ, MAP_PRIVATE, fdin, SECURE_BOOT_HEADERS_SIZE);
	if (!payload)
		die(EX_OSERR, "Cannot mmap file at descriptor: %d (%s)", fdin,
				strerror(errno));

	p = SHA512(payload, payload_st.st_size - SECURE_BOOT_HEADERS_SIZE, md);
	if (!p)
		die(EX_SOFTWARE, "%s", "Cannot get SHA512");

	return true;
}

static bool getVerificationHash(char *input, unsigned char *md, int len)
{
	char buf[len * 2 + 1 + 2]; // allow trailing \n and leading "0x"
	char *p;
	struct stat s;
	int r;

	if (isValidHex(input, len)) {
		p = input;
	} else {
		int fdin = open(input, O_RDONLY);
		if (fdin <= 0)
			die(EX_NOINPUT, "%s",
					"Verify requested but no valid hash or hash file provided");

		r = fstat(fdin, &s);
		if (r != 0)
			die(EX_NOINPUT, "Cannot stat hash file: %s (%s)", input,
					strerror(errno));
		if ((size_t) s.st_size > (sizeof(buf)))
			die(EX_DATAERR,
					"Verify hash file \"%s\" invalid size: expected a %d byte hexadecimal value",
					input, len);

		r = read(fdin, buf, s.st_size);
		if (r <= 0)
			die(EX_NOINPUT, "Cannot read hash file: %s (%s)", input,
					strerror(errno));
		p = (char *) buf;

		for (unsigned int i = 0; i < sizeof(buf); i++) // strip newline char
			if (buf[i] == '\n')
				buf[i] = '\0';

		close(fdin);
	}

	// Convert hexascii to binary.
	if (isValidHex(p, len)) {
		if (!strncmp(p, "0x", 2)) // skip leading "0x"
			p += 2;
		for (int count = 0; count < len; count++) {
			sscanf(p, "%2hhx", &md[count]);
			p += 2;
		}
	} else
		die(EX_DATAERR,
				"Verify hash file \"%s\" invalid data: expected a %d byte hexadecimal value",
				input, len);

	return true;
}

__attribute__((__noreturn__)) static void usage (int status)
{
	if (status != 0) {
			fprintf(stderr, "Try '%s --help' for more information.\n", progname);
	}
	else {
		printf("Usage: %s [options]\n", progname);
		printf(
			"\n"
			"Options:\n"
			" -h, --help              display this message and exit\n"
			" -v, --verbose           show verbose output\n"
			" -d, --debug             show additional debug output\n"
			" -w, --wrap              column at which to wrap long output (wrap=0 => unlimited)\n"
			" -s, --stats             additionally print container stats\n"
			" -I, --imagefile         containerized image to display (input)\n"
			"     --validate          perform all checks to ensure is container valid for secure boot\n"
			"     --verify            value, or filename containing value, of the HW Keys hash to\n"
			"                         verify the container against. must be valid 64 byte hexascii.\n"
			"\n");
	};
	exit(status);
}

static struct option const opts[] = {
	{ "help",             no_argument,       0,  'h' },
	{ "verbose",          no_argument,       0,  'v' },
	{ "debug",            no_argument,       0,  'd' },
	{ "wrap",             required_argument, 0,  'w' },
	{ "stats",            no_argument,       0,  's' },
	{ "imagefile",        required_argument, 0,  'I' },
	{ "validate",         no_argument,       0,  128 },
	{ "verify",           required_argument, 0,  129 },
	{ "no-print",         no_argument,       0,  130 },
	{ "print",            no_argument,       0,  131 },
	{ NULL, 0, NULL, 0 }
};

static struct {
	char *imagefn;
	bool validate;
	char *verify;
	bool print_container;
} params;


int main(int argc, char* argv[])
{
	int indexptr;
	int r;
	struct stat st;
	void *container;
	struct parsed_stb_container c;
	int container_status = EX_OK;
	int validate_status = UNATTEMPTED;
	int verify_status = UNATTEMPTED;
	int fdin;

	params.print_container = true;

	progname = strrchr(argv[0], '/');
	if (progname != NULL)
		++progname;
	else
		progname = argv[0];

	while (1) {
		int opt;
		opt = getopt_long(argc, argv, "hvdw:sI:", opts, &indexptr);
		if (opt == -1)
			break;

		switch (opt) {
		case 'h':
		case '?':
			usage(EX_OK);
			break;
		case 'v':
			verbose = true;
			break;
		case 'd':
			debug = true;
			break;
		case 'w':
			wrap = atoi(optarg);
			wrap = (wrap < 2) ? INT_MAX : wrap;
			break;
		case 's':
			print_stats = true;
			break;
		case 'I':
			params.imagefn = optarg;
			break;
		case 128:
			params.validate = true;
			break;
		case 129:
			params.verify = optarg;
			break;
		case 130:
			params.print_container = false;
			break;
		case 131:
			params.print_container = true;
			break;
		default:
			usage(EX_USAGE);
		}
	}

	fdin = open(params.imagefn, O_RDONLY);
	if (fdin <= 0)
		die(EX_NOINPUT, "Cannot open container file: %s (%s)", params.imagefn,
				strerror(errno));

	r = fstat(fdin, &st);
	if (r != 0)
		die(EX_NOINPUT, "Cannot stat container file: %s (%s)", params.imagefn,
				strerror(errno));

	container = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fdin, 0);
	if (!container)
		die(EX_OSERR, "Cannot mmap file: %s (%s)", params.imagefn,
				strerror(errno));

	if (!stb_is_container(container, SECURE_BOOT_HEADERS_SIZE))
		die(EX_DATAERR, "%s", "Not a container, missing magic number");

	if (parse_stb_container(container, SECURE_BOOT_HEADERS_SIZE, &c) != 0)
		die(EX_DATAERR, "%s", "Failed to parse container");

	if (params.print_container)
		display_container(c);

	if (params.validate)
		validate_status = validate_container(c, fdin);

	if (params.verify)
		verify_status = verify_container(c, params.verify);

	if ((validate_status != UNATTEMPTED) || (verify_status != UNATTEMPTED)) {

		printf("Container validity check %s. Container verification check %s.\n\n",
				(validate_status == UNATTEMPTED) ?
						"not attempted" :
						((validate_status == PASSED) ? "PASSED" : "FAILED"),
				(verify_status == UNATTEMPTED) ?
						"not attempted" :
						((verify_status == PASSED) ? "PASSED" : "FAILED"));

		if ((validate_status == FAILED) || (verify_status == FAILED))
			container_status = 1;
	}

	close(fdin);
	return container_status;
}
