/* 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_key2.h"
#include "host_keyblock.h"
#include "host_key.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 keyblock */
	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, VB2_KEYBLOCK_MAGIC, VB2_KEYBLOCK_MAGIC_SIZE);
	h->header_version_major = VB2_KEYBLOCK_VERSION_MAJOR;
	h->header_version_minor = VB2_KEYBLOCK_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 keyblock */
	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, VB2_KEYBLOCK_MAGIC, VB2_KEYBLOCK_MAGIC_SIZE);
	h->header_version_major = VB2_KEYBLOCK_VERSION_MAJOR;
	h->header_version_minor = VB2_KEYBLOCK_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_FIRMWARE_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 keyblock file: %s\n", filename);
		return NULL;
	}

	/* Verify the hash of the keyblock, since we can do that without
	 * the public signing key. */
	if (VB2_SUCCESS != vb2_verify_keyblock_hash(block, file_size, &wb)) {
		fprintf(stderr, "Invalid keyblock 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);
}
