/* 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 && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
		vb2api_fail(ctx, VB2_RECOVERY_SECDATA_KERNEL_INIT, rv);
		return rv;
	}
	sd->kernel_version_secdata =
		vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_VERSIONS);

	/* 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);

	/*
	 * 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)) {
		vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_VERSIONS,
					    sd->kernel_version);
		sd->kernel_version_secdata = sd->kernel_version;
	}

	return VB2_SUCCESS;
}
