/*
 * Copyright 2014 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <inttypes.h>
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "bmpblk_header.h"
#include "fmap.h"
#include "futility.h"
#include "gbb_header.h"
#include "host_common.h"
#include "kernel_blob.h"
#include "traversal.h"
#include "util_misc.h"
#include "vb1_helper.h"
#include "vboot_common.h"

/* Local values for cb_area_s._flags */
enum callback_flags {
	AREA_IS_VALID =     0x00000001,
};

/* Local structure for args, etc. */
static struct local_data_s {
	VbPrivateKey *signprivate;
	VbKeyBlockHeader *keyblock;
	VbPublicKey *kernel_subkey;
	VbPrivateKey *devsignprivate;
	VbKeyBlockHeader *devkeyblock;
	uint32_t version;
	int version_specified;
	uint32_t flags;
	int flags_specified;
	char *loemdir;
	char *loemid;
	uint8_t *bootloader_data;
	uint64_t bootloader_size;
	uint8_t *config_data;
	uint64_t config_size;
	enum arch_t arch;
	int fv_specified;
	uint32_t kloadaddr;
	uint32_t padding;
	int vblockonly;
	char *outfile;
	int create_new_outfile;
	char *pem_signpriv;
	int pem_algo_specified;
	uint32_t pem_algo;
	char *pem_external;
} option = {
	.version = 1,
	.arch = ARCH_UNSPECIFIED,
	.kloadaddr = CROS_32BIT_ENTRY_ADDR,
	.padding = 65536,
};


/* Helper to complain about invalid args. Returns num errors discovered */
static int no_opt_if(int expr, const char *optname)
{
	if (expr) {
		fprintf(stderr, "Missing --%s option\n", optname);
		return 1;
	}
	return 0;
}

/* This wraps/signs a public key, producing a keyblock. */
int futil_cb_sign_pubkey(struct futil_traverse_state_s *state)
{
	VbPublicKey *data_key = (VbPublicKey *)state->my_area->buf;
	VbKeyBlockHeader *vblock;

	if (option.pem_signpriv) {
		if (option.pem_external) {
			/* External signing uses the PEM file directly. */
			vblock = KeyBlockCreate_external(
				data_key,
				option.pem_signpriv,
				option.pem_algo, option.flags,
				option.pem_external);
		} else {
			option.signprivate = PrivateKeyReadPem(
				option.pem_signpriv, option.pem_algo);
			if (!option.signprivate) {
				fprintf(stderr,
					"Unable to read PEM signing key: %s\n",
					strerror(errno));
				return 1;
			}
			vblock = KeyBlockCreate(data_key, option.signprivate,
						option.flags);
		}
	} else {
		/* Not PEM. Should already have a signing key. */
		vblock = KeyBlockCreate(data_key, option.signprivate,
					option.flags);
	}

	/* Write it out */
	return WriteSomeParts(option.outfile,
			      vblock, vblock->key_block_size,
			      NULL, 0);
}

/*
 * This handles FW_MAIN_A and FW_MAIN_B while processing a BIOS image.
 * The data in state->my_area is just the RW firmware blob, so there's nothing
 * useful to show about it. We'll just mark it as present so when we encounter
 * corresponding VBLOCK area, we'll have this to verify.
 */
int futil_cb_sign_fw_main(struct futil_traverse_state_s *state)
{
	state->my_area->_flags |= AREA_IS_VALID;
	return 0;
}

/*
 * This handles VBLOCK_A and VBLOCK_B while processing a BIOS image.
 * We don't do any signing here. We just check to see if the VBLOCK
 * area contains a firmware preamble.
 */
int futil_cb_sign_fw_vblock(struct futil_traverse_state_s *state)
{
	VbKeyBlockHeader *key_block = (VbKeyBlockHeader *)state->my_area->buf;
	uint32_t len = state->my_area->len;

	/*
	 * If we have a valid keyblock and fw_preamble, then we can use them to
	 * determine the size of the firmware body. Otherwise, we'll have to
	 * just sign the whole region.
	 */
	if (VBOOT_SUCCESS != KeyBlockVerify(key_block, len, NULL, 1)) {
		fprintf(stderr, "Warning: %s keyblock is invalid. "
			"Signing the entire FW FMAP region...\n",
			state->name);
		goto whatever;
	}

	RSAPublicKey *rsa = PublicKeyToRSA(&key_block->data_key);
	if (!rsa) {
		fprintf(stderr, "Warning: %s public key is invalid. "
			"Signing the entire FW FMAP region...\n",
			state->name);
		goto whatever;
	}
	uint32_t more = key_block->key_block_size;
	VbFirmwarePreambleHeader *preamble =
		(VbFirmwarePreambleHeader *)(state->my_area->buf + more);
	uint32_t fw_size = preamble->body_signature.data_size;
	struct cb_area_s *fw_body_area = 0;

	switch (state->component) {
	case CB_FMAP_VBLOCK_A:
		fw_body_area = &state->cb_area[CB_FMAP_FW_MAIN_A];
		/* Preserve the flags if they're not specified */
		if (!option.flags_specified)
			option.flags = preamble->flags;
		break;
	case CB_FMAP_VBLOCK_B:
		fw_body_area = &state->cb_area[CB_FMAP_FW_MAIN_B];
		break;
	default:
		DIE;
	}

	if (fw_size > fw_body_area->len) {
		fprintf(stderr,
			"%s says the firmware is larger than we have\n",
			state->name);
		return 1;
	}

	/* Update the firmware size */
	fw_body_area->len = fw_size;

whatever:
	state->my_area->_flags |= AREA_IS_VALID;

	return 0;
}

int futil_cb_create_kernel_part(struct futil_traverse_state_s *state)
{
	uint8_t *vmlinuz_data, *kblob_data, *vblock_data;
	uint64_t vmlinuz_size, kblob_size, vblock_size;
	int rv;

	vmlinuz_data = state->my_area->buf;
	vmlinuz_size = state->my_area->len;

	kblob_data = CreateKernelBlob(
		vmlinuz_data, vmlinuz_size,
		option.arch, option.kloadaddr,
		option.config_data, option.config_size,
		option.bootloader_data, option.bootloader_size,
		&kblob_size);
	if (!kblob_data) {
		fprintf(stderr, "Unable to create kernel blob\n");
		return 1;
	}
	Debug("kblob_size = 0x%" PRIx64 "\n", kblob_size);

	vblock_data = SignKernelBlob(kblob_data, kblob_size, option.padding,
				     option.version, option.kloadaddr,
				     option.keyblock, option.signprivate,
				     &vblock_size);
	if (!vblock_data) {
		fprintf(stderr, "Unable to sign kernel blob\n");
		free(kblob_data);
		return 1;
	}
	Debug("vblock_size = 0x%" PRIx64 "\n", vblock_size);

	/* We should be creating a completely new output file.
	 * If not, something's wrong. */
	if (!option.create_new_outfile)
		DIE;

	if (option.vblockonly)
		rv = WriteSomeParts(option.outfile,
				    vblock_data, vblock_size,
				    NULL, 0);
	else
		rv = WriteSomeParts(option.outfile,
				    vblock_data, vblock_size,
				    kblob_data, kblob_size);

	free(vblock_data);
	free(kblob_data);
	return rv;
}

int futil_cb_resign_kernel_part(struct futil_traverse_state_s *state)
{
	uint8_t *kpart_data, *kblob_data, *vblock_data;
	uint64_t kpart_size, kblob_size, vblock_size;
	VbKeyBlockHeader *keyblock = NULL;
	VbKernelPreambleHeader *preamble = NULL;
	int rv = 0;

	kpart_data = state->my_area->buf;
	kpart_size = state->my_area->len;

	/* Note: This just sets some static pointers. It doesn't malloc. */
	kblob_data = UnpackKPart(kpart_data, kpart_size, option.padding,
				 &keyblock, &preamble, &kblob_size);

	if (!kblob_data) {
		fprintf(stderr, "Unable to unpack kernel partition\n");
		return 1;
	}

	/*
	 * We don't let --kloadaddr change when resigning, because the original
	 * vbutil_kernel program didn't do it right. Since obviously no one
	 * ever noticed, we'll maintain bug-compatibility by just not allowing
	 * it here either. To enable it, we'd need to update the zeropage
	 * table's cmd_line_ptr as well as the preamble.
	 */
	option.kloadaddr = preamble->body_load_address;

	/* Replace the config if asked */
	if (option.config_data &&
	    0 != UpdateKernelBlobConfig(kblob_data, kblob_size,
					option.config_data,
					option.config_size)) {
		fprintf(stderr, "Unable to update config\n");
		return 1;
	}

	/* Preserve the version unless a new one is given */
	if (!option.version_specified)
		option.version = preamble->kernel_version;

	/* Replace the keyblock if asked */
	if (option.keyblock)
		keyblock = option.keyblock;

	/* Compute the new signature */
	vblock_data = SignKernelBlob(kblob_data, kblob_size, option.padding,
				     option.version, option.kloadaddr,
				     keyblock, option.signprivate,
				     &vblock_size);
	if (!vblock_data) {
		fprintf(stderr, "Unable to sign kernel blob\n");
		return 1;
	}
	Debug("vblock_size = 0x%" PRIx64 "\n", vblock_size);

	if (option.create_new_outfile) {
		/* Write out what we've been asked for */
		if (option.vblockonly)
			rv = WriteSomeParts(option.outfile,
					    vblock_data, vblock_size,
					    NULL, 0);
		else
			rv = WriteSomeParts(option.outfile,
					    vblock_data, vblock_size,
					    kblob_data, kblob_size);
	} else {
		/* If we're modifying an existing file, it's mmap'ed so that
		 * all our modifications to the buffer will get flushed to
		 * disk when we close it. */
		Memcpy(kpart_data, vblock_data, vblock_size);
	}

	free(vblock_data);
	return rv;
}


int futil_cb_sign_raw_firmware(struct futil_traverse_state_s *state)
{
	VbSignature *body_sig;
	VbFirmwarePreambleHeader *preamble;
	int rv;

	body_sig = CalculateSignature(state->my_area->buf, state->my_area->len,
				      option.signprivate);
	if (!body_sig) {
		fprintf(stderr, "Error calculating body signature\n");
		return 1;
	}

	preamble = CreateFirmwarePreamble(option.version,
					  option.kernel_subkey,
					  body_sig,
					  option.signprivate,
					  option.flags);
	if (!preamble) {
		fprintf(stderr, "Error creating firmware preamble.\n");
		free(body_sig);
		return 1;
	}

	rv = WriteSomeParts(option.outfile,
			    option.keyblock, option.keyblock->key_block_size,
			    preamble, preamble->preamble_size);

	free(preamble);
	free(body_sig);

	return rv;
}


int futil_cb_sign_begin(struct futil_traverse_state_s *state)
{
	if (state->in_type == FILE_TYPE_UNKNOWN) {
		fprintf(stderr, "Unable to determine type of %s\n",
			state->in_filename);
		return 1;
	}

	return 0;
}

static int write_new_preamble(struct cb_area_s *vblock,
			      struct cb_area_s *fw_body,
			      VbPrivateKey *signkey,
			      VbKeyBlockHeader *keyblock)
{
	VbSignature *body_sig;
	VbFirmwarePreambleHeader *preamble;

	body_sig = CalculateSignature(fw_body->buf, fw_body->len, signkey);
	if (!body_sig) {
		fprintf(stderr, "Error calculating body signature\n");
		return 1;
	}

	preamble = CreateFirmwarePreamble(option.version,
					  option.kernel_subkey,
					  body_sig,
					  signkey,
					  option.flags);
	if (!preamble) {
		fprintf(stderr, "Error creating firmware preamble.\n");
		free(body_sig);
		return 1;
	}

	/* Write the new keyblock */
	uint32_t more = keyblock->key_block_size;
	memcpy(vblock->buf, keyblock, more);
	/* and the new preamble */
	memcpy(vblock->buf + more, preamble, preamble->preamble_size);

	free(preamble);
	free(body_sig);

	return 0;
}

static int write_loem(const char *ab, struct cb_area_s *vblock)
{
	char filename[PATH_MAX];
	int n;
	n = snprintf(filename, sizeof(filename), "%s/vblock_%s.%s",
		     option.loemdir ? option.loemdir : ".",
		     ab, option.loemid);
	if (n >= sizeof(filename)) {
		fprintf(stderr, "LOEM args produce bogus filename\n");
		return 1;
	}

	FILE *fp = fopen(filename, "w");
	if (!fp) {
		fprintf(stderr, "Can't open %s for writing: %s\n",
			filename, strerror(errno));
		return 1;
	}

	if (1 != fwrite(vblock->buf, vblock->len, 1, fp)) {
		fprintf(stderr, "Can't write to %s: %s\n",
			filename, strerror(errno));
		fclose(fp);
		return 1;
	}
	if (fclose(fp)) {
		fprintf(stderr, "Failed closing loem output: %s\n",
			strerror(errno));
		return 1;
	}

	return 0;
}

/* This signs a full BIOS image after it's been traversed. */
static int sign_bios_at_end(struct futil_traverse_state_s *state)
{
	struct cb_area_s *vblock_a = &state->cb_area[CB_FMAP_VBLOCK_A];
	struct cb_area_s *vblock_b = &state->cb_area[CB_FMAP_VBLOCK_B];
	struct cb_area_s *fw_a = &state->cb_area[CB_FMAP_FW_MAIN_A];
	struct cb_area_s *fw_b = &state->cb_area[CB_FMAP_FW_MAIN_B];
	int retval = 0;

	if (state->errors ||
	    !(vblock_a->_flags & AREA_IS_VALID) ||
	    !(vblock_b->_flags & AREA_IS_VALID) ||
	    !(fw_a->_flags & AREA_IS_VALID) ||
	    !(fw_b->_flags & AREA_IS_VALID)) {
		fprintf(stderr, "Something's wrong. Not changing anything\n");
		return 1;
	}

	/* Do A & B differ ? */
	if (fw_a->len != fw_b->len ||
	    memcmp(fw_a->buf, fw_b->buf, fw_a->len)) {
		/* Yes, must use DEV keys for A */
		if (!option.devsignprivate || !option.devkeyblock) {
			fprintf(stderr,
				"FW A & B differ. DEV keys are required.\n");
			return 1;
		}
		retval |= write_new_preamble(vblock_a, fw_a,
					     option.devsignprivate,
					     option.devkeyblock);
	} else {
		retval |= write_new_preamble(vblock_a, fw_a,
					     option.signprivate,
					     option.keyblock);
	}

	/* FW B is always normal keys */
	retval |= write_new_preamble(vblock_b, fw_b,
				     option.signprivate,
				     option.keyblock);




	if (option.loemid) {
		retval |= write_loem("A", vblock_a);
		retval |= write_loem("B", vblock_b);
	}

	return retval;
}

int futil_cb_sign_end(struct futil_traverse_state_s *state)
{
	switch (state->in_type) {
	case FILE_TYPE_BIOS_IMAGE:
	case FILE_TYPE_OLD_BIOS_IMAGE:
		return sign_bios_at_end(state);

	default:
		/* Any other cleanup needed? */
		break;
	}

	return state->errors;
}

static const char usage[] = "\n"
	"Usage:  " MYNAME " %s [PARAMS] INFILE [OUTFILE]\n"
	"\n"
	"Where INFILE is a\n"
	"\n"
	"  public key (.vbpubk); OUTFILE is a keyblock\n"
	"  raw firmware blob (FW_MAIN_A/B); OUTFILE is a VBLOCK_A/B\n"
	"  complete firmware image (bios.bin)\n"
	"  raw linux kernel; OUTFILE is a kernel partition image\n"
	"  kernel partition image (/dev/sda2, /dev/mmcblk0p2)\n";

static const char usage_pubkey[] = "\n"
	"-----------------------------------------------------------------\n"
	"To sign a public key / create a new keyblock:\n"
	"\n"
	"Required PARAMS:\n"
	"  [--datapubkey]   INFILE          The public key to wrap\n"
	"  [--outfile]      OUTFILE         The resulting keyblock\n"
	"\n"
	"Optional PARAMS:\n"
	"  A private signing key, specified as either\n"
	"    -s|--signprivate FILE.vbprivk  Signing key in .vbprivk format\n"
	"  Or\n"
	"    --pem_signpriv   FILE.pem      Signing key in PEM format...\n"
	"    --pem_algo       NUM           AND the algorithm to use (0 - %d)\n"
	"\n"
	"  If a signing key is not given, the keyblock will not be signed (duh)."
	"\n\n"
	"And these, too:\n\n"
	"  -f|--flags       NUM             Flags specifying use conditions\n"
	"  --pem_external   PROGRAM"
	"         External program to compute the signature\n"
	"                                     (requires a PEM signing key)\n";

static const char usage_fw_main[] = "\n"
	"-----------------------------------------------------------------\n"
	"To sign a raw firmware blob (FW_MAIN_A/B):\n"
	"\n"
	"Required PARAMS:\n"
	"  -s|--signprivate FILE.vbprivk    The private firmware data key\n"
	"  -b|--keyblock    FILE.keyblock   The keyblock containing the\n"
	"                                     public firmware data key\n"
	"  -k|--kernelkey   FILE.vbpubk     The public kernel subkey\n"
	"  -v|--version     NUM             The firmware version number\n"
	"  [--fv]           INFILE"
	"          The raw firmware blob (FW_MAIN_A/B)\n"
	"  [--outfile]      OUTFILE         Output VBLOCK_A/B\n"
	"\n"
	"Optional PARAMS:\n"
	"  -f|--flags       NUM             The preamble flags value"
	" (default is 0)\n";

static const char usage_bios[] = "\n"
	"-----------------------------------------------------------------\n"
	"To sign a complete firmware image (bios.bin):\n"
	"\n"
	"Required PARAMS:\n"
	"  -s|--signprivate FILE.vbprivk    The private firmware data key\n"
	"  -b|--keyblock    FILE.keyblock   The keyblock containing the\n"
	"                                     public firmware data key\n"
	"  -k|--kernelkey   FILE.vbpubk     The public kernel subkey\n"
	"  [--infile]       INFILE          Input firmware image (modified\n"
	"                                     in place if no OUTFILE given)\n"
	"\n"
	"These are required if the A and B firmware differ:\n"
	"  -S|--devsign     FILE.vbprivk    The DEV private firmware data key\n"
	"  -B|--devkeyblock FILE.keyblock   The keyblock containing the\n"
	"                                     DEV public firmware data key\n"
	"\n"
	"Optional PARAMS:\n"
	"  -v|--version     NUM             The firmware version number"
	" (default %d)\n"
	"  -f|--flags       NUM             The preamble flags value"
	" (default is\n"
	"                                     unchanged, or 0 if unknown)\n"
	"  -d|--loemdir     DIR             Local OEM output vblock directory\n"
	"  -l|--loemid      STRING          Local OEM vblock suffix\n"
	"  [--outfile]      OUTFILE         Output firmware image\n";

static const char usage_new_kpart[] = "\n"
	"-----------------------------------------------------------------\n"
	"To create a new kernel parition image (/dev/sda2, /dev/mmcblk0p2):\n"
	"\n"
	"Required PARAMS:\n"
	"  -s|--signprivate FILE.vbprivk"
	"    The private key to sign the kernel blob\n"
	"  -b|--keyblock    FILE.keyblock   The keyblock containing the public\n"
	"                                     key to verify the kernel blob\n"
	"  -v|--version     NUM             The kernel version number\n"
	"  --bootloader     FILE            Bootloader stub\n"
	"  --config         FILE            The kernel commandline file\n"
	"  --arch           ARCH            The CPU architecture (one of\n"
	"                                     x86|amd64, arm|aarch64, mips)\n"
	"  [--vmlinuz]      INFILE          Linux kernel bzImage file\n"
	"  [--outfile]      OUTFILE         Output kernel partition or vblock\n"
	"\n"
	"Optional PARAMS:\n"
	"  --kloadaddr      NUM"
	"             RAM address to load the kernel body\n"
	"                                     (default 0x%x)\n"
	"  --pad            NUM             The vblock padding size in bytes\n"
	"                                     (default 0x%x)\n"
	" --vblockonly                      Emit just the vblock (requires a\n"
	"                                     distinct outfile)\n";

static const char usage_old_kpart[] = "\n"
	"-----------------------------------------------------------------\n"
	"To resign an existing kernel parition (/dev/sda2, /dev/mmcblk0p2):\n"
	"\n"
	"Required PARAMS:\n"
	"  -s|--signprivate FILE.vbprivk"
	"    The private key to sign the kernel blob\n"
	"  [--infile]       INFILE          Input kernel partition (modified\n"
	"                                     in place if no OUTFILE given)\n"
	"\n"
	"Optional PARAMS:\n"
	"  -b|--keyblock    FILE.keyblock   The keyblock containing the public\n"
	"                                     key to verify the kernel blob\n"
	"  -v|--version     NUM             The kernel version number\n"
	"  --config         FILE            The kernel commandline file\n"
	"  --pad            NUM             The vblock padding size in bytes\n"
	"                                     (default 0x%x)\n"
	"  [--outfile]      OUTFILE         Output kernel partition or vblock\n"
	"  --vblockonly                     Emit just the vblock (requires a\n"
	"                                     distinct OUTFILE)\n"
	"\n";

static void print_help(const char *prog)
{
	printf(usage, prog);
	printf(usage_pubkey, kNumAlgorithms - 1);
	puts(usage_fw_main);
	printf(usage_bios, option.version);
	printf(usage_new_kpart, option.kloadaddr, option.padding);
	printf(usage_old_kpart, option.padding);
}

enum no_short_opts {
	OPT_FV = 1000,
	OPT_INFILE,			/* aka "--vmlinuz" */
	OPT_OUTFILE,
	OPT_BOOTLOADER,
	OPT_CONFIG,
	OPT_ARCH,
	OPT_KLOADADDR,
	OPT_PADDING,
	OPT_PEM_SIGNPRIV,
	OPT_PEM_ALGO,
	OPT_PEM_EXTERNAL,
};

static const struct option long_opts[] = {
	/* name    hasarg *flag  val */
	{"signprivate",  1, NULL, 's'},
	{"keyblock",     1, NULL, 'b'},
	{"kernelkey",    1, NULL, 'k'},
	{"devsign",      1, NULL, 'S'},
	{"devkeyblock",  1, NULL, 'B'},
	{"version",      1, NULL, 'v'},
	{"flags",        1, NULL, 'f'},
	{"loemdir",      1, NULL, 'd'},
	{"loemid",       1, NULL, 'l'},
	{"fv",           1, NULL, OPT_FV},
	{"infile",       1, NULL, OPT_INFILE},
	{"datapubkey",   1, NULL, OPT_INFILE},	/* alias */
	{"vmlinuz",      1, NULL, OPT_INFILE},	/* alias */
	{"outfile",      1, NULL, OPT_OUTFILE},
	{"bootloader",   1, NULL, OPT_BOOTLOADER},
	{"config",       1, NULL, OPT_CONFIG},
	{"arch",         1, NULL, OPT_ARCH},
	{"kloadaddr",    1, NULL, OPT_KLOADADDR},
	{"pad",          1, NULL, OPT_PADDING},
	{"pem_signpriv", 1, NULL, OPT_PEM_SIGNPRIV},
	{"pem_algo",     1, NULL, OPT_PEM_ALGO},
	{"pem_external", 1, NULL, OPT_PEM_EXTERNAL},
	{"vblockonly",   0, &option.vblockonly, 1},
	{"debug",        0, &debugging_enabled, 1},
	{NULL,           0, NULL, 0},
};
static char *short_opts = ":s:b:k:S:B:v:f:d:l:";

static int do_sign(int argc, char *argv[])
{
	char *infile = 0;
	int i;
	int ifd = -1;
	int errorcnt = 0;
	struct futil_traverse_state_s state;
	uint8_t *buf;
	uint32_t buf_len;
	char *e = 0;
	enum futil_file_type type;
	int inout_file_count = 0;
	int mapping;

	opterr = 0;		/* quiet, you */
	while ((i = getopt_long(argc, argv, short_opts, long_opts, 0)) != -1) {
		switch (i) {
		case 's':
			option.signprivate = PrivateKeyRead(optarg);
			if (!option.signprivate) {
				fprintf(stderr, "Error reading %s\n", optarg);
				errorcnt++;
			}
			break;
		case 'b':
			option.keyblock = KeyBlockRead(optarg);
			if (!option.keyblock) {
				fprintf(stderr, "Error reading %s\n", optarg);
				errorcnt++;
			}
			break;
		case 'k':
			option.kernel_subkey = PublicKeyRead(optarg);
			if (!option.kernel_subkey) {
				fprintf(stderr, "Error reading %s\n", optarg);
				errorcnt++;
			}
			break;
		case 'S':
			option.devsignprivate = PrivateKeyRead(optarg);
			if (!option.devsignprivate) {
				fprintf(stderr, "Error reading %s\n", optarg);
				errorcnt++;
			}
			break;
		case 'B':
			option.devkeyblock = KeyBlockRead(optarg);
			if (!option.devkeyblock) {
				fprintf(stderr, "Error reading %s\n", optarg);
				errorcnt++;
			}
			break;
		case 'v':
			option.version_specified = 1;
			option.version = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr,
					"Invalid --version \"%s\"\n", optarg);
				errorcnt++;
			}
			break;

		case 'f':
			option.flags_specified = 1;
			option.flags = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr,
					"Invalid --flags \"%s\"\n", optarg);
				errorcnt++;
			}
			break;
		case 'd':
			option.loemdir = optarg;
			break;
		case 'l':
			option.loemid = optarg;
			break;
		case OPT_FV:
			option.fv_specified = 1;
			/* fallthrough */
		case OPT_INFILE:		/* aka "--vmlinuz" */
			inout_file_count++;
			infile = optarg;
			break;
		case OPT_OUTFILE:
			inout_file_count++;
			option.outfile = optarg;
			break;
		case OPT_BOOTLOADER:
			option.bootloader_data = ReadFile(
				optarg, &option.bootloader_size);
			if (!option.bootloader_data) {
				fprintf(stderr,
					"Error reading bootloader file: %s\n",
					strerror(errno));
				errorcnt++;
			}
			Debug("bootloader file size=0x%" PRIx64 "\n",
			      option.bootloader_size);
			break;
		case OPT_CONFIG:
			option.config_data = ReadConfigFile(
				optarg, &option.config_size);
			if (!option.config_data) {
				fprintf(stderr,
					"Error reading config file: %s\n",
					strerror(errno));
				errorcnt++;
			}
			break;
		case OPT_ARCH:
			/* check the first 3 characters to also match x86_64 */
			if ((!strncasecmp(optarg, "x86", 3)) ||
			    (!strcasecmp(optarg, "amd64")))
				option.arch = ARCH_X86;
			else if ((!strcasecmp(optarg, "arm")) ||
				 (!strcasecmp(optarg, "aarch64")))
				option.arch = ARCH_ARM;
			else if (!strcasecmp(optarg, "mips"))
				option.arch = ARCH_MIPS;
			else {
				fprintf(stderr,
					"Unknown architecture: \"%s\"\n",
					optarg);
				errorcnt++;
			}
			break;
		case OPT_KLOADADDR:
			option.kloadaddr = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr,
					"Invalid --kloadaddr \"%s\"\n", optarg);
				errorcnt++;
			}
			break;
		case OPT_PADDING:
			option.padding = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr,
					"Invalid --padding \"%s\"\n", optarg);
				errorcnt++;
			}
			break;
		case OPT_PEM_SIGNPRIV:
			option.pem_signpriv = optarg;
			break;
		case OPT_PEM_ALGO:
			option.pem_algo_specified = 1;
			option.pem_algo = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e) ||
			    (option.pem_algo >= kNumAlgorithms)) {
				fprintf(stderr,
					"Invalid --pem_algo \"%s\"\n", optarg);
				errorcnt++;
			}
			break;
		case OPT_PEM_EXTERNAL:
			option.pem_external = optarg;
			break;

		case '?':
			if (optopt)
				fprintf(stderr, "Unrecognized option: -%c\n",
					optopt);
			else
				fprintf(stderr, "Unrecognized option: %s\n",
					argv[optind - 1]);
			errorcnt++;
			break;
		case ':':
			fprintf(stderr, "Missing argument to -%c\n", optopt);
			errorcnt++;
			break;
		case 0:				/* handled option */
			break;
		default:
			Debug("i=%d\n", i);
			DIE;
		}
	}

	/* If we don't have an input file already, we need one */
	if (!infile) {
		if (argc - optind <= 0) {
			errorcnt++;
			fprintf(stderr, "ERROR: missing input filename\n");
			goto done;
		} else {
			inout_file_count++;
			infile = argv[optind++];
		}
	}

	/* Look for an output file if we don't have one, just in case. */
	if (!option.outfile && argc - optind > 0) {
		inout_file_count++;
		option.outfile = argv[optind++];
	}

	/* What are we looking at? */
	type = futil_what_file_type(infile);

	/* We may be able to infer the type based on the other args */
	if (type == FILE_TYPE_UNKNOWN) {
		if (option.bootloader_data || option.config_data
		    || option.arch != ARCH_UNSPECIFIED)
			type = FILE_TYPE_RAW_KERNEL;
		else if (option.kernel_subkey || option.fv_specified)
			type = FILE_TYPE_RAW_FIRMWARE;
	}

	Debug("type=%s\n", futil_file_type_str[type]);

	/* Check the arguments for the type of thing we want to sign */
	switch (type) {
	case FILE_TYPE_UNKNOWN:
		fprintf(stderr,
			"Unable to determine the type of the input file\n");
		errorcnt++;
		goto done;
	case FILE_TYPE_PUBKEY:
		option.create_new_outfile = 1;
		if (option.signprivate && option.pem_signpriv) {
			fprintf(stderr,
				"Only one of --signprivate and --pem_signpriv"
				" can be specified\n");
			errorcnt++;
		}
		if ((option.signprivate && option.pem_algo_specified) ||
		    (option.pem_signpriv && !option.pem_algo_specified)) {
			fprintf(stderr, "--pem_algo must be used with"
				" --pem_signpriv\n");
			errorcnt++;
		}
		if (option.pem_external && !option.pem_signpriv) {
			fprintf(stderr, "--pem_external must be used with"
				" --pem_signpriv\n");
			errorcnt++;
		}
		/* We'll wait to read the PEM file, since the external signer
		 * may want to read it instead. */
		break;
	case FILE_TYPE_KEYBLOCK:
		fprintf(stderr, "Resigning a keyblock is kind of pointless.\n");
		fprintf(stderr, "Just create a new one.\n");
		errorcnt++;
		break;
	case FILE_TYPE_FW_PREAMBLE:
		fprintf(stderr,
			"%s IS a signature. Sign the firmware instead\n",
			infile);
		break;
	case FILE_TYPE_GBB:
		fprintf(stderr, "There's no way to sign a GBB\n");
		errorcnt++;
		break;
	case FILE_TYPE_BIOS_IMAGE:
	case FILE_TYPE_OLD_BIOS_IMAGE:
		errorcnt += no_opt_if(!option.signprivate, "signprivate");
		errorcnt += no_opt_if(!option.keyblock, "keyblock");
		errorcnt += no_opt_if(!option.kernel_subkey, "kernelkey");
		break;
	case FILE_TYPE_KERN_PREAMBLE:
		errorcnt += no_opt_if(!option.signprivate, "signprivate");
		if (option.vblockonly || inout_file_count > 1)
			option.create_new_outfile = 1;
		break;
	case FILE_TYPE_RAW_FIRMWARE:
		option.create_new_outfile = 1;
		errorcnt += no_opt_if(!option.signprivate, "signprivate");
		errorcnt += no_opt_if(!option.keyblock, "keyblock");
		errorcnt += no_opt_if(!option.kernel_subkey, "kernelkey");
		errorcnt += no_opt_if(!option.version_specified, "version");
		break;
	case FILE_TYPE_RAW_KERNEL:
		option.create_new_outfile = 1;
		errorcnt += no_opt_if(!option.signprivate, "signprivate");
		errorcnt += no_opt_if(!option.keyblock, "keyblock");
		errorcnt += no_opt_if(!option.version_specified, "version");
		errorcnt += no_opt_if(!option.bootloader_data, "bootloader");
		errorcnt += no_opt_if(!option.config_data, "config");
		errorcnt += no_opt_if(option.arch == ARCH_UNSPECIFIED, "arch");
		break;
	default:
		DIE;
	}

	Debug("infile=%s\n", infile);
	Debug("inout_file_count=%d\n", inout_file_count);
	Debug("option.create_new_outfile=%d\n", option.create_new_outfile);

	/* Make sure we have an output file if one is needed */
	if (!option.outfile) {
		if (option.create_new_outfile) {
			errorcnt++;
			fprintf(stderr, "Missing output filename\n");
			goto done;
		} else {
			option.outfile = infile;
		}
	}

	Debug("option.outfile=%s\n", option.outfile);

	if (argc - optind > 0) {
		errorcnt++;
		fprintf(stderr, "ERROR: too many arguments left over\n");
	}

	if (errorcnt)
		goto done;

	memset(&state, 0, sizeof(state));
	state.op = FUTIL_OP_SIGN;

	if (option.create_new_outfile) {
		/* The input is read-only, the output is write-only. */
		mapping = MAP_RO;
		state.in_filename = infile;
		Debug("open RO %s\n", infile);
		ifd = open(infile, O_RDONLY);
		if (ifd < 0) {
			errorcnt++;
			fprintf(stderr, "Can't open %s for reading: %s\n",
				infile, strerror(errno));
			goto done;
		}
	} else {
		/* We'll read-modify-write the output file */
		mapping = MAP_RW;
		state.in_filename = option.outfile;
		if (inout_file_count > 1)
			futil_copy_file_or_die(infile, option.outfile);
		Debug("open RW %s\n", option.outfile);
		ifd = open(option.outfile, O_RDWR);
		if (ifd < 0) {
			errorcnt++;
			fprintf(stderr, "Can't open %s for writing: %s\n",
				option.outfile, strerror(errno));
			goto done;
		}
	}

	if (0 != futil_map_file(ifd, mapping, &buf, &buf_len)) {
		errorcnt++;
		goto done;
	}

	errorcnt += futil_traverse(buf, buf_len, &state, type);

	errorcnt += futil_unmap_file(ifd, MAP_RW, buf, buf_len);

done:
	if (ifd >= 0 && close(ifd)) {
		errorcnt++;
		fprintf(stderr, "Error when closing ifd: %s\n",
			strerror(errno));
	}

	if (option.signprivate)
		free(option.signprivate);
	if (option.keyblock)
		free(option.keyblock);
	if (option.kernel_subkey)
		free(option.kernel_subkey);

	if (errorcnt)
		fprintf(stderr, "Use --help for usage instructions\n");

	return !!errorcnt;
}

DECLARE_FUTIL_COMMAND(sign, do_sign,
		      "Sign / resign various binary components",
		      print_help);
