/* Copyright 2015 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 - kernel version space
 */

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

#define MAJOR_VER(x) (((x) & 0xf0) >> 4)
#define MINOR_VER(x) ((x) & 0x0f)

static inline int is_v0(struct vb2_context *ctx)
{
	struct vb2_secdata_kernel_v1 *sec = (void *)ctx->secdata_kernel;
	return MAJOR_VER(sec->struct_version) == 0;
}

uint8_t vb2_secdata_kernel_crc(struct vb2_context *ctx)
{
	size_t offset, size;

	if (is_v0(ctx)) {
		offset = 0;
		size = offsetof(struct vb2_secdata_kernel_v0, crc8);
	} else {
		struct vb2_secdata_kernel_v1 *sec
			= (void *)ctx->secdata_kernel;
		offset = offsetof(struct vb2_secdata_kernel_v1, reserved0);
		size = sec->struct_size - offset;
	}

	return vb2_crc8(ctx->secdata_kernel + offset, size);
}

static vb2_error_t secdata_kernel_check_v0(struct vb2_context *ctx,
					   uint8_t *size)
{
	struct vb2_secdata_kernel_v0 *sec = (void *)ctx->secdata_kernel;
	uint8_t ver = sec->struct_version;

	if (MINOR_VER(ver) != MINOR_VER(VB2_SECDATA_KERNEL_VERSION_V02)) {
		VB2_DEBUG("secdata_kernel: bad struct_version (%d.%d)\n",
			  MAJOR_VER(ver), MINOR_VER(ver));
		return VB2_ERROR_SECDATA_KERNEL_VERSION;
	}

	*size = VB2_SECDATA_KERNEL_SIZE_V02;

	/* Verify CRC */
	if (sec->crc8 != vb2_secdata_kernel_crc(ctx)) {
		VB2_DEBUG("secdata_kernel: bad CRC\n");
		return VB2_ERROR_SECDATA_KERNEL_CRC;
	}

	/* Verify UID */
	if (sec->uid != VB2_SECDATA_KERNEL_UID) {
		VB2_DEBUG("secdata_kernel: bad UID\n");
		return VB2_ERROR_SECDATA_KERNEL_UID;
	}

	return VB2_SUCCESS;
}

static vb2_error_t secdata_kernel_check_v1(struct vb2_context *ctx,
					   uint8_t *size)
{
	struct vb2_secdata_kernel_v1 *sec = (void *)ctx->secdata_kernel;
	uint8_t ver = sec->struct_version;

	if (MAJOR_VER(ver) != MAJOR_VER(VB2_SECDATA_KERNEL_VERSION_V10)) {
		VB2_DEBUG("secdata_kernel: bad struct_version (%d.%d)\n",
			  MAJOR_VER(ver), MINOR_VER(ver));
		return VB2_ERROR_SECDATA_KERNEL_VERSION;
	}

	if (sec->struct_size < VB2_SECDATA_KERNEL_SIZE_V10 ||
			VB2_SECDATA_KERNEL_MAX_SIZE < sec->struct_size) {
		VB2_DEBUG("secdata_kernel: bad struct_size (%d)\n",
			  sec->struct_size);
		return VB2_ERROR_SECDATA_KERNEL_STRUCT_SIZE;
	}

	if (*size < sec->struct_size) {
		VB2_DEBUG("secdata_kernel: incomplete data (missing %d bytes)\n",
			  sec->struct_size - *size);
		*size = sec->struct_size;
		return VB2_ERROR_SECDATA_KERNEL_INCOMPLETE;
	}

	/*
	 * In case larger data should be passed, kindly let the caller know
	 * the right size.
	 */
	*size = sec->struct_size;

	/* Verify CRC */
	if (sec->crc8 != vb2_secdata_kernel_crc(ctx)) {
		VB2_DEBUG("secdata_kernel: bad CRC\n");
		return VB2_ERROR_SECDATA_KERNEL_CRC;
	}

	return VB2_SUCCESS;
}

vb2_error_t vb2api_secdata_kernel_check(struct vb2_context *ctx, uint8_t *size)
{
	if (*size < VB2_SECDATA_KERNEL_MIN_SIZE) {
		VB2_DEBUG("secdata_kernel: data size too small!\n");
		*size = VB2_SECDATA_KERNEL_MIN_SIZE;
		return VB2_ERROR_SECDATA_KERNEL_INCOMPLETE;
	}

	if (is_v0(ctx))
		return secdata_kernel_check_v0(ctx, size);
	else
		return secdata_kernel_check_v1(ctx, size);
}

uint32_t vb2api_secdata_kernel_create(struct vb2_context *ctx)
{
	struct vb2_secdata_kernel_v1 *sec = (void *)ctx->secdata_kernel;

	/* Populate the struct */
	memset(sec, 0, sizeof(*sec));
	sec->struct_version = VB2_SECDATA_KERNEL_VERSION_LATEST;
	sec->struct_size = sizeof(*sec);
	sec->crc8 = vb2_secdata_kernel_crc(ctx);

	/* Mark as changed */
	ctx->flags |= VB2_CONTEXT_SECDATA_KERNEL_CHANGED;

	return sizeof(*sec);
}

/* For TPM 1.2 */
uint32_t vb2api_secdata_kernel_create_v0(struct vb2_context *ctx)
{
	struct vb2_secdata_kernel_v0 *sec = (void *)ctx->secdata_kernel;

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

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

	/* Set UID */
	sec->uid = VB2_SECDATA_KERNEL_UID;

	/* Calculate initial CRC */
	sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdata_kernel_v0, crc8));

	/* Mark as changed */
	ctx->flags |= VB2_CONTEXT_SECDATA_KERNEL_CHANGED;

	return sizeof(*sec);
}

vb2_error_t vb2_secdata_kernel_init(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	uint8_t size = VB2_SECDATA_KERNEL_MAX_SIZE;

	VB2_TRY(vb2api_secdata_kernel_check(ctx, &size));

	/* Set status flag */
	sd->status |= VB2_SD_STATUS_SECDATA_KERNEL_INIT;

	return VB2_SUCCESS;
}

uint32_t vb2_secdata_kernel_get(struct vb2_context *ctx,
				enum vb2_secdata_kernel_param param)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	const char *msg;

	if (!(sd->status & VB2_SD_STATUS_SECDATA_KERNEL_INIT)) {
		msg = "get before init";
		goto fail;
	}

	switch (param) {
	case VB2_SECDATA_KERNEL_VERSIONS:
		if (is_v0(ctx)) {
			struct vb2_secdata_kernel_v0 *sec =
					(void *)ctx->secdata_kernel;
			return sec->kernel_versions;
		} else {
			struct vb2_secdata_kernel_v1 *sec =
					(void *)ctx->secdata_kernel;
			return sec->kernel_versions;
		}
	default:
		msg = "invalid param";
	}

 fail:
	VB2_REC_OR_DIE(ctx, "%s\n", msg);
	return 0;
}

void vb2_secdata_kernel_set(struct vb2_context *ctx,
			    enum vb2_secdata_kernel_param param,
			    uint32_t value)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	const char *msg;
	struct vb2_secdata_kernel_v0 *v0 = (void *)ctx->secdata_kernel;
	struct vb2_secdata_kernel_v1 *v1 = (void *)ctx->secdata_kernel;
	uint32_t *ptr;

	if (!(sd->status & VB2_SD_STATUS_SECDATA_KERNEL_INIT)) {
		msg = "set before init";
		goto fail;
	}

	/* If not changing the value, just return early */
	if (value == vb2_secdata_kernel_get(ctx, param))
		return;

	switch (param) {
	case VB2_SECDATA_KERNEL_VERSIONS:
		ptr = is_v0(ctx) ? &v0->kernel_versions : &v1->kernel_versions;
		VB2_DEBUG("secdata_kernel versions updated from %#x to %#x\n",
			  *ptr, value);
		break;

	default:
		msg = "invalid param";
		goto fail;
	}

	*ptr = value;

	if (is_v0(ctx))
		v0->crc8 = vb2_secdata_kernel_crc(ctx);
	else
		v1->crc8 = vb2_secdata_kernel_crc(ctx);

	ctx->flags |= VB2_CONTEXT_SECDATA_KERNEL_CHANGED;
	return;

 fail:
	VB2_REC_OR_DIE(ctx, "%s\n", msg);
}

const uint8_t *vb2_secdata_kernel_get_ec_hash(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	struct vb2_secdata_kernel_v1 *sec = (void *)ctx->secdata_kernel;

	if (!(sd->status & VB2_SD_STATUS_SECDATA_KERNEL_INIT)) {
		VB2_REC_OR_DIE(ctx, "Get kernel secdata before init\n");
		return NULL;
	}
	if (is_v0(ctx)) {
		VB2_DEBUG("kernel secdata v.0* doesn't support EC hash\n");
		return NULL;
	}

	return sec->ec_hash;
}

void vb2_secdata_kernel_set_ec_hash(struct vb2_context *ctx,
				    const uint8_t *sha256)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	struct vb2_secdata_kernel_v1 *sec = (void *)ctx->secdata_kernel;

	if (!(sd->status & VB2_SD_STATUS_SECDATA_KERNEL_INIT)) {
		VB2_REC_OR_DIE(ctx, "Get kernel secdata before init\n");
		return;
	}
	if (is_v0(ctx)) {
		VB2_REC_OR_DIE(ctx, "Invalid version of kernel secdata\n");
		return;
	}

	memcpy(sec->ec_hash, sha256, sizeof(sec->ec_hash));
	sec->crc8 = vb2_secdata_kernel_crc(ctx);

	ctx->flags |= VB2_CONTEXT_SECDATA_KERNEL_CHANGED;

	return;
}
