/* 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.
 *
 * Firmware management parameters (FWMP) APIs
 */

#include "2common.h"
#include "2crc8.h"
#include "2misc.h"
#include "2secdata.h"
#include "2secdata_struct.h"

test_mockable
vb2_error_t vb2api_secdata_fwmp_check(struct vb2_context *ctx, uint8_t *size)
{
	struct vb2_secdata_fwmp *sec =
		(struct vb2_secdata_fwmp *)&ctx->secdata_fwmp;

	/* Verify that at least the minimum size has been read */
	if (*size < VB2_SECDATA_FWMP_MIN_SIZE) {
		VB2_DEBUG("FWMP: missing %d bytes for minimum size\n",
			  VB2_SECDATA_FWMP_MIN_SIZE - *size);
		*size = VB2_SECDATA_FWMP_MIN_SIZE;
		return VB2_ERROR_SECDATA_FWMP_INCOMPLETE;
	}

	/* Verify that struct_size is reasonable */
	if (sec->struct_size < VB2_SECDATA_FWMP_MIN_SIZE ||
	    sec->struct_size > VB2_SECDATA_FWMP_MAX_SIZE) {
		VB2_DEBUG("FWMP: invalid size: %d\n", sec->struct_size);
		return VB2_ERROR_SECDATA_FWMP_SIZE;
	}

	/* Verify that we have read full structure */
	if (*size < sec->struct_size) {
		VB2_DEBUG("FWMP: missing %d bytes\n", sec->struct_size - *size);
		*size = sec->struct_size;
		return VB2_ERROR_SECDATA_FWMP_INCOMPLETE;
	}
	*size = sec->struct_size;

	/* Verify CRC */
	if (sec->crc8 != vb2_secdata_fwmp_crc(sec)) {
		VB2_DEBUG("FWMP: bad CRC\n");
		return VB2_ERROR_SECDATA_FWMP_CRC;
	}

	/* Verify major version is compatible */
	if ((sec->struct_version >> 4) != (VB2_SECDATA_FWMP_VERSION >> 4)) {
		VB2_DEBUG("FWMP: major version incompatible\n");
		return VB2_ERROR_SECDATA_FWMP_VERSION;
	}

	/*
	 * If this were a 1.1+ reader and the source was a 1.0 struct,
	 * we would need to take care of initializing the extra fields
	 * added in 1.1+.  But that's not an issue yet.
	 */
	return VB2_SUCCESS;
}

uint32_t vb2api_secdata_fwmp_create(struct vb2_context *ctx)
{
	struct vb2_secdata_fwmp *sec = (void *)&ctx->secdata_fwmp;

	/* Clear the entire struct */
	memset(sec, 0, sizeof(*sec));

	/* Set to current version */
	sec->struct_version = VB2_SECDATA_FWMP_VERSION;

	/* Set the structure size */
	sec->struct_size = sizeof(*sec);

	/* Calculate initial CRC */
	sec->crc8 = vb2_secdata_fwmp_crc(sec);

	return sizeof(*sec);
}

vb2_error_t vb2_secdata_fwmp_init(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	struct vb2_secdata_fwmp *sec =
		(struct vb2_secdata_fwmp *)&ctx->secdata_fwmp;

	/* Skip checking if NO_SECDATA_FWMP is set. */
	if (!(ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP))
		VB2_TRY(vb2api_secdata_fwmp_check(ctx, &sec->struct_size));

	/* Mark as initialized */
	sd->status |= VB2_SD_STATUS_SECDATA_FWMP_INIT;

	return VB2_SUCCESS;
}

int vb2_secdata_fwmp_get_flag(struct vb2_context *ctx,
			      enum vb2_secdata_fwmp_flags flag)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	struct vb2_secdata_fwmp *sec =
		(struct vb2_secdata_fwmp *)&ctx->secdata_fwmp;

	if (!(sd->status & VB2_SD_STATUS_SECDATA_FWMP_INIT)) {
		VB2_REC_OR_DIE(ctx, "Must init FWMP before retrieving flag\n");
		return 0;
	}

	if (ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP)
		return 0;

	return !!(sec->flags & flag);
}

uint8_t *vb2_secdata_fwmp_get_dev_key_hash(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	struct vb2_secdata_fwmp *sec =
		(struct vb2_secdata_fwmp *)&ctx->secdata_fwmp;

	if (!(sd->status & VB2_SD_STATUS_SECDATA_FWMP_INIT)) {
		VB2_REC_OR_DIE(ctx, "Must init FWMP before get dev key hash\n");
		return NULL;
	}

	if (ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP)
		return NULL;

	return sec->dev_key_hash;
}
