/* 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"

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]
		__attribute__((aligned(VB2_WORKBUF_ALIGN)));
	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);
}
