/* Copyright 2012 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.
 *
 * Verified boot kernel utility
 */

#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <inttypes.h>		/* For PRIu64 */
#include <sys/ioctl.h>
#include <linux/fs.h>		/* For BLKGETSIZE64 */
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "cryptolib.h"
#include "futility.h"
#include "host_common.h"
#include "kernel_blob.h"
#include "util_misc.h"
#include "vboot_common.h"

/* Global opts */
static int opt_verbose;
static int opt_vblockonly;
static uint64_t opt_pad = 65536;

/* Command line options */
enum {
	OPT_MODE_PACK = 1000,
	OPT_MODE_REPACK,
	OPT_MODE_VERIFY,
	OPT_ARCH,
	OPT_OLDBLOB,
	OPT_KLOADADDR,
	OPT_KEYBLOCK,
	OPT_SIGNPUBKEY,
	OPT_SIGNPRIVATE,
	OPT_VERSION,
	OPT_VMLINUZ,
	OPT_BOOTLOADER,
	OPT_CONFIG,
	OPT_VBLOCKONLY,
	OPT_PAD,
	OPT_VERBOSE,
	OPT_MINVERSION,
};

static const struct option long_opts[] = {
	{"pack", 1, 0, OPT_MODE_PACK},
	{"repack", 1, 0, OPT_MODE_REPACK},
	{"verify", 1, 0, OPT_MODE_VERIFY},
	{"arch", 1, 0, OPT_ARCH},
	{"oldblob", 1, 0, OPT_OLDBLOB},
	{"kloadaddr", 1, 0, OPT_KLOADADDR},
	{"keyblock", 1, 0, OPT_KEYBLOCK},
	{"signpubkey", 1, 0, OPT_SIGNPUBKEY},
	{"signprivate", 1, 0, OPT_SIGNPRIVATE},
	{"version", 1, 0, OPT_VERSION},
	{"minversion", 1, 0, OPT_MINVERSION},
	{"vmlinuz", 1, 0, OPT_VMLINUZ},
	{"bootloader", 1, 0, OPT_BOOTLOADER},
	{"config", 1, 0, OPT_CONFIG},
	{"vblockonly", 0, 0, OPT_VBLOCKONLY},
	{"pad", 1, 0, OPT_PAD},
	{"verbose", 0, &opt_verbose, 1},
	{"debug", 0, &debugging_enabled, 1},
	{NULL, 0, 0, 0}
};



static const char usage[] =
	"\n"
	"Usage:  " MYNAME " %s --pack <file> [PARAMETERS]\n"
	"\n"
	"  Required parameters:\n"
	"    --keyblock <file>         Key block in .keyblock format\n"
	"    --signprivate <file>      Private key to sign kernel data,\n"
	"                                in .vbprivk format\n"
	"    --version <number>        Kernel version\n"
	"    --vmlinuz <file>          Linux kernel bzImage file\n"
	"    --bootloader <file>       Bootloader stub\n"
	"    --config <file>           Command line file\n"
	"    --arch <arch>             Cpu architecture (default x86)\n"
	"\n"
	"  Optional:\n"
	"    --kloadaddr <address>     Assign kernel body load address\n"
	"    --pad <number>            Verification padding size in bytes\n"
	"    --vblockonly              Emit just the verification blob\n"
	"\nOR\n\n"
	"Usage:  " MYNAME " %s --repack <file> [PARAMETERS]\n"
	"\n"
	"  Required parameters:\n"
	"    --signprivate <file>      Private key to sign kernel data,\n"
	"                                in .vbprivk format\n"
	"    --oldblob <file>          Previously packed kernel blob\n"
	"                                (including verfication blob)\n"
	"\n"
	"  Optional:\n"
	"    --keyblock <file>         Key block in .keyblock format\n"
	"    --config <file>           New command line file\n"
	"    --version <number>        Kernel version\n"
	"    --kloadaddr <address>     Assign kernel body load address\n"
	"    --pad <number>            Verification blob size in bytes\n"
	"    --vblockonly              Emit just the verification blob\n"
	"\nOR\n\n"
	"Usage:  " MYNAME " %s --verify <file> [PARAMETERS]\n"
	"\n"
	"  Optional:\n"
	"    --signpubkey <file>"
	"       Public key to verify kernel keyblock,\n"
	"                                in .vbpubk format\n"
	"    --verbose                 Print a more detailed report\n"
	"    --keyblock <file>         Outputs the verified key block,\n"
	"                                in .keyblock format\n"
	"    --pad <number>            Verification padding size in bytes\n"
	"    --minversion <number>     Minimum combined kernel key version\n"
	"                              and kernel version\n"
	"\n";


/* Print help and return error */
static void print_help(const char *progname)
{
	printf(usage, progname, progname, progname);
}

static void Fatal(const char *format, ...)
{
	va_list ap;
	va_start(ap, format);
	fprintf(stderr, "ERROR: ");
	vfprintf(stderr, format, ap);
	va_end(ap);
	exit(1);
}

/* Return an explanation when fread() fails. */
static const char *error_fread(FILE *fp)
{
	const char *retval = "beats me why";
	if (feof(fp))
		retval = "EOF";
	else if (ferror(fp))
		retval = strerror(errno);
	clearerr(fp);
	return retval;
}

/* Return the smallest integral multiple of [alignment] that is equal
 * to or greater than [val]. Used to determine the number of
 * pages/sectors/blocks/whatever needed to contain [val]
 * items/bytes/etc. */
static uint64_t roundup(uint64_t val, uint64_t alignment)
{
	uint64_t rem = val % alignment;
	if (rem)
		return val + (alignment - rem);
	return val;
}

/* Match regexp /\b--\b/ to delimit the start of the kernel commandline. If we
 * don't find one, we'll use the whole thing. */
static unsigned int find_cmdline_start(char *input, unsigned int max_len)
{
	int start = 0;
	int i;
	for (i = 0; i < max_len - 1 && input[i]; i++) {
		if ('-' == input[i] && '-' == input[i + 1]) {
			if ((i == 0 || ' ' == input[i - 1]) &&
			    (i + 2 >= max_len || ' ' == input[i + 2])) {
				/* found "--" with nothing before or after it */
				start = i + 2;	/* hope for a trailing '\0' */
				break;
			}
		}
	}
	while (' ' == input[start])	/* skip leading spaces */
		start++;

	return start;
}

/****************************************************************************/
/* Here are globals containing all the bits & pieces I'm working on. */

/* The individual parts that go into the kernel blob */
static uint8_t *g_kernel_data;
static uint64_t g_kernel_size;
static uint8_t *g_param_data;
static uint64_t g_param_size;
static uint8_t *g_config_data;
static uint64_t g_config_size;
static uint8_t *g_bootloader_data;
static uint64_t g_bootloader_size;
static uint64_t g_bootloader_address;

/* The individual parts of the verification blob (including the data that
 * immediately follows the headers) */
static VbKeyBlockHeader *g_keyblock;
static VbKernelPreambleHeader *g_preamble;

/****************************************************************************/

/*
 * Read the kernel command line from a file. Get rid of \n characters along
 * the way and verify that the line fits into a 4K buffer.
 *
 * Return the buffer contaning the line on success (and set the line length
 * using the passed in parameter), or NULL in case something goes wrong.
 */
static uint8_t *sReadConfigFile(const char *config_file, uint64_t *config_size)
{
	uint8_t *config_buf;
	int ii;

	config_buf = ReadFile(config_file, config_size);
	Debug(" config file size=0x%" PRIx64 "\n", *config_size);
	if (CROS_CONFIG_SIZE <= *config_size) {	/* room for trailing '\0' */
		VbExError("Config file %s is too large (>= %d bytes)\n",
			  config_file, CROS_CONFIG_SIZE);
		return NULL;
	}

	/* Replace newlines with spaces */
	for (ii = 0; ii < *config_size; ii++)
		if ('\n' == config_buf[ii])
			config_buf[ii] = ' ';

	return config_buf;
}

/* Offset of kernel command line string from start of packed kernel blob */
static uint64_t CmdLineOffset(VbKernelPreambleHeader *preamble)
{
	return preamble->bootloader_address - preamble->body_load_address -
	    CROS_CONFIG_SIZE - CROS_PARAMS_SIZE;
}

/* This initializes g_vmlinuz and g_param from a standard vmlinuz file.
 * It returns 0 on error. */
static int ImportVmlinuzFile(const char *vmlinuz_file, enum arch_t arch,
			     uint64_t kernel_body_load_address)
{
	uint8_t *kernel_buf;
	uint64_t kernel_size;
	uint64_t kernel32_start = 0;
	uint64_t kernel32_size = 0;
	struct linux_kernel_params *params = NULL, *lh = NULL;

	/* Read the kernel */
	Debug("Reading %s\n", vmlinuz_file);
	kernel_buf = ReadFile(vmlinuz_file, &kernel_size);
	if (!kernel_buf)
		return 0;
	Debug(" kernel file size=0x%" PRIx64 "\n", kernel_size);
	if (!kernel_size)
		Fatal("Empty kernel file\n");

	/* Go ahead and allocate the param region anyway. I don't think we need
	 * it for non-x86, but let's keep it for now. */
	g_param_size = CROS_PARAMS_SIZE;
	g_param_data = VbExMalloc(g_param_size);
	Memset(g_param_data, 0, g_param_size);

	/* Unless we're handling x86, the kernel is the kernel; we're done. */
	if (arch != ARCH_X86) {
		g_kernel_data = kernel_buf;
		g_kernel_size = kernel_size;
		return 1;
	}

	/* The first part of the x86 vmlinuz is a header, followed by a
	 * real-mode boot stub.  We only want the 32-bit part. */
	lh = (struct linux_kernel_params *)kernel_buf;
	kernel32_start = (lh->setup_sects + 1) << 9;
	if (kernel32_start >= kernel_size)
		Fatal("Malformed kernel\n");
	kernel32_size = kernel_size - kernel32_start;

	Debug(" kernel32_start=0x%" PRIx64 "\n", kernel32_start);
	Debug(" kernel32_size=0x%" PRIx64 "\n", kernel32_size);

	/* Keep just the 32-bit kernel. */
	if (kernel32_size) {
		g_kernel_size = kernel32_size;
		g_kernel_data = VbExMalloc(g_kernel_size);
		Memcpy(g_kernel_data, kernel_buf + kernel32_start,
		       kernel32_size);
	}

	/* Copy the original zeropage data from kernel_buf into g_param_data,
	 * then tweak a few fields for our purposes */
	params = (struct linux_kernel_params *)(g_param_data);
	Memcpy(&(params->setup_sects), &(lh->setup_sects),
	       offsetof(struct linux_kernel_params, e820_entries)
	       - offsetof(struct linux_kernel_params, setup_sects));
	params->boot_flag = 0;
	params->ramdisk_image = 0;	/* we don't support initrd */
	params->ramdisk_size = 0;
	params->type_of_loader = 0xff;
	/* We need to point to the kernel commandline arg. On disk, it will come
	 *  right after the 32-bit part of the kernel. */
	params->cmd_line_ptr = kernel_body_load_address +
	    roundup(kernel32_size, CROS_ALIGN) +
	    find_cmdline_start((char *)g_config_data, g_config_size);
	Debug(" cmdline_addr=0x%x\n", params->cmd_line_ptr);
	Debug(" version=0x%x\n", params->version);
	Debug(" kernel_alignment=0x%x\n", params->kernel_alignment);
	Debug(" relocatable_kernel=0x%x\n", params->relocatable_kernel);
	/* A fake e820 memory map with 2 entries */
	params->n_e820_entry = 2;
	params->e820_entries[0].start_addr = 0x00000000;
	params->e820_entries[0].segment_size = 0x00001000;
	params->e820_entries[0].segment_type = E820_TYPE_RAM;
	params->e820_entries[1].start_addr = 0xfffff000;
	params->e820_entries[1].segment_size = 0x00001000;
	params->e820_entries[1].segment_type = E820_TYPE_RESERVED;

	/* done */
	free(kernel_buf);
	return 1;
}

/* This returns just the kernel blob, with the verification blob separated
 * and copied to new memory in g_keyblock and g_preamble. */
static uint8_t *ReadOldBlobFromFileOrDie(const char *filename,
					 uint64_t *size_ptr)
{
	FILE *fp = NULL;
	struct stat statbuf;
	VbKeyBlockHeader *key_block;
	VbKernelPreambleHeader *preamble;
	uint64_t now = 0;
	uint8_t *buf;
	uint8_t *kernel_blob_data;
	uint64_t kernel_blob_size;
	uint64_t file_size = 0;

	if (0 != stat(filename, &statbuf))
		Fatal("Unable to stat %s: %s\n", filename, strerror(errno));

	if (S_ISBLK(statbuf.st_mode)) {
		int fd = open(filename, O_RDONLY);
		if (fd >= 0) {
			ioctl(fd, BLKGETSIZE64, &file_size);
			close(fd);
		}
	} else {
		file_size = statbuf.st_size;
	}
	Debug("%s size is 0x%" PRIx64 "\n", filename, file_size);
	if (file_size < opt_pad)
		Fatal("%s is too small to be a valid kernel blob\n");

	Debug("Reading %s\n", filename);
	fp = fopen(filename, "rb");
	if (!fp)
		Fatal("Unable to open file %s: %s\n", filename,
		      strerror(errno));

	buf = VbExMalloc(opt_pad);
	if (1 != fread(buf, opt_pad, 1, fp))
		Fatal("Unable to read header from %s: %s\n", filename,
		      error_fread(fp));

	/* Sanity-check the key_block */
	key_block = (VbKeyBlockHeader *) buf;
	Debug("Keyblock is 0x%" PRIx64 " bytes\n", key_block->key_block_size);
	now += key_block->key_block_size;
	if (now > file_size)
		Fatal("key_block_size advances past the end of the blob\n");
	if (now > opt_pad)
		Fatal("key_block_size advances past %" PRIu64 " byte padding\n",
		      opt_pad);
	/* LGTM */
	g_keyblock = (VbKeyBlockHeader *) VbExMalloc(key_block->key_block_size);
	Memcpy(g_keyblock, key_block, key_block->key_block_size);

	/* And the preamble */
	preamble = (VbKernelPreambleHeader *) (buf + now);
	Debug("Preamble is 0x%" PRIx64 " bytes\n", preamble->preamble_size);
	now += preamble->preamble_size;
	if (now > file_size)
		Fatal("preamble_size advances past the end of the blob\n");
	if (now > opt_pad)
		Fatal("preamble_size advances past %" PRIu64 " byte padding\n",
		      opt_pad);
	/* LGTM */
	Debug(" kernel_version = %d\n", preamble->kernel_version);
	Debug(" bootloader_address = 0x%" PRIx64 "\n",
	      preamble->bootloader_address);
	Debug(" bootloader_size = 0x%" PRIx64 "\n", preamble->bootloader_size);
	Debug(" kern_blob_size = 0x%" PRIx64 "\n",
	      preamble->body_signature.data_size);
	g_preamble =
	    (VbKernelPreambleHeader *) VbExMalloc(preamble->preamble_size);
	Memcpy(g_preamble, preamble, preamble->preamble_size);

	/* Now for the kernel blob */
	Debug("kernel blob is at offset 0x%" PRIx64 "\n", now);
	if (0 != fseek(fp, now, SEEK_SET))
		Fatal("Unable to seek to 0x%" PRIx64 " in %s: %s\n", now,
		      filename, strerror(errno));

	/* Sanity check */
	kernel_blob_size = file_size - now;
	if (!kernel_blob_size)
		Fatal("No kernel blob found\n");
	if (kernel_blob_size < preamble->body_signature.data_size)
		fprintf(stderr,
			"Warning: kernel file only has 0x%" PRIx64 " bytes\n",
			kernel_blob_size);
	kernel_blob_data = VbExMalloc(kernel_blob_size);

	/* Read it in */
	if (1 != fread(kernel_blob_data, kernel_blob_size, 1, fp))
		Fatal("Unable to read kernel blob from %s: %s\n", filename,
		      error_fread(fp));

	/* Done */
	VbExFree(buf);

	if (size_ptr)
		*size_ptr = kernel_blob_size;

	return kernel_blob_data;
}

/* Split a kernel blob into separate g_kernel, g_param, g_config, and
 * g_bootloader parts. */
static void UnpackKernelBlob(uint8_t *kernel_blob_data,
			     uint64_t kernel_blob_size)
{

	uint64_t k_blob_size = g_preamble->body_signature.data_size;
	uint64_t k_blob_ofs = 0;
	uint64_t b_size = g_preamble->bootloader_size;
	uint64_t b_ofs = k_blob_ofs + g_preamble->bootloader_address -
	    g_preamble->body_load_address;
	uint64_t p_ofs = b_ofs - CROS_CONFIG_SIZE;
	uint64_t c_ofs = p_ofs - CROS_PARAMS_SIZE;

	Debug("k_blob_size    = 0x%" PRIx64 "\n", k_blob_size);
	Debug("k_blob_ofs     = 0x%" PRIx64 "\n", k_blob_ofs);
	Debug("b_size         = 0x%" PRIx64 "\n", b_size);
	Debug("b_ofs          = 0x%" PRIx64 "\n", b_ofs);
	Debug("p_ofs          = 0x%" PRIx64 "\n", p_ofs);
	Debug("c_ofs          = 0x%" PRIx64 "\n", c_ofs);

	g_kernel_size = c_ofs;
	g_kernel_data = VbExMalloc(g_kernel_size);
	Memcpy(g_kernel_data, kernel_blob_data, g_kernel_size);

	g_param_size = CROS_PARAMS_SIZE;
	g_param_data = VbExMalloc(g_param_size);
	Memcpy(g_param_data, kernel_blob_data + p_ofs, g_param_size);

	g_config_size = CROS_CONFIG_SIZE;
	g_config_data = VbExMalloc(g_config_size);
	Memcpy(g_config_data, kernel_blob_data + c_ofs, g_config_size);

	g_bootloader_size = b_size;
	g_bootloader_data = VbExMalloc(g_bootloader_size);
	Memcpy(g_bootloader_data, kernel_blob_data + b_ofs, g_bootloader_size);
}

/****************************************************************************/

static uint8_t *CreateKernBlob(uint64_t kernel_body_load_address,
			       enum arch_t arch, uint64_t *size_ptr)
{
	uint8_t *kern_blob;
	uint64_t kern_blob_size;
	uint64_t now;
	uint64_t bootloader_size = roundup(g_bootloader_size, CROS_ALIGN);

	/* Put the kernel blob together */
	kern_blob_size = roundup(g_kernel_size, CROS_ALIGN) +
	    CROS_CONFIG_SIZE + CROS_PARAMS_SIZE + bootloader_size;
	Debug("kern_blob_size=0x%" PRIx64 "\n", kern_blob_size);
	kern_blob = VbExMalloc(kern_blob_size);
	Memset(kern_blob, 0, kern_blob_size);
	now = 0;

	Debug("kernel goes at kern_blob+0x%" PRIx64 "\n", now);

	Memcpy(kern_blob + now, g_kernel_data, g_kernel_size);
	now += roundup(g_kernel_size, CROS_ALIGN);

	Debug("config goes at kern_blob+0x%" PRIx64 "\n", now);
	if (g_config_size)
		Memcpy(kern_blob + now, g_config_data, g_config_size);
	now += CROS_CONFIG_SIZE;

	Debug("params goes at kern_blob+0x%" PRIx64 "\n", now);
	if (g_param_size)
		Memcpy(kern_blob + now, g_param_data, g_param_size);
	now += CROS_PARAMS_SIZE;

	Debug("bootloader goes at kern_blob+0x%" PRIx64 "\n", now);
	g_bootloader_address = kernel_body_load_address + now;
	Debug(" bootloader_address=0x%" PRIx64 "\n", g_bootloader_address);
	Debug(" bootloader_size=0x%" PRIx64 "\n", bootloader_size);
	if (bootloader_size)
		Memcpy(kern_blob + now, g_bootloader_data, g_bootloader_size);
	now += bootloader_size;
	Debug("end of kern_blob at kern_blob+0x%" PRIx64 "\n", now);

	/* Done */
	if (size_ptr)
		*size_ptr = kern_blob_size;

	return kern_blob;
}

static int Pack(const char *outfile,
		uint8_t *kernel_blob,
		uint64_t kernel_size,
		int version,
		uint64_t kernel_body_load_address,
		VbPrivateKey *signpriv_key)
{
	VbSignature *body_sig;
	FILE *f;
	uint64_t i;
	uint64_t written = 0;

	/* Sign the kernel data */
	body_sig = CalculateSignature(kernel_blob, kernel_size, signpriv_key);
	if (!body_sig)
		Fatal("Error calculating body signature\n");

	/* Create preamble */
	g_preamble = CreateKernelPreamble(version,
					  kernel_body_load_address,
					  g_bootloader_address,
					  roundup(g_bootloader_size,
						  CROS_ALIGN), body_sig,
					  opt_pad - g_keyblock->key_block_size,
					  signpriv_key);
	if (!g_preamble) {
		VbExError("Error creating preamble.\n");
		return 1;
	}
	/* Write the output file */
	Debug("writing %s...\n", outfile);
	f = fopen(outfile, "wb");
	if (!f) {
		VbExError("Can't open output file %s\n", outfile);
		return 1;
	}
	Debug("0x%" PRIx64 " bytes of key_block\n", g_keyblock->key_block_size);
	Debug("0x%" PRIx64 " bytes of preamble\n", g_preamble->preamble_size);
	i = ((1 != fwrite(g_keyblock, g_keyblock->key_block_size, 1, f)) ||
	     (1 != fwrite(g_preamble, g_preamble->preamble_size, 1, f)));
	if (i) {
		VbExError("Can't write output file %s\n", outfile);
		fclose(f);
		unlink(outfile);
		return 1;
	}
	written += g_keyblock->key_block_size;
	written += g_preamble->preamble_size;

	if (!opt_vblockonly) {
		Debug("0x%" PRIx64 " bytes of kern_blob\n", kernel_size);
		i = (1 != fwrite(kernel_blob, kernel_size, 1, f));
		if (i) {
			fclose(f);
			unlink(outfile);
			Fatal("Can't write output file %s\n", outfile);
		}
		written += kernel_size;
	}
	Debug("0x%" PRIx64 " bytes total\n", written);
	fclose(f);

	/* Success */
	return 0;
}

static int Verify(uint8_t *kernel_blob,
		  uint64_t kernel_size,
		  VbPublicKey *signpub_key,
		  const char *keyblock_outfile,
		  uint64_t min_version)
{
	VbPublicKey *data_key;
	RSAPublicKey *rsa;

	if (0 != KeyBlockVerify(g_keyblock, g_keyblock->key_block_size,
				signpub_key, (0 == signpub_key)))
		Fatal("Error verifying key block.\n");

	printf("Key block:\n");
	data_key = &g_keyblock->data_key;
	if (opt_verbose)
		printf("  Signature:           %s\n",
		       signpub_key ? "valid" : "ignored");
	printf("  Size:                0x%" PRIx64 "\n",
	       g_keyblock->key_block_size);
	printf("  Flags:               %" PRIu64 " ",
	       g_keyblock->key_block_flags);
	if (g_keyblock->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_0)
		printf(" !DEV");
	if (g_keyblock->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_1)
		printf(" DEV");
	if (g_keyblock->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_0)
		printf(" !REC");
	if (g_keyblock->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_1)
		printf(" REC");
	printf("\n");
	printf("  Data key algorithm:  %" PRIu64 " %s\n", data_key->algorithm,
	       (data_key->algorithm < kNumAlgorithms ?
		algo_strings[data_key->algorithm] : "(invalid)"));
	printf("  Data key version:    %" PRIu64 "\n", data_key->key_version);
	printf("  Data key sha1sum:    ");
	PrintPubKeySha1Sum(data_key);
	printf("\n");

	if (keyblock_outfile) {
		FILE *f = NULL;
		f = fopen(keyblock_outfile, "wb");
		if (!f)
			Fatal("Can't open key block file %s\n",
			      keyblock_outfile);
		if (1 != fwrite(g_keyblock, g_keyblock->key_block_size, 1, f))
			Fatal("Can't write key block file %s\n",
			      keyblock_outfile);
		fclose(f);
	}

	if (data_key->key_version < (min_version >> 16))
		Fatal("Data key version %" PRIu64
		      " is lower than minimum %" PRIu64 ".\n",
		      data_key->key_version, (min_version >> 16));

	rsa = PublicKeyToRSA(data_key);
	if (!rsa)
		Fatal("Error parsing data key.\n");

	/* Verify preamble */
	if (0 !=
	    VerifyKernelPreamble(g_preamble, g_preamble->preamble_size, rsa))
		Fatal("Error verifying preamble.\n");

	printf("Preamble:\n");
	printf("  Size:                0x%" PRIx64 "\n",
	       g_preamble->preamble_size);
	printf("  Header version:      %" PRIu32 ".%" PRIu32 "\n",
	       g_preamble->header_version_major,
	       g_preamble->header_version_minor);
	printf("  Kernel version:      %" PRIu64 "\n",
	       g_preamble->kernel_version);
	printf("  Body load address:   0x%" PRIx64 "\n",
	       g_preamble->body_load_address);
	printf("  Body size:           0x%" PRIx64 "\n",
	       g_preamble->body_signature.data_size);
	printf("  Bootloader address:  0x%" PRIx64 "\n",
	       g_preamble->bootloader_address);
	printf("  Bootloader size:     0x%" PRIx64 "\n",
	       g_preamble->bootloader_size);

	if (g_preamble->kernel_version < (min_version & 0xFFFF))
		Fatal("Kernel version %" PRIu64 " is lower than minimum %"
		      PRIu64 ".\n", g_preamble->kernel_version,
		      (min_version & 0xFFFF));

	/* Verify body */
	if (0 != VerifyData(kernel_blob, kernel_size,
			    &g_preamble->body_signature, rsa))
		Fatal("Error verifying kernel body.\n");
	printf("Body verification succeeded.\n");

	if (opt_verbose)
		printf("Config:\n%s\n",
		       kernel_blob + CmdLineOffset(g_preamble));

	return 0;
}

/****************************************************************************/

static int do_vbutil_kernel(int argc, char *argv[])
{
	char *filename = NULL;
	char *oldfile = NULL;
	char *keyblock_file = NULL;
	char *signpubkey_file = NULL;
	char *signprivkey_file = NULL;
	char *version_str = NULL;
	int version = -1;
	char *vmlinuz_file = NULL;
	char *bootloader_file = NULL;
	char *config_file = NULL;
	enum arch_t arch = ARCH_X86;
	char *address_str = NULL;
	uint64_t kernel_body_load_address = CROS_32BIT_ENTRY_ADDR;
	int mode = 0;
	int parse_error = 0;
	uint64_t min_version = 0;
	char *e;
	int i;
	VbPrivateKey *signpriv_key = NULL;
	VbPublicKey *signpub_key = NULL;
	uint8_t *kernel_blob = NULL;
	uint64_t kernel_size = 0;

	while (((i = getopt_long(argc, argv, ":", long_opts, NULL)) != -1) &&
	       !parse_error) {
		switch (i) {
		default:
		case '?':
			/* Unhandled option */
			parse_error = 1;
			break;

		case 0:
			/* silently handled option */
			break;

		case OPT_MODE_PACK:
		case OPT_MODE_REPACK:
		case OPT_MODE_VERIFY:
			if (mode && (mode != i)) {
				fprintf(stderr,
					"Only one mode can be specified\n");
				parse_error = 1;
				break;
			}
			mode = i;
			filename = optarg;
			break;

		case OPT_ARCH:
			/* check the first 3 characters to also detect x86_64 */
			if ((!strncasecmp(optarg, "x86", 3)) ||
			    (!strcasecmp(optarg, "amd64")))
				arch = ARCH_X86;
			else if ((!strcasecmp(optarg, "arm")) ||
				 (!strcasecmp(optarg, "aarch64")))
				arch = ARCH_ARM;
			else if (!strcasecmp(optarg, "mips"))
				arch = ARCH_MIPS;
			else {
				fprintf(stderr,
					"Unknown architecture string: %s\n",
					optarg);
				parse_error = 1;
			}
			break;

		case OPT_OLDBLOB:
			oldfile = optarg;
			break;

		case OPT_KLOADADDR:
			address_str = optarg;
			kernel_body_load_address = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr, "Invalid --kloadaddr\n");
				parse_error = 1;
			}
			break;

		case OPT_KEYBLOCK:
			keyblock_file = optarg;
			break;

		case OPT_SIGNPUBKEY:
			signpubkey_file = optarg;
			break;

		case OPT_SIGNPRIVATE:
			signprivkey_file = optarg;
			break;

		case OPT_VMLINUZ:
			vmlinuz_file = optarg;
			break;

		case OPT_BOOTLOADER:
			bootloader_file = optarg;
			break;

		case OPT_CONFIG:
			config_file = optarg;
			break;

		case OPT_VBLOCKONLY:
			opt_vblockonly = 1;
			break;

		case OPT_VERSION:
			version_str = optarg;
			version = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr, "Invalid --version\n");
				parse_error = 1;
			}
			break;

		case OPT_MINVERSION:
			min_version = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr, "Invalid --minversion\n");
				parse_error = 1;
			}
			break;

		case OPT_PAD:
			opt_pad = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr, "Invalid --pad\n");
				parse_error = 1;
			}
			break;
		}
	}

	if (parse_error) {
		print_help(argv[0]);
		return 1;
	}

	switch (mode) {
	case OPT_MODE_PACK:

		/* Required */

		if (!keyblock_file)
			Fatal("Missing required keyblock file.\n");

		g_keyblock = (VbKeyBlockHeader *) ReadFile(keyblock_file, 0);
		if (!g_keyblock)
			Fatal("Error reading key block.\n");

		if (!signprivkey_file)
			Fatal("Missing required signprivate file.\n");

		signpriv_key = PrivateKeyRead(signprivkey_file);
		if (!signpriv_key)
			Fatal("Error reading signing key.\n");

		/* Optional */

		if (config_file) {
			Debug("Reading %s\n", config_file);
			g_config_data =
			    sReadConfigFile(config_file, &g_config_size);
			if (!g_config_data)
				Fatal("Error reading config file.\n");
		}

		if (vmlinuz_file)
			if (!ImportVmlinuzFile
			    (vmlinuz_file, arch, kernel_body_load_address))
				Fatal("Error reading kernel file.\n");

		if (bootloader_file) {
			Debug("Reading %s\n", bootloader_file);
			g_bootloader_data =
			    ReadFile(bootloader_file, &g_bootloader_size);
			if (!g_bootloader_data)
				Fatal("Error reading bootloader file.\n");
			Debug(" bootloader file size=0x%" PRIx64 "\n",
			      g_bootloader_size);
		}

		/* Do it */

		kernel_blob = CreateKernBlob(kernel_body_load_address, arch,
					     &kernel_size);

		return Pack(filename, kernel_blob, kernel_size,
			    version, kernel_body_load_address, signpriv_key);

	case OPT_MODE_REPACK:

		/* Required */

		if (!signprivkey_file)
			Fatal("Missing required signprivate file.\n");

		signpriv_key = PrivateKeyRead(signprivkey_file);
		if (!signpriv_key)
			Fatal("Error reading signing key.\n");

		if (!oldfile)
			Fatal("Missing previously packed blob.\n");

		/* Load the old blob */

		kernel_blob = ReadOldBlobFromFileOrDie(oldfile, &kernel_size);
		if (0 != Verify(kernel_blob, kernel_size, 0, 0, 0))
			Fatal("The oldblob doesn't verify\n");

		/* Take it apart */

		UnpackKernelBlob(kernel_blob, kernel_size);
		free(kernel_blob);

		/* Load optional params */

		if (!version_str)
			version = g_preamble->kernel_version;

		if (!address_str)
			kernel_body_load_address =
			    g_preamble->body_load_address;

		if (config_file) {
			if (g_config_data)
				free(g_config_data);
			Debug("Reading %s\n", config_file);
			g_config_data =
			    sReadConfigFile(config_file, &g_config_size);
			if (!g_config_data)
				Fatal("Error reading config file.\n");
		}

		if (keyblock_file) {
			if (g_keyblock)
				free(g_keyblock);
			g_keyblock =
			    (VbKeyBlockHeader *) ReadFile(keyblock_file, 0);
			if (!g_keyblock)
				Fatal("Error reading key block.\n");
		}

		/* Put it back together */

		kernel_blob = CreateKernBlob(kernel_body_load_address, arch,
					     &kernel_size);

		return Pack(filename, kernel_blob, kernel_size,
			    version, kernel_body_load_address, signpriv_key);

	case OPT_MODE_VERIFY:

		/* Optional */

		if (signpubkey_file) {
			signpub_key = PublicKeyRead(signpubkey_file);
			if (!signpub_key)
				Fatal("Error reading public key.\n");
		}

		/* Do it */

		kernel_blob = ReadOldBlobFromFileOrDie(filename, &kernel_size);

		return Verify(kernel_blob, kernel_size, signpub_key,
			      keyblock_file, min_version);
	}

	fprintf(stderr,
		"You must specify a mode: --pack, --repack or --verify\n");
	print_help(argv[0]);
	return 1;
}

DECLARE_FUTIL_COMMAND(vbutil_kernel, do_vbutil_kernel,
		      "Creates, signs, and verifies the kernel blob",
		      print_help);
