/*
 * 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'},
	{"add_gbb",       0, NULL, 'G'},
	{"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:Gb: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"
	"  -G|--add_gbb                     Add the `GBB` FMAP section to the\n"
	"                                     ranges covered by the signature.\n"
	"                                     This option takes special care\n"
	"                                     to exclude the HWID (and its\n"
	"                                     digest) from this range.\n"
	"  -b|--board_id  <string|hex>      The Board ID of the board for\n"
	"                                     which the image is signed.\n"
	"                                     Can be passed as a 4-letter\n"
	"                                     string or a hexadecimal number.\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 mode)
{
	if (futil_open_and_map_file(file_name, &file->fd, mode, &file->data,
				    &file->len))
		return 1;

	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");
		futil_unmap_and_close_file(file->fd, mode, file->data,
					   file->len);
		file->fd = -1;
		file->data = NULL;
		file->len = 0;
		return 1;
	}

	return 0;
}

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

	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;
	FmapAreaHeader *si_all;
	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;
	}

	/* Intel boards can have an SI_ALL region that's not in WP_RO but is
	   protected by platform-specific mechanisms, and may still contain
	   components that we want to protect from physical attack. */
	if (!fmap_find_by_name(file->data, file->len, NULL, "SI_ALL", &si_all))
		si_all = NULL;

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

		/* Must fit into WP_RO or SI_ALL. */
		if (!range_fits(ranges->ranges + i, wp_ro) &&
		    (!si_all || !range_fits(ranges->ranges + i, si_all))) {
			ERROR("Range %#x..+%#x does not fit in WP_RO/SI_ALL\n",
				ranges->ranges[i].offset,
				ranges->ranges[i].size);
			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;
	}

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

/**
 * Add GBB to ranges.
 *
 * Splits the `GBB` FMAP section into separate ranges to exclude the HWID string
 * and the `hwid_digest` field in the header. Will also exclude the empty area
 * behind the end of the actual GBB data.
 *
 * @param ranges pointer to the ranges container
 * @param file   pointer to the AP firmware file layout descriptor
 */
static int add_gbb(struct gscvd_ro_ranges *ranges, const struct file_buf *file)
{
	FmapAreaHeader *area;

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

	struct vb2_gbb_header *gbb = (void *)file->data + area->area_offset;
	uint32_t maxlen;

	if (!futil_valid_gbb_header(gbb, area->area_size, &maxlen)) {
		ERROR("GBB is invalid.\n");
		return 1;
	}

	/*
	 * This implementation relies on the fact that no meaningful fields come
	 * after the `hwid_digest` field in the header. If we ever make new GBB
	 * versions that add more fields, the code below needs to be adapted.
	 * Older versions than 1.2 or GBBs with a bmpblk are not expected with
	 * GSCVD images.
	 */
	if (gbb->major_version != 1 || gbb->minor_version != 2 ||
	    gbb->bmpfv_size != 0) {
		ERROR("Unsupported GBB version.\n");
		return 1;
	}

	uint32_t lower_key_offset = VB2_MIN(gbb->rootkey_offset,
					    gbb->recovery_key_offset);
	if (gbb->hwid_offset > lower_key_offset) {
		ERROR("Weird GBB layout (HWID should come first)\n");
		return 1;
	}

	if (ranges->range_count >= ARRAY_SIZE(ranges->ranges) - 2) {
		ERROR("Too many ranges, can't fit GBB!\n");
		return 1;
	}

	ranges->ranges[ranges->range_count].offset = area->area_offset;
	ranges->ranges[ranges->range_count].size =
				offsetof(struct vb2_gbb_header, hwid_digest);
	ranges->range_count++;

	ranges->ranges[ranges->range_count].offset = area->area_offset +
						     lower_key_offset;
	ranges->ranges[ranges->range_count].size = maxlen - lower_key_offset;
	ranges->range_count++;

	return 0;
}

/**
 * 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, FILE_RO))
			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)) {
			ERROR("Keyblock not signed by root key\n");
			break;
		}

		if (validate_gvd_signature(gvd, &kblock->data_key)) {
			ERROR("GVD not signed by platform key\n");
			break;
		}

		rv = 0;
	} while (false);

	if (ap_firmware_file.fd != -1)
		futil_unmap_and_close_file(ap_firmware_file.fd, FILE_RO,
					   ap_firmware_file.data,
					   ap_firmware_file.len);

	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;
	bool do_gbb = false;
	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 'G':
			do_gbb = true;
			break;
		case 'b': {
			char *e;
			long long bid;

			if (strlen(optarg) == 4) {
				board_id = optarg[0] << 24 |
					   optarg[1] << 16 |
					   optarg[2] << 8 |
					   optarg[3];
				break;
			}

			bid = strtoull(optarg, &e, 16);
			if (*e || (bid >= UINT32_MAX)) {
				ERROR("Cannot parse Board ID '%s'\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");
		goto usage_out;
	}

	if (errorcount) /* Error message(s) should have been printed by now. */
		goto usage_out;

	if (!root_pubk) {
		ERROR("Missing --root_pub_key argument\n");
		goto usage_out;
	}

	if (!kblock) {
		ERROR("Missing --keyblock argument\n");
		goto usage_out;
	}

	if (!plat_privk) {
		ERROR("Missing --platform_priv argument\n");
		goto usage_out;
	}

	if (board_id == UINT32_MAX) {
		ERROR("Missing --board_id argument\n");
		goto usage_out;
	}

	if (!ranges.range_count && !do_gbb) {
		ERROR("Missing --ranges argument\n");
		goto usage_out;
	}

	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, FILE_RW))
			break;

		if (do_gbb && add_gbb(&ranges, &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);

	if (ap_firmware_file.fd != -1)
		futil_unmap_and_close_file(ap_firmware_file.fd, FILE_RW,
					   ap_firmware_file.data,
					   ap_firmware_file.len);

	return rv;

usage_out:
	fputs(usage, stderr);
	return 1;
}

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