/*
 * Copyright 2014 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 <getopt.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "futility.h"

static void print_help(int argc, char *argv[])
{
	printf("\n"
		"Usage:  " MYNAME " %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"
		"     --digest        \tReport digest of hwid (>= v1.2)\n"
	        "     --roothash      \tCheck ryu root key hash\n"
		" -k, --rootkey=FILE  \tFile name to export Root Key.\n"
		" -b, --bmpfv=FILE    \tFile name to export Bitmap FV.\n"
		" -r  --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"
		"     --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"
		" -r  --recoverykey=FILE\tFile name of new Recovery Key.\n"
		"\n"
		"CREATE MODE:\n"
		"-c, --create=hwid_size,rootkey_size,bmpfv_size,"
		"recoverykey_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\n",
		argv[0], argv[0], argv[0], argv[0]);
}

enum {
	OPT_HWID = 1000,
	OPT_FLAGS,
	OPT_DIGEST,
	OPT_HELP,
	OPT_ROOTHASH,
};

/* Command line options */
static struct option long_opts[] = {
	/* name  has_arg *flag val */
	{"get", 0, NULL, 'g'},
	{"set", 0, NULL, 's'},
	{"create", 1, NULL, 'c'},
	{"output", 1, NULL, 'o'},
	{"rootkey", 1, NULL, 'k'},
	{"bmpfv", 1, NULL, 'b'},
	{"recoverykey", 1, NULL, 'r'},
	{"hwid", 0, NULL, OPT_HWID},
	{"flags", 0, NULL, OPT_FLAGS},
	{"digest", 0, NULL, OPT_DIGEST},
	{"help", 0, NULL, OPT_HELP},
	{"roothash", 0, NULL, OPT_ROOTHASH},
	{NULL, 0, NULL, 0},
};

static const char *short_opts = ":gsc:o:k:b:r:";

/* Change the has_arg field of a long_opts entry */
static void opt_has_arg(const char *name, int val)
{
	struct option *p;
	for (p = long_opts; p->name; p++)
		if (!strcmp(name, p->name)) {
			p->has_arg = val;
			break;
		}
}

static int errorcnt;

#define GBB_SEARCH_STRIDE 4
static struct vb2_gbb_header *FindGbbHeader(uint8_t *ptr, size_t size)
{
	size_t i;
	struct vb2_gbb_header *tmp, *gbb_header = NULL;
	int count = 0;

	for (i = 0; i <= size - GBB_SEARCH_STRIDE; i += GBB_SEARCH_STRIDE) {
		if (0 != memcmp(ptr + i, VB2_GBB_SIGNATURE,
				VB2_GBB_SIGNATURE_SIZE))
			continue;

		/* Found something. See if it's any good. */
		tmp = (struct vb2_gbb_header *) (ptr + i);
		if (futil_valid_gbb_header(tmp, size - i, NULL))
			if (!count++)
				gbb_header = tmp;
	}

	switch (count) {
	case 0:
		errorcnt++;
		return NULL;
	case 1:
		return gbb_header;
	default:
		fprintf(stderr, "ERROR: multiple GBB headers found\n");
		errorcnt++;
		return NULL;
	}
}

static uint8_t *create_gbb(const char *desc, off_t *sizeptr)
{
	char *str, *sizes, *param, *e = NULL;
	size_t size = EXPECTED_VB2_GBB_HEADER_SIZE;
	int i = 0;
	/* Danger Will Robinson! four entries ==> four paramater blocks */
	uint32_t val[] = { 0, 0, 0, 0 };
	uint8_t *buf;
	struct vb2_gbb_header *gbb;

	sizes = strdup(desc);
	if (!sizes) {
		errorcnt++;
		fprintf(stderr, "ERROR: strdup() failed: %s\n",
			strerror(errno));
		return NULL;
	}

	for (str = sizes; (param = strtok(str, ", ")) != NULL; str = NULL) {
		val[i] = (uint32_t) strtoul(param, &e, 0);
		if (e && *e) {
			errorcnt++;
			fprintf(stderr,
				"ERROR: invalid creation parameter: \"%s\"\n",
				param);
			free(sizes);
			return NULL;
		}
		size += val[i++];
		if (i > ARRAY_SIZE(val))
			break;
	}

	buf = (uint8_t *) calloc(1, size);
	if (!buf) {
		errorcnt++;
		fprintf(stderr, "ERROR: can't malloc %zu bytes: %s\n",
			size, strerror(errno));
		free(sizes);
		return NULL;
	} else if (sizeptr) {
		*sizeptr = size;
	}

	gbb = (struct vb2_gbb_header *) buf;
	memcpy(gbb->signature, VB2_GBB_SIGNATURE, VB2_GBB_SIGNATURE_SIZE);
	gbb->major_version = VB2_GBB_MAJOR_VER;
	gbb->minor_version = VB2_GBB_MINOR_VER;
	gbb->header_size = EXPECTED_VB2_GBB_HEADER_SIZE;
	gbb->flags = 0;

	i = EXPECTED_VB2_GBB_HEADER_SIZE;
	gbb->hwid_offset = i;
	gbb->hwid_size = val[0];
	i += val[0];

	gbb->rootkey_offset = i;
	gbb->rootkey_size = val[1];
	i += val[1];

	gbb->bmpfv_offset = i;
	gbb->bmpfv_size = val[2];
	i += val[2];

	gbb->recovery_key_offset = i;
	gbb->recovery_key_size = val[3];
	i += val[1];

	free(sizes);
	return buf;
}

static uint8_t *read_entire_file(const char *filename, off_t *sizeptr)
{
	FILE *fp = NULL;
	uint8_t *buf = NULL;
	struct stat sb;

	fp = fopen(filename, "rb");
	if (!fp) {
		fprintf(stderr, "ERROR: Unable to open %s for reading: %s\n",
			filename, strerror(errno));
		goto fail;
	}

	if (0 != fstat(fileno(fp), &sb)) {
		fprintf(stderr, "ERROR: can't fstat %s: %s\n",
			filename, strerror(errno));
		goto fail;
	}
	if (sizeptr)
		*sizeptr = sb.st_size;

	buf = (uint8_t *) malloc(sb.st_size);
	if (!buf) {
		fprintf(stderr, "ERROR: can't malloc %" PRIi64 " bytes: %s\n",
			sb.st_size, strerror(errno));
		goto fail;
	}

	if (1 != fread(buf, sb.st_size, 1, fp)) {
		fprintf(stderr, "ERROR: Unable to read from %s: %s\n",
			filename, strerror(errno));
		goto fail;
	}

	if (0 != fclose(fp)) {
		fprintf(stderr, "ERROR: Unable to close %s: %s\n",
			filename, strerror(errno));
		fp = NULL;  /* Don't try to close it again */
		goto fail;
	}

	return buf;

fail:
	errorcnt++;

	if (buf)
		free(buf);

	if (fp && 0 != fclose(fp))
		fprintf(stderr, "ERROR: Unable to close %s: %s\n",
			filename, strerror(errno));
	return NULL;
}

static int write_to_file(const char *msg, const char *filename,
			 uint8_t *start, size_t size)
{
	FILE *fp;
	int r = 0;

	fp = fopen(filename, "wb");
	if (!fp) {
		fprintf(stderr, "ERROR: Unable to open %s for writing: %s\n",
			filename, strerror(errno));
		errorcnt++;
		return errno;
	}

	/* Don't write zero bytes */
	if (size && 1 != fwrite(start, size, 1, fp)) {
		fprintf(stderr, "ERROR: Unable to write to %s: %s\n",
			filename, strerror(errno));
		errorcnt++;
		r = errno;
	}

	if (0 != fclose(fp)) {
		fprintf(stderr, "ERROR: Unable to close %s: %s\n",
			filename, strerror(errno));
		errorcnt++;
		if (!r)
			r = errno;
	}

	if (!r && msg)
		printf("%s %s\n", msg, filename);

	return r;
}

static int read_from_file(const char *msg, const char *filename,
			  uint8_t *start, uint32_t size)
{
	FILE *fp;
	struct stat sb;
	size_t count;
	int r = 0;

	fp = fopen(filename, "rb");
	if (!fp) {
		fprintf(stderr, "ERROR: Unable to open %s for reading: %s\n",
			filename, strerror(errno));
		errorcnt++;
		return errno;
	}

	if (0 != fstat(fileno(fp), &sb)) {
		fprintf(stderr, "ERROR: can't fstat %s: %s\n",
			filename, strerror(errno));
		errorcnt++;
		r = errno;
		goto done_close;
	}

	if (sb.st_size > size) {
		fprintf(stderr,
			"ERROR: file %s exceeds capacity (%" PRIu32 ")\n",
			filename, size);
		errorcnt++;
		r = errno;
		goto done_close;
	}

	/* Wipe existing data. */
	memset(start, 0, size);

	/* It's okay if we read less than size. That's just the max. */
	count = fread(start, 1, size, fp);
	if (ferror(fp)) {
		fprintf(stderr,
			"ERROR: Read %zu/%" PRIi64 " bytes from %s: %s\n",
			count, sb.st_size, filename, strerror(errno));
		errorcnt++;
		r = errno;
	}

done_close:
	if (0 != fclose(fp)) {
		fprintf(stderr, "ERROR: Unable to close %s: %s\n",
			filename, strerror(errno));
		errorcnt++;
		if (!r)
			r = errno;
	}

	if (!r && msg)
		printf(" - import %s from %s: success\n", msg, filename);

	return r;
}

static int do_gbb(int argc, char *argv[])
{
	enum do_what_now { DO_GET, DO_SET, DO_CREATE } mode = DO_GET;
	char *infile = NULL;
	char *outfile = NULL;
	char *opt_create = NULL;
	char *opt_rootkey = NULL;
	char *opt_bmpfv = NULL;
	char *opt_recoverykey = NULL;
	char *opt_hwid = NULL;
	char *opt_flags = NULL;
	int sel_hwid = 0;
	int sel_digest = 0;
	int sel_flags = 0;
	int sel_roothash = 0;
	uint8_t *inbuf = NULL;
	off_t filesize;
	uint8_t *outbuf = NULL;
	struct vb2_gbb_header *gbb;
	uint8_t *gbb_base;
	int i;

	opterr = 0;		/* quiet, you */
	while ((i = getopt_long(argc, argv, short_opts, long_opts, 0)) != -1) {
		switch (i) {
		case 'g':
			mode = DO_GET;
			opt_has_arg("flags", 0);
			opt_has_arg("hwid", 0);
			break;
		case 's':
			mode = DO_SET;
			opt_has_arg("flags", 1);
			opt_has_arg("hwid", 1);
			break;
		case 'c':
			mode = DO_CREATE;
			opt_create = optarg;
			break;
		case 'o':
			outfile = optarg;
			break;
		case 'k':
			opt_rootkey = optarg;
			break;
		case 'b':
			opt_bmpfv = optarg;
			break;
		case 'r':
			opt_recoverykey = optarg;
			break;
		case OPT_HWID:
			/* --hwid is optional: null might be okay */
			opt_hwid = optarg;
			sel_hwid = 1;
			break;
		case OPT_FLAGS:
			/* --flags is optional: null might be okay */
			opt_flags = optarg;
			sel_flags = 1;
			break;
		case OPT_DIGEST:
			sel_digest = 1;
			break;
		case OPT_ROOTHASH:
			sel_roothash = 1;
			break;
		case OPT_HELP:
			print_help(argc, argv);
			return !!errorcnt;

		case '?':
			errorcnt++;
			if (optopt)
				fprintf(stderr,
					"ERROR: unrecognized option: -%c\n",
					optopt);
			else if (argv[optind - 1])
				fprintf(stderr,
					"ERROR: unrecognized option "
					"(possibly \"%s\")\n",
					argv[optind - 1]);
			else
				fprintf(stderr, "ERROR: unrecognized option\n");
			break;
		case ':':
			errorcnt++;
			if (argv[optind - 1])
				fprintf(stderr,
					"ERROR: missing argument to -%c (%s)\n",
					optopt, argv[optind - 1]);
			else
				fprintf(stderr,
					"ERROR: missing argument to -%c\n",
					optopt);
			break;
		default:
			errorcnt++;
			fprintf(stderr,
				"ERROR: error while parsing options\n");
		}
	}

	/* Problems? */
	if (errorcnt) {
		print_help(argc, argv);
		return 1;
	}

	/* Now try to do something */
	switch (mode) {
	case DO_GET:
		if (argc - optind < 1) {
			fprintf(stderr, "\nERROR: missing input filename\n");
			print_help(argc, argv);
			return 1;
		} else {
			infile = argv[optind++];
		}

		/* With no args, show the HWID */
		if (!opt_rootkey && !opt_bmpfv && !opt_recoverykey
		    && !sel_flags && !sel_digest)
			sel_hwid = 1;

		inbuf = read_entire_file(infile, &filesize);
		if (!inbuf)
			break;

		gbb = FindGbbHeader(inbuf, filesize);
		if (!gbb) {
			fprintf(stderr, "ERROR: No GBB found in %s\n", infile);
			break;
		}
		gbb_base = (uint8_t *) gbb;

		/* Get the stuff */
		if (sel_hwid)
			printf("hardware_id: %s\n",
			       gbb->hwid_size ? (char *)(gbb_base +
							 gbb->
							 hwid_offset) : "");
		if (sel_digest)
			print_hwid_digest(gbb, "digest: ", "\n");

		if (sel_roothash)
			verify_ryu_root_header(inbuf, filesize, gbb);

		if (sel_flags)
			printf("flags: 0x%08x\n", gbb->flags);
		if (opt_rootkey)
			write_to_file(" - exported root_key to file:",
				      opt_rootkey,
				      gbb_base + gbb->rootkey_offset,
				      gbb->rootkey_size);
		if (opt_bmpfv)
			write_to_file(" - exported bmp_fv to file:", opt_bmpfv,
				      gbb_base + gbb->bmpfv_offset,
				      gbb->bmpfv_size);
		if (opt_recoverykey)
			write_to_file(" - exported recovery_key to file:",
				      opt_recoverykey,
				      gbb_base + gbb->recovery_key_offset,
				      gbb->recovery_key_size);
		break;

	case DO_SET:
		if (argc - optind < 1) {
			fprintf(stderr, "\nERROR: missing input filename\n");
			print_help(argc, argv);
			return 1;
		}
		infile = argv[optind++];
		if (!outfile)
			outfile = (argc - optind < 1) ? infile : argv[optind++];

		if (sel_hwid && !opt_hwid) {
			fprintf(stderr, "\nERROR: missing new HWID value\n");
			print_help(argc, argv);
			return 1;
		}
		if (sel_flags && (!opt_flags || !*opt_flags)) {
			fprintf(stderr, "\nERROR: missing new flags value\n");
			print_help(argc, argv);
			return 1;
		}

		/* With no args, we'll either copy it unchanged or do nothing */
		inbuf = read_entire_file(infile, &filesize);
		if (!inbuf)
			break;

		gbb = FindGbbHeader(inbuf, filesize);
		if (!gbb) {
			fprintf(stderr, "ERROR: No GBB found in %s\n", infile);
			break;
		}
		gbb_base = (uint8_t *) gbb;

		outbuf = (uint8_t *) malloc(filesize);
		if (!outbuf) {
			errorcnt++;
			fprintf(stderr,
				"ERROR: can't malloc %" PRIi64 " bytes: %s\n",
				filesize, strerror(errno));
			break;
		}

		/* Switch pointers to outbuf */
		memcpy(outbuf, inbuf, filesize);
		gbb = FindGbbHeader(outbuf, filesize);
		if (!gbb) {
			fprintf(stderr,
				"INTERNAL ERROR: No GBB found in outbuf\n");
			exit(1);
		}
		gbb_base = (uint8_t *) gbb;

		if (opt_hwid) {
			if (strlen(opt_hwid) + 1 > gbb->hwid_size) {
				fprintf(stderr,
					"ERROR: null-terminated HWID"
					" exceeds capacity (%d)\n",
					gbb->hwid_size);
				errorcnt++;
			} else {
				/* Wipe data before writing new value. */
				memset(gbb_base + gbb->hwid_offset, 0,
				       gbb->hwid_size);
				strcpy((char *)(gbb_base + gbb->hwid_offset),
				       opt_hwid);
				update_hwid_digest(gbb);
			}
		}

		if (opt_flags) {
			char *e = NULL;
			uint32_t val;
			val = (uint32_t) strtoul(opt_flags, &e, 0);
			if (e && *e) {
				fprintf(stderr,
					"ERROR: invalid flags value: %s\n",
					opt_flags);
				errorcnt++;
			} else {
				gbb->flags = val;
			}
		}

		if (opt_rootkey) {
			read_from_file("root_key", opt_rootkey,
				       gbb_base + gbb->rootkey_offset,
				       gbb->rootkey_size);

			if (fill_ryu_root_header(outbuf, filesize, gbb))
				errorcnt++;
		}
		if (opt_bmpfv)
			read_from_file("bmp_fv", opt_bmpfv,
				       gbb_base + gbb->bmpfv_offset,
				       gbb->bmpfv_size);
		if (opt_recoverykey)
			read_from_file("recovery_key", opt_recoverykey,
				       gbb_base + gbb->recovery_key_offset,
				       gbb->recovery_key_size);

		/* Write it out if there are no problems. */
		if (!errorcnt)
			write_to_file("successfully saved new image to:",
				      outfile, outbuf, filesize);

		break;

	case DO_CREATE:
		if (!outfile) {
			if (argc - optind < 1) {
				fprintf(stderr,
					"\nERROR: missing output filename\n");
				print_help(argc, argv);
				return 1;
			}
			outfile = argv[optind++];
		}
		/* Parse the creation args */
		outbuf = create_gbb(opt_create, &filesize);
		if (!outbuf) {
			fprintf(stderr,
				"\nERROR: unable to parse creation spec (%s)\n",
				opt_create);
			print_help(argc, argv);
			return 1;
		}
		if (!errorcnt)
			write_to_file("successfully created new GBB to:",
				      outfile, outbuf, filesize);
		break;
	}

	if (inbuf)
		free(inbuf);
	if (outbuf)
		free(outbuf);
	return !!errorcnt;
}

DECLARE_FUTIL_COMMAND(gbb, do_gbb, VBOOT_VERSION_ALL,
		      "Manipulate the Google Binary Block (GBB)");
DECLARE_FUTIL_COMMAND(gbb_utility, do_gbb, VBOOT_VERSION_ALL,
		      "Legacy name for `gbb` command");
