/* 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 "2sysincludes.h"
#include "2api.h"
#include "2common.h"
#include "2misc.h"
#include "2nvstorage.h"
#include "2secdata.h"
#include "2sha.h"
#include "2rsa.h"
#include "vb21_common.h"

/**
 * Read an object with a common struct header from a verified boot resource.
 *
 * On success, an object buffer will be allocated in the work buffer, the
 * object will be stored into the buffer, and *buf_ptr will point to the
 * object.
 *
 * @param ctx		Vboot context
 * @param index		Resource index to read
 * @param offset	Byte offset within resource to start at
 * @param buf_ptr	Destination for object pointer
 * @return VB2_SUCCESS, or error code on error.
 */
static int vb21_read_resource_object(struct vb2_context *ctx,
				     enum vb2_resource_index index,
				     uint32_t offset,
				     struct vb2_workbuf *wb,
				     void **buf_ptr)
{
	struct vb21_struct_common c;
	void *buf;
	int rv;

	*buf_ptr = NULL;

	/* Read the common header */
	rv = vb2ex_read_resource(ctx, index, offset, &c, sizeof(c));
	if (rv)
		return rv;

	/* Allocate a buffer for the object, now that we know how big it is */
	buf = vb2_workbuf_alloc(wb, c.total_size);
	if (!buf)
		return VB2_ERROR_READ_RESOURCE_OBJECT_BUF;

	/* Read the object */
	rv = vb2ex_read_resource(ctx, index, offset, buf, c.total_size);
	if (rv) {
		vb2_workbuf_free(wb, c.total_size);
		return rv;
	}

	/* Save the pointer */
	*buf_ptr = buf;
	return VB2_SUCCESS;
}

int vb21_load_fw_keyblock(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;
	struct vb21_packed_key *packed_key;
	struct vb2_public_key root_key;
	struct vb21_keyblock *kb;

	int rv;

	vb2_workbuf_from_ctx(ctx, &wb);

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

	rv = vb2ex_read_resource(ctx, VB2_RES_GBB, sd->gbb_rootkey_offset,
				 key_data, key_size);
	if (rv)
		return rv;

	/* Unpack the root key */
	rv = vb21_unpack_key(&root_key, key_data, key_size);
	if (rv)
		return rv;

	/*
	 * Load the firmware keyblock common header into the work buffer after
	 * the root key.
	 */
	rv = vb21_read_resource_object(ctx, VB2_RES_FW_VBLOCK, 0, &wb,
				       (void **)&kb);
	if (rv)
		return rv;

	/* Verify the keyblock */
	rv = vb21_verify_keyblock(kb, kb->c.total_size, &root_key, &wb);
	if (rv) {
		vb2_fail(ctx, VB2_RECOVERY_FW_KEYBLOCK, rv);
		return rv;
	}

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

	packed_key = (struct vb21_packed_key *)((uint8_t *)kb + kb->key_offset);

	/* Key version is the upper 16 bits of the composite firmware version */
	if (packed_key->key_version > 0xffff)
		rv = VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE;
	if (!rv && packed_key->key_version < (sd->fw_version_secdata >> 16)) {
		if (sd->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) {
		vb2_fail(ctx, VB2_RECOVERY_FW_KEY_ROLLBACK, rv);
		return rv;
	}

	sd->fw_version = packed_key->key_version << 16;

	/*
	 * Save the data key in the work buffer.  This overwrites the root key
	 * we read above.  That's ok, because now that we have the data key we
	 * no longer need the root key.
	 *
	 * Use memmove() instead of memcpy().  In theory, the destination will
	 * never overlap 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.
	 */
	memmove(key_data, packed_key, packed_key->c.total_size);
	packed_key = (struct vb21_packed_key *)key_data;

	/* Save the packed key offset and size */
	sd->workbuf_data_key_offset = vb2_offset_of(ctx->workbuf, key_data);
	sd->workbuf_data_key_size = packed_key->c.total_size;

	/* Data key will persist in the workbuf after we return */
	vb2_set_workbuf_used(ctx, sd->workbuf_data_key_offset +
			     sd->workbuf_data_key_size);

	return VB2_SUCCESS;
}

int vb21_load_fw_preamble(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	struct vb2_workbuf wb;

	uint8_t *key_data = ctx->workbuf + sd->workbuf_data_key_offset;
	uint32_t key_size = sd->workbuf_data_key_size;
	struct vb2_public_key data_key;

	/* Preamble goes in the next unused chunk of work buffer */
	struct vb21_fw_preamble *pre;

	int rv;

	vb2_workbuf_from_ctx(ctx, &wb);

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

	rv = vb21_unpack_key(&data_key, key_data, key_size);
	if (rv)
		return rv;

	/* Load the firmware preamble */
	rv = vb21_read_resource_object(ctx, VB2_RES_FW_VBLOCK,
				       sd->vblock_preamble_offset, &wb,
				       (void **)&pre);
	if (rv)
		return rv;

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

	/* Verify the preamble */
	rv = vb21_verify_fw_preamble(pre, pre->c.total_size, &data_key, &wb);
	if (rv) {
		vb2_fail(ctx, VB2_RECOVERY_FW_PREAMBLE, rv);
		return rv;
	}

	/* Move the preamble down now that the data key is no longer used */
	memmove(key_data, pre, pre->c.total_size);
	pre = (struct vb21_fw_preamble *)key_data;

	/* Data key is now gone */
	sd->workbuf_data_key_offset = sd->workbuf_data_key_size = 0;

	/*
	 * Firmware version is the lower 16 bits of the composite firmware
	 * version.
	 */
	if (pre->fw_version > 0xffff)
		rv = VB2_ERROR_FW_PREAMBLE_VERSION_RANGE;
	/* Combine with the key version from vb2_load_fw_keyblock() */
	sd->fw_version |= pre->fw_version;
	if (!rv && sd->fw_version < sd->fw_version_secdata) {
		if (sd->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) {
		vb2_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.
	 */
	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;
		rv = vb2_secdata_set(ctx, VB2_SECDATA_VERSIONS, sd->fw_version);
		if (rv)
			return rv;
	}

	/* Keep track of where we put the preamble */
	sd->workbuf_preamble_offset = vb2_offset_of(ctx->workbuf, pre);
	sd->workbuf_preamble_size = pre->c.total_size;

	/* Preamble will persist in work buffer after we return */
	vb2_set_workbuf_used(ctx, sd->workbuf_preamble_offset +
			     sd->workbuf_preamble_size);

	return VB2_SUCCESS;
}
