/*
 * 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"
#include "gbb_header.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 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 GoogleBinaryBlockHeader *FindGbbHeader(uint8_t *ptr, size_t size)
{
	size_t i;
	GoogleBinaryBlockHeader *tmp, *gbb_header = NULL;
	int count = 0;

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

		/* Found something. See if it's any good. */
		tmp = (GoogleBinaryBlockHeader *) (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 = GBB_HEADER_SIZE;
	int i = 0;
	/* Danger Will Robinson! four entries ==> four paramater blocks */
	uint32_t val[] = { 0, 0, 0, 0 };
	uint8_t *buf;
	GoogleBinaryBlockHeader *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 = (GoogleBinaryBlockHeader *) buf;
	memcpy(gbb->signature, GBB_SIGNATURE, GBB_SIGNATURE_SIZE);
	gbb->major_version = GBB_MAJOR_VER;
	gbb->minor_version = GBB_MINOR_VER;
	gbb->header_size = GBB_HEADER_SIZE;
	gbb->flags = 0;

	i = 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;
	GoogleBinaryBlockHeader *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");
