/* 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 int 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;
	int rv;

	/* 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;
	rv = vb2ex_read_resource(ctx, VB2_RES_GBB, offset, *keyp,
				 sizeof(**keyp));
	if (rv)
		return rv;

	rv = vb2_verify_packed_key_inside(*keyp, *size, *keyp);
	if (rv)
		return rv;

	/* Deal with a zero-size key (used in testing). */
	*size = (*keyp)->key_offset + (*keyp)->key_size;
	if (*size < sizeof(**keyp))
		*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;

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

int 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;
	int ret = vb2_gbb_read_key(ctx, gbb->rootkey_offset,
				   &size_in, keyp, wb);
	if (size)
		*size = size_in;
	return ret;
}

int 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;
	int ret = vb2_gbb_read_key(ctx, gbb->recovery_key_offset,
				   &size_in, keyp, wb);
	if (size)
		*size = size_in;
	return ret;
}

int 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;
	int ret;

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

	if (*size > VB2_GBB_HWID_MAX_SIZE)
		*size = VB2_GBB_HWID_MAX_SIZE;
	if (*size > gbb->hwid_size)
		*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;
}
