/*
 * Copyright 2015 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 "2sysincludes.h"
#include "2common.h"
#include "2sha.h"
#include "cryptolib.h"
#include "futility.h"
#include "gbb_header.h"

#define SEARCH_STRIDE 4

/**
 * Check if the pointer contains the magic string.  We need to use a
 * case-swapped version, so that the actual magic string doesn't appear in the
 * code, to avoid falsely finding it when searching for the struct.
 */
static int is_magic(const void *ptr)
{
	const char magic_inv[RYU_ROOT_KEY_HASH_MAGIC_SIZE] =
		RYU_ROOT_KEY_HASH_MAGIC_INVCASE;
	const char *magic = ptr;
	int i;

	for (i = 0; i < RYU_ROOT_KEY_HASH_MAGIC_SIZE; i++) {
		if (magic[i] != (magic_inv[i] ^ 0x20))
			return 0;
	}

	return 1;
}

static int valid_ryu_root_header(struct vb2_ryu_root_key_hash *hash,
				 size_t size)
{
	if (!is_magic(hash->magic))
		return 0;  /* Wrong magic */

	if (hash->header_version_major != RYU_ROOT_KEY_HASH_VERSION_MAJOR)
		return 0;  /* Version we can't parse */

	if (hash->struct_size < EXPECTED_VB2_RYU_ROOT_KEY_HASH_SIZE)
		return 0;  /* Header too small */

	if (hash->struct_size > size)
		return 0;  /* Claimed size doesn't fit in buffer */

	return 1;
}

/**
 * Find the root key hash struct and return it or NULL if error.
 */
static struct vb2_ryu_root_key_hash *find_ryu_root_header(uint8_t *ptr,
							  size_t size)
{
	size_t i;
	struct vb2_ryu_root_key_hash *tmp, *hash = NULL;
	int count = 0;

	/* Look for the ryu root key hash header */
	for (i = 0; i <= size - SEARCH_STRIDE; i += SEARCH_STRIDE) {
		if (!is_magic(ptr + i))
			continue;

		/* Found something. See if it's any good. */
		tmp = (struct vb2_ryu_root_key_hash *) (ptr + i);
		if (valid_ryu_root_header(tmp, size - i))
			if (!count++)
				hash = tmp;
	}

	switch (count) {
	case 0:
		return NULL;
	case 1:
		return hash;
	default:
		fprintf(stderr,
			"WARNING: multiple ryu root hash headers found\n");
		/* But hey, it's only a warning.  Use the first one. */
		return hash;
	}
}

static void calculate_root_key_hash(uint8_t *digest, size_t digest_size,
				    const GoogleBinaryBlockHeader *gbb)
{
	const uint8_t *gbb_base = (const uint8_t *)gbb;

	vb2_digest_buffer(gbb_base + gbb->rootkey_offset,
			  gbb->rootkey_size,
			  VB2_HASH_SHA256,
			  digest,
			  digest_size);
}

int fill_ryu_root_header(uint8_t *ptr, size_t size,
			 const GoogleBinaryBlockHeader *gbb)
{
	struct vb2_ryu_root_key_hash *hash;

	/*
	 * Find the ryu root header.  If not found, nothing we can do, but
	 * that's ok because most images don't have the header.
	 */
	hash = find_ryu_root_header(ptr, size);
	if (!hash)
		return 0;

	/* Update the hash stored in the header based on the root key */
	calculate_root_key_hash(hash->root_key_hash_digest,
				sizeof(hash->root_key_hash_digest),
				gbb);

	printf(" - calculate ryu root hash: success\n");
	return 0;
}

int verify_ryu_root_header(uint8_t *ptr, size_t size,
			   const GoogleBinaryBlockHeader *gbb)
{
	uint8_t digest[VB2_SHA256_DIGEST_SIZE] = {0};

	struct vb2_ryu_root_key_hash *hash;

	/*
	 * Find the ryu root header.  If not found, nothing we can do, but
	 * that's ok because most images don't have the header.
	 */
	hash = find_ryu_root_header(ptr, size);
	if (!hash) {
		printf(" - ryu root hash not found\n");
		return 0;
	}

	/* Check for all 0's, which means hash hasn't been set */
	if (0 == memcmp(digest, hash->root_key_hash_digest, sizeof(digest))) {
		printf(" - ryu root hash is unset\n");
		return 0;
	}

	/* Update the hash stored in the header based on the root key */
	calculate_root_key_hash(digest, sizeof(digest), gbb);

	if (0 == memcmp(digest, hash->root_key_hash_digest, sizeof(digest))) {
		printf(" - ryu root hash verified\n");
		return 0;
	} else {
		printf(" - ryu root hash does not verify\n");
		return -1;
	}
}
