/* Copyright (c) 2012 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.
 *
 * Common functions between firmware and kernel verified boot.
 * (Firmware portion)
 */

#include "vboot_api.h"
#include "vboot_common.h"
#include "utility.h"

const char *kVbootErrors[VBOOT_ERROR_MAX] = {
	"Success.",
	"Key block invalid.",
	"Key block signature failed.",
	"Key block hash failed.",
	"Public key invalid.",
	"Preamble invalid.",
	"Preamble signature check failed.",
	"Shared data invalid."
};

uint64_t OffsetOf(const void *base, const void *ptr)
{
	return (uint64_t)(size_t)ptr - (uint64_t)(size_t)base;
}

/* Helper functions to get data pointed to by a public key or signature. */

uint8_t *GetPublicKeyData(VbPublicKey *key)
{
	return (uint8_t *)key + key->key_offset;
}

const uint8_t *GetPublicKeyDataC(const VbPublicKey *key)
{
	return (const uint8_t *)key + key->key_offset;
}

uint8_t *GetSignatureData(VbSignature *sig)
{
	return (uint8_t *)sig + sig->sig_offset;
}

const uint8_t *GetSignatureDataC(const VbSignature *sig)
{
	return (const uint8_t *)sig + sig->sig_offset;
}

/*
 * Helper functions to verify the data pointed to by a subfield is inside
 * the parent data.  Returns 0 if inside, 1 if error.
 */

int VerifyMemberInside(const void *parent, uint64_t parent_size,
                       const void *member, uint64_t member_size,
                       uint64_t member_data_offset,
                       uint64_t member_data_size)
{
	uint64_t end = OffsetOf(parent, member);

	if (end > parent_size)
		return 1;

	if (UINT64_MAX - end < member_size)
		return 1;  /* Detect wraparound in integer math */
	if (end + member_size > parent_size)
		return 1;

	if (UINT64_MAX - end < member_data_offset)
		return 1;
	end += member_data_offset;
	if (end > parent_size)
		return 1;

	if (UINT64_MAX - end < member_data_size)
		return 1;
	if (end + member_data_size > parent_size)
		return 1;

	return 0;
}

int VerifyPublicKeyInside(const void *parent, uint64_t parent_size,
                          const VbPublicKey *key)
{
	return VerifyMemberInside(parent, parent_size,
				  key, sizeof(VbPublicKey),
				  key->key_offset, key->key_size);
}

int VerifySignatureInside(const void *parent, uint64_t parent_size,
                          const VbSignature *sig)
{
	return VerifyMemberInside(parent, parent_size,
				  sig, sizeof(VbSignature),
				  sig->sig_offset, sig->sig_size);
}

void PublicKeyInit(VbPublicKey *key, uint8_t *key_data, uint64_t key_size)
{
	key->key_offset = OffsetOf(key, key_data);
	key->key_size = key_size;
	key->algorithm = kNumAlgorithms; /* Key not present yet */
	key->key_version = 0;
}

int PublicKeyCopy(VbPublicKey *dest, const VbPublicKey *src)
{
	if (dest->key_size < src->key_size)
		return 1;

	dest->key_size = src->key_size;
	dest->algorithm = src->algorithm;
	dest->key_version = src->key_version;
	Memcpy(GetPublicKeyData(dest), GetPublicKeyDataC(src), src->key_size);
	return 0;
}

RSAPublicKey *PublicKeyToRSA(const VbPublicKey *key)
{
	RSAPublicKey *rsa;
	uint64_t key_size;

	if (kNumAlgorithms <= key->algorithm) {
		VBDEBUG(("Invalid algorithm.\n"));
		return NULL;
	}
	if (!RSAProcessedKeySize(key->algorithm, &key_size) ||
	    key_size != key->key_size) {
		VBDEBUG(("Wrong key size for algorithm\n"));
		return NULL;
	}

	rsa = RSAPublicKeyFromBuf(GetPublicKeyDataC(key), key->key_size);
	if (!rsa)
		return NULL;

	rsa->algorithm = (unsigned int)key->algorithm;
	return rsa;
}

int VerifyData(const uint8_t *data, uint64_t size, const VbSignature *sig,
               const RSAPublicKey *key)
{
	if (sig->sig_size != siglen_map[key->algorithm]) {
		VBDEBUG(("Wrong signature size for algorithm.\n"));
		return 1;
	}
	if (sig->data_size > size) {
		VBDEBUG(("Data buffer smaller than length of signed data.\n"));
		return 1;
	}

	if (!RSAVerifyBinary_f(NULL, key, data, sig->data_size,
			       GetSignatureDataC(sig), key->algorithm))
		return 1;

	return 0;
}

int VerifyDigest(const uint8_t *digest, const VbSignature *sig,
                 const RSAPublicKey *key)
{
	if (sig->sig_size != siglen_map[key->algorithm]) {
		VBDEBUG(("Wrong signature size for algorithm.\n"));
		return 1;
	}

	if (!RSAVerifyBinaryWithDigest_f(NULL, key, digest,
					 GetSignatureDataC(sig),
					 key->algorithm))
		return 1;

	return 0;
}

int KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size,
                   const VbPublicKey *key, int hash_only)
{
	const VbSignature *sig;

	/* Sanity checks before attempting signature of data */
	if(size < sizeof(VbKeyBlockHeader)) {
		VBDEBUG(("Not enough space for key block header.\n"));
		return VBOOT_KEY_BLOCK_INVALID;
	}
	if (SafeMemcmp(block->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE)) {
		VBDEBUG(("Not a valid verified boot key block.\n"));
		return VBOOT_KEY_BLOCK_INVALID;
	}
	if (block->header_version_major != KEY_BLOCK_HEADER_VERSION_MAJOR) {
		VBDEBUG(("Incompatible key block header version.\n"));
		return VBOOT_KEY_BLOCK_INVALID;
	}
	if (size < block->key_block_size) {
		VBDEBUG(("Not enough data for key block.\n"));
		return VBOOT_KEY_BLOCK_INVALID;
	}
	if (!hash_only && !key) {
		VBDEBUG(("Missing required public key.\n"));
		return VBOOT_PUBLIC_KEY_INVALID;
	}

	/*
	 * Check signature or hash, depending on the hash_only parameter. Note
	 * that we don't require a key even if the keyblock has a signature,
	 * because the caller may not care if the keyblock itself is signed
	 * (for example, booting a Google-signed kernel in developer mode).
	 */
	if (hash_only) {
		/* Check hash */
		uint8_t *header_checksum = NULL;
		int rv;

		sig = &block->key_block_checksum;

		if (VerifySignatureInside(block, block->key_block_size, sig)) {
			VBDEBUG(("Key block hash off end of block\n"));
			return VBOOT_KEY_BLOCK_INVALID;
		}
		if (sig->sig_size != SHA512_DIGEST_SIZE) {
			VBDEBUG(("Wrong hash size for key block.\n"));
			return VBOOT_KEY_BLOCK_INVALID;
		}

		/* Make sure advertised signature data sizes are sane. */
		if (block->key_block_size < sig->data_size) {
			VBDEBUG(("Signature calculated past end of block\n"));
			return VBOOT_KEY_BLOCK_INVALID;
		}

		VBDEBUG(("Checking key block hash only...\n"));
		header_checksum = DigestBuf((const uint8_t *)block,
					    sig->data_size,
					    SHA512_DIGEST_ALGORITHM);
		rv = SafeMemcmp(header_checksum, GetSignatureDataC(sig),
				SHA512_DIGEST_SIZE);
		VbExFree(header_checksum);
		if (rv) {
			VBDEBUG(("Invalid key block hash.\n"));
			return VBOOT_KEY_BLOCK_HASH;
		}
	} else {
		/* Check signature */
		RSAPublicKey *rsa;
		int rv;

		sig = &block->key_block_signature;

		if (VerifySignatureInside(block, block->key_block_size, sig)) {
			VBDEBUG(("Key block signature off end of block\n"));
			return VBOOT_KEY_BLOCK_INVALID;
		}

		rsa = PublicKeyToRSA(key);
		if (!rsa) {
			VBDEBUG(("Invalid public key\n"));
			return VBOOT_PUBLIC_KEY_INVALID;
		}

		/* Make sure advertised signature data sizes are sane. */
		if (block->key_block_size < sig->data_size) {
			VBDEBUG(("Signature calculated past end of block\n"));
			RSAPublicKeyFree(rsa);
			return VBOOT_KEY_BLOCK_INVALID;
		}

		VBDEBUG(("Checking key block signature...\n"));
		rv = VerifyData((const uint8_t *)block, size, sig, rsa);
		RSAPublicKeyFree(rsa);
		if (rv) {
			VBDEBUG(("Invalid key block signature.\n"));
			return VBOOT_KEY_BLOCK_SIGNATURE;
		}
	}

	/* Verify we signed enough data */
	if (sig->data_size < sizeof(VbKeyBlockHeader)) {
		VBDEBUG(("Didn't sign enough data\n"));
		return VBOOT_KEY_BLOCK_INVALID;
	}

	/* Verify data key is inside the block and inside signed data */
	if (VerifyPublicKeyInside(block, block->key_block_size,
				  &block->data_key)) {
		VBDEBUG(("Data key off end of key block\n"));
		return VBOOT_KEY_BLOCK_INVALID;
	}
	if (VerifyPublicKeyInside(block, sig->data_size, &block->data_key)) {
		VBDEBUG(("Data key off end of signed data\n"));
		return VBOOT_KEY_BLOCK_INVALID;
	}

	/* Success */
	return VBOOT_SUCCESS;
}

int VerifyFirmwarePreamble(const VbFirmwarePreambleHeader *preamble,
                           uint64_t size, const RSAPublicKey *key)
{
	const VbSignature *sig = &preamble->preamble_signature;

	/* Sanity checks before attempting signature of data */
	if(size < EXPECTED_VBFIRMWAREPREAMBLEHEADER2_0_SIZE) {
		VBDEBUG(("Not enough data for preamble header 2.0.\n"));
		return VBOOT_PREAMBLE_INVALID;
	}
	if (preamble->header_version_major !=
	    FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) {
		VBDEBUG(("Incompatible firmware preamble header version.\n"));
		return VBOOT_PREAMBLE_INVALID;
	}
	if (size < preamble->preamble_size) {
		VBDEBUG(("Not enough data for preamble.\n"));
		return VBOOT_PREAMBLE_INVALID;
	}

	/* Check signature */
	if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) {
		VBDEBUG(("Preamble signature off end of preamble\n"));
		return VBOOT_PREAMBLE_INVALID;
	}

	/* Make sure advertised signature data sizes are sane. */
	if (preamble->preamble_size < sig->data_size) {
		VBDEBUG(("Signature calculated past end of the block\n"));
		return VBOOT_PREAMBLE_INVALID;
	}

	if (VerifyData((const uint8_t *)preamble, size, sig, key)) {
		VBDEBUG(("Preamble signature validation failed\n"));
		return VBOOT_PREAMBLE_SIGNATURE;
	}

	/* Verify we signed enough data */
	if (sig->data_size < sizeof(VbFirmwarePreambleHeader)) {
		VBDEBUG(("Didn't sign enough data\n"));
		return VBOOT_PREAMBLE_INVALID;
	}

	/* Verify body signature is inside the signed data */
	if (VerifySignatureInside(preamble, sig->data_size,
				  &preamble->body_signature)) {
		VBDEBUG(("Firmware body signature off end of preamble\n"));
		return VBOOT_PREAMBLE_INVALID;
	}

	/* Verify kernel subkey is inside the signed data */
	if (VerifyPublicKeyInside(preamble, sig->data_size,
				  &preamble->kernel_subkey)) {
		VBDEBUG(("Kernel subkey off end of preamble\n"));
		return VBOOT_PREAMBLE_INVALID;
	}

	/*
	 * If the preamble header version is at least 2.1, verify we have space
	 * for the added fields from 2.1.
	 */
	if (preamble->header_version_minor >= 1) {
		if(size < EXPECTED_VBFIRMWAREPREAMBLEHEADER2_1_SIZE) {
			VBDEBUG(("Not enough data for preamble header 2.1.\n"));
			return VBOOT_PREAMBLE_INVALID;
		}
	}

	/* Success */
	return VBOOT_SUCCESS;
}

uint32_t VbGetFirmwarePreambleFlags(const VbFirmwarePreambleHeader *preamble)
{
	if (preamble->header_version_minor < 1) {
		/*
		 * Old structure; return default flags.  (Note that we don't
		 * need to check header_version_major; if that's not 2 then
		 * VerifyFirmwarePreamble() would have already failed.
		 */
		return 0;
	}

	return preamble->flags;
}

int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble,
                         uint64_t size, const RSAPublicKey *key)
{
	const VbSignature *sig = &preamble->preamble_signature;

	/* Sanity checks before attempting signature of data */
	if(size < sizeof(VbKernelPreambleHeader)) {
		VBDEBUG(("Not enough data for preamble header.\n"));
		return VBOOT_PREAMBLE_INVALID;
	}
	if (preamble->header_version_major !=
	    KERNEL_PREAMBLE_HEADER_VERSION_MAJOR) {
		VBDEBUG(("Incompatible kernel preamble header version.\n"));
		return VBOOT_PREAMBLE_INVALID;
	}
	if (size < preamble->preamble_size) {
		VBDEBUG(("Not enough data for preamble.\n"));
		return VBOOT_PREAMBLE_INVALID;
	}

	/* Check signature */
	if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) {
		VBDEBUG(("Preamble signature off end of preamble\n"));
		return VBOOT_PREAMBLE_INVALID;
	}
	if (VerifyData((const uint8_t *)preamble, size, sig, key)) {
		VBDEBUG(("Preamble signature validation failed\n"));
		return VBOOT_PREAMBLE_SIGNATURE;
	}

	/* Verify we signed enough data */
	if (sig->data_size < sizeof(VbKernelPreambleHeader)) {
		VBDEBUG(("Didn't sign enough data\n"));
		return VBOOT_PREAMBLE_INVALID;
	}

	/* Verify body signature is inside the signed data */
	if (VerifySignatureInside(preamble, sig->data_size,
				  &preamble->body_signature)) {
		VBDEBUG(("Kernel body signature off end of preamble\n"));
		return VBOOT_PREAMBLE_INVALID;
	}

	/* Success */
	return VBOOT_SUCCESS;
}

int VbSharedDataInit(VbSharedDataHeader *header, uint64_t size)
{
	VBDEBUG(("VbSharedDataInit, %d bytes, header %d bytes\n", (int)size,
		 sizeof(VbSharedDataHeader)));

	if (size < sizeof(VbSharedDataHeader)) {
		VBDEBUG(("Not enough data for header.\n"));
		return VBOOT_SHARED_DATA_INVALID;
	}
	if (size < VB_SHARED_DATA_MIN_SIZE) {
		VBDEBUG(("Shared data buffer too small.\n"));
		return VBOOT_SHARED_DATA_INVALID;
	}

	if (!header)
		return VBOOT_SHARED_DATA_INVALID;

	/* Zero the header */
	Memset(header, 0, sizeof(VbSharedDataHeader));

	/* Initialize fields */
	header->magic = VB_SHARED_DATA_MAGIC;
	header->struct_version = VB_SHARED_DATA_VERSION;
	header->struct_size = sizeof(VbSharedDataHeader);
	header->data_size = size;
	header->data_used = sizeof(VbSharedDataHeader);
	header->firmware_index = 0xFF;

	/* Success */
	return VBOOT_SUCCESS;
}

uint64_t VbSharedDataReserve(VbSharedDataHeader *header, uint64_t size)
{
	uint64_t offs = header->data_used;

	VBDEBUG(("VbSharedDataReserve %d bytes at %d\n", (int)size, (int)offs));

	if (!header || size > header->data_size - header->data_used) {
		VBDEBUG(("VbSharedData buffer out of space.\n"));
		return 0;  /* Not initialized, or not enough space left. */
	}
	header->data_used += size;
	return offs;
}

int VbSharedDataSetKernelKey(VbSharedDataHeader *header, const VbPublicKey *src)
{
	VbPublicKey *kdest = &header->kernel_subkey;

	if (!header)
		return VBOOT_SHARED_DATA_INVALID;

	/* Attempt to allocate space for key, if it hasn't been allocated yet */
	if (!header->kernel_subkey_data_offset) {
		header->kernel_subkey_data_offset =
			VbSharedDataReserve(header, src->key_size);
		if (!header->kernel_subkey_data_offset)
			return VBOOT_SHARED_DATA_INVALID;
		header->kernel_subkey_data_size = src->key_size;
	}

	/* Copy the kernel sign key blob into the destination buffer */
	PublicKeyInit(kdest,
		      (uint8_t *)header + header->kernel_subkey_data_offset,
		      header->kernel_subkey_data_size);

	return PublicKeyCopy(kdest, src);
}
