/* Copyright (c) 2011 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 <getopt.h>
#include <inttypes.h>  /* For PRIu64 */
#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 opt */
static int opt_debug = 0;

static const int DEFAULT_PADDING = 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,
};

enum {
  ARCH_ARM,
  ARCH_X86 /* default */
};

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, 0,                   OPT_VERBOSE                 },
  {"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, 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 (of --keyblock, --config, and --version \n"
          "    at least one is required):\n"
          "    --keyblock <file>         Key block in .keyblock format\n"
          "    --signprivate <file>"
          "      Private key to sign kernel data, in .vbprivk format\n"
          "    --oldblob <file>          Previously packed kernel blob\n"
          "    --config <file>           New command line file\n"
          "    --version <number>        Kernel version\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 --verify <file> [PARAMETERS]\n"
          "\n"
          "  Optional:\n"
          "    --signpubkey <file>"
          "       Public key to verify kernel keyblock, in .vbpubk format\n"
          "    --verbose                 Print a more detailed report\n"
          "    --keyblock <file>"
          "         Outputs the verified key block, in .keyblock format\n"
          "    --kloadaddr <address>     Assign kernel body load address\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);
}


/* 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;
}


typedef struct blob_s {
  /* Stuff needed by VbKernelPreambleHeader */
  uint64_t kernel_version;
  uint64_t bootloader_address;
  uint64_t bootloader_size;
  /* Raw kernel blob data */
  uint64_t blob_size;
  uint8_t *blob;

  /* these fields are not always initialized */
  VbKernelPreambleHeader* preamble;
  VbKeyBlockHeader* key_block;
  uint8_t *buf;

} blob_t;

/* Given a blob return the location of the kernel command line buffer. */
static char* BpCmdLineLocation(blob_t *bp, uint64_t kernel_body_load_address)
{
  return (char*)(bp->blob + bp->bootloader_address - kernel_body_load_address -
                 CROS_CONFIG_SIZE - CROS_PARAMS_SIZE);
}

static void FreeBlob(blob_t *bp) {
  if (bp) {
    if (bp->blob)
      free(bp->blob);
    if (bp->buf)
      free(bp->buf);
    free(bp);
  }
}

/*
 * 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;
}

/* Create a blob from its components */
static blob_t *NewBlob(uint64_t version,
                       const char* vmlinuz,
                       const char* bootloader_file,
                       const char* config_file,
                       int arch,
                       uint64_t kernel_body_load_address) {
  blob_t* bp;
  struct linux_kernel_header* lh = 0;
  struct linux_kernel_params* params = 0;
  uint8_t* config_buf;
  uint64_t config_size;
  uint8_t* bootloader_buf;
  uint64_t bootloader_size;
  uint8_t* kernel_buf;
  uint64_t kernel_size;
  uint64_t kernel32_start = 0;
  uint64_t kernel32_size = 0;
  uint32_t cmdline_addr;
  uint8_t* blob = NULL;
  uint64_t now = 0;

  if (!vmlinuz || !bootloader_file || !config_file) {
    VbExError("Must specify all input files\n");
    return 0;
  }

  bp = (blob_t *)malloc(sizeof(blob_t));
  if (!bp) {
    VbExError("Couldn't allocate bytes for blob_t.\n");
    return 0;
  }

  Memset(bp, 0, sizeof(*bp));
  bp->kernel_version = version;

  /* Read the config file */
  Debug("Reading %s\n", config_file);
  config_buf = ReadConfigFile(config_file, &config_size);
  if (!config_buf)
    return 0;

  /* Read the bootloader */
  Debug("Reading %s\n", bootloader_file);
  bootloader_buf = ReadFile(bootloader_file, &bootloader_size);
  if (!bootloader_buf)
    return 0;
  Debug(" bootloader file size=0x%" PRIx64 "\n", bootloader_size);

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

  if (arch == ARCH_X86) {
    /* The first part of vmlinuz is a header, followed by a real-mode
     * boot stub.  We only want the 32-bit part. */
    lh = (struct linux_kernel_header *)kernel_buf;
    kernel32_start = (lh->setup_sects + 1) << 9;
    if (kernel32_start >= kernel_size) {
      VbExError("Malformed kernel\n");
      return 0;
    }
  } else
    kernel32_start = 0;
  kernel32_size = kernel_size - kernel32_start;
  Debug(" kernel32_start=0x%" PRIx64 "\n", kernel32_start);
  Debug(" kernel32_size=0x%" PRIx64 "\n", kernel32_size);

  /* Allocate and zero the blob we need. */
  bp->blob_size = roundup(kernel32_size, CROS_ALIGN) +
      CROS_CONFIG_SIZE +
      CROS_PARAMS_SIZE +
      roundup(bootloader_size, CROS_ALIGN);
  blob = (uint8_t *)malloc(bp->blob_size);
  Debug("blob_size=0x%" PRIx64 "\n", bp->blob_size);
  if (!blob) {
    VbExError("Couldn't allocate %ld bytes.\n", bp->blob_size);
    return 0;
  }
  Memset(blob, 0, bp->blob_size);
  bp->blob = blob;

  /* Copy the 32-bit kernel. */
  Debug("kernel goes at blob+=0x%" PRIx64 "\n", now);
  if (kernel32_size)
    Memcpy(blob + now, kernel_buf + kernel32_start, kernel32_size);
  now += roundup(now + kernel32_size, CROS_ALIGN);

  Debug("config goes at blob+0x%" PRIx64 "\n", now);
  /* Find the load address of the commandline. We'll need it later. */
  cmdline_addr = kernel_body_load_address + now +
      find_cmdline_start((char *)config_buf, config_size);
  Debug(" cmdline_addr=0x%" PRIx64 "\n", cmdline_addr);

  /* Copy the config. */
  if (config_size)
    Memcpy(blob + now, config_buf, config_size);
  now += CROS_CONFIG_SIZE;

  /* The zeropage data is next. Overlay the linux_kernel_header onto it, and
   * tweak a few fields. */
  Debug("params goes at blob+=0x%" PRIx64 "\n", now);
  params = (struct linux_kernel_params *)(blob + now);
  if (arch == ARCH_X86)
    Memcpy(&(params->setup_sects), &(lh->setup_sects),
           sizeof(*lh) - offsetof(struct linux_kernel_header, setup_sects));
  else
    Memset(&(params->setup_sects), 0,
           sizeof(*lh) - offsetof(struct linux_kernel_header, setup_sects));
  params->boot_flag = 0;
  params->ramdisk_image = 0;             /* we don't support initrd */
  params->ramdisk_size = 0;
  params->type_of_loader = 0xff;
  params->cmd_line_ptr = cmdline_addr;
  /* 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;
  now += CROS_PARAMS_SIZE;

  /* Finally, append the bootloader. Remember where it will load in
   * memory, too. */
  Debug("bootloader goes at blob+=0x%" PRIx64 "\n", now);
  bp->bootloader_address = kernel_body_load_address + now;
  bp->bootloader_size = roundup(bootloader_size, CROS_ALIGN);
  Debug(" bootloader_address=0x%" PRIx64 "\n", bp->bootloader_address);
  Debug(" bootloader_size=0x%" PRIx64 "\n", bp->bootloader_size);
  if (bootloader_size)
    Memcpy(blob + now, bootloader_buf, bootloader_size);
  now += bp->bootloader_size;
  Debug("end of blob is 0x%" PRIx64 "\n", now);

  /* Free input buffers */
  free(kernel_buf);
  free(config_buf);
  free(bootloader_buf);

  /* Success */
  return bp;
}


/* Pull the blob_t stuff out of a prepacked kernel blob file */
static blob_t *OldBlob(const char* filename, uint64_t pad) {
  FILE* fp = NULL;
  blob_t *bp = NULL;
  struct stat statbuf;
  VbKeyBlockHeader* key_block;
  VbKernelPreambleHeader* preamble;
  uint64_t now = 0;
  uint8_t* buf = NULL;
  int ret_error = 1;

  if (!filename) {
    VbExError("Must specify prepacked blob to read\n");
    return 0;
  }

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

  Debug("%s size is 0x%" PRIx64 "\n", filename, statbuf.st_size);
  if (statbuf.st_size < pad) {
    VbExError("%s is too small to be a valid kernel blob\n");
    return 0;
  }

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

  buf = malloc(pad);
  if (!buf) {
    VbExError("Unable to allocate padding\n");
    goto unwind_oldblob;
  }

  if (1 != fread(buf, pad, 1, fp)) {
    VbExError("Unable to read header from %s: %s\n", filename, error_fread(fp));
    goto unwind_oldblob;
  }

  /* Skip 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 > statbuf.st_size) {
    VbExError("key_block_size advances past the end of the blob\n");
    goto unwind_oldblob;
  }
  if (now > pad) {
    VbExError("key_block_size advances past %" PRIu64 " byte padding\n", pad);
    goto unwind_oldblob;
  }

  /* Skip the preamble */
  preamble = (VbKernelPreambleHeader*)(buf + now);
  Debug("Preamble is 0x%" PRIx64 " bytes\n", preamble->preamble_size);
  now += preamble->preamble_size;
  if (now > statbuf.st_size) {
    VbExError("preamble_size advances past the end of the blob\n");
    goto unwind_oldblob;
  }
  if (now > pad) {
    VbExError("preamble_size advances past %" PRIu64 " byte padding\n", pad);
    goto unwind_oldblob;
  }

  /* Go find the kernel blob */
  Debug("kernel blob is at offset 0x%" PRIx64 "\n", now);
  if (0 != fseek(fp, now, SEEK_SET)) {
    VbExError("Unable to seek to 0x%" PRIx64 " in %s: %s\n", now, filename,
          strerror(errno));
    goto unwind_oldblob;
  }

  /* Remember what we've got */
  bp = (blob_t *)malloc(sizeof(blob_t));
  if (!bp) {
    VbExError("Couldn't allocate bytes for blob_t.\n");
    goto unwind_oldblob;
  }

  bp->buf = buf;
  bp->key_block = key_block;
  bp->preamble = preamble;

  bp->kernel_version = preamble->kernel_version;
  bp->bootloader_address = preamble->bootloader_address;
  bp->bootloader_size = preamble->bootloader_size;
  bp->blob_size = preamble->body_signature.data_size;

  Debug(" kernel_version = %d\n", bp->kernel_version);
  Debug(" bootloader_address = 0x%" PRIx64 "\n", bp->bootloader_address);
  Debug(" bootloader_size = 0x%" PRIx64 "\n", bp->bootloader_size);
  Debug(" blob_size = 0x%" PRIx64 "\n", bp->blob_size);

  if (!bp->blob_size) {
    VbExError("No kernel blob found\n");
    goto unwind_oldblob;
  }

  bp->blob = (uint8_t *)malloc(bp->blob_size);
  if (!bp->blob) {
    VbExError("Couldn't allocate 0x%" PRIx64 " bytes for blob_t.\n",
              bp->blob_size);
    goto unwind_oldblob;
  }

  /* read it in */
  if (1 != fread(bp->blob, bp->blob_size, 1, fp)) {
    VbExError("Unable to read kernel blob from %s: %s\n", filename,
              error_fread(fp));
    goto unwind_oldblob;
  }

  ret_error = 0;

  /* done */
unwind_oldblob:
  fclose(fp);
  if (ret_error) {
    if (bp) {
      FreeBlob(bp);
      bp = NULL;
    } else if (buf) {
      free(buf);
    }
  }
  return bp;
}


/* Pack a .kernel */
static int Pack(const char* outfile, const char* keyblock_file,
                const char* signprivate, blob_t *bp, uint64_t pad,
                int vblockonly,
                uint64_t kernel_body_load_address) {
  VbPrivateKey* signing_key;
  VbSignature* body_sig;
  VbKernelPreambleHeader* preamble;
  VbKeyBlockHeader* key_block;
  uint64_t key_block_size;
  FILE* f;
  uint64_t i;

  if (!outfile) {
    VbExError("Must specify output filename\n");
    return 1;
  }
  if ((!keyblock_file && !bp->key_block) || !signprivate) {
    VbExError("Must specify all keys\n");
    return 1;
  }
  if (!bp) {
    VbExError("Refusing to pack invalid kernel blob\n");
    return 1;
  }

  /* Get the key block and read the private key. */
  if (keyblock_file) {
    key_block = (VbKeyBlockHeader*)ReadFile(keyblock_file, &key_block_size);
    if (!key_block) {
      VbExError("Error reading key block.\n");
      return 1;
    }
  } else {
    key_block = bp->key_block;
    key_block_size = key_block->key_block_size;
  }

  if (pad < key_block->key_block_size) {
    VbExError("Pad too small\n");
    return 1;
  }

  signing_key = PrivateKeyRead(signprivate);
  if (!signing_key) {
    VbExError("Error reading signing key.\n");
    return 1;
  }

  /* Sign the kernel data */
  body_sig = CalculateSignature(bp->blob, bp->blob_size, signing_key);
  if (!body_sig) {
    VbExError("Error calculating body signature\n");
    return 1;
  }

  /* Create preamble */
  preamble = CreateKernelPreamble(bp->kernel_version,
                                  kernel_body_load_address,
                                  bp->bootloader_address,
                                  bp->bootloader_size,
                                  body_sig,
                                  pad - key_block_size,
                                  signing_key);
  if (!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", key_block_size);
  Debug("0x%" PRIx64 " bytes of preamble\n", preamble->preamble_size);
  i = ((1 != fwrite(key_block, key_block_size, 1, f)) ||
       (1 != fwrite(preamble, preamble->preamble_size, 1, f)));
  if (i) {
    VbExError("Can't write output file %s\n", outfile);
    fclose(f);
    unlink(outfile);
    return 1;
  }

  if (!vblockonly) {
    Debug("0x%" PRIx64 " bytes of blob\n", bp->blob_size);
    i = (1 != fwrite(bp->blob, bp->blob_size, 1, f));
    if (i) {
      VbExError("Can't write output file %s\n", outfile);
      fclose(f);
      unlink(outfile);
      return 1;
    }
  }

  fclose(f);

  /* Success */
  return 0;
}

/*
 * Replace kernel command line in a blob representing a kernel.
 */
static int ReplaceConfig(blob_t* bp, const char* config_file,
    uint64_t kernel_body_load_address)
{
  uint8_t* new_conf;
  uint64_t config_size;

  if (!config_file) {
    return 0;
  }

  new_conf = ReadConfigFile(config_file, &config_size);
  if (!new_conf) {
    return 1;
  }

  /* fill the config buffer with zeros */
  Memset(BpCmdLineLocation(bp, kernel_body_load_address), 0, CROS_CONFIG_SIZE);
  Memcpy(BpCmdLineLocation(bp, kernel_body_load_address),
      new_conf, config_size);
  free(new_conf);
  return 0;
}

static int Verify(const char* infile, const char* signpubkey, int verbose,
                  const char* key_block_file,
                  uint64_t kernel_body_load_address, uint64_t min_version,
                  uint64_t pad) {

  VbKeyBlockHeader* key_block;
  VbKernelPreambleHeader* preamble;
  VbPublicKey* data_key;
  VbPublicKey* sign_key = NULL;
  RSAPublicKey* rsa;
  blob_t* bp;
  uint64_t now;
  int rv = 1;

  if (!infile) {
    VbExError("Must specify filename\n");
    return 1;
  }

  /* Read public signing key */
  if (signpubkey) {
    sign_key = PublicKeyRead(signpubkey);
    if (!sign_key) {
      VbExError("Error reading signpubkey.\n");
      return 1;
    }
  }

  /* Read blob */
  bp = OldBlob(infile, pad);
  if (!bp) {
    VbExError("Error reading input file\n");
    return 1;
  }

  /* Verify key block */
  key_block = bp->key_block;
  if (0 != KeyBlockVerify(key_block, bp->blob_size, sign_key,
                          (sign_key ? 0 : 1))) {
    VbExError("Error verifying key block.\n");
    goto verify_exit;
  }
  now = key_block->key_block_size;

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

  printf("Key block:\n");
  data_key = &key_block->data_key;
  if (verbose)
    printf("  Signature:           %s\n", sign_key ? "valid" : "ignored");
  printf("  Size:                0x%" PRIx64 "\n", key_block->key_block_size);
  printf("  Flags:               %" PRIu64 " ", key_block->key_block_flags);
  if (key_block->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_0)
    printf(" !DEV");
  if (key_block->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_1)
    printf(" DEV");
  if (key_block->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_0)
    printf(" !REC");
  if (key_block->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 (data_key->key_version < (min_version >> 16)) {
    VbExError("Data key version %" PRIu64
              " is lower than minimum %" PRIu64".\n",
              data_key->key_version, (min_version >> 16));
    goto verify_exit;
  }

  rsa = PublicKeyToRSA(&key_block->data_key);
  if (!rsa) {
    VbExError("Error parsing data key.\n");
    goto verify_exit;
  }

  /* Verify preamble */
  preamble = bp->preamble;
  if (0 != VerifyKernelPreamble(
        preamble, bp->blob_size - key_block->key_block_size, rsa)) {
    VbExError("Error verifying preamble.\n");
    goto verify_exit;
  }
  now += preamble->preamble_size;

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

  if (preamble->kernel_version < (min_version & 0xFFFF)) {
    VbExError("Kernel version %" PRIu64 " is lower than minimum %" PRIu64 ".\n",
              preamble->kernel_version, (min_version & 0xFFFF));
    goto verify_exit;
  }

  /* Verify body */
  if (0 != VerifyData(bp->blob, bp->blob_size, &preamble->body_signature,
                      rsa)) {
    VbExError("Error verifying kernel body.\n");
    goto verify_exit;
  }
  printf("Body verification succeeded.\n");

  rv = 0;

  if (!verbose) {
    goto verify_exit;
  }

  printf("Config:\n%s\n", BpCmdLineLocation(bp, kernel_body_load_address));

verify_exit:
  FreeBlob(bp);
  return rv;
}


int main(int argc, char* argv[]) {
  char* filename = NULL;
  char* oldfile = NULL;
  char* key_block_file = NULL;
  char* signpubkey = NULL;
  char* signprivate = NULL;
  int version = -1;
  char* vmlinuz = NULL;
  char* bootloader = NULL;
  char* config_file = NULL;
  int arch = ARCH_X86;
  int vblockonly = 0;
  int verbose = 0;
  uint64_t kernel_body_load_address = CROS_32BIT_ENTRY_ADDR;
  uint64_t pad = DEFAULT_PADDING;
  int mode = 0;
  int parse_error = 0;
  uint64_t min_version = 0;
  char* e;
  int i,r;
  blob_t *bp;


  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 single mode can be specified\n");
          parse_error = 1;
          break;
        }
        mode = i;
        filename = optarg;
        break;

      case OPT_ARCH:
        if (!strcasecmp(optarg, "x86"))
          arch = ARCH_X86;
        else if (!strcasecmp(optarg, "arm"))
          arch = ARCH_ARM;
        else {
          fprintf(stderr, "Unknown architecture string: %s\n", optarg);
          parse_error = 1;
        }
        break;

      case OPT_OLDBLOB:
        oldfile = optarg;
        break;

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

      case OPT_KEYBLOCK:
        key_block_file = optarg;
        break;

      case OPT_SIGNPUBKEY:
        signpubkey = optarg;
        break;

      case OPT_SIGNPRIVATE:
        signprivate = optarg;
        break;

      case OPT_VMLINUZ:
        vmlinuz = optarg;
        break;

      case OPT_BOOTLOADER:
        bootloader = optarg;
        break;

      case OPT_CONFIG:
        config_file = optarg;
        break;

      case OPT_VBLOCKONLY:
        vblockonly = 1;
        break;

      case OPT_VERSION:
        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:
        pad = strtoul(optarg, &e, 0);
        if (!*optarg || (e && *e)) {
          fprintf(stderr, "Invalid --pad\n");
          parse_error = 1;
        }
        break;

      case OPT_VERBOSE:
        verbose = 1;
        break;
    }
  }

  if (parse_error)
    return PrintHelp(progname);

  switch(mode) {
    case OPT_MODE_PACK:
      bp = NewBlob(version, vmlinuz, bootloader, config_file, arch,
          kernel_body_load_address);
      if (!bp)
        return 1;
      r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly,
          kernel_body_load_address);
      FreeBlob(bp);
      return r;

    case OPT_MODE_REPACK:
      if (!config_file && !key_block_file && (version<0)) {
        fprintf(stderr,
                "You must supply at least one of "
                "--config, --keyblock or --version\n");
        return 1;
      }

      bp = OldBlob(oldfile, pad);
      if (!bp)
        return 1;
      r = ReplaceConfig(bp, config_file, kernel_body_load_address);
      if (!r) {
        if (version >= 0) {
          bp->kernel_version = (uint64_t) version;
        }
        r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly,
            kernel_body_load_address);
      }
      FreeBlob(bp);
      return r;

    case OPT_MODE_VERIFY:
      return Verify(filename, signpubkey, verbose, key_block_file,
                    kernel_body_load_address, min_version, pad);

    default:
      fprintf(stderr,
              "You must specify a mode: --pack, --repack or --verify\n");
      return PrintHelp(progname);
  }
}
