/* Copyright 2016 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.
 *
 * Common boot flow utility
 */

#include <getopt.h>
#include <stdio.h>
#include <unistd.h>

#include "2sysincludes.h"
#include "2common.h"
#include "bdb.h"
#include "bdb_struct.h"
#include "futility.h"
#include "host.h"

static long int version;

/* Command line options */
enum {
	/* mode options */
	OPT_MODE_NONE,
	OPT_MODE_ADD,
	OPT_MODE_CREATE,
	OPT_MODE_RESIGN,
	OPT_MODE_VERIFY,
	/* file options */
	OPT_BDBKEY_PRI,
	OPT_BDBKEY_PUB,
	OPT_DATAKEY_PRI,
	OPT_DATAKEY_PUB,
	OPT_DATA,
	OPT_KEY_DIGEST,
	/* versions */
	OPT_BDBKEY_VERSION,
	OPT_DATAKEY_VERSION,
	OPT_DATA_VERSION,
	/* integer options */
	OPT_OFFSET,
	OPT_PARTITION,
	OPT_TYPE,
	OPT_LOAD_ADDRESS,
	/* Misc. options */
	OPT_IGNORE_KEY_DIGEST,
	OPT_VERSION,
	OPT_HELP,
};

static const struct option long_opts[] = {
	{"add", 1, 0, OPT_MODE_ADD},
	{"create", 1, 0, OPT_MODE_CREATE},
	{"resign", 1, 0, OPT_MODE_RESIGN},
	{"verify", 1, 0, OPT_MODE_VERIFY},
	{"bdbkey_pri", 1, 0, OPT_BDBKEY_PRI},
	{"bdbkey_pub", 1, 0, OPT_BDBKEY_PUB},
	{"datakey_pri", 1, 0, OPT_DATAKEY_PRI},
	{"datakey_pub", 1, 0, OPT_DATAKEY_PUB},
	{"bdbkey_version", 1, 0, OPT_BDBKEY_VERSION},
	{"datakey_version", 1, 0, OPT_DATAKEY_VERSION},
	{"data_version", 1, 0, OPT_DATA_VERSION},
	{"data", 1, 0, OPT_DATA},
	{"key_digest", 1, 0, OPT_KEY_DIGEST},
	{"offset", 1, 0, OPT_OFFSET},
	{"partition", 1, 0, OPT_PARTITION},
	{"type", 1, 0, OPT_TYPE},
	{"load_address", 1, 0, OPT_LOAD_ADDRESS},
	{"ignore_key_digest", 0, 0, OPT_IGNORE_KEY_DIGEST},
	{"version", 1, 0, OPT_VERSION},
	{"help", 0, 0, OPT_HELP},
	{NULL, 0, 0, 0}
};

/**
 * Add hash entry to BDB
 *
 * This adds a hash entry to a BDB. It does not change the signature. Hence,
 * the produced BDB needs to be resigned using the resign sub-command.
 */
static int do_add(const char *bdb_filename, const char *data_filename,
		  uint64_t offset, uint8_t partition,
		  uint8_t type, uint64_t load_address)
{
	uint8_t *bdb, *data, *new_bdb = NULL;
	uint32_t bdb_size, data_size;
	struct bdb_header *bdb_header;
	struct bdb_data *data_header;
	struct bdb_hash *new_hash;
	int rv = -1;

	bdb = read_file(bdb_filename, &bdb_size);
	data = read_file(data_filename, &data_size);
	if (!bdb || !data) {
		fprintf(stderr, "Unable to load BDB or data\n");
		goto exit;
	}

	/* Create a copy of BDB */
	new_bdb = calloc(1, bdb_size + sizeof(*new_hash));
	if (!new_bdb) {
		fprintf(stderr, "Unable to allocate memory\n");
		goto exit;
	}
	/* Copy up to the end of hashes. This implicitly clears the data
	 * sig because it's not copied. */
	memcpy(new_bdb, bdb, vb2_offset_of(bdb, bdb_get_data_sig(bdb)));

	/* Update new BDB header */
	bdb_header = (struct bdb_header *)bdb_get_header(new_bdb);
	bdb_header->bdb_size += sizeof(*new_hash);

	data_header = (struct bdb_data *)bdb_get_data(new_bdb);

	/* Update new hash. We're overwriting the data signature, which
	 * is already invalid anyway. */
	new_hash = (struct bdb_hash *)((uint8_t *)data_header
			+ data_header->signed_size);
	new_hash->size = data_size;
	new_hash->type = type;
	new_hash->load_address = load_address;
	new_hash->partition = partition;
	new_hash->offset = offset;
	if (bdb_sha256(new_hash->digest, data, data_size)) {
		fprintf(stderr, "Unable to calculate hash\n");
		goto exit;
	}

	/* Update data header */
	data_header->num_hashes++;
	data_header->signed_size += sizeof(*new_hash);

	rv = write_file(bdb_filename, bdb_header, bdb_header->bdb_size);
	if (rv) {
		fprintf(stderr, "Unable to write BDB\n");
		goto exit;
	}

	fprintf(stderr, "Hash is added to BDB successfully. Resign required\n");

exit:
	free(bdb);
	free(data);
	free(new_bdb);

	return rv;
}

/**
 * Create a new BDB
 *
 * This creates a new BDB using a pair of BDB keys and a pair of data keys.
 * A private data key is needed even with no hash entries.
 */
static int do_create(const char *bdb_filename,
		     const char *bdbkey_pri_filename,
		     const char *bdbkey_pub_filename,
		     uint32_t bdbkey_version,
		     const char *datakey_pri_filename,
		     const char *datakey_pub_filename,
		     uint32_t datakey_version,
		     uint64_t load_address)
{
	struct bdb_key *bdbkey;
	struct bdb_key *datakey;
	struct rsa_st *bdbkey_pri;
	struct rsa_st *datakey_pri;
	struct bdb_create_params params;
	struct bdb_header *header;
	int rv = -1;

	/* Check arguments */
	if (!bdb_filename || !bdbkey_pri_filename || !bdbkey_pub_filename
			|| !datakey_pri_filename || !datakey_pub_filename) {
		fprintf(stderr, "Missing filenames\n");
		return rv;
	}

	/* Load keys */
	bdbkey = bdb_create_key(bdbkey_pub_filename, bdbkey_version, NULL);
	bdbkey_pri = read_pem(bdbkey_pri_filename);
	datakey = bdb_create_key(datakey_pub_filename, datakey_version, NULL);
	datakey_pri = read_pem(datakey_pri_filename);
	if (!bdbkey || !bdbkey_pri || !datakey || !datakey_pri) {
		fprintf(stderr, "Unable to load keys\n");
		goto exit;
	}

	memset(&params, 0, sizeof(params));
	params.bdb_load_address = load_address;
	params.bdbkey = bdbkey;
	params.datakey = datakey;
	params.private_bdbkey = bdbkey_pri;
	params.private_datakey = datakey_pri;
	params.num_hashes = 0;

	header = bdb_create(&params);
	if (!header) {
		fprintf(stderr, "Unable to create BDB\n");
		goto exit;
	}

	rv = write_file(bdb_filename, header, header->bdb_size);
	if (rv) {
		fprintf(stderr, "Unable to write BDB\n");
		goto exit;
	}

	fprintf(stderr, "BDB is created successfully\n");

exit:
	/* Free keys and buffers */
	free(bdbkey);
	free(datakey);
	RSA_free(bdbkey_pri);
	RSA_free(datakey_pri);

	return rv;
}

static int install_bdbkey(uint8_t **bdb, const struct bdb_key *new_key)
{
	struct bdb_header *header;
	const struct bdb_key *key;
	uint8_t *p, *q;
	uint8_t *new_bdb;
	size_t new_size;
	size_t l;

	header = (struct bdb_header *)bdb_get_header(*bdb);
	key = bdb_get_bdbkey(*bdb);
	new_size = bdb_size_of(*bdb) + new_key->struct_size - key->struct_size;
	new_bdb = calloc(1, new_size);
	if (!new_bdb) {
		fprintf(stderr, "Unable to allocate memory\n");
		return -1;
	}

	/* copy BDB header */
	p = *bdb;
	q = new_bdb;
	l = header->struct_size;
	memcpy(q, p, l);

	/* copy new BDB key */
	p += l;
	q += l;
	memcpy(q, new_key, new_key->struct_size);

	/* copy the rest */
	p += key->struct_size;
	q += new_key->struct_size;
	l = bdb_size_of(*bdb) - vb2_offset_of(*bdb, p);
	memcpy(q, p, l);

	/* update size */
	header = (struct bdb_header *)bdb_get_header(new_bdb);
	header->bdb_size = new_size;

	free(*bdb);
	*bdb = new_bdb;

	return 0;
}

static int install_datakey(uint8_t **bdb, const struct bdb_key *new_key)
{
	struct bdb_header *header;
	struct bdb_key *key;
	uint8_t *p, *q;
	uint8_t *new_bdb;
	size_t new_size;
	uint32_t l;

	key = (struct bdb_key *)bdb_get_datakey(*bdb);
	new_size = bdb_size_of(*bdb) + new_key->struct_size - key->struct_size;
	new_bdb = calloc(1, new_size);
	if (!new_bdb) {
		fprintf(stderr, "Unable to allocate memory\n");
		return -1;
	}

	/* copy the stuff up to datakey */
	p = *bdb;
	q = new_bdb;
	l = bdb_offset_of_datakey(*bdb);
	memcpy(q, p, l);

	/* copy new data key */
	p += l;
	q += l;
	memcpy(q, new_key, new_key->struct_size);

	/* copy the rest */
	p += key->struct_size;
	q += new_key->struct_size;
	l = bdb_size_of(*bdb) - vb2_offset_of(*bdb, p);
	memcpy(q, p, l);

	/* update size */
	header = (struct bdb_header *)bdb_get_header(new_bdb);
	header->bdb_size = new_size;
	header->signed_size = header->oem_area_0_size + new_key->struct_size;

	free(*bdb);
	*bdb = new_bdb;

	return 0;
}
/**
 * Resign a BDB using new keys
 *
 * It first installs given public keys to the BDB, then, runs verification.
 * If verification fails due to an invalid signature, it tries to 'fix' it
 * by resigning it using a given private key, then runs verification again.
 * Whether a key is required or not depends on which signature is invalid.
 * If a private key is required but not provided, it returns an error.
 */
static int do_resign(const char *bdb_filename,
		     const char *bdbkey_pri_filename,
		     const char *bdbkey_pub_filename,
		     uint32_t bdbkey_version,
		     const char *datakey_pri_filename,
		     const char *datakey_pub_filename,
		     uint32_t datakey_version,
		     uint32_t data_version)
{
	uint8_t *bdb = NULL;
	struct rsa_st *bdbkey_pri = NULL;
	struct rsa_st *datakey_pri = NULL;
	uint32_t bdb_size;
	int resigned = 0;
	int rv = -1;

	if (!bdb_filename) {
		fprintf(stderr, "BDB file must be specified\n");
		goto exit;
	}

	bdb = read_file(bdb_filename, &bdb_size);
	if (!bdb) {
		fprintf(stderr, "Unable to read %s\n", bdb_filename);
		goto exit;
	}

	if (data_version != -1) {
		struct bdb_data *data = (struct bdb_data *)bdb_get_data(bdb);
		data->data_version = data_version;
	}

	if (bdbkey_pub_filename) {
		struct bdb_key *key = bdb_create_key(bdbkey_pub_filename,
						     bdbkey_version, NULL);
		if (!key) {
			fprintf(stderr, "Unable to read BDB key\n");
			goto exit;
		}
		if (install_bdbkey(&bdb, key)) {
			fprintf(stderr, "Unable to install new BDB key\n");
			goto exit;
		}
	}

	if (datakey_pub_filename) {
		struct bdb_key *key = bdb_create_key(datakey_pub_filename,
						     datakey_version, NULL);
		if (!key) {
			fprintf(stderr, "Unable to read data key\n");
			goto exit;
		}
		if (install_datakey(&bdb, key)) {
			fprintf(stderr, "Unable to install new data key\n");
			goto exit;
		}
	}

	/* Check validity for the new bdb key */
	rv = bdb_verify(bdb, bdb_size_of(bdb), NULL);
	if (rv == BDB_ERROR_HEADER_SIG) {
		/* This is expected failure if we installed a new BDB key.
		 * Let's resign to fix it. */
		resigned = 1;
		fprintf(stderr, "Data key signature is invalid. Need to resign "
			"the key.\n");
		if (!bdbkey_pri_filename) {
			fprintf(stderr, "Private BDB key is required but not "
				"provided.\n");
			goto exit;
		}
		bdbkey_pri = read_pem(bdbkey_pri_filename);
		rv = bdb_sign_datakey(&bdb, bdbkey_pri);
		if (rv) {
			fprintf(stderr, "Failed to resign data key: %d\n", rv);
			goto exit;
		}
		fprintf(stderr, "Data key is resigned.\n");
	} else {
		fprintf(stderr, "Resigning data key is not required.\n");
	}

	/* Check validity for the new data key */
	rv = bdb_verify(bdb, bdb_size_of(bdb), NULL);
	switch (rv) {
	case BDB_ERROR_DATA_SIG:
	case BDB_ERROR_DATA_CHECK_SIG:
		/* This is expected failure if we installed a new data key
		 * or sig is corrupted, which happens when a new hash is added
		 * by 'add' sub-command. Let's resign the data */
		resigned = 1;
		fprintf(stderr,
			"Data signature is invalid. Need to resign data.\n");
		if (!datakey_pri_filename) {
			fprintf(stderr, "Private data key is required but not "
				"provided.\n");
			goto exit;
		}
			datakey_pri = read_pem(datakey_pri_filename);
			rv = bdb_sign_data(&bdb, datakey_pri);
			if (rv) {
			fprintf(stderr, "Failed to resign hashes: %d\n", rv);
				goto exit;
			}
		fprintf(stderr, "Data is resigned.\n");
		break;
	case BDB_GOOD_OTHER_THAN_KEY:
	case BDB_SUCCESS:
		fprintf(stderr, "Resigning the data is not required.\n");
		break;
	default:
		fprintf(stderr, "Verifying BDB failed unexpectedly: %d\n", rv);
			goto exit;
	}

	if (!resigned)
		goto exit;

	/* Check validity one last time */
	rv = bdb_verify(bdb, bdb_size_of(bdb), NULL);
	if (rv && rv != BDB_GOOD_OTHER_THAN_KEY) {
		/* This is not expected. We installed new keys and resigned
		 * BDB but it's still invalid. */
		fprintf(stderr, "BDB is resigned but it's invalid: %d\n", rv);
		goto exit;
	}

	rv = write_file(bdb_filename, bdb, bdb_size_of(bdb));
	if (rv) {
		fprintf(stderr, "Unable to write BDB.\n");
		goto exit;
	}

	fprintf(stderr, "Successfully resigned BDB.\n");

exit:
	free(bdb);
	RSA_free(bdbkey_pri);
	RSA_free(datakey_pri);

	return rv;
}

static int do_verify(const char *bdb_filename, const char *key_digest_filename,
		     int ignore_key_digest)
{
	uint8_t *bdb = NULL;
	uint8_t *key_digest = NULL;
	uint32_t bdb_size, key_digest_size;
	int rv = -1;

	bdb = read_file(bdb_filename, &bdb_size);
	if (!bdb) {
		fprintf(stderr, "Unable to load BDB\n");
		goto exit;
	}

	if (key_digest_filename) {
		key_digest = read_file(key_digest_filename, &key_digest_size);
		if (!key_digest) {
			fprintf(stderr, "Unable to read key digest\n");
			goto exit;
		}
		if (key_digest_size != BDB_SHA256_DIGEST_SIZE) {
			fprintf(stderr,
				"Invalid digest size: %d\n", key_digest_size);
			goto exit;
		}
	}

	rv = bdb_verify(bdb, bdb_size, key_digest);
	switch (rv) {
	case BDB_SUCCESS:
		fprintf(stderr, "BDB is successfully verified.\n");
		break;
	case BDB_GOOD_OTHER_THAN_KEY:
		fprintf(stderr, "BDB is valid.");
		if (ignore_key_digest) {
			rv = BDB_SUCCESS;
			fprintf(stderr,
				" Key digest doesn't match but ignored.\n");
		} else {
			fprintf(stderr,
				" Key digest doesn't match.\n");
		}
		break;
	default:
		/* TODO: Probably nice to print translation of the error code */
		fprintf(stderr, "BDB is invalid: %d.\n", rv);
	}

exit:
	free(bdb);
	free(key_digest);

	return rv;
}

/* Print help and return error */
static void print_help(int argc, char *argv[])
{
	printf("\nUsage: " MYNAME " %s <--create|--add|--resign|--verify>\n"
	       "\n"
	       "Utility for managing boot descriptor blocks (BDBs).\n"
	       "\n"
	       "For '--add <bdb_file> [OPTIONS]', required OPTIONS are:\n"
	       "  --data <file>               Data to be added\n"
	       "  --offset <offset>           Offset\n"
	       "  --partition <number>        Partition number\n"
	       "  --type <number>             Data type\n"
	       "  --load_address <number>     Data load address\n"
	       "\n"
	       "For '--create <bdb_file> [OPTIONS]', required OPTIONS are:\n"
	       "  --bdbkey_pri <file>         BDB key in .pem format\n"
	       "  --bdbkey_pub <file>         BDB key in .keyb format\n"
	       "  --datakey_pri <file>        Data key in .pem format\n"
	       "  --datakey_pub <file>        Data key in .keyb format\n"
	       "  --load_address <number>     BDB load address\n"
	       "\n"
	       "For '--resign <bdb_file> [OPTIONS]', optional OPTIONS are:\n"
	       "  --bdbkey_pri <file>         New BDB key in .pem format\n"
	       "  --bdbkey_pub <file>         New BDB key in .keyb format\n"
	       "  --datakey_pri <file>        New data key in .pem format\n"
	       "  --datakey_pub <file>        New data key in .keyb format\n"
	       "  --data_version <number>     Data version\n"
	       "\n"
	       "For '--verify <bdb_file> [OPTIONS]', optional OPTIONS are:\n"
	       "  --key_digest <file>         BDB key digest\n"
	       "  --ignore_key_digest         Ignore key digest mismatch\n"
	       "\n",
	       argv[0]);
}

static int do_bdb(int argc, char *argv[])
{
	int mode = 0;
	const char *bdb_filename = NULL;
	const char *bdbkey_pri_filename = NULL;
	const char *bdbkey_pub_filename = NULL;
	const char *datakey_pri_filename = NULL;
	const char *datakey_pub_filename = NULL;
	const char *data_filename = NULL;
	const char *key_digest_filename = NULL;
	uint32_t bdbkey_version = 0;
	uint32_t datakey_version = 0;
	uint32_t data_version = -1;
	uint64_t offset = 0;
	uint8_t partition = 0;
	uint8_t type = 0;
	uint64_t load_address = -1;
	int ignore_key_digest = 0;
	int parse_error = 0;
	char *e;
	int i;

	while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
		switch (i) {
		case '?':
			/* Unhandled option */
			fprintf(stderr, "Unknown option or missing value\n");
			parse_error = 1;
			break;
		case OPT_HELP:
			print_help(argc, argv);
			return !!parse_error;
		case OPT_MODE_CREATE:
			mode = i;
			bdb_filename = optarg;
			break;
		case OPT_MODE_ADD:
			mode = i;
			bdb_filename = optarg;
			break;
		case OPT_MODE_RESIGN:
			mode = i;
			bdb_filename = optarg;
			break;
		case OPT_MODE_VERIFY:
			mode = i;
			bdb_filename = optarg;
			break;
		case OPT_BDBKEY_PRI:
			bdbkey_pri_filename = optarg;
			break;
		case OPT_BDBKEY_PUB:
			bdbkey_pub_filename = optarg;
			break;
		case OPT_DATAKEY_PRI:
			datakey_pri_filename = optarg;
			break;
		case OPT_DATAKEY_PUB:
			datakey_pub_filename = optarg;
			break;
		case OPT_DATA:
			data_filename = optarg;
			break;
		case OPT_KEY_DIGEST:
			key_digest_filename = optarg;
			break;
		case OPT_BDBKEY_VERSION:
			bdbkey_version = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr, "Invalid --bdbkey_version\n");
				parse_error = 1;
			}
			break;
		case OPT_DATAKEY_VERSION:
			datakey_version = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr, "Invalid --datakey_version\n");
				parse_error = 1;
			}
			break;
		case OPT_DATA_VERSION:
			data_version = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr, "Invalid --data_version\n");
				parse_error = 1;
			}
			break;
		case OPT_OFFSET:
			offset = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr, "Invalid --offset\n");
				parse_error = 1;
			}
			break;
		case OPT_PARTITION:
			partition = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr, "Invalid --partition\n");
				parse_error = 1;
			}
			break;
		case OPT_TYPE:
			type = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr, "Invalid --type\n");
				parse_error = 1;
			}
			break;
		case OPT_LOAD_ADDRESS:
			load_address = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr, "Invalid --load_address\n");
				parse_error = 1;
			}
			break;
		case OPT_IGNORE_KEY_DIGEST:
			ignore_key_digest = 1;
			break;
		case OPT_VERSION:
			version = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr, "Invalid --version\n");
				parse_error = 1;
			}
			break;
		}
	}

	if (parse_error) {
		print_help(argc, argv);
		return 1;
	}

	switch (mode) {
	case OPT_MODE_ADD:
		return do_add(bdb_filename, data_filename,
			      offset, partition, type, load_address);
	case OPT_MODE_CREATE:
		return do_create(bdb_filename, bdbkey_pri_filename,
				 bdbkey_pub_filename, bdbkey_version,
				 datakey_pri_filename, datakey_pub_filename,
				 datakey_version, load_address);
	case OPT_MODE_RESIGN:
		return do_resign(bdb_filename, bdbkey_pri_filename,
				 bdbkey_pub_filename, bdbkey_version,
				 datakey_pri_filename, datakey_pub_filename,
				 datakey_version, data_version);
	case OPT_MODE_VERIFY:
		return do_verify(bdb_filename,
				 key_digest_filename, ignore_key_digest);
	case OPT_MODE_NONE:
	default:
		fprintf(stderr, "Must specify a mode.\n");
		print_help(argc, argv);
		return 1;
	}
}

DECLARE_FUTIL_COMMAND(bdb, do_bdb, VBOOT_VERSION_1_0,
		      "Common boot flow utility");
