/*
 * Copyright 2021 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.
 */

#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <openssl/bn.h>
#include <openssl/pem.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>

#include "fmap.h"
#include "futility.h"
#include "gsc_ro.h"
#include "host_key21.h"
#include "host_keyblock.h"
#include "host_signature.h"

/*
 * for testing purposes let's use
 * - tests/devkeys/arv_root.vbprivk as the root private key
 * - tests/devkeys/arv_root.vbpubk as the root public key
 *   used for signing of the platform public key
 * - tests/devkeys/arv_platform.vbprivk signing platform key
 * - tests/devkeys/arv_platform.vbpubk - public key used for signature
 *       verification
 *------------
 * Command to create the signed public key block in ~/tmp/packed:
 *
  ./build/futility/futility vbutil_keyblock --pack ~/tmp/packed \
      --datapubkey  tests/devkeys/arv_platform.vbpubk \
      --signprivate tests/devkeys/arv_root.vbprivk
 *------------
 * Command to fill RO_GSCVD FMAP area in an AP firmware file. The input AP
 *   firmware file is ~/tmp/image-guybrush.serial.bin, the output signed
 *   AP firmware file is ~/tmp/guybrush-signed:
 *
  ./build/futility/futility gscvd --outfile ~/tmp/guybrush-signed \
     -R 818100:10000,f00000:100,f80000:2000,f8c000:1000,0x00804000:0x00000800 \
     -k ~/tmp/packed -p tests/devkeys/arv_platform.vbprivk -b 5a5a4352  \
     -r tests/devkeys/arv_root.vbpubk ~/tmp/image-guybrush.serial.bin
 *------------
 * Command to validate a previously signed AP firmware file. The hash is the
 *  sha256sum of tests/devkeys/kernel_subkey.vbpubk:
 *
  build/futility/futility gscvd ~/tmp/guybrush-signed \
   3d74429f35be8d34bcb425d4397e2218e6961afed456a78ce30047f5b54ed158
 */

/* Command line options processing support. */
enum no_short_opts {
	OPT_OUTFILE = 1000,
};

static const struct option long_opts[] = {
	/* name       hasarg *flag  val */
	{"outfile",       1, NULL, OPT_OUTFILE},
	{"ranges",        1, NULL, 'R'},
	{"board_id",      1, NULL, 'b'},
	{"root_pub_key",  1, NULL, 'r'},
	{"keyblock",      1, NULL, 'k'},
	{"platform_priv", 1, NULL, 'p'},
	{"help",          0, NULL, 'h'},
	{}
};

static const char *short_opts = "R:b:hk:p:r:";

static const char usage[] =
	"\n"
	"This utility creates an RO verification space in the Chrome OS AP\n"
	"firmware image or allows to validate a previously prepared image\n"
	"containing the RO verification space.\n\n"
	"Usage: " MYNAME " gscvd PARAMS <AP FIRMWARE FILE> [<root key hash>]\n"
	"\n\nCreation of RO Verification space:\n\n"
	"Required PARAMS:\n"
	"  -R|--ranges        STRING        Comma separated colon delimited\n"
	"                                     hex tuples <offset>:<size>, the\n"
	"                                     areas of the RO covered by the\n"
	"                                     signature\n"
	"  -b|--board_id  <hex value>      The Board ID of the board for which\n"
	"                                     the image is being signed\n"
	"  -r|--root_pub_key  <file>        The main public key, in .vbpubk\n"
	"                                     format, used to verify platform\n"
	"                                     key\n"
	"  -k|--keyblock      <file>        Signed platform public key in\n"
	"                                     .keyblock format, used for run\n"
	"                                     time RO verifcation\n"
	"  -p|--platform_priv <file>        Private platform key in .vbprivk\n"
	"                                     format, used for signing RO\n"
	"                                     verification data\n"
	"Optional PARAMS:\n"
	"  [--outfile]        OUTFILE       Output firmware image containing\n"
	"                                     RO verification information\n"
	"\n\n"
	"Validation of RO Verification space:\n\n"
	"   The only required parameter is <AP FIRMWARE FILE>, if optional\n"
	"   <root key hash> is given, it is compared to the hash\n"
	"   of the root key found in <AP_FIRMWARE_FILE>.\n"
	"\n\n"
	"  -h|--help                        Print this message\n\n";

/* Structure helping to keep track of the file mapped into memory. */
struct file_buf {
	uint32_t len;
	uint8_t *data;
	int fd;
	FmapAreaHeader *ro_gscvd;
};

/*
 * Max number of RO ranges to cover. 32 is more than enough, this must be kept
 * in sync with APRO_MAX_NUM_RANGES declaration in
 * common/ap_ro_integrity_check.c in the Cr50 tree.
 */
#define MAX_RANGES 32

/*
 * Container keeping track of the set of ranges to include in hash
 * calculation.
 */
struct gscvd_ro_ranges {
	size_t range_count;
	struct gscvd_ro_range ranges[MAX_RANGES];
};

/**
 * Load the AP firmware file into memory.
 *
 * Map the requested file into memory, find RO_GSCVD area in the file, and
 * cache the information in the passed in file_buf structure.
 *
 * @param file_name  name of the AP firmware file
 * @param file_buf   pointer to the helper structure keeping information about
 *                   the file
 *
 * @return 0 on success 1 on failure.
 */
static int load_ap_firmware(const char *file_name, struct file_buf *file)
{
	int fd;
	int rv;

	fd = open(file_name, O_RDWR);
	if (fd < 0) {
		ERROR("Can't open %s: %s\n", file_name,
		      strerror(errno));
		return 1;
	}

	file->fd = fd;
	do {
		rv = 1;

		if (futil_map_file(fd, MAP_RW, &file->data, &file->len)) {
			file->data = NULL;
			break;
		}

		if (!fmap_find_by_name(file->data, file->len, NULL, "RO_GSCVD",
				       &file->ro_gscvd)) {
			ERROR("Could not find RO_GSCVD in the FMAP\n");
			break;
		}
		rv = 0;
	} while (false);

	return rv;
}

/**
 * Check if the passed in offset falls into the passed in FMAP area.
 */
static bool in_range(uint32_t offset, const FmapAreaHeader *ah)
{
	return (offset >= ah->area_offset) &&
	       (offset <= (ah->area_offset + ah->area_size));
}

/**
 * Check if the passed in range fits into the passed in FMAP area.
 */
static bool range_fits(const struct gscvd_ro_range *range,
		       const FmapAreaHeader *ah)
{
	if (in_range(range->offset, ah) &&
	    in_range(range->offset + range->size, ah))
		return true;

	ERROR("Range %#x..+%#x does not fit in %s\n", range->offset,
	      range->size, ah->area_name);

	return false;
}

/**
 * Check if the passed in range overlaps with the area.
 *
 * @param range  pointer to the range to check
 * @param offset  offset of the area to check against
 * @param size  size of the area to check against
 *
 * @return true if range overlaps with the area, false otherwise.
 */
static bool range_overlaps(const struct gscvd_ro_range *range, uint32_t offset,
			   size_t size)
{
	if (((range->offset + range->size) <= offset) ||
	    (offset + size) <= range->offset)
		return false;

	ERROR("Range %x..+%x overlaps with %x..+%zx\n", range->offset,
	      range->size, offset, size);

	return true;
}

/*
 * Check validity of the passed in ranges.
 *
 * All ranges must
 * - fit into the WP_RO FMAP area
 * - not overlap with the RO_GSCVD FMAP area
 * - not overlap with each other
 *
 * @param ranges - pointer to the container of ranges to check
 * @param file - pointer to the file layout descriptor
 *
 * @return zero on success, -1 on failures
 */
static int verify_ranges(const struct gscvd_ro_ranges *ranges,
			 const struct file_buf *file)
{
	size_t i;
	FmapAreaHeader *wp_ro;
	int errorcount;

	if (!fmap_find_by_name(file->data, file->len, NULL, "WP_RO", &wp_ro)) {
		ERROR("Could not find WP_RO in the FMAP\n");
		return 1;
	}

	errorcount = 0;
	for (i = 0; i < ranges->range_count; i++) {
		size_t j;

		/* Must fit into WP_RO. */
		if (!range_fits(ranges->ranges + i, wp_ro))
			errorcount++;

		/* Must not overlap with RO_GSCVD. */
		if (range_overlaps(ranges->ranges + i,
				   file->ro_gscvd->area_offset,
				   file->ro_gscvd->area_size))
			errorcount++;

		/* The last range is nothing to compare against. */
		if (i == ranges->range_count - 1)
			break;

		/* Must not overlap with all following ranges. */
		for (j = i + 1; j < ranges->range_count; j++)
			if (range_overlaps(ranges->ranges + i,
					   ranges->ranges[j].offset,
					   ranges->ranges[j].size))
				errorcount++;
	}

	return errorcount ? -1 : 0;
}

/**
 * Parse range specification supplied by the user.
 *
 * The input is a string of the following format:
 * <hex base>:<hex size>[,<hex base>:<hex size>[,...]]
 *
 * @param input  user input, part of the command line
 * @param output  pointer to the ranges container
 *
 * @return zero on success, -1 on failure
 */
static int parse_ranges(const char *input, struct gscvd_ro_ranges *output)
{
	char *cursor;
	char *delim;
	char *str = strdup(input);
	int rv = 0;

	if (!str) {
		ERROR("Failed to allocate memory for ranges string copy!\n");
		return -1;
	}

	output->range_count = 0;
	cursor = str;
	do {
		char *colon;
		char *e;

		if (output->range_count >= ARRAY_SIZE(output->ranges)) {
			ERROR("Too many ranges!\n");
			rv = -1;
			break;
		}

		delim = strchr(cursor, ',');
		if (delim)
			*delim = '\0';
		colon = strchr(cursor, ':');
		if (!colon) {
			rv = -1;
			break;
		}
		*colon = '\0';

		errno = 0;
		output->ranges[output->range_count].offset =
			strtol(cursor, &e, 16);
		if (errno || *e) {
			rv = -1;
			break;
		}

		output->ranges[output->range_count].size =
			strtol(colon + 1, &e, 16);
		if (errno || *e) {
			rv = -1;
			break;
		}

		output->range_count++;
		cursor = delim + 1;
		/* Iterate until there is no more commas. */
	} while (delim);

	free(str);
	if (rv)
		ERROR("Misformatted ranges string\n");

	return rv;
}

/**
 * Calculate hash of the RO ranges.
 *
 * @param ap_firmware_file  pointer to the AP firmware file layout descriptor
 * @param ranges  pointer to the container of ranges to include in hash
 *		  calculation
 * @param hash_alg  algorithm to use for hashing
 * @param digest  memory to copy the calculated hash to
 * @param digest_ size requested size of the digest, padded with zeros if the
 *	          SHA digest size is smaller than digest_size
 *
 * @return zero on success, -1 on failure.
 */
static int calculate_ranges_digest(const struct file_buf *ap_firmware_file,
				   const struct gscvd_ro_ranges *ranges,
				   enum vb2_hash_algorithm hash_alg,
				   void *digest, size_t digest_size)
{
	struct vb2_digest_context dc;
	size_t i;

	/* Calculate the ranges digest. */
	if (vb2_digest_init(&dc, hash_alg) != VB2_SUCCESS) {
		ERROR("Failed to init digest!\n");
		return 1;
	}

	for (i = 0; i < ranges->range_count; i++) {
		if (vb2_digest_extend(&dc,
				      ap_firmware_file->data +
					      ranges->ranges[i].offset,
				      ranges->ranges[i].size) != VB2_SUCCESS) {
			ERROR("Failed to extend digest!\n");
			return -1;
		}
	}

	memset(digest, 0, digest_size);
	if (vb2_digest_finalize(&dc, digest, digest_size) != VB2_SUCCESS) {
		ERROR("Failed to finalize digest!\n");
		return -1;
	}

	return 0;
}

/**
 * Build GSC verification data.
 *
 * Calculate size of the structure including the signature and the root key,
 * allocate memory, fill up the structure, calculate AP RO ranges digest and
 * then the GVD signature.
 *
 * @param ap_firmware_file  pointer to the AP firmware file layout descriptor
 * @param ranges  pointer to the container of ranges to include in verification
 * @param root_pubk  pointer to the root pubk container
 * @param privk   pointer to the private key to use for signing
 * @param board_id  Board ID value to use.
 *
 * @return pointer to the created GVD (to be freed by the caller) on success,
 *         NULL on failure.
 */
static
struct gsc_verification_data *create_gvd(struct file_buf *ap_firmware_file,
					 struct gscvd_ro_ranges *ranges,
					 const struct vb2_packed_key *root_pubk,
					 const struct vb2_private_key *privk,
					 uint32_t board_id)
{
	struct gsc_verification_data *gvd;
	size_t total_size;
	size_t sig_size;
	size_t ranges_size;
	struct vb2_signature *sig;
	const FmapHeader *fmh;

	sig_size = vb2_rsa_sig_size(privk->sig_alg);
	ranges_size = ranges->range_count * sizeof(struct gscvd_ro_range);
	total_size = sizeof(struct gsc_verification_data) +
		root_pubk->key_size + sig_size + ranges_size;

	gvd = calloc(total_size, 1);

	if (!gvd) {
		ERROR("Failed to allocate %zd bytes for gvd\n", total_size);
		return NULL;
	}

	gvd->gv_magic = GSC_VD_MAGIC;
	gvd->size = total_size;
	gvd->gsc_board_id = board_id;
	gvd->rollback_counter = GSC_VD_ROLLBACK_COUNTER;

	/* Guaranteed to succeed. */
	fmh = fmap_find(ap_firmware_file->data, ap_firmware_file->len);

	gvd->fmap_location = (uintptr_t)fmh - (uintptr_t)ap_firmware_file->data;

	gvd->hash_alg = VB2_HASH_SHA256;

	if (calculate_ranges_digest(ap_firmware_file, ranges, gvd->hash_alg,
				    gvd->ranges_digest,
				    sizeof(gvd->ranges_digest))) {
		free(gvd);
		return NULL;
	}

	/* Prepare signature header. */
	vb2_init_signature(&gvd->sig_header,
			   (uint8_t *)(gvd + 1) + ranges_size,
			   sig_size,
			   sizeof(struct gsc_verification_data) + ranges_size);

	/* Copy root key into the structure. */
	vb2_init_packed_key(&gvd->root_key_header,
			    (uint8_t *)(gvd + 1) + ranges_size + sig_size,
			    root_pubk->key_size);
	vb2_copy_packed_key(&gvd->root_key_header, root_pubk);

	/* Copy ranges into the ranges section. */
	gvd->range_count = ranges->range_count;
	memcpy(gvd->ranges, ranges->ranges, ranges_size);

	sig = vb2_calculate_signature((uint8_t *)gvd,
				      sizeof(struct gsc_verification_data) +
				      ranges_size, privk);
	if (!sig) {
		ERROR("Failed to calculate signature\n");
		free(gvd);
		return NULL;
	}

	/* Copy signature body into GVD after some basic checks. */
	if ((sig_size == sig->sig_size) &&
	    (gvd->sig_header.data_size == sig->data_size)) {
		vb2_copy_signature(&gvd->sig_header, sig);
	} else {
		ERROR("Inconsistent signature headers\n");
		free(sig);
		free(gvd);
		return NULL;
	}

	free(sig);

	return gvd;
}

/**
 * Fill RO_GSCVD FMAP area.
 *
 * All trust chain components have been verified, AP RO sections digest
 * calculated, and GVD signature created; put it all together in the dedicated
 * FMAP area.
 *
 * @param ap_firmware_file  pointer to the AP firmware file layout descriptor
 * @param gvd  pointer to the GVD header
 * @param keyblock  pointer to the keyblock container
 *
 * @return zero on success, -1 on failure
 */
static int fill_gvd_area(struct file_buf *ap_firmware_file,
			 struct gsc_verification_data *gvd,
			 struct vb2_keyblock *keyblock)
{
	size_t total;
	uint8_t *cursor;

	/* How much room is needed for the whole thing? */
	total = gvd->size + keyblock->keyblock_size;

	if (total > ap_firmware_file->ro_gscvd->area_size) {
		ERROR("GVD section does not fit, %zd > %d\n",
		      total, ap_firmware_file->ro_gscvd->area_size);
		return -1;
	}

	cursor = ap_firmware_file->data +
		 ap_firmware_file->ro_gscvd->area_offset;

	/* Copy GSC verification data */
	memcpy(cursor, gvd, gvd->size);
	cursor += gvd->size;

	/* Keyblock, size includes everything. */
	memcpy(cursor, keyblock, keyblock->keyblock_size);

	return 0;
}

/**
 * Initialize a work buffer structure.
 *
 * Embedded vboot reference code does not use malloc/free, it uses the so
 * called work buffer structure to provide a poor man's memory management
 * tool. This program uses some of the embedded library functions, let's
 * implement work buffer support to keep the embedded code happy.
 *
 * @param wb  pointer to the workubffer structure to initialize
 * @param size  size of the buffer to allocate
 *
 * @return pointer to the allocated buffer on success, NULL on failure.
 */
static void *init_wb(struct vb2_workbuf *wb, size_t size)
{
	void *buf = malloc(size);

	if (!buf)
		ERROR("Failed to allocate workblock of %zd\n", size);
	else
		vb2_workbuf_init(wb, buf, size);

	return buf;
}

/**
 * Validate that platform key keyblock was signed by the root key.
 *
 * This function performs the same step the GSC is supposed to perform:
 * validate the platform key keyblock signature using the root public key.
 *
 * @param root_pubk  pointer to the root public key container
 * @param kblock  pointer to the platform public key keyblock
 *
 * @return 0 on success, -1 on failure
 */
static int validate_pubk_signature(const struct vb2_packed_key *root_pubk,
				   struct vb2_keyblock *kblock)
{
	struct vb2_public_key pubk;
	struct vb2_workbuf wb;
	uint32_t kbsize;
	int rv;
	void *buf;

	if (vb2_unpack_key(&pubk, root_pubk) != VB2_SUCCESS) {
		ERROR("Failed to unpack public key\n");
		return -1;
	}

	/* Let's create an ample sized work buffer. */
	buf = init_wb(&wb, 8192);
	if (!buf)
		return -1;

	rv = -1;
	do {
		void *work;

		kbsize = kblock->keyblock_size;
		work = vb2_workbuf_alloc(&wb, kbsize);
		if (!work) {
			ERROR("Failed to allocate workblock space %d\n",
			      kbsize);
			break;
		}

		memcpy(work, kblock, kbsize);

		if (vb2_verify_keyblock(work, kbsize, &pubk, &wb) !=
		    VB2_SUCCESS) {
			ERROR("Root and keyblock mismatch\n");
			break;
		}

		rv = 0;
	} while (false);

	free(buf);

	return rv;
}

/**
 * Validate that private and public parts of the platform key match.
 *
 * This is a fairly routine validation, the N components of the private and
 * public RSA keys are compared.
 *
 * @param keyblock  pointer to the keyblock containing the public key
 * @param plat_privk  pointer to the matching private key
 *
 * @return 0 on success, nonzero on failure
 */
static int validate_privk(struct vb2_keyblock *kblock,
			  struct vb2_private_key *plat_privk)
{
	const BIGNUM *privn;
	BIGNUM *pubn;
	struct vb2_public_key pubk;
	int rv;

	privn = pubn = NULL;

	RSA_get0_key(plat_privk->rsa_private_key, &privn, NULL, NULL);

	if (vb2_unpack_key(&pubk, &kblock->data_key) != VB2_SUCCESS) {
		ERROR("Failed to unpack public key\n");
		return -1;
	}

	pubn = BN_new();
	pubn = BN_lebin2bn((uint8_t *)pubk.n, vb2_rsa_sig_size(pubk.sig_alg),
			   pubn);
	rv = BN_cmp(pubn, privn);
	if (rv)
		ERROR("Public/private key N mismatch!\n");

	BN_free(pubn);
	return rv;
}

/**
 * Copy ranges from AP firmware file into gscvd_ro_ranges container
 *
 * While copying the ranges verify that they do not overlap.
 *
 * @param ap_firmware_file  pointer to the AP firmware file layout descriptor
 * @param gvd  pointer to the GVD header followed by the ranges
 * @param ranges  pointer to the ranges container to copy ranges to
 *
 * @return 0 on successful copy nonzero on errors.
 */
static int copy_ranges(const struct file_buf *ap_firmware_file,
		       const struct gsc_verification_data *gvd,
		       struct gscvd_ro_ranges *ranges)
{
	ranges->range_count = gvd->range_count;
	memcpy(ranges->ranges, gvd->ranges,
	       sizeof(ranges->ranges[0]) * ranges->range_count);

	return verify_ranges(ranges, ap_firmware_file);
}

/**
 * Basic validation of GVD included in a AP firmware file.
 *
 * This is not a cryptographic verification, just a check that the structure
 * makes sense and the expected values are found in certain fields.
 *
 * @param gvd  pointer to the GVD header followed by the ranges
 * @param ap_firmware_file  pointer to the AP firmware file layout descriptor
 *
 * @return zero on success, -1 on failure.
 */
static int validate_gvd(const struct gsc_verification_data *gvd,
			const struct file_buf *ap_firmware_file)
{
	const FmapHeader *fmh;

	if (gvd->gv_magic != GSC_VD_MAGIC) {
		ERROR("Incorrect gscvd magic %x\n", gvd->gv_magic);
		return -1;
	}

	if (!gvd->range_count || (gvd->range_count > MAX_RANGES)) {
		ERROR("Incorrect gscvd range count %d\n", gvd->range_count);
		return -1;
	}

	/* Guaranteed to succeed. */
	fmh = fmap_find(ap_firmware_file->data, ap_firmware_file->len);

	if (gvd->fmap_location !=
	    ((uintptr_t)fmh - (uintptr_t)ap_firmware_file->data)) {
		ERROR("Incorrect gscvd fmap offset %x\n", gvd->fmap_location);
		return -1;
	}

	/* Make sure signature and root key fit. */
	if (vb2_verify_signature_inside(gvd, gvd->size, &gvd->sig_header) !=
	    VB2_SUCCESS) {
		ERROR("Corrupted signature header in GVD\n");
		return -1;
	}

	if (vb2_verify_packed_key_inside(gvd, gvd->size,
					 &gvd->root_key_header) !=
	    VB2_SUCCESS) {
		ERROR("Corrupted root key header in GVD\n");
		return -1;
	}

	return 0;
}

/**
 * Validate GVD signature.
 *
 * Given the entire GVD space (header plus ranges array), the signature and
 * the public key, verify that the signature matches.
 *
 * @param gvd  pointer to gsc_verification_data followed by the ranges array
 * @param gvd_signature  pointer to the vb2 signature container
 * @param packedk  pointer to the keyblock containing the public key
 *
 * @return zero on success, non-zero on failure
 */
static int validate_gvd_signature(struct gsc_verification_data *gvd,
				  const struct vb2_packed_key *packedk)
{
	struct vb2_workbuf wb;
	void *buf;
	int rv;
	struct vb2_public_key pubk;
	size_t signed_size;

	/* Extract public key from the public key keyblock. */
	if (vb2_unpack_key(&pubk, packedk) != VB2_SUCCESS) {
		ERROR("Failed to unpack public key\n");
		return -1;
	}

	/* Let's create an ample sized work buffer. */
	buf = init_wb(&wb, 8192);
	if (!buf)
		return -1;

	signed_size = sizeof(struct gsc_verification_data) +
		gvd->range_count * sizeof(gvd->ranges[0]);

	rv = vb2_verify_data((const uint8_t *)gvd, signed_size,
			     &gvd->sig_header,
			     &pubk, &wb);

	free(buf);
	return rv;
}

/*
 * Validate GVD of the passed in AP firmware file and possibly the root key hash
 *
 * The input parameters are the subset of the command line, the first argv
 * string is the AP firmware file name, the second string, if present, is the
 * hash of the root public key included in the RO_GSCVD area of the AP
 * firmware file.
 *
 * @return zero on success, -1 on failure.
 */
static int validate_gscvd(int argc, char *argv[])
{
	struct file_buf ap_firmware_file;
	int rv;
	struct gscvd_ro_ranges ranges;
	struct gsc_verification_data *gvd;
	const char *file_name;
	uint8_t digest[sizeof(gvd->ranges_digest)];
	struct vb2_hash root_key_digest = { .algo = VB2_HASH_SHA256 };

	/* Guaranteed to be available. */
	file_name = argv[0];

	if (argc > 1)
		parse_digest_or_die(root_key_digest.sha256,
				    sizeof(root_key_digest.sha256),
				    argv[1]);

	do {
		struct vb2_keyblock *kblock;

		rv = -1; /* Speculative, will be cleared on success. */

		if (load_ap_firmware(file_name, &ap_firmware_file))
			break;

		/* Copy ranges from gscvd to local structure. */
		gvd = (struct gsc_verification_data
			       *)(ap_firmware_file.data +
				  ap_firmware_file.ro_gscvd->area_offset);

		if (validate_gvd(gvd, &ap_firmware_file))
			break;

		if (copy_ranges(&ap_firmware_file, gvd, &ranges))
			break;

		if (calculate_ranges_digest(&ap_firmware_file, &ranges,
					    gvd->hash_alg, digest,
					    sizeof(digest)))
			break;

		if (memcmp(digest, gvd->ranges_digest, sizeof(digest))) {
			ERROR("Ranges digest mismatch\n");
			break;
		}

		/* Find the keyblock. */
		kblock = (struct vb2_keyblock *)((uintptr_t)gvd + gvd->size);

		if ((argc > 1) && (vb2_hash_verify
				   (vb2_packed_key_data(&gvd->root_key_header),
				    gvd->root_key_header.key_size,
				    &root_key_digest) != VB2_SUCCESS)) {
			ERROR("Sha256 mismatch\n");
			break;
		}

		if (validate_pubk_signature(&gvd->root_key_header,
					    kblock))
			break;

		if (validate_gvd_signature(gvd, &kblock->data_key))
			break;

		rv = 0;
	} while (false);

	return rv;
}

/**
 * Calculate and report sha256 hash of the public key body.
 *
 * The hash will be incorporated into GVC firmware to allow it to validate the
 * root key.
 *
 * @param pubk pointer to the public key to process.
 */
static void dump_pubk_hash(const struct vb2_packed_key *pubk)
{
	struct vb2_hash hash;
	size_t i;

	vb2_hash_calculate(vb2_packed_key_data(pubk), pubk->key_size,
			   VB2_HASH_SHA256, &hash);

	printf("Root key body sha256 hash:\n");

	for (i = 0; i < sizeof(hash.sha256); i++)
		printf("%02x", hash.sha256[i]);

	printf("\n");
}

/**
 * The main function of this futilty option.
 *
 * See the usage string for input details.
 *
 * @return zero on success, nonzero on failure.
 */
static int do_gscvd(int argc, char *argv[])
{
	int i;
	int longindex;
	char *infile = NULL;
	char *outfile = NULL;
	char *work_file = NULL;
	struct gscvd_ro_ranges ranges;
	int errorcount = 0;
	struct vb2_packed_key *root_pubk = NULL;
	struct vb2_keyblock *kblock = NULL;
	struct vb2_private_key *plat_privk = NULL;
	struct gsc_verification_data *gvd = NULL;
	struct file_buf ap_firmware_file = { .fd = -1 };
	uint32_t board_id = UINT32_MAX;
	int rv = 0;

	ranges.range_count = 0;

	while ((i = getopt_long(argc, argv, short_opts, long_opts,
				&longindex)) != -1) {
		switch (i) {
		case OPT_OUTFILE:
			outfile = optarg;
			break;
		case 'R':
			if (parse_ranges(optarg, &ranges)) {
				ERROR("Could not parse ranges\n");
				/* Error message has been already printed. */
				errorcount++;
			}
			break;
		case 'b': {
			char *e;
			long long bid;

			bid = strtoull(optarg, &e, 16);
			if (*e || (bid >= UINT32_MAX)) {
				ERROR("Board ID value '%s' is invalid\n",
				      optarg);
				errorcount++;
			} else {
				board_id = (uint32_t)bid;
			}
			break;
		}
		case 'r':
			root_pubk = vb2_read_packed_key(optarg);
			if (!root_pubk) {
				ERROR("Could not read %s\n", optarg);
				errorcount++;
			}
			break;
		case 'k':
			kblock = vb2_read_keyblock(optarg);
			if (!kblock) {
				ERROR("Could not read %s\n", optarg);
				errorcount++;
			}
			break;
		case 'p':
			plat_privk = vb2_read_private_key(optarg);
			if (!plat_privk) {
				ERROR("Could not read %s\n", optarg);
				errorcount++;
			}
			break;
		case 'h':
			printf("%s", usage);
			return 0;
		case '?':
			if (optopt)
				ERROR("Unrecognized option: -%c\n", optopt);
			else
				ERROR("Unrecognized option: %s\n",
				      argv[optind - 1]);
			errorcount++;
			break;
		case ':':
			ERROR("Missing argument to -%c\n", optopt);
			errorcount++;
			break;
		case 0: /* handled option */
			break;
		default:
			FATAL("Unrecognized getopt output: %d\n", i);
		}
	}

	if ((optind == 1) && (argc > 1))
		/* This must be a validation request. */
		return validate_gscvd(argc - 1, argv + 1);

	if (optind != (argc - 1)) {
		ERROR("Misformatted command line\n%s\n", usage);
		return 1;
	}

	if (errorcount || !ranges.range_count || !root_pubk || !kblock ||
	    !plat_privk || (board_id == UINT32_MAX)) {
		/* Error message(s) should have been printed by now. */
		ERROR("%s\n", usage);
		return 1;
	}

	infile = argv[optind];

	if (outfile) {
		futil_copy_file_or_die(infile, outfile);
		work_file = outfile;
	} else {
		work_file = infile;
	}

	do {
		rv = 1; /* Speculative, will be cleared on success. */

		if (validate_pubk_signature(root_pubk, kblock))
			break;

		if (validate_privk(kblock, plat_privk))
			break;

		if (load_ap_firmware(work_file, &ap_firmware_file))
			break;

		if (verify_ranges(&ranges, &ap_firmware_file))
			break;

		gvd = create_gvd(&ap_firmware_file, &ranges,
				 root_pubk, plat_privk, board_id);
		if (!gvd)
			break;

		if (fill_gvd_area(&ap_firmware_file, gvd, kblock))
			break;

		dump_pubk_hash(root_pubk);

		rv = 0;
	} while (false);

	free(gvd);
	free(root_pubk);
	free(kblock);
	vb2_private_key_free(plat_privk);

	/* Now flush the file. */
	if (ap_firmware_file.data) {
		rv |= futil_unmap_file(ap_firmware_file.fd, true,
				       ap_firmware_file.data,
				       ap_firmware_file.len);
	}

	if (ap_firmware_file.fd != -1)
		close(ap_firmware_file.fd);

	return rv;
}

DECLARE_FUTIL_COMMAND(gscvd, do_gscvd, VBOOT_VERSION_2_1,
		      "Create RO verification structure");
