/* Copyright (c) 2011 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.
 *
 * Routines for verifying a firmware image's signature.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "2common.h"
#include "2misc.h"
#include "2sysincludes.h"

const char *gbb_fname;
const char *vblock_fname;
const char *body_fname;

/**
 * Local implementation which reads resources from individual files.  Could be
 * more elegant and read from bios.bin, if we understood the fmap.
 */
vb2_error_t vb2ex_read_resource(struct vb2_context *c,
				enum vb2_resource_index index, uint32_t offset,
				void *buf, uint32_t size)
{
	const char *fname;
	FILE *f;
	int got_size;

	/* Get the filename for the resource */
	switch (index) {
	case VB2_RES_GBB:
		fname = gbb_fname;
		break;
	case VB2_RES_FW_VBLOCK:
		fname = vblock_fname;
		break;
	default:
		return VB2_ERROR_UNKNOWN;
	}

	/* Open file and seek to the requested offset */
	f = fopen(fname, "rb");
	if (!f)
		return VB2_ERROR_UNKNOWN;

	if (fseek(f, offset, SEEK_SET)) {
		fclose(f);
		return VB2_ERROR_UNKNOWN;
	}

	/* Read data and close file */
	got_size = fread(buf, 1, size, f);
	fclose(f);

	/* Return success if we read everything */
	return got_size == size ? VB2_SUCCESS : VB2_ERROR_UNKNOWN;
}

vb2_error_t vb2ex_tpm_clear_owner(struct vb2_context *c)
{
	// TODO: implement
	return VB2_SUCCESS;
}

/**
 * Save non-volatile and/or secure data if needed.
 */
static void save_if_needed(struct vb2_context *c)
{

	if (c->flags & VB2_CONTEXT_NVDATA_CHANGED) {
		// TODO: implement
		c->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
	}

	if (c->flags & VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED) {
		// TODO: implement
		c->flags &= ~VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED;
	}
}

/**
 * Verify firmware body
 */
static vb2_error_t hash_body(struct vb2_context *c)
{
	uint32_t remaining;
	uint8_t block[8192];
	uint32_t size;
	FILE *f;
	vb2_error_t rv;

	/* Open the body data */
	f = fopen(body_fname, "rb");
	if (!f)
		return VB2_ERROR_TEST_INPUT_FILE;

	/* Start the body hash */
	rv = vb2api_init_hash(c, VB2_HASH_TAG_FW_BODY);
	if (rv) {
		fclose(f);
		return rv;
	}

	remaining = vb2api_get_firmware_size(c);
	printf("Expect %d bytes of body...\n", remaining);

	/* Extend over the body */
	while (remaining) {
		size = sizeof(block);
		if (size > remaining)
			size = remaining;

		/* Read next body block */
		size = fread(block, 1, size, f);
		if (size <= 0)
			break;

		/* Hash it */
		rv = vb2api_extend_hash(c, block, size);
		if (rv) {
			fclose(f);
			return rv;
		}

		remaining -= size;
	}

	fclose(f);

	/* Check the result */
	rv = vb2api_check_hash(c);
	if (rv)
		return rv;

	return VB2_SUCCESS;
}

static void print_help(const char *progname)
{
	printf("Usage: %s <gbb> <vblock> <body>\n", progname);
}

int main(int argc, char *argv[])
{
	uint8_t workbuf[16384] __attribute__((aligned(VB2_WORKBUF_ALIGN)));
	struct vb2_context *ctx;
	struct vb2_shared_data *sd;
	vb2_error_t rv;

	if (argc < 4) {
		print_help(argv[0]);
		return 1;
	}

	/* Save filenames */
	gbb_fname = argv[1];
	vblock_fname = argv[2];
	body_fname = argv[3];

	/* Set up context */
	if (vb2api_init(workbuf, sizeof(workbuf), &ctx)) {
		printf("Failed to initialize workbuf.\n");
		return 1;
	}
	sd = vb2_get_sd(ctx);

	/* Initialize secure context */
	vb2api_secdata_firmware_create(ctx);

	// TODO: optional args to set contents for nvdata, secdata?

	/* Do early init */
	printf("Phase 1...\n");
	rv = vb2api_fw_phase1(ctx);
	if (rv) {
		printf("Phase 1 wants recovery mode.\n");
		save_if_needed(ctx);
		return rv;
	}

	/* Determine which firmware slot to boot */
	printf("Phase 2...\n");
	rv = vb2api_fw_phase2(ctx);
	if (rv) {
		printf("Phase 2 wants reboot.\n");
		save_if_needed(ctx);
		return rv;
	}

	/* Try that slot */
	printf("Phase 3...\n");
	rv = vb2api_fw_phase3(ctx);
	if (rv) {
		printf("Phase 3 wants reboot.\n");
		save_if_needed(ctx);
		return rv;
	}

	/* Verify body */
	printf("Hash body...\n");
	rv = hash_body(ctx);
	save_if_needed(ctx);
	if (rv) {
		printf("Phase 4 wants reboot.\n");
		return rv;
	}

	printf("Yaay!\n");

	printf("Workbuf used = %d bytes\n", sd->workbuf_used);

	return 0;
}
