/* 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 utility for EC firmware
 */

#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "cryptolib.h"
#include "fmap.h"
#include "host_common.h"
#include "vboot_common.h"


/* Command line options */
enum {
  OPT_MODE_SIGN = 1000,
  OPT_MODE_VERIFY,
  OPT_KEYBLOCK,
  OPT_SIGNPUBKEY,
  OPT_SIGNPRIVATE,
  OPT_VERSION,
  OPT_FV,
  OPT_KERNELKEY,
  OPT_FLAGS,
  OPT_NAME,
};

static struct option long_opts[] = {
  {"sign", 1, 0,                      OPT_MODE_SIGN               },
  {"verify", 1, 0,                    OPT_MODE_VERIFY             },
  {"keyblock", 1, 0,                  OPT_KEYBLOCK                },
  {"signpubkey", 1, 0,                OPT_SIGNPUBKEY              },
  {"signprivate", 1, 0,               OPT_SIGNPRIVATE             },
  {"version", 1, 0,                   OPT_VERSION                 },
  {"flags", 1, 0,                     OPT_FLAGS                   },
  {"name", 1, 0,                      OPT_NAME                    },
  {NULL, 0, 0, 0}
};


/* Print help and return error */
static int PrintHelp(void) {

  puts("vbutil_ec - Verified boot signing utility for EC firmware\n"
       "\n"
       "This will sign, re-sign, or test a complete EC firmware image.\n"
       "The EC image is initially completely unsigned. To make it bootable\n"
       "the pubic root key must be installed in the RO section, and each RW\n"
       "section must be signed with the appropriate private keys.\n"
       "\n"
       "To sign an image:   vbutil_ec --sign <file> [OPTIONS]\n"
       "\n"
       "For signing, these options are required:\n"
       "\n"
       "  --keyblock <file>           Key block in .keyblock format\n"
       "  --signprivate <file>        Signing private key in .vbprivk format\n"
       "  --version <number>          Firmware version\n"
       "\n"
       "If the RO public key has not been installed, you will also need\n"
       "\n"
       "  --signpubkey <file>         Signing public key in .vbpubk format\n"
       "\n"
       "Optional args are:\n"
       "\n"
       "  --flags <number>            Preamble flags (defaults to 0)\n"
       "  --name <string>             Human-readable description\n"
       "\n"
       "\n"
       "To verify an image:   vbutil_ec --verify <file>\n"
       "\n");
  return 1;
}


static int FindInFmap(FmapHeader *fh, const char *name,
                      uint8_t *base, uint64_t base_size,
                      uint8_t **data, uint64_t *size) {
  const FmapAreaHeader *ah;
  int i;

  ah = (FmapAreaHeader *)(fh + 1);
  for (i = 0; i < fh->fmap_nareas; i++)
    if (!strncmp(ah[i].area_name, name, FMAP_NAMELEN)) {
      if (ah[i].area_size + ah[i].area_offset > base_size) {
        printf("FMAP region %s extends off image file\n", name);
        return 0;
      }
      if (data)
        *data = base + ah[i].area_offset;
      if (size)
        *size = ah[i].area_size;
      return 1;
    }

  return 0;
}

static int GoodKey(VbPublicKey *key, uint64_t region_size)
{
  uint64_t key_size;

  if (0 != VerifyPublicKeyInside(key, region_size, key))
    return 0;

  if (key->algorithm >= kNumAlgorithms)
    return 0;

  /* Currently, TPM only supports 16-bit version */
  if (key->key_version > 0xFFFF)
    return 0;

  if (!RSAProcessedKeySize(key->algorithm, &key_size) ||
      key_size != key->key_size)
    return 0;

  return 1;
}


/* We build the image file with a non-FF byte at the end of each RW firmware,
 * just so we can do this. */
static uint64_t FindImageEnd(uint8_t *data, uint64_t size)
{
  for (size-- ; size && data[size] == 0xff; size--)
    ;
  return size;
}

static void SignImage(const char *filename,
                      VbKeyBlockHeader *key_block, uint64_t key_block_size,
                      VbPrivateKey *privkey, uint64_t version,
                      VbPublicKey *pubkey, uint32_t preamble_flags,
                      const char *name) {
  struct stat sb;
  int fd;
  void *image;
  uint64_t image_size;
  FmapHeader* fmap;
  VbECPreambleHeader *preamble;
  uint8_t *fv_data = 0;
  uint8_t *vblock_data = 0;
  uint64_t fv_size, vblock_size;
  VbSignature* body_digest;

  if (name && strlen(name)+1 > sizeof(preamble->name))
    VbExError("Name string is too long\n");

  if (0 != stat(filename, &sb))
    VbExError("Can't stat %s: %s\n", filename, strerror(errno));

  fd = open(filename, O_RDWR);
  if (fd < 0)
    VbExError("Can't open %s: %s\n", filename, strerror(errno));

  image = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  if (image == (void *)-1)
    VbExError("Can't mmap %s: %s\n", filename, strerror(errno));
  close(fd);                            /* done with this now */

  fmap = (FmapHeader *)FmapFind(image, sb.st_size);
  if (!fmap)
    VbExError("File %s doesn't have an FMAP - can't continue.\n");

  if (fmap->fmap_size > sb.st_size)
    VbExError("FMAP is bigger than file size (%ld vs %ld)\n",
              fmap->fmap_size, sb.st_size);

  image_size = sb.st_size;

  /* Install pubkey if provided */
  if (pubkey) {
    if (!FindInFmap(fmap, "ROOT_KEY", image, image_size,
                    &vblock_data, &vblock_size))
      VbExError("Can't find ROOT_KEY in %s\n", filename);

    if (pubkey->key_offset + pubkey->key_size > vblock_size)
      VbExError("ROOT_KEY is too small for pubkey (%d bytes, needs %d)\n",
                vblock_size, pubkey->key_offset + pubkey->key_size);

    memcpy(vblock_data, pubkey, pubkey->key_offset + pubkey->key_size);
  }


  /* Sign FW A */
  if (!FindInFmap(fmap, "FW_MAIN_A", image, image_size, &fv_data, &fv_size))
    VbExError("Can't find FW_MAIN_A in %s\n", filename);

  if (!FindInFmap(fmap, "VBLOCK_A", image, image_size,
                  &vblock_data, &vblock_size))
    VbExError("Can't find VBLOCK_A in %s\n", filename);

  fv_size = FindImageEnd(fv_data, fv_size);

  body_digest = CalculateHash(fv_data, fv_size, privkey);
  if (!body_digest)
    VbExError("Error calculating body digest\n");

  preamble = CreateECPreamble(version, body_digest, privkey,
                              preamble_flags, name);
  if (!preamble)
    VbExError("Error creating preamble.\n");

  if (key_block_size + preamble->preamble_size > vblock_size)
    VbExError("VBLOCK_A is too small for digest (%d bytes, needs %d)\n",
              vblock_size, key_block_size + preamble->preamble_size);

  memcpy(vblock_data, key_block, key_block_size);
  memcpy(vblock_data + key_block_size, preamble, preamble->preamble_size);

  free(body_digest);
  free(preamble);


  /* Sign FW B - skip if there isn't one */
  if (!FindInFmap(fmap, "FW_MAIN_B", image, image_size, &fv_data, &fv_size) ||
      !FindInFmap(fmap, "VBLOCK_B", image, image_size,
                  &vblock_data, &vblock_size)) {
    printf("Image does not contain FW B - ignoring that part\n");
  } else {
    fv_size = FindImageEnd(fv_data, fv_size);

    body_digest = CalculateHash(fv_data, fv_size, privkey);
    if (!body_digest)
      VbExError("Error calculating body digest\n");

    preamble = CreateECPreamble(version, body_digest, privkey,
                                preamble_flags, name);
    if (!preamble)
      VbExError("Error creating preamble.\n");

    if (key_block_size + preamble->preamble_size > vblock_size)
      VbExError("VBLOCK_B is too small for digest (%d bytes, needs %d)\n",
                vblock_size, key_block_size + preamble->preamble_size);

    memcpy(vblock_data, key_block, key_block_size);
    memcpy(vblock_data + key_block_size, preamble, preamble->preamble_size);

    free(body_digest);
    free(preamble);
  }

  /* Unmap to write changes to disk. */
  if (0 != munmap(image, sb.st_size))
    VbExError("Can't munmap %s: %s\n", filename, strerror(errno));

  printf("Image signing completed\n");

}

static int Verify(const char *filename) {
  struct stat sb;
  int fd;
  void *image;
  uint64_t image_size;
  FmapHeader* fmap;
  VbECPreambleHeader *preamble;
  VbPublicKey *pubkey;
  uint64_t pubkey_size;
  VbKeyBlockHeader *key_block;
  uint64_t key_block_size;
  uint8_t *fv_data = 0;
  uint64_t fv_size;
  VbPublicKey *data_key;
  RSAPublicKey* rsa;
  int errorcnt = 0;
  char buf[80];
  int i;

  if (0 != stat(filename, &sb))
    VbExError("Can't stat %s: %s\n", filename, strerror(errno));

  fd = open(filename, O_RDONLY);
  if (fd < 0)
    VbExError("Can't open %s: %s\n", filename, strerror(errno));

  image = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  if (image == (void *)-1)
    VbExError("Can't mmap %s: %s\n", filename, strerror(errno));
  close(fd);                            /* done with this now */

  fmap = (FmapHeader *)FmapFind(image, sb.st_size);
  if (!fmap)
    VbExError("File %s doesn't have an FMAP - can't continue.\n");

  if (fmap->fmap_size > sb.st_size)
    VbExError("FMAP is bigger than file size (%ld vs %ld)\n",
              fmap->fmap_size, sb.st_size);

  image_size = sb.st_size;

  /* Read pubkey */
  if (!FindInFmap(fmap, "ROOT_KEY", image, image_size,
                  (uint8_t **)&pubkey, &pubkey_size)) {
    printf("Can't find ROOT_KEY in %s\n", filename);
    errorcnt++;
  } else if (!GoodKey(pubkey, pubkey_size)) {
    printf("ROOT_KEY is invalid\n");
    errorcnt++;
  } else {
    printf("ROOT_KEY\n");
    printf("  Algorithm:         %" PRIu64 " %s\n", pubkey->algorithm,
           (pubkey->algorithm < kNumAlgorithms ?
            algo_strings[pubkey->algorithm] : "(invalid)"));
    printf("  Key Version:       %" PRIu64 "\n", pubkey->key_version);
    printf("  Key sha1sum:       ");
    PrintPubKeySha1Sum(pubkey);
    printf("\n");
  }

  for (i = 'A'; i <= 'B'; i++) {

    fv_data = 0;
    key_block = 0;
    preamble = 0;

    printf("FW %c\n", i);
    sprintf(buf, "FW_MAIN_%c", i);
    if (!FindInFmap(fmap, buf, image, image_size, &fv_data, &fv_size)) {
      printf("Can't find %s in %s\n", buf, filename);
      /* Not an error for firmware B */
      if (i != 'B')
        errorcnt++;
      continue;
    }

    sprintf(buf, "VBLOCK_%c", i);
    if (!FindInFmap(fmap, buf, image, image_size,
                    (uint8_t **)&key_block, &key_block_size)) {
      printf("Can't find %s in %s\n", buf, filename);
      /* Not an error for firmware B */
      if (i != 'B')
        errorcnt++;
      continue;
    }

    if (0 != KeyBlockVerify(key_block, key_block_size, pubkey, !pubkey)) {
      printf("Error verifying key block for %s.\n", buf);
      errorcnt++;
      continue;
    }
    printf("  Key block:\n");
    data_key = &key_block->data_key;
    printf("    Size:                %" PRIu64 "\n",
           key_block->key_block_size);
    printf("    Flags:               %" PRIu64 " (ignored)\n",
           key_block->key_block_flags);
    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");

    preamble = (VbECPreambleHeader*)
      ((uint8_t *)key_block + key_block->key_block_size);

    rsa = PublicKeyToRSA(&key_block->data_key);
    if (!rsa) {
      printf("Error parsing data key.\n");
      errorcnt++;
    }
    /* Verify preamble */
    if (0 != VerifyECPreamble(preamble,
                              key_block_size - key_block->key_block_size,
                              rsa)) {
      printf("Error verifying preamble.\n");
      errorcnt++;
      free(rsa);
      continue;
    }
    printf("  Preamble:\n");
    printf("    Size:                  %" PRIu64 "\n",
           preamble->preamble_size);
    printf("    Header version:        %" PRIu32 ".%" PRIu32"\n",
           preamble->header_version_major,
           preamble->header_version_minor);
    printf("    Firmware version:      %" PRIu64 "\n",
           preamble->firmware_version);
    printf("    Firmware body size:    %" PRIu64 "\n",
           preamble->body_digest.data_size);
    printf("    Preamble flags:        %" PRIu32 "\n", preamble->flags);
    printf("    Preamble name:         %s\n", preamble->name);

    /* TODO: verify body size same as signature size */

    /* Verify body */
    if (preamble->flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {
      printf("Preamble requests USE_RO_NORMAL; skipping verification.\n");
    } else {
      if (0 != EqualData(fv_data, fv_size,
                         &preamble->body_digest, rsa)) {
        printf("Error verifying firmware body.\n");
        errorcnt++;
      }
    }
    free(rsa);
  }

  /* Done */
  if (0 != munmap(image, sb.st_size))
    VbExError("Can't munmap %s: %s\n", filename, strerror(errno));

  printf("Done\n");
  return errorcnt;
}

int main(int argc, char* argv[]) {

  char* filename = NULL;
  uint64_t version = 0;
  int got_version = 0;
  uint32_t preamble_flags = 0;
  char *name = NULL;
  int mode = 0;
  VbKeyBlockHeader* key_block = 0;
  VbPrivateKey* privkey = 0;
  VbPublicKey* pubkey = 0;
  uint64_t key_block_size;
  int errorcnt = 0;
  char* e;
  int i;

  while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
    switch (i) {
    case '?':
      /* Unhandled option */
      printf("Unknown option\n");
      errorcnt++;
      break;

    case OPT_MODE_SIGN:
    case OPT_MODE_VERIFY:
      mode = i;
      filename = optarg;
      break;

    case OPT_KEYBLOCK:
      /* Read the key block and keys */
      key_block = (VbKeyBlockHeader*)ReadFile(optarg, &key_block_size);
      if (!key_block) {
        printf("Error reading key block from %s\n", optarg);
        errorcnt++;
      }
      break;

    case OPT_SIGNPUBKEY:
      pubkey = PublicKeyRead(optarg);
      if (!pubkey) {
        printf("Error reading public key from %s\n", optarg);
        errorcnt++;
      }
      break;

    case OPT_SIGNPRIVATE:
      privkey = PrivateKeyRead(optarg);
      if (!privkey) {
        printf("Error reading private key from %s\n", optarg);
        errorcnt++;
      }
      break;

    case OPT_VERSION:
      version = strtoul(optarg, &e, 0);
      if (!*optarg || (e && *e)) {
        printf("Invalid --version argument: \"%s\"\n", optarg);
        errorcnt++;
      }
      got_version = 1;
      break;

    case OPT_FLAGS:
      preamble_flags = strtoul(optarg, &e, 0);
      if (!*optarg || (e && *e)) {
        printf("Invalid --flags argument: \"%s\"\n", optarg);
        errorcnt++;
      }
      break;

    case OPT_NAME:
      name = optarg;
      break;
    }
  }

  switch(mode) {

  case OPT_MODE_SIGN:
    /* Check required args */
    if (!key_block) {
      printf("The ----keyblock arg is required when signing\n");
      errorcnt++;
    }
    if (!privkey) {
      printf("The --signprivate arg is required when signing\n");
      errorcnt++;
    }
    if (!got_version) {
      printf("The --version arg is required when signing\n");
      errorcnt++;
    }

    if (errorcnt)
      return PrintHelp();

    /* Sign or die */
    SignImage(filename, key_block, key_block_size,
              privkey, version, pubkey, preamble_flags, name);

    /* fall through and verify what we've just done */

  case OPT_MODE_VERIFY:
    return Verify(filename);

  default:
    printf("\nMust specify a mode, either --sign or --verify.\n\n");
    return PrintHelp();
  }
}
