cleanup: remove a couple of unused functions and files

scripts/sign_data.sh is just a wrapper to do this:

  ./signature_digest_utility $1 $3 \
    | openssl rsautl -sign -pkcs -inkey $2

AFAICT, that script is only invoked by the SignatureFile()
function in host/lib/file_keys.c, which is not referenced by
anything. I think I can remove both of those things.

Also remove utility/gbb_utility.cc, which should have been done
long ago in commit 6f39615.

BUG=none
BRANCH=ToT
TEST=make runalltests

Also ran it on daisy_spring-paladin and link-tot-paladin.

Change-Id: I16de5022765806f11bf6144d7ffd8cc849578a68
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/216719
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/README b/README
index 8242fff..e093390 100644
--- a/README
+++ b/README
@@ -1,30 +1,53 @@
 This directory contains a reference implementation for Chrome OS
 verified boot in firmware.
 
----------- 
-Directory Structure 
+----------
+Directory Structure
 ----------
 
 The source is organized into distinct modules -
 
-firmware/ - Contains ONLY the code required by the BIOS to validate
-the secure boot components. There shouldn't be any code in here that
-signs or generates images. BIOS should require ONLY this directory to
-implement secure boot. Refer to firmware/README for futher details.
+firmware/
 
-cgpt/ - Utility to read/write/modify GPT partitions.  Much like the
-gpt tool, but with support for Chrome OS extensiosn.
+  Contains ONLY the code required by the BIOS to validate the secure boot
+  components. There shouldn't be any code in here that signs or generates
+  images. BIOS should require ONLY this directory to implement secure boot.
+  Refer to firmware/README for futher details.
 
-host/ - Miscellaneous functions used by userland utilities.
+cgpt/
 
-utility/ - Utilities for generating and verifying signed
-firmware and kernel images, as well as arbitrary blobs.
+  Utility to read/write/modify GPT partitions. Similar to GNU parted or any
+  other GPT tool, but this has support for Chrome OS extensions.
 
-tests/ - User-land tests and benchmarks that test the reference
-implementation. Please have a look at these if you'd like to
-understand how to use the reference implementation.
+host/
 
-build/ - a directory where the generated files go to.
+  Miscellaneous functions needed by userland utilities.
+
+futility/
+
+  The "firmware utility" tool, used to create, sign, and validate Chrome OS
+  images.
+
+utility/
+
+  Random other utilities, not necesssarily related to verified boot as such.
+
+tests/
+
+  User-land tests and benchmarks that test the reference implementation.
+  Please have a look at these if you'd like to understand how to use the
+  reference implementation.
+
+build/
+
+  The output directory where the generated files will be placed, and where
+  tests are run.
+
+scripts/
+
+  Tools and scripts used to generate and use new signing keypairs. These are
+  typically used only on a secure machine.
+
 
 --------------------
 Building and testing
@@ -37,67 +60,63 @@
 researching what packages the files belong to and install the missing packages
 before reporting a problem.
 
-To build the software run
 
-make
+The commands are the more-or-less expected ones:
 
-in the top level directory. The build output is placed in the ./build
-directory.
-
-To run the tests either invoke
-
-RUNTESTS=1 make
-
-in the top level directory or
-
-cd tests
-BUILD=../build make runtests
+  make
+  make runtests
+  make install [ DESTDIR=/usr/local/bin ]
 
 
----------- 
-Some useful utilities: 
+
+----------
+Some useful utilities:
 ----------
 
-vbutil_key		Convert a public key into .vbpubk format
-vbutil_keyblock		Wrap a public key inside a signature and checksum
-vbutil_firmware		Create a .vblock with signature info for a
-			firmware image
-vbutil_kernel		Pack a kernel image, bootloader, and config into
-			a signed binary
+futility vbutil_key         Convert a public key into .vbpubk format
+futility vbutil_keyblock    Wrap a public key inside a signature and checksum
+futility vbutil_firmware    Create a .vblock with signature info for a
+                              firmware image
+futility vbutil_kernel      Pack a kernel image, bootloader, and config into
+                              a signed binary
 
-dumpRSAPublicKey 	Dump RSA Public key (from a DER-encoded X509
-			certificate) in a format suitable for
-		   	use by RSAVerify* functions in
-                   	crypto/.
+dumpRSAPublicKey            Dump RSA Public key (from a DER-encoded X509
+                            certificate) in a format suitable for use by
+                            RSAVerify* functions in crypto/.
 
-verify_data.c Verify a given signature on a given file.
-				 
+verify_data.c               Verify a given signature on a given file.
 
- 
----------- 
-Generating a signed firmware image: 
+
+
 ----------
+Generating a signed firmware image:
+----------
+
+* Step 0: Build the tools, install them somewhere.
 
 * Step 1: Generate RSA root and signing keys.
 
-# Root key is always 8192 bits. 
-$ openssl genrsa -F4 -out root_key.pem 8192
+  The root key is always 8192 bits.
 
-# Signing key can be between 1024-8192 bits.
-$ openssl genrsa -F4 -out signing_key.pem <1024|2048|4096|8192>
+    $ openssl genrsa -F4 -out root_key.pem 8192
 
-Note: The -F4 option must be specified to generate RSA keys with
-      a public exponent of 65535. RSA keys with 3 as a public
-      exponent (the default) won't work.
+  The signing key can be between 1024-8192 bits.
+
+    $ openssl genrsa -F4 -out signing_key.pem <1024|2048|4096|8192>
+
+  Note: The -F4 option must be specified to generate RSA keys with a public
+  exponent of 65535. RSA keys with 3 as a public exponent (the default)
+  won't work.
 
 * Step 2: Generate pre-processed public versions of the above keys using
-        utility/dumpRSAPublicKey
+          dumpRSAPublicKey. This utility expects an x509 certificate as
+          input, and emits an intermediate representation for further
+          processing.
 
-# dumpRSAPublicKey expects an x509 certificate as input.
-$ openssl req -batch -new -x509 -key root_key.pem -out root_key.crt
-$ openssl req -batch -new -x509 -key signing_key.pem -out signing_key.crt
-$ utility/dumpRSAPublicKey root_key.crt > root_key.keyb
-$ utility/dumpRSAPublicKey signing_key.crt > signing_key.keyb
+    $ openssl req -batch -new -x509 -key root_key.pem -out root_key.crt
+    $ openssl req -batch -new -x509 -key signing_key.pem -out signing_key.crt
+    $ dumpRSAPublicKey root_key.crt > root_key.keyb
+    $ dumpRSAPublicKey signing_key.crt > signing_key.keyb
 
 ************** TODO: STUFF PAST HERE IS OUT OF DATE ***************
 
@@ -121,13 +140,13 @@
   --in <firmware blob file> \
   --out <output file>
 
-Where <algoid> is based on the signature algorithm to use for firmware 
+Where <algoid> is based on the signature algorithm to use for firmware
 signining. The list of <algoid> specifications can be output by running
 'utility/firmware_utility' without any arguments.
 
-Note: --firmware_key_version and --firmware_version are part of a signed 
+Note: --firmware_key_version and --firmware_version are part of a signed
       image and are used to prevent rollbacks to older version. For testing,
-      they can just be set valid values. 
+      they can just be set to valid values.
 
 
 * Step 4: Verify that this image verifies.
@@ -144,8 +163,8 @@
       final firmware, this will be a fixed public key which cannot be
       changed and must be stored in RO firmware.
 
----------- 
-Generating a signed kernel image: 
+----------
+Generating a signed kernel image:
 ----------
 
 The steps for generating a signed kernel image are similar to that of
diff --git a/host/lib/file_keys.c b/host/lib/file_keys.c
index c311e6a..ac9af17 100644
--- a/host/lib/file_keys.c
+++ b/host/lib/file_keys.c
@@ -79,42 +79,3 @@
   close(input_fd);
   return digest;
 }
-
-uint8_t* SignatureFile(const char* input_file, const char* key_file,
-                       unsigned int algorithm) {
-  char* sign_utility = "./sign_data.sh";
-  char* cmd;  /* Command line to invoke. */
-  int cmd_len;
-  FILE* cmd_out;  /* File descriptor to command output. */
-  uint8_t* signature = NULL;
-  int signature_size = siglen_map[algorithm];
-
-  /* Build command line:
-   * sign_data.sh <algorithm> <key file> <input file>
-   */
-  cmd_len = (strlen(sign_utility) + 1 + /* +1 for space. */
-             2 + 1 + /* For [algorithm]. */
-             strlen(key_file) + 1 + /* +1 for space. */
-             strlen(input_file) +
-             1);  /* For the trailing '\0'. */
-  cmd = (char*) malloc(cmd_len);
-  snprintf(cmd, cmd_len, "%s %u %s %s", sign_utility, algorithm, key_file,
-           input_file);
-  cmd_out = popen(cmd, "r");
-  free(cmd);
-  if (!cmd_out) {
-    VBDEBUG(("Couldn't execute: %s\n", cmd));
-    return NULL;
-  }
-
-  signature = (uint8_t*) malloc(signature_size);
-  if (fread(signature, signature_size, 1, cmd_out) != 1) {
-    VBDEBUG(("Couldn't read signature.\n"));
-    pclose(cmd_out);
-    free(signature);
-    return NULL;
-  }
-
-  pclose(cmd_out);
-  return signature;
-}
diff --git a/host/lib/include/file_keys.h b/host/lib/include/file_keys.h
index 39fdc5a..ac6f9ee 100644
--- a/host/lib/include/file_keys.h
+++ b/host/lib/include/file_keys.h
@@ -31,13 +31,4 @@
  */
 uint8_t* DigestFile(char* input_file, int sig_algorithm);
 
-/* Helper function to invoke external program to calculate signature on
- * [input_file] using private key [key_file] and signature algorithm
- * [algorithm].
- *
- * Returns the signature. Caller owns the buffer and must Free() it.
- */
-uint8_t* SignatureFile(const char* input_file, const char* key_file,
-                       unsigned int algorithm);
-
 #endif  /* VBOOT_REFERENCE_FILE_KEYS_H_ */
diff --git a/host/linktest/main.c b/host/linktest/main.c
index 56ab21c..7ad89ee 100644
--- a/host/linktest/main.c
+++ b/host/linktest/main.c
@@ -47,7 +47,6 @@
   BufferFromFile(0, 0);
   RSAPublicKeyFromFile(0);
   DigestFile(0, 0);
-  SignatureFile(0, 0, 0);
 
   /* signature_digest.h */
   PrependDigestInfo(0, 0);
diff --git a/scripts/sign_data.sh b/scripts/sign_data.sh
deleted file mode 100755
index 05de5a6..0000000
--- a/scripts/sign_data.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-if [ $# -ne 3 ]
-then
-  echo "Usage: `basename $0` <algorithm> <key file> <input file>"
-  exit -1
-fi
-
-./signature_digest_utility $1 $3 | openssl rsautl -sign -pkcs -inkey $2 
diff --git a/utility/gbb_utility.cc b/utility/gbb_utility.cc
deleted file mode 100644
index 2a8c234..0000000
--- a/utility/gbb_utility.cc
+++ /dev/null
@@ -1,879 +0,0 @@
-// Copyright 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.
-//
-// Utility for manipulating Google Binary Block (GBB)
-//
-
-#include <assert.h>
-#include <getopt.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <string>
-#include <vector>
-#include <algorithm>
-
-#include "gbb_utility.h"
-
-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;
-}
-
-// utility function: convert integer to little-endian encoded bytes
-// return the byte array in string type
-static string int2bytes(const uint32_t value) {
-  const char *pvalue = reinterpret_cast<const char*>(&value);
-  return string(pvalue, sizeof(value));
-}
-
-// utility function: convert little-endian encoded bytes to integer
-// return value in uint32_t type
-static uint32_t bytes2int(const string &bytes) {
-  assert(bytes.size() == sizeof(uint32_t));
-  return *reinterpret_cast<const uint32_t*>(bytes.c_str());
-}
-
-// utility function: compare a GBB header with given version numbers.
-// return 1 for "larger", 0 for "equal" and -1 for "smaller".
-static int version_compare(const GoogleBinaryBlockHeader& header,
-                           int major, int minor) {
-  if (header.major_version != major)
-    return header.major_version - major;
-  return header.minor_version - minor;
-}
-
-///////////////////////////////////////////////////////////////////////
-// 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;
-}
-
-// utility 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) {
-    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_FLAGS:
-      *poffset = (uint8_t*)&header_.flags - (uint8_t*)&header_;
-      *psize = sizeof(header_.flags);
-      if (pname)
-        *pname = "flags";
-      break;
-
-    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;
-
-  // special processing by version
-  if (version_compare(header_, 1, 1) < 0) {
-    if (i == PROP_FLAGS) {
-      assert(value.size() == prop.size());
-      if (int2bytes(0) != value) {
-        if (verbose)
-          fprintf(stderr,
-                  "error: property %s is not supported on GBB version %d.%d\n",
-                  prop_name, header_.major_version, header_.minor_version);
-        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;
-  }
-
-  // special properties
-  switch (i) {
-    case PROP_HWID:
-      if (value.size() == prop_size) {
-        if (verbose)
-          fprintf(stderr,
-                  "error: NUL-terminated string exceed capacity (%d): %s\n",
-                  prop_size, prop_name);
-        return false;
-      }
-      break;
-
-    case PROP_FLAGS:
-      assert(value.size() == prop_size);
-      header_.flags = bytes2int(value);
-      break;
-
-    default:
-      break;
-  }
-
-  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 "";
-  }
-
-  // special processing by version
-  if (version_compare(header_, 1, 1) < 0) {
-    if (i == PROP_FLAGS)
-      return int2bytes(0);
-  }
-
-  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;
-}
-
-uint32_t GoogleBinaryBlockUtil::get_flags() const {
-  return bytes2int(get_property(PROP_FLAGS));
-}
-
-bool GoogleBinaryBlockUtil::set_flags(const uint32_t flags) {
-  return set_property(PROP_FLAGS, int2bytes(flags));
-}
-
-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
-
-#ifndef FOR_LIBRARY
-
-///////////////////////////////////////////////////////////////////////
-// 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) {
-  const char *basename = strrchr(prog_name, '/');
-  if (basename)
-    basename++;
-  else
-    basename = prog_name;
-  fprintf(stderr,
-    "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"
-    "     --flags         \tReport header flags.\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"
-    "     --flags=FLAGS   \tThe new (numeric) flags value.\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",
-    basename, basename, basename, basename);
-  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
-    if (idx == GoogleBinaryBlockUtil::PROP_FLAGS)
-      printf("%s: 0x%08x\n", name, bytes2int(value));
-    else
-      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);
-    if (idx == GoogleBinaryBlockUtil::PROP_FLAGS)
-      printf(" - %s changed from 0x%08x to 0x%08x: %s\n",
-             prop_name.c_str(), bytes2int(old_value), bytes2int(source),
-             result ? "success" : "failed");
-    else
-      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 ? parsed + 1 : parsed;
-  } 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' },
-    {"flags", 2, NULL, 'L' },
-    { 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)) {
-          fprintf(stderr, "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 : "")) {
-          fprintf(stderr, "error: cannot assign multiple HWID parameters\n");
-          usagehelp_exit(myname);
-        }
-        break;
-
-      case 'k':
-        if (!opt_props.set_new_value(
-              GoogleBinaryBlockUtil::PROP_ROOTKEY, optarg)) {
-          fprintf(stderr, "error: cannot assign multiple rootkey parameters\n");
-          usagehelp_exit(myname);
-        }
-        break;
-
-      case 'b':
-        if (!opt_props.set_new_value(
-              GoogleBinaryBlockUtil::PROP_BMPFV, optarg)) {
-          fprintf(stderr, "error: cannot assign multiple bmpfv parameters\n");
-          usagehelp_exit(myname);
-        }
-        break;
-
-      case 'R':
-        if (!opt_props.set_new_value(
-              GoogleBinaryBlockUtil::PROP_RCVKEY, optarg)) {
-          fprintf(stderr,
-                  "error: cannot assign multiple recovery_key parameters\n");
-          usagehelp_exit(myname);
-        }
-        break;
-
-      case 'L':
-        {
-          uint32_t flags = 0;
-          char *endptr = optarg;
-
-          if (optarg) {
-            flags = strtoul(optarg, &endptr, 0);
-            if (endptr == optarg) {
-              fprintf(stderr, "error: invalid --flags value\n");
-              usagehelp_exit(myname);
-            }
-          }
-
-          if (!opt_props.set_new_value(GoogleBinaryBlockUtil::PROP_FLAGS,
-                                       optarg ? int2bytes(flags) : "")) {
-            fprintf(stderr, "error: cannot assign multiple flags parameters\n");
-            usagehelp_exit(myname);
-          }
-        }
-        break;
-
-      default:
-      case '?':
-        fprintf(stderr, "error: unknown param: %c\n", opt);
-        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 {
-    fprintf(stderr, "error: unexpected parameters (%d)\n", argc);
-    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++) {
-      if (i->first == GoogleBinaryBlockUtil::PROP_HWID ||
-          i->first == GoogleBinaryBlockUtil::PROP_FLAGS) {
-        if (!i->second.empty()) {
-          printf("error: cannot assign value for --hwid/flags in --get.\n");
-          usagehelp_exit(myname);
-        }
-      }
-      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/flags are assigned in command line parameters
-      if (i->first == GoogleBinaryBlockUtil::PROP_HWID ||
-          i->first == GoogleBinaryBlockUtil::PROP_FLAGS)
-        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  // FOR_LIBRARY