/* 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 "2sysincludes.h"
#include "2api.h"
#include "futility.h"

const char *progname = "vb2_verify_fw";

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.
 */
int vb2ex_read_resource(struct vb2_context *ctx,
			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;
}

int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
{
	// TODO: implement
	return VB2_SUCCESS;
}

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

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

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

/**
 * Verify firmware body
 */
int hash_body(struct vb2_context *ctx)
{
	uint32_t expect_size;
	uint8_t block[8192];
	uint32_t size;
	FILE *f;
	int rv;

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

	/* Start the body hash */
	rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expect_size);
	if (rv)
		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(ctx, block, size);
		if (rv)
			return rv;

		expect_size -= size;
	}

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

	return VB2_SUCCESS;
}

int do_vb2_verify_fw(int argc, char *argv[])
{
	struct vb2_context ctx;
	uint8_t workbuf[16384];
	int rv;

	progname = strrchr(argv[0], '/');
	if (progname)
		progname++;
	else
		progname = argv[0];

	if (argc < 4) {
		fprintf(stderr,
			"usage: %s <gbb> <vblock> <body>\n", progname);
		return 1;
	}

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

	/* Set up context */
	memset(&ctx, 0, sizeof(ctx));
	ctx.workbuf = workbuf;
	ctx.workbuf_size = sizeof(workbuf);

	/* Initialize secure context */
	rv = vb2api_secdata_create(&ctx);
	if (rv) {
		fprintf(stderr,
			"error: vb2api_secdata_create() failed (%d)\n", rv);
		return 1;
	}

	// 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", ctx.workbuf_used);

	return 0;
}

DECLARE_FUTIL_COMMAND(vb2_verify_fw, do_vb2_verify_fw,
		      "Verifies firmware using vboot2 library");
