/* 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 expect_size;
	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, &expect_size);
	if (rv) {
		fclose(f);
		return rv;
	}

	printf("Expect %d bytes of body...\n", expect_size);

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

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

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