/* Copyright (c) 2014 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.
 *
 * Misc functions which need access to vb2_context but are not public APIs
 */

#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 vb2_load_fw_keyblock(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
	struct vb2_workbuf wb;

	uint8_t *key_data;
	uint32_t key_size;
	struct vb2_public_key root_key;

	struct vb2_keyblock *kb;
	uint32_t block_size;

	vb2_error_t rv = VB2_SUCCESS;

	vb2_workbuf_from_ctx(ctx, &wb);

	/* Read the root key */
	key_size = gbb->rootkey_size;
	key_data = vb2_workbuf_alloc(&wb, key_size);
	if (!key_data)
		return VB2_ERROR_FW_KEYBLOCK_WORKBUF_ROOT_KEY;

	VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_GBB, gbb->rootkey_offset,
				    key_data, key_size));

	/* Unpack the root key */
	VB2_TRY(vb2_unpack_key_buffer(&root_key, key_data, key_size));

	root_key.allow_hwcrypto = vb2_hwcrypto_rsa_allowed(ctx);

	/* Load the firmware keyblock header after the root key */
	kb = vb2_workbuf_alloc(&wb, sizeof(*kb));
	if (!kb)
		return VB2_ERROR_FW_KEYBLOCK_WORKBUF_HEADER;

	VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0,
				    kb, sizeof(*kb)));

	block_size = kb->keyblock_size;

	/*
	 * Load the entire keyblock, now that we know how big it is.  Note that
	 * we're loading the entire keyblock instead of just the piece after
	 * the header.  That means we re-read the header.  But that's a tiny
	 * amount of data, and it makes the code much more straightforward.
	 */
	kb = vb2_workbuf_realloc(&wb, sizeof(*kb), block_size);
	if (!kb)
		return VB2_ERROR_FW_KEYBLOCK_WORKBUF;

	VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0, kb, block_size));

	/* Verify the keyblock */
	VB2_TRY(vb2_verify_keyblock(kb, block_size, &root_key, &wb),
		ctx, VB2_RECOVERY_FW_KEYBLOCK);

	/* Key version is the upper 16 bits of the composite firmware version */
	if (kb->data_key.key_version > VB2_MAX_KEY_VERSION)
		rv = VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE;
	if (!rv && kb->data_key.key_version < (sd->fw_version_secdata >> 16)) {
		if (gbb->flags & VB2_GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)
			VB2_DEBUG("Ignoring FW key rollback due to GBB flag\n");
		else
			rv = VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK;
	}
	if (rv) {
		vb2api_fail(ctx, VB2_RECOVERY_FW_KEY_ROLLBACK, rv);
		return rv;
	}

	sd->fw_version = kb->data_key.key_version << 16;

	/* Preamble follows the keyblock in the vblock. */
	sd->vblock_preamble_offset = kb->keyblock_size;

	/*
	 * Save the data key in the work buffer.  We'll overwrite the root key
	 * we read above.  That's ok, because now that we have the data key we
	 * no longer need the root key.  First, let's double-check that it is
	 * well-formed though (although the keyblock was signed anyway).
	 */
	VB2_TRY(vb2_verify_packed_key_inside(kb, block_size, &kb->data_key));

	/* Save the future offset and size while kb->data_key is still valid.
	   The check above made sure that key_offset and key_size are valid. */
	sd->data_key_offset = vb2_offset_of(sd, key_data);
	sd->data_key_size = kb->data_key.key_offset + kb->data_key.key_size;

	/*
	 * Use memmove() instead of memcpy().  In theory, the destination will
	 * never overlap because with the source because the root key is likely
	 * to be at least as large as the data key, but there's no harm here in
	 * being paranoid.  Make sure we immediately invalidate 'kb' after the
	 * move to guarantee we won't try to access it anymore.
	 */
	memmove(key_data, &kb->data_key, sd->data_key_size);
	kb = NULL;

	/*
	 * Data key will persist in the workbuf after we return.
	 *
	 * Work buffer now contains:
	 *   - vb2_shared_data
	 *   - packed firmware data key
	 */
	vb2_set_workbuf_used(ctx, sd->data_key_offset + sd->data_key_size);

	return VB2_SUCCESS;
}

vb2_error_t vb2_load_fw_preamble(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
	struct vb2_workbuf wb;

	uint8_t *key_data = vb2_member_of(sd, sd->data_key_offset);
	uint32_t key_size = sd->data_key_size;
	struct vb2_public_key data_key;

	/* Preamble goes in the next unused chunk of work buffer */
	struct vb2_fw_preamble *pre;
	uint32_t pre_size;

	vb2_error_t rv = VB2_SUCCESS;

	vb2_workbuf_from_ctx(ctx, &wb);

	/* Unpack the firmware data key */
	if (!sd->data_key_size)
		return VB2_ERROR_FW_PREAMBLE2_DATA_KEY;

	VB2_TRY(vb2_unpack_key_buffer(&data_key, key_data, key_size));

	data_key.allow_hwcrypto = vb2_hwcrypto_rsa_allowed(ctx);

	/* Load the firmware preamble header */
	pre = vb2_workbuf_alloc(&wb, sizeof(*pre));
	if (!pre)
		return VB2_ERROR_FW_PREAMBLE2_WORKBUF_HEADER;

	VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
				    sd->vblock_preamble_offset,
				    pre, sizeof(*pre)));

	pre_size = pre->preamble_size;

	/* Load the entire firmware preamble, now that we know how big it is */
	pre = vb2_workbuf_realloc(&wb, sizeof(*pre), pre_size);
	if (!pre)
		return VB2_ERROR_FW_PREAMBLE2_WORKBUF;

	VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
				    sd->vblock_preamble_offset,
				    pre, pre_size));

	/* Work buffer now contains the data subkey data and the preamble */

	/* Verify the preamble */
	VB2_TRY(vb2_verify_fw_preamble(pre, pre_size, &data_key, &wb),
		ctx, VB2_RECOVERY_FW_PREAMBLE);

	/*
	 * Firmware version is the lower 16 bits of the composite firmware
	 * version.
	 */
	if (pre->firmware_version > VB2_MAX_PREAMBLE_VERSION)
		rv = VB2_ERROR_FW_PREAMBLE_VERSION_RANGE;
	/* Combine with the key version from vb2_load_fw_keyblock() */
	sd->fw_version |= pre->firmware_version;
	if (!rv && sd->fw_version < sd->fw_version_secdata) {
		if (gbb->flags & VB2_GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)
			VB2_DEBUG("Ignoring FW rollback due to GBB flag\n");
		else
			rv = VB2_ERROR_FW_PREAMBLE_VERSION_ROLLBACK;
	}
	if (rv) {
		vb2api_fail(ctx, VB2_RECOVERY_FW_ROLLBACK, rv);
		return rv;
	}

	/*
	 * If this is a newer version than in secure storage, and we
	 * successfully booted the same slot last boot, roll forward the
	 * version in secure storage.
	 *
	 * Note that this happens before we've verified the firmware data this
	 * boot; we're relying on the indicator that the last boot was
	 * successful.  That's ok, because even if the firmware data has a
	 * valid hash, the only way we can know if it's functional is to trust
	 * the status from the last boot.
	 */
	if (sd->fw_version > sd->fw_version_secdata &&
	    sd->last_fw_slot == sd->fw_slot &&
	    sd->last_fw_result == VB2_FW_RESULT_SUCCESS) {
		sd->fw_version_secdata = sd->fw_version;
		vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_VERSIONS,
					 sd->fw_version);
	}

	/* Keep track of where we put the preamble */
	sd->preamble_offset = vb2_offset_of(sd, pre);
	sd->preamble_size = pre_size;

	/*
	 * Preamble will persist in work buffer after we return.
	 *
	 * Work buffer now contains:
	 *   - vb2_shared_data
	 *   - vb2_gbb_header
	 *   - packed firmware data key
	 *   - firmware preamble
	 *
	 * TODO: we could move the preamble down over the firmware data key
	 * since we don't need it anymore.
	 */
	vb2_set_workbuf_used(ctx, sd->preamble_offset + pre_size);

	return VB2_SUCCESS;
}
