/* Copyright (c) 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 "host_common.h"
#include "kernel_blob.h"
#include "vboot_common.h"

/* Global opts */
static int opt_debug = 0;
static int opt_verbose = 0;
static int opt_vblockonly = 0;
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,
};

typedef enum {
  ARCH_ARM,
  ARCH_X86, /* default */
  ARCH_MIPS
} arch_t;

static 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, &opt_debug, 1                                      },
  {NULL, 0, 0, 0}
};


/* Print help and return error */
static int PrintHelp(char *progname) {
  fprintf(stderr,
          "This program creates, signs, and verifies the kernel blob\n");
  fprintf(stderr,
          "\n"
          "Usage:  %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",
          progname);
  fprintf(stderr,
          "\nOR\n\n"
          "Usage:  %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",
          progname);
  fprintf(stderr,
          "\nOR\n\n"
          "Usage:  %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",
          progname);
  return 1;
}

static void Debug(const char *format, ...) {
  if (!opt_debug)
    return;

  va_list ap;
  va_start(ap, format);
  fprintf(stderr, "DEBUG: ");
  vfprintf(stderr, format, ap);
  va_end(ap);
}

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]) {  /* found a "--" */
      if ((i == 0 || ' ' == input[i - 1]) &&   /* nothing before it */
          (i + 2 >= max_len || ' ' == input[i+2])) {  /* nothing after it */
        start = i+2;          /* note: hope there's 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 */
uint8_t *g_kernel_data;
uint64_t g_kernel_size;
uint8_t *g_param_data;
uint64_t g_param_size;
uint8_t *g_config_data;
uint64_t g_config_size;
uint8_t *g_bootloader_data;
uint64_t g_bootloader_size;
uint64_t g_bootloader_address;


/* The individual parts of the verification blob (including the data that
 * immediately follows the headers) */
VbKeyBlockHeader* g_keyblock;
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* ReadConfigFile(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) {  /* need 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, 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, so 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;

    if ((fd = open(filename, O_RDONLY)) >= 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* CreateKernelBlob(uint64_t kernel_body_load_address,
                                 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;
}

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

int main(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;
  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;

  char *progname = strrchr(argv[0], '/');
  if (progname)
    progname++;
  else
    progname = argv[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 a single 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"))
        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)
    return PrintHelp(progname);

  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 = ReadConfigFile(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 = CreateKernelBlob(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 = ReadConfigFile(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 = CreateKernelBlob(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");
  return PrintHelp(progname);
}
