/* Copyright 2019 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.
 *
 * GBB accessor functions.
 */

#include "2common.h"
#include "2misc.h"

static vb2_error_t vb2_gbb_read_key(struct vb2_context *ctx, uint32_t offset,
				    uint32_t *size,
				    struct vb2_packed_key **keyp,
				    struct vb2_workbuf *wb)
{
	struct vb2_workbuf wblocal = *wb;

	/* Check offset and size. */
	if (offset < sizeof(struct vb2_gbb_header))
		return VB2_ERROR_GBB_INVALID;
	if (*size < sizeof(**keyp))
		return VB2_ERROR_GBB_INVALID;

	/* GBB header might be padded.  Retrieve the vb2_packed_key
	   header so we can find out what the real size is. */
	*keyp = vb2_workbuf_alloc(&wblocal, sizeof(**keyp));
	if (!*keyp)
		return VB2_ERROR_GBB_WORKBUF;
	VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_GBB, offset, *keyp,
				    sizeof(**keyp)));

	VB2_TRY(vb2_verify_packed_key_inside(*keyp, *size, *keyp));

	/* Deal with a zero-size key (used in testing). */
	*size = (*keyp)->key_offset + (*keyp)->key_size;
	*size = VB2_MAX(*size, sizeof(**keyp));

	/* Now that we know the real size of the key, retrieve the key
	   data, and write it on the workbuf, directly after vb2_packed_key. */
	*keyp = vb2_workbuf_realloc(&wblocal, sizeof(**keyp), *size);
	if (!*keyp)
		return VB2_ERROR_GBB_WORKBUF;

	VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_GBB,
				    offset + sizeof(**keyp),
				    (void *)*keyp + sizeof(**keyp),
				    *size - sizeof(**keyp)));
	*wb = wblocal;
	return VB2_SUCCESS;
}

vb2_error_t vb2_gbb_read_root_key(struct vb2_context *ctx,
				  struct vb2_packed_key **keyp, uint32_t *size,
				  struct vb2_workbuf *wb)
{
	struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
	uint32_t size_in = gbb->rootkey_size;
	vb2_error_t ret = vb2_gbb_read_key(ctx, gbb->rootkey_offset,
					   &size_in, keyp, wb);
	if (size)
		*size = size_in;
	return ret;
}

vb2_error_t vb2_gbb_read_recovery_key(struct vb2_context *ctx,
				      struct vb2_packed_key **keyp,
				      uint32_t *size, struct vb2_workbuf *wb)
{
	struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
	uint32_t size_in = gbb->recovery_key_size;
	vb2_error_t ret = vb2_gbb_read_key(ctx, gbb->recovery_key_offset,
					   &size_in, keyp, wb);
	if (size)
		*size = size_in;
	return ret;
}

vb2_error_t vb2api_gbb_read_hwid(struct vb2_context *ctx, char *hwid,
				 uint32_t *size)
{
	struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
	uint32_t i;
	vb2_error_t ret;

	if (gbb->hwid_size == 0) {
		VB2_DEBUG("invalid HWID size %d\n", gbb->hwid_size);
		return VB2_ERROR_GBB_INVALID;
	}

	*size = VB2_MIN(*size, VB2_GBB_HWID_MAX_SIZE);
	*size = VB2_MIN(*size, gbb->hwid_size);

	ret = vb2ex_read_resource(ctx, VB2_RES_GBB, gbb->hwid_offset,
				  hwid, *size);
	if (ret) {
		VB2_DEBUG("read resource failure: %d\n", ret);
		return ret;
	}

	/* Count HWID size, and ensure that it fits in the given buffer. */
	for (i = 0; i < *size; i++) {
		if (hwid[i] == '\0') {
			*size = i + 1;
			break;
		}
	}
	if (hwid[*size - 1] != '\0')
		return VB2_ERROR_INVALID_PARAMETER;

	return VB2_SUCCESS;
}

vb2_gbb_flags_t vb2api_gbb_get_flags(struct vb2_context *ctx)
{
	struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
	return gbb->flags;
}
