/* Copyright (c) 2013 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.
 *
 * Host functions for verified boot.
 *
 * TODO: change all 'return 0', 'return 1' into meaningful return codes.
 */

#include <string.h>

#include "host_common.h"
#include "cryptolib.h"
#include "utility.h"
#include "vboot_common.h"

VbFirmwarePreambleHeader *CreateFirmwarePreamble(
	uint64_t firmware_version,
	const VbPublicKey *kernel_subkey,
	const VbSignature *body_signature,
	const VbPrivateKey *signing_key,
	uint32_t flags)
{
	VbFirmwarePreambleHeader *h;
	uint64_t signed_size = (sizeof(VbFirmwarePreambleHeader) +
				kernel_subkey->key_size +
				body_signature->sig_size);
	uint64_t block_size = signed_size + siglen_map[signing_key->algorithm];
	uint8_t *kernel_subkey_dest;
	uint8_t *body_sig_dest;
	uint8_t *block_sig_dest;
	VbSignature *sigtmp;

	/* Allocate key block */
	h = (VbFirmwarePreambleHeader *)malloc(block_size);
	if (!h)
		return NULL;

	Memset(h, 0, block_size);
	kernel_subkey_dest = (uint8_t *)(h + 1);
	body_sig_dest = kernel_subkey_dest + kernel_subkey->key_size;
	block_sig_dest = body_sig_dest + body_signature->sig_size;

	h->header_version_major = FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR;
	h->header_version_minor = FIRMWARE_PREAMBLE_HEADER_VERSION_MINOR;
	h->preamble_size = block_size;
	h->firmware_version = firmware_version;
	h->flags = flags;

	/* Copy data key */
	PublicKeyInit(&h->kernel_subkey, kernel_subkey_dest,
		      kernel_subkey->key_size);
	PublicKeyCopy(&h->kernel_subkey, kernel_subkey);

	/* Copy body signature */
	SignatureInit(&h->body_signature, body_sig_dest,
		      body_signature->sig_size, 0);
	SignatureCopy(&h->body_signature, body_signature);

	/* Set up signature struct so we can calculate the signature */
	SignatureInit(&h->preamble_signature, block_sig_dest,
		      siglen_map[signing_key->algorithm], signed_size);

	/* Calculate signature */
	sigtmp = CalculateSignature((uint8_t *)h, signed_size, signing_key);
	SignatureCopy(&h->preamble_signature, sigtmp);
	free(sigtmp);

	/* Return the header */
	return h;
}

VbKernelPreambleHeader *CreateKernelPreamble(
	uint64_t kernel_version,
	uint64_t body_load_address,
	uint64_t bootloader_address,
	uint64_t bootloader_size,
	const VbSignature *body_signature,
	uint64_t desired_size,
	const VbPrivateKey *signing_key)
{
	VbKernelPreambleHeader *h;
	uint64_t signed_size = (sizeof(VbKernelPreambleHeader) +
				body_signature->sig_size);
	uint64_t block_size = signed_size + siglen_map[signing_key->algorithm];
	uint8_t *body_sig_dest;
	uint8_t *block_sig_dest;
	VbSignature *sigtmp;

	/* If the block size is smaller than the desired size, pad it */
	if (block_size < desired_size)
		block_size = desired_size;

	/* Allocate key block */
	h = (VbKernelPreambleHeader *)malloc(block_size);
	if (!h)
		return NULL;

	Memset(h, 0, block_size);
	body_sig_dest = (uint8_t *)(h + 1);
	block_sig_dest = body_sig_dest + body_signature->sig_size;

	h->header_version_major = KERNEL_PREAMBLE_HEADER_VERSION_MAJOR;
	h->header_version_minor = KERNEL_PREAMBLE_HEADER_VERSION_MINOR;
	h->preamble_size = block_size;
	h->kernel_version = kernel_version;
	h->body_load_address = body_load_address;
	h->bootloader_address = bootloader_address;
	h->bootloader_size = bootloader_size;

	/* Copy body signature */
	SignatureInit(&h->body_signature, body_sig_dest,
		      body_signature->sig_size, 0);
	SignatureCopy(&h->body_signature, body_signature);

	/* Set up signature struct so we can calculate the signature */
	SignatureInit(&h->preamble_signature, block_sig_dest,
		      siglen_map[signing_key->algorithm], signed_size);

	/* Calculate signature */
	sigtmp = CalculateSignature((uint8_t *)h, signed_size, signing_key);
	SignatureCopy(&h->preamble_signature, sigtmp);
	free(sigtmp);

	/* Return the header */
	return h;
}
