/* 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.
 *
 * Secure storage APIs
 */

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

int vb2_secdata_check_crc(const struct vb2_context *ctx)
{
	const struct vb2_secdata *sec =
		(const struct vb2_secdata *)ctx->secdata;

	/* Verify CRC */
	if (sec->crc8 != vb2_crc8(sec, offsetof(struct vb2_secdata, crc8)))
		return VB2_ERROR_BAD_SECDATA;

	return VB2_SUCCESS;
}

int vb2_secdata_create(struct vb2_context *ctx)
{
	struct vb2_secdata *sec = (struct vb2_secdata *)ctx->secdata;

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

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

	/* Calculate initial CRC */
	sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdata, crc8));
	ctx->flags |= VB2_CONTEXT_SECDATA_CHANGED;
	return VB2_SUCCESS;
}

int vb2_secdata_init(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	struct vb2_secdata *sec = (struct vb2_secdata *)ctx->secdata;
	int rv;

	/* Data must be new enough to have a CRC */
	if (sec->struct_version < 2)
		return VB2_ERROR_BAD_SECDATA;

	rv = vb2_secdata_check_crc(ctx);
	if (rv)
		return rv;

	/* Set status flag */
	sd->status |= VB2_SD_STATUS_SECDATA_INIT;
	// TODO: unit test for that

	return VB2_SUCCESS;
}

int vb2_secdata_get(struct vb2_context *ctx,
		    enum vb2_secdata_param param,
		    uint32_t *dest)
{
	struct vb2_secdata *sec = (struct vb2_secdata *)ctx->secdata;

	switch(param) {
	case VB2_SECDATA_FLAGS:
		*dest = sec->flags;
		return VB2_SUCCESS;

	case VB2_SECDATA_VERSIONS:
		*dest = sec->fw_versions;
		return VB2_SUCCESS;

	default:
		return VB2_ERROR_UNKNOWN;
	}
}

int vb2_secdata_set(struct vb2_context *ctx,
		    enum vb2_secdata_param param,
		    uint32_t value)
{
	struct vb2_secdata *sec = (struct vb2_secdata *)ctx->secdata;
	uint32_t now;

	/* If not changing the value, don't regenerate the CRC. */
	if (vb2_secdata_get(ctx, param, &now) == VB2_SUCCESS && now == value)
		return VB2_SUCCESS;

	switch(param) {
	case VB2_SECDATA_FLAGS:
		/* Make sure flags is in valid range */
		if (value > 0xff)
			return VB2_ERROR_UNKNOWN;

		sec->flags = value;
		break;

	case VB2_SECDATA_VERSIONS:
		sec->fw_versions = value;
		break;

	default:
		return VB2_ERROR_UNKNOWN;
	}

	/* Regenerate CRC */
	sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdata, crc8));
	ctx->flags |= VB2_CONTEXT_SECDATA_CHANGED;
	return VB2_SUCCESS;
}
