// Copyright (c) 2010 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.
//
// Utility for manipulating Google Binary Block (GBB)
//

#include "gbb_utility.h"

#include <assert.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <string>
#include <vector>
#include <algorithm>

using std::string;

///////////////////////////////////////////////////////////////////////
// Simple File Utilities

// utility function: read a non-empty file.
// return file content, or empty for any failure.
static string read_nonempty_file(const char *filename) {
  string file_content;
  std::vector<char> buffer;     // since image files are small, should be OK

  FILE *fp = fopen(filename, "rb");
  if (!fp) {
    perror(filename);
    return file_content;
  }

  // prepare buffer on successful seek
  if (fseek(fp, 0, SEEK_END) == 0) {
    buffer.resize(ftell(fp));
    rewind(fp);
  }

  if (!buffer.empty()) {
    if (fread(&buffer[0], buffer.size(), 1, fp) != 1) {
      perror(filename);
      buffer.clear();  // discard buffer when read fail.
    } else {
      file_content.assign(buffer.begin(), buffer.end());
    }
  }

  fclose(fp);
  return file_content;
}

// utility function: write non-empty content to file.
// return true on success, otherwise false.
static bool write_nonempty_file(const char *filename, const string &content) {
  assert(!content.empty());

  FILE *fp = fopen(filename, "wb");
  if (!fp) {
    perror(filename);
    return false;
  }

  int r = fwrite(content.c_str(), content.size(), 1, fp);
  fclose(fp);

  if (r != 1)
    perror(filename);

  return r == 1;
}

///////////////////////////////////////////////////////////////////////
// GBB Utility implementation

namespace vboot_reference {

GoogleBinaryBlockUtil::GoogleBinaryBlockUtil() {
  assert(sizeof(header_) == GBB_HEADER_SIZE);
  initialize();
}

GoogleBinaryBlockUtil::~GoogleBinaryBlockUtil() {
}

void GoogleBinaryBlockUtil::initialize() {
  verbose = true;
  is_valid_gbb = false;
  header_offset_ = 0;
  memset(&header_, 0, sizeof(header_));
  file_content_.clear();
}

bool GoogleBinaryBlockUtil::create_new(
    const std::vector<uint32_t> &create_param) {
  uint32_t *prop = &header_.hwid_offset;  // must be first entry.
  uint32_t allocated_size = sizeof(header_);
  std::vector<uint32_t>::const_iterator i = create_param.begin();

  // max properties = available space in header / size of record (offset+size)
  size_t max_properties =
      (sizeof(header_) - (reinterpret_cast<uint8_t*>(prop) -
                          reinterpret_cast<uint8_t*>(&header_))) /
      (sizeof(uint32_t) * 2);

  if (create_param.size() >= max_properties) {
    if (verbose)
      fprintf(stderr, "error: creation parameters cannot exceed %zu entries.\n",
              max_properties);
    return false;
  }

  initialize();
  memcpy(header_.signature, GBB_SIGNATURE, GBB_SIGNATURE_SIZE);
  header_.major_version = GBB_MAJOR_VER;
  header_.minor_version = GBB_MINOR_VER;
  header_.header_size = GBB_HEADER_SIZE;

  while (i != create_param.end()) {
    *prop++ = allocated_size;  // property offset
    *prop++ = *i;  // property size
    allocated_size += *i;
    i++;
  }

  file_content_.resize(allocated_size);
  std::copy(reinterpret_cast<char*>(&header_),
            reinterpret_cast<char*>(&header_ + 1),
            file_content_.begin());
  is_valid_gbb = true;
  return true;
}


bool GoogleBinaryBlockUtil::load_from_file(const char *filename) {
  is_valid_gbb = false;

  file_content_ = read_nonempty_file(filename);
  if (file_content_.empty())
    return false;

  switch (search_header_signatures(file_content_, &header_offset_)) {
    case 0:
      if (verbose)
        fprintf(stderr, " error: cannot find any GBB signature.\n");
      break;

    case 1:
      // fetch a copy of block header to check more detail
      if (!load_gbb_header(file_content_, header_offset_, &header_)) {
        if (verbose)
          fprintf(stderr, " error: invalid GBB in image file.\n");
      } else {
        is_valid_gbb = true;
      }
      break;

    default:
      if (verbose)
        fprintf(stderr, " error: found multiple GBB signatures.\n");
      file_content_.clear();
      break;
  }

  // discard if anything goes wrong
  if (!is_valid_gbb)
    initialize();

  return is_valid_gbb;
}

bool GoogleBinaryBlockUtil::save_to_file(const char *filename) {
  assert(is_valid_gbb && !file_content_.empty());
  return write_nonempty_file(filename, file_content_);
}

int GoogleBinaryBlockUtil::search_header_signatures(const string &image,
                                                    long *poffset) const {
  int found_signatures = 0;
  size_t last_found_pos = 0;

  while ((last_found_pos =
          file_content_.find(GBB_SIGNATURE, last_found_pos, GBB_SIGNATURE_SIZE))
            != file_content_.npos) {
    *poffset = last_found_pos;
    found_signatures++;
    last_found_pos++;  // for next iteration
  }

  return found_signatures;
}

// uility function for load_gbb_header to check property range
static bool check_property_range(uint32_t off, uint32_t sz,
                                 uint32_t hdr_sz, uint32_t max_sz,
                                 const char *prop_name, bool verbose) {
  // for backward compatibility, we allow zero entry here.
  if (off == 0 && sz == 0) {
    if (verbose)
      fprintf(stderr, " warning: property %s is EMPTY.\n", prop_name);
    return true;
  }

  if (off + sz > max_sz) {
    if (verbose)
      fprintf(stderr, " error: property %s exceed GBB.\n", prop_name);
    return false;
  }

  if (off < hdr_sz) {
    if (verbose)
      fprintf(stderr, " error: property %s overlap GBB header.\n", prop_name);
    return false;
  }

  return true;
}

bool GoogleBinaryBlockUtil::load_gbb_header(const string &image, long offset,
                                         GoogleBinaryBlockHeader *phdr) const {
  assert(phdr);

  // check that GBB header does not extend past end of image
  if (image.size() < (size_t)offset + GBB_HEADER_SIZE) {
    if (verbose)
      fprintf(stderr, " error: incomplete GBB.\n");
    return false;
  }

  string::const_iterator block_ptr = image.begin() + offset;
  size_t block_size = image.size() - offset;

  std::copy(block_ptr, block_ptr + GBB_HEADER_SIZE,
      reinterpret_cast<char*>(phdr));

  const GoogleBinaryBlockHeader &h = *phdr;  // for quick access

  // check version
  if (h.major_version != GBB_MAJOR_VER ||
      h.minor_version != GBB_MINOR_VER) {
    if (verbose)
      fprintf(stderr, " error: invalid GBB version (%d.%d)\n",
          h.major_version, h.minor_version);
    return false;
  }

  if (h.header_size < GBB_HEADER_SIZE) {
    if (verbose)
      fprintf(stderr, " error: incompatible header size (%d < %d)\n",
          h.header_size, GBB_HEADER_SIZE);
    return false;
  }

  // verify properties
  for (int i = 0; i < PROP_RANGE; i++) {
    uint32_t off, size;
    const char *name;

    if (!find_property(static_cast<PROPINDEX>(i),
          &off, &size, &name)) {
      assert(!"invalid property.");
      return false;
    }

    if (!check_property_range(off, size,
          h.header_size, block_size, name, verbose))
      return false;
  }

  return true;
}

bool GoogleBinaryBlockUtil::find_property(PROPINDEX i,
                                          uint32_t *poffset,
                                          uint32_t *psize,
                                          const char** pname) const {
  switch (i) {
    case PROP_HWID:
      *poffset = header_.hwid_offset;
      *psize = header_.hwid_size;
      if (pname)
        *pname = "hardware_id";
      break;

    case PROP_ROOTKEY:
      *poffset = header_.rootkey_offset;
      *psize = header_.rootkey_size;
      if (pname)
        *pname = "root_key";
      break;

    case PROP_BMPFV:
      *poffset = header_.bmpfv_offset;
      *psize = header_.bmpfv_size;
      if (pname)
        *pname = "bmp_fv";
      break;

    case PROP_RCVKEY:
      *poffset = header_.recovery_key_offset;;
      *psize = header_.recovery_key_size;
      if (pname)
        *pname = "recovery_key";
      break;

    default:
      if (verbose) {
        fprintf(stderr, " internal error: unknown property (%d).\n",
            static_cast<int>(i));
      }
      assert(!"invalid property index.");
      return false;
  }

  return true;
}

bool GoogleBinaryBlockUtil::set_property(PROPINDEX i, const string &value) {
  uint32_t prop_size;
  uint32_t prop_offset;
  const char *prop_name;

  assert(is_valid_gbb);

  if (!find_property(i, &prop_offset, &prop_size, &prop_name))
    return false;

  if (prop_size < value.size()) {
    if (verbose)
      fprintf(stderr, " error: value size (%zu) exceed property capacity "
              "(%u): %s\n", value.size(), prop_size, prop_name);
    return false;
  }

  if (i == PROP_HWID && prop_size == value.size()) {
    // special case: this is NUL-terminated so it's better to keep one more \0
    if (verbose)
      fprintf(stderr, "error: NUL-terminated string exceed capacity (%d): %s\n",
          prop_size, prop_name);
    return false;
  }

  string::iterator dest = file_content_.begin() + header_offset_ + prop_offset;
  file_content_.replace(dest, dest+prop_size, prop_size, '\0');  // wipe first
  std::copy(value.begin(), value.end(), dest);

  return true;
}

string GoogleBinaryBlockUtil::get_property(PROPINDEX i) const {
  uint32_t prop_size;
  uint32_t prop_offset;
  const char *prop_name;

  assert(is_valid_gbb);

  if (!find_property(i, &prop_offset, &prop_size, &prop_name))
    return "";

  // check range again to allow empty value (for compatbility)
  if (prop_offset == 0 && prop_size == 0) {
    if (verbose)
      fprintf(stderr, " warning: empty property (%d): %s.\n",
              static_cast<int>(i), prop_name);
    return "";
  }

  string::const_iterator dest = file_content_.begin() +
                                header_offset_ + prop_offset;
  return string(dest, dest + prop_size);
}

string GoogleBinaryBlockUtil::get_property_name(PROPINDEX i) const {
  uint32_t unused_off, unused_size;
  const char *prop_name;

  if (!find_property(i, &unused_off, &unused_size, &prop_name)) {
    assert(!"invalid property index.");
    return "";
  }

  return prop_name;
}

bool GoogleBinaryBlockUtil::set_hwid(const char *hwid) {
  return set_property(PROP_HWID, hwid);
}

bool GoogleBinaryBlockUtil::set_rootkey(const std::string &value) {
  return set_property(PROP_ROOTKEY, value);
}

bool GoogleBinaryBlockUtil::set_bmpfv(const string &value) {
  return set_property(PROP_BMPFV, value);
}

bool GoogleBinaryBlockUtil::set_recovery_key(const string &value) {
  return set_property(PROP_RCVKEY, value);
}

}  // namespace vboot_reference

#ifdef WITH_UTIL_MAIN

///////////////////////////////////////////////////////////////////////
// command line utilities

#include <map>

using vboot_reference::GoogleBinaryBlockUtil;

// utility function: provide usage of this utility and exit.
static void usagehelp_exit(const char *prog_name) {
  printf(
    "Utility to manage Google Binary Block (GBB)\n"
    "Usage: %s [-g|-s|-c] [OPTIONS] bios_file [output_file]\n"
    "\n"
    "GET MODE:\n"
    "-g, --get   (default)\tGet (read) from bios_file, "
                            "with following options:\n"
    "     --hwid          \tReport hardware id (default).\n"
    " -k, --rootkey=FILE  \tFile name to export Root Key.\n"
    " -b, --bmpfv=FILE    \tFile name to export Bitmap FV.\n"
    "     --recoverykey=FILE\tFile name to export Recovery Key.\n"
    "\n"
    "SET MODE:\n"
    "-s, --set            \tSet (write) to bios_file, "
                            "with following options:\n"
    " -o, --output=FILE   \tNew file name for ouptput.\n"
    " -i, --hwid=HWID     \tThe new hardware id to be changed.\n"
    " -k, --rootkey=FILE  \tFile name of new Root Key.\n"
    " -b, --bmpfv=FILE    \tFile name of new Bitmap FV.\n"
    "     --recoverykey=FILE\tFile name of new Recovery Key.\n"
    "\n"
    "CREATE MODE:\n"
    "-c, --create=prop1_size,prop2_size...\n"
    "                     \tCreate a GBB blob by given size list.\n"
    "SAMPLE:\n"
    "  %s -g bios.bin\n"
    "  %s --set --hwid='New Model' -k key.bin bios.bin newbios.bin\n"
    "  %s -c 0x100,0x1000,0x03DE80,0x1000 gbb.blob\n"
    , prog_name, prog_name, prog_name, prog_name);
  exit(1);
}

// utility function: export a property from GBB to given file.
// if filename was empty, export to console (screen).
// return true on success, otherwise false.
static bool export_property(GoogleBinaryBlockUtil::PROPINDEX idx,
                            const string &filename,
                            const GoogleBinaryBlockUtil &util) {
  string prop_name = util.get_property_name(idx),
         value = util.get_property(idx);
  const char *name = prop_name.c_str();

  if (filename.empty()) {
    // write to console
    printf("%s: %s\n", name, value.c_str());
  } else {
    const char *fn = filename.c_str();

    if (!write_nonempty_file(fn, value)) {
      fprintf(stderr, "error: failed to export %s to file: %s\n", name, fn);
      return false;
    }
    printf(" - exported %s to file: %s\n", name, fn);
  }

  return true;
}

// utility function: import a property to GBB by given source (file or string).
// return true on success, otherwise false.
// is succesfully imported into GBB.
static bool import_property(
    GoogleBinaryBlockUtil::PROPINDEX idx, const string &source,
    bool source_as_file, GoogleBinaryBlockUtil *putil) {
  assert(!source.empty());
  string prop_name = putil->get_property_name(idx);

  if (source_as_file) {
    printf(" - import %s from %s: ", prop_name.c_str(), source.c_str());
    string v = read_nonempty_file(source.c_str());
    if (v.empty()) {
      printf("invalid file.\n");
      return false;
    }
    if (!putil->set_property(idx, v)) {
      printf("invalid content.\n");
      return false;
    }
    printf("success.\n");
  } else {
    // source as string
    string old_value = putil->get_property(idx);
    bool result = putil->set_property(idx, source);
    printf(" - %s changed from '%s' to '%s': %s\n",
        prop_name.c_str(), old_value.c_str(), source.c_str(),
        result ? "success" : "failed");
    if (!result)
      return false;
  }

  return true;
}

static bool parse_creation_param(const string &input_string,
                                 std::vector<uint32_t> *output_vector) {
  const char *input = input_string.c_str();
  char *parsed = NULL;
  uint32_t param;

  if (input_string.empty())
    return false;

  do {
    param = (uint32_t)strtol(input, &parsed, 0);
    if (*parsed && *parsed != ',')
      return false;
    output_vector->push_back(param);
    input = parsed + 1;
    // printf("(debug) param: %zd\n", param);
  } while (*input);

  return true;
}

///////////////////////////////////////////////////////////////////////
// main

int main(int argc, char *argv[]) {
  const char *myname = argv[0];
  int err_stage = 0;    // an indicator for error exits
  GoogleBinaryBlockUtil util;

  // small parameter helper class
  class OptPropertyMap: public
                        std::map<GoogleBinaryBlockUtil::PROPINDEX, string> {
    public:
      bool set_new_value(GoogleBinaryBlockUtil::PROPINDEX id, const string &v) {
        if (find(id) != end())
          return false;

        (*this)[id] = v;
        return true;
      }
  };
  OptPropertyMap opt_props;

  struct GBBUtilOptions {
    bool get_mode, set_mode, create_mode;
    string input_fn, output_fn;
    std::vector<uint32_t> create_param;
  } myopts;
  myopts.get_mode = myopts.set_mode = myopts.create_mode = false;

  // snippets for getopt_long
  int option_index, opt;
  static struct option long_options[] = {
    {"get", 0, NULL, 'g' },
    {"set", 0, NULL, 's' },
    {"create", 1, NULL, 'c' },
    {"output", 1, NULL, 'o' },
    {"hwid", 2, NULL, 'i' },
    {"rootkey", 1, NULL, 'k' },
    {"bmpfv", 1, NULL, 'b' },
    {"recoverykey", 1, NULL, 'R' },
    { NULL, 0, NULL, 0 },
  };

  // parse command line options
  while ((opt = getopt_long(argc, argv, "gsc:o:i:k:b:",
                            long_options, &option_index)) >= 0) {
    switch (opt) {
      case 'g':
        myopts.get_mode = true;
        break;

      case 's':
        myopts.set_mode = true;
        break;

      case 'c':
        myopts.create_mode = true;
        assert(optarg);
        if (!*optarg || !parse_creation_param(optarg, &myopts.create_param)) {
          printf("error: invalid creation parameter: %s\n", optarg);
          usagehelp_exit(myname);
        }
        break;

      case 'o':
        myopts.output_fn = optarg;
        break;

      case 'i':
        if (!opt_props.set_new_value(
              GoogleBinaryBlockUtil::PROP_HWID, optarg ? optarg : ""))
          usagehelp_exit(myname);
        break;

      case 'k':
        if (!opt_props.set_new_value(
              GoogleBinaryBlockUtil::PROP_ROOTKEY, optarg))
          usagehelp_exit(myname);
        break;

      case 'b':
        if (!opt_props.set_new_value(
              GoogleBinaryBlockUtil::PROP_BMPFV, optarg))
          usagehelp_exit(myname);
        break;

      case 'R':
        if (!opt_props.set_new_value(
              GoogleBinaryBlockUtil::PROP_RCVKEY, optarg))
          usagehelp_exit(myname);
        break;

      default:
      case '?':
        usagehelp_exit(myname);
        break;
    }
  }
  argc -= optind;
  argv += optind;

  // adjust non-dashed parameters
  if (myopts.output_fn.empty() && argc == 2) {
    myopts.output_fn = argv[1];
    argc--;
  }

  // currently, the only parameter is 'input file'.
  if (argc == 1) {
    myopts.input_fn = argv[0];
  } else {
    usagehelp_exit(myname);
  }

  // stage: complete parameter parsing and checking
  err_stage++;
  if (myopts.create_mode) {
    if (myopts.get_mode || myopts.set_mode) {
      printf("error: please assign only one mode from get/set/create.\n");
      return err_stage;
    }
    if (!opt_props.empty() || myopts.create_param.empty()) {
      printf("error: creation parameter syntax error.\n");
      return err_stage;
    }
    if (myopts.output_fn.empty()) {
      myopts.output_fn = myopts.input_fn;
    }
  } else if (myopts.get_mode == myopts.set_mode) {
    if (myopts.get_mode) {
      printf("error: please assign either get or set mode.\n");
      return err_stage;
    } else {
      // enter 'get' mode by default, if not assigned.
      myopts.get_mode = true;
    }
  }
  if (myopts.get_mode && !myopts.output_fn.empty()) {
    printf("error: get-mode does not create output files.\n");
    return err_stage;
  }

  if (myopts.create_mode) {
    if (!util.create_new(myopts.create_param))
      return err_stage;

    assert(!myopts.output_fn.empty());
    if (!util.save_to_file(myopts.output_fn.c_str())) {
      printf("error: cannot create to file: %s\n", myopts.output_fn.c_str());
      return err_stage;
    } else {
      printf("successfully created new GBB to: %s\n", myopts.output_fn.c_str());
    }
    return 0;
  }

  // stage: load image files
  err_stage++;
  assert(!myopts.input_fn.empty());
  if (!util.load_from_file(myopts.input_fn.c_str())) {
    printf("error: cannot load valid BIOS file: %s\n", myopts.input_fn.c_str());
    return err_stage;
  }

  // stage: processing by mode
  err_stage++;
  if (myopts.get_mode) {
    // get mode
    if (opt_props.empty())  // enable hwid by default
      opt_props.set_new_value(GoogleBinaryBlockUtil::PROP_HWID, "");

    for (OptPropertyMap::const_iterator i = opt_props.begin();
         i != opt_props.end();
         i++) {
      export_property(i->first, i->second, util);
    }

  } else {
    // set mode
    assert(myopts.set_mode);

    if (opt_props.empty()) {
      printf("nothing to change. abort.\n");
      return err_stage;
    }

    for (OptPropertyMap::const_iterator i = opt_props.begin();
         i != opt_props.end();
         i++) {
      bool source_as_file = true;

      // the hwid command line parameter was a simple string.
      if (i->first == GoogleBinaryBlockUtil::PROP_HWID)
        source_as_file = false;

      if (!import_property(i->first, i->second, source_as_file, &util)) {
        printf("error: cannot set properties. abort.\n");
        return err_stage;
      }
    }

    // stage: write output
    err_stage++;

    // use input filename (overwrite) by default
    if (myopts.output_fn.empty())
      myopts.output_fn = myopts.input_fn;

    assert(!myopts.output_fn.empty());
    if (!util.save_to_file(myopts.output_fn.c_str())) {
      printf("error: cannot save to file: %s\n", myopts.output_fn.c_str());
      return err_stage;
    } else {
      printf("successfully saved new image to: %s\n", myopts.output_fn.c_str());
    }
  }

  return 0;
}

#endif  // WITH_UTIL_MAIN
