/* Copyright 2015 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.
 *
 * Externally-callable APIs
 * (Kernel portion)
 */

#include "2api.h"
#include "2misc.h"
#include "2nvstorage.h"
#include "2rsa.h"
#include "2secdata.h"
#include "2sha.h"
#include "2sysincludes.h"
#include "vb2_common.h"

vb2_error_t vb2api_kernel_phase1(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	struct vb2_workbuf wb;
	uint8_t *key_data;
	uint32_t key_size;
	vb2_error_t rv;

	vb2_workbuf_from_ctx(ctx, &wb);

	/* Initialize secure kernel data and read version */
	rv = vb2_secdata_kernel_init(ctx);
	if (!rv) {
		rv = vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_VERSIONS,
					    &sd->kernel_version_secdata);
	}

	if (rv) {
		if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) {
			/* Ignore failure to get kernel version in recovery */
			sd->kernel_version_secdata = 0;
		} else {
			vb2api_fail(ctx, VB2_RECOVERY_SECDATA_KERNEL_INIT, rv);
			return rv;
		}
	}

	/* Find the key to use to verify the kernel keyblock */
	if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) {
		/* Recovery key from GBB */
		struct vb2_gbb_header *gbb;
		uint32_t key_offset;

		/* Read GBB header into next chunk of work buffer */
		gbb = vb2_workbuf_alloc(&wb, sizeof(*gbb));
		if (!gbb)
			return VB2_ERROR_GBB_WORKBUF;

		rv = vb2_read_gbb_header(ctx, gbb);
		if (rv)
			return rv;

		/* Only need the recovery key position and size */
		key_offset = gbb->recovery_key_offset;
		key_size = gbb->recovery_key_size;

		/* Free the GBB header */
		vb2_workbuf_free(&wb, sizeof(*gbb));

		/* Load the recovery key itself */
		key_data = vb2_workbuf_alloc(&wb, key_size);
		if (!key_data)
			return VB2_ERROR_API_KPHASE1_WORKBUF_REC_KEY;

		rv = vb2ex_read_resource(ctx, VB2_RES_GBB, key_offset,
					 key_data, key_size);
		if (rv)
			return rv;

		sd->kernel_key_offset = vb2_offset_of(sd, key_data);
	} else {
		/* Kernel subkey from firmware preamble */
		struct vb2_fw_preamble *pre;
		struct vb2_packed_key *pre_key, *packed_key;

		/* Make sure we have a firmware preamble loaded */
		if (!sd->preamble_size)
			return VB2_ERROR_API_KPHASE1_PREAMBLE;

		pre = (struct vb2_fw_preamble *)
			vb2_member_of(sd, sd->preamble_offset);
		pre_key = &pre->kernel_subkey;

		/*
		 * At this point, we no longer need the packed firmware
		 * data key, firmware preamble, or hash data.  So move the
		 * kernel key from the preamble down after the shared data.
		 */
		sd->kernel_key_offset = vb2_wb_round_up(sizeof(*sd));
		key_data = vb2_member_of(sd, sd->kernel_key_offset);
		packed_key = (struct vb2_packed_key *)key_data;
		memmove(packed_key, pre_key, sizeof(*packed_key));
		packed_key->key_offset = sizeof(*packed_key);
		memmove(key_data + packed_key->key_offset,
			(uint8_t *)pre_key + pre_key->key_offset,
			pre_key->key_size);

		key_size = packed_key->key_offset + packed_key->key_size;
	}

	/* Firmware stage structs are no longer present */
	sd->data_key_size = 0;
	sd->preamble_size = 0;
	sd->hash_size = 0;

	/*
	 * Kernel key will persist in the workbuf after we return.
	 *
	 * Work buffer now contains:
	 *   - vb2_shared_data
	 *   - kernel key
	 */
	sd->kernel_key_size = key_size;
	vb2_set_workbuf_used(ctx, sd->kernel_key_offset +
			     sd->kernel_key_size);

	return VB2_SUCCESS;
}

vb2_error_t vb2api_load_kernel_vblock(struct vb2_context *ctx)
{
	vb2_error_t rv;

	/* Verify kernel keyblock */
	rv = vb2_load_kernel_keyblock(ctx);
	if (rv)
		return rv;

	/* Verify kernel preamble */
	rv = vb2_load_kernel_preamble(ctx);
	if (rv)
		return rv;

	return VB2_SUCCESS;
}

vb2_error_t vb2api_get_kernel_size(struct vb2_context *ctx,
				   uint32_t *offset_ptr, uint32_t *size_ptr)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	const struct vb2_kernel_preamble *pre;

	/* Get preamble pointer */
	if (!sd->preamble_size)
		return VB2_ERROR_API_GET_KERNEL_SIZE_PREAMBLE;

	pre = (const struct vb2_kernel_preamble *)
		vb2_member_of(sd, sd->preamble_offset);

	if (offset_ptr) {
		/* The kernel implicitly follows the preamble */
		*offset_ptr = sd->vblock_preamble_offset +
			sd->preamble_size;
	}

	if (size_ptr) {
		/* Expect the kernel to be the size of data we signed */
		*size_ptr = pre->body_signature.data_size;
	}

	return VB2_SUCCESS;
}

vb2_error_t vb2api_verify_kernel_data(struct vb2_context *ctx, const void *buf,
				      uint32_t size)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	struct vb2_kernel_preamble *pre;
	struct vb2_digest_context *dc;
	struct vb2_public_key key;
	struct vb2_workbuf wb;

	uint8_t *digest;
	uint32_t digest_size;

	vb2_error_t rv;

	vb2_workbuf_from_ctx(ctx, &wb);

	/* Get preamble pointer */
	if (!sd->preamble_size)
		return VB2_ERROR_API_VERIFY_KDATA_PREAMBLE;

	pre = (struct vb2_kernel_preamble *)
		vb2_member_of(sd, sd->preamble_offset);

	/* Make sure we were passed the right amount of data */
	if (size != pre->body_signature.data_size)
		return VB2_ERROR_API_VERIFY_KDATA_SIZE;

	/* Allocate workbuf space for the hash */
	dc = vb2_workbuf_alloc(&wb, sizeof(*dc));
	if (!dc)
		return VB2_ERROR_API_VERIFY_KDATA_WORKBUF;

	/*
	 * Unpack the kernel data key to see which hashing algorithm we
	 * should use.
	 *
	 * TODO: really, the kernel body should be hashed, and not signed,
	 * because the signature we're checking is already signed as part of
	 * the kernel preamble.  But until we can change the signing scripts,
	 * we're stuck with a signature here instead of a hash.
	 */
	if (!sd->data_key_size)
		return VB2_ERROR_API_VERIFY_KDATA_KEY;

	rv = vb2_unpack_key_buffer(&key,
				   vb2_member_of(sd, sd->data_key_offset),
				   sd->data_key_size);
	if (rv)
		return rv;

	rv = vb2_digest_init(dc, key.hash_alg);
	if (rv)
		return rv;

	rv = vb2_digest_extend(dc, buf, size);
	if (rv)
		return rv;

	digest_size = vb2_digest_size(key.hash_alg);
	digest = vb2_workbuf_alloc(&wb, digest_size);
	if (!digest)
		return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST;

	rv = vb2_digest_finalize(dc, digest, digest_size);
	if (rv)
		return rv;

	/*
	 * The body signature is currently a *signature* of the body data, not
	 * just its hash.  So we need to verify the signature.
	 */

	/*
	 * Check digest vs. signature.  Note that this destroys the signature.
	 * That's ok, because we only check each signature once per boot.
	 */
	return vb2_verify_digest(&key, &pre->body_signature, digest, &wb);
}

vb2_error_t vb2api_kernel_phase3(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	vb2_error_t rv;

	/*
	 * If the kernel is a newer version than in secure storage, and the
	 * kernel signature is valid, and we're not in recovery mode, and we're
	 * allowed to, roll forward the version in secure storage.
	 */
	if (sd->kernel_version > sd->kernel_version_secdata &&
	    (sd->flags & VB2_SD_FLAG_KERNEL_SIGNED) &&
	    !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE) &&
	    (ctx->flags & VB2_CONTEXT_ALLOW_KERNEL_ROLL_FORWARD)) {
		rv = vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_VERSIONS,
					    sd->kernel_version);
		if (rv)
			return rv;
		sd->kernel_version_secdata = sd->kernel_version;
	}

	return VB2_SUCCESS;
}
