/* 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.
 *
 * Host functions for verified boot.
 */

#include <stdio.h>

#include "2sysincludes.h"

#include "2api.h"
#include "2common.h"
#include "2rsa.h"
#include "2sha.h"
#include "host_common.h"
#include "host_key.h"
#include "host_key2.h"
#include "host_keyblock.h"
#include "vb2_common.h"
#include "vb2_struct.h"
#include "vboot_common.h"

struct vb2_keyblock *vb2_create_keyblock(
		const struct vb2_packed_key *data_key,
		const struct vb2_private_key *signing_key,
		uint32_t flags)
{
	/* Allocate key block */
	uint32_t signed_size = sizeof(struct vb2_keyblock) + data_key->key_size;
	uint32_t sig_data_size =
		(signing_key ? vb2_rsa_sig_size(signing_key->sig_alg) : 0);
	uint32_t block_size =
		signed_size + VB2_SHA512_DIGEST_SIZE + sig_data_size;
	struct vb2_keyblock *h = (struct vb2_keyblock *)calloc(block_size, 1);
	if (!h)
		return NULL;

	uint8_t *data_key_dest = (uint8_t *)(h + 1);
	uint8_t *block_chk_dest = data_key_dest + data_key->key_size;
	uint8_t *block_sig_dest = block_chk_dest + VB2_SHA512_DIGEST_SIZE;

	memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE);
	h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR;
	h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR;
	h->keyblock_size = block_size;
	h->keyblock_flags = flags;

	/* Copy data key */
	vb2_init_packed_key(&h->data_key, data_key_dest, data_key->key_size);
	vb2_copy_packed_key(&h->data_key, data_key);

	/* Set up signature structs so we can calculate the signatures */
	vb2_init_signature(&h->keyblock_hash, block_chk_dest,
			   VB2_SHA512_DIGEST_SIZE, signed_size);
	if (signing_key) {
		vb2_init_signature(&h->keyblock_signature, block_sig_dest,
				   sig_data_size, signed_size);
	} else {
		memset(&h->keyblock_signature, 0,
		       sizeof(h->keyblock_signature));
	}

	/* Calculate hash */
	struct vb2_signature *chk =
		vb2_sha512_signature((uint8_t*)h, signed_size);
	vb2_copy_signature(&h->keyblock_hash, chk);
	free(chk);

	/* Calculate signature */
	if (signing_key) {
		struct vb2_signature *sigtmp =
			vb2_calculate_signature((uint8_t*)h,
						signed_size,
						signing_key);
		vb2_copy_signature(&h->keyblock_signature, sigtmp);
		free(sigtmp);
	}

	/* Return the header */
	return h;
}

/* TODO(gauravsh): This could easily be integrated into the function above
 * since the code is almost a mirror - I have kept it as such to avoid changing
 * the existing interface. */
struct vb2_keyblock *vb2_create_keyblock_external(
		const struct vb2_packed_key *data_key,
                const char *signing_key_pem_file,
                uint32_t algorithm,
                uint32_t flags,
                const char *external_signer)
{
	if (!signing_key_pem_file || !data_key || !external_signer)
		return NULL;

	uint32_t signed_size = sizeof(struct vb2_keyblock) + data_key->key_size;
	uint32_t sig_data_size = vb2_rsa_sig_size(vb2_crypto_to_signature(algorithm));
	uint32_t block_size =
		signed_size + VB2_SHA512_DIGEST_SIZE + sig_data_size;

	/* Allocate key block */
	struct vb2_keyblock *h = (struct vb2_keyblock *)calloc(block_size, 1);
	if (!h)
		return NULL;

	uint8_t *data_key_dest = (uint8_t *)(h + 1);
	uint8_t *block_chk_dest = data_key_dest + data_key->key_size;
	uint8_t *block_sig_dest = block_chk_dest + VB2_SHA512_DIGEST_SIZE;

	memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE);
	h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR;
	h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR;
	h->keyblock_size = block_size;
	h->keyblock_flags = flags;

	/* Copy data key */
	vb2_init_packed_key(&h->data_key, data_key_dest, data_key->key_size);
	vb2_copy_packed_key(&h->data_key, data_key);

	/* Set up signature structs so we can calculate the signatures */
	vb2_init_signature(&h->keyblock_hash, block_chk_dest,
			   VB2_SHA512_DIGEST_SIZE, signed_size);
	vb2_init_signature(&h->keyblock_signature, block_sig_dest,
			   sig_data_size, signed_size);

	/* Calculate checksum */
	struct vb2_signature *chk =
		vb2_sha512_signature((uint8_t*)h, signed_size);
	vb2_copy_signature(&h->keyblock_hash, chk);
	free(chk);

	/* Calculate signature */
	struct vb2_signature *sigtmp =
		vb2_external_signature((uint8_t*)h, signed_size,
				       signing_key_pem_file, algorithm,
				       external_signer);
	vb2_copy_signature(&h->keyblock_signature, sigtmp);
	free(sigtmp);

	/* Return the header */
	return h;
}

struct vb2_keyblock *vb2_read_keyblock(const char *filename)
{
	uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE];
	struct vb2_workbuf wb;
	vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));

	struct vb2_keyblock *block;
	uint32_t file_size;
	if (VB2_SUCCESS !=
	    vb2_read_file(filename, (uint8_t **)&block, &file_size)) {
		fprintf(stderr, "Error reading key block file: %s\n", filename);
		return NULL;
	}

	/* Verify the hash of the key block, since we can do that without
	 * the public signing key. */
	if (VB2_SUCCESS != vb2_verify_keyblock_hash(block, file_size, &wb)) {
		fprintf(stderr, "Invalid key block file: %s\n", filename);
		free(block);
		return NULL;
	}

	return block;
}


int vb2_write_keyblock(const char *filename,
		       const struct vb2_keyblock *keyblock)
{
	return vb2_write_file(filename, keyblock, keyblock->keyblock_size);
}
