/* 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.
 *
 * Tests for firmware secure storage library.
 */

#include "2api.h"
#include "2common.h"
#include "2crc8.h"
#include "2misc.h"
#include "2secdata.h"
#include "2secdata_struct.h"
#include "2sysincludes.h"
#include "common/tests.h"

static uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE]
	__attribute__((aligned(VB2_WORKBUF_ALIGN)));
static struct vb2_context *ctx;
static struct vb2_shared_data *sd;
static struct vb2_secdata_firmware *sec;

static void reset_common_data(void)
{
	memset(workbuf, 0xaa, sizeof(workbuf));
	TEST_SUCC(vb2api_init(workbuf, sizeof(workbuf), &ctx),
		  "vb2api_init failed");

	sd = vb2_get_sd(ctx);

	/* Most tests assume we have passed fw_phase1() */
	sd->status |= VB2_SD_STATUS_RECOVERY_DECIDED;

	sec = (struct vb2_secdata_firmware *)ctx->secdata_firmware;
}

static void test_changed(struct vb2_context *c, int changed, const char *why)
{
	if (changed)
		TEST_NEQ(c->flags & VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED,
			 0, why);
	else
		TEST_EQ(c->flags & VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED,
			0, why);

	c->flags &= ~VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED;
};

static void secdata_firmware_test(void)
{
	uint32_t v = 1;
	reset_common_data();

	/* Check size constant */
	TEST_EQ(VB2_SECDATA_FIRMWARE_SIZE, sizeof(struct vb2_secdata_firmware),
		"Struct size constant");

	/* Blank data is invalid */
	memset(&ctx->secdata_firmware, 0xa6, sizeof(ctx->secdata_firmware));
	TEST_EQ(vb2api_secdata_firmware_check(ctx),
		VB2_ERROR_SECDATA_FIRMWARE_CRC, "Check blank CRC");
	TEST_EQ(vb2_secdata_firmware_init(ctx),
		VB2_ERROR_SECDATA_FIRMWARE_CRC, "Init blank CRC");

	/* Ensure zeroed buffers are invalid (coreboot relies on this) */
	memset(&ctx->secdata_firmware, 0, sizeof(ctx->secdata_firmware));
	TEST_EQ(vb2_secdata_firmware_init(ctx),
		VB2_ERROR_SECDATA_FIRMWARE_VERSION,
		"Zeroed buffer (invalid version)");

	/* Try with bad version */
	TEST_EQ(vb2api_secdata_firmware_create(ctx), VB2_SECDATA_FIRMWARE_SIZE,
		"Create");
	sec->struct_version -= 1;
	sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdata_firmware, crc8));
	TEST_EQ(vb2api_secdata_firmware_check(ctx),
		VB2_ERROR_SECDATA_FIRMWARE_VERSION, "Check invalid version");
	TEST_EQ(vb2_secdata_firmware_init(ctx),
		VB2_ERROR_SECDATA_FIRMWARE_VERSION, "Init invalid version");

	/* Create good data */
	vb2api_secdata_firmware_create(ctx);
	TEST_SUCC(vb2api_secdata_firmware_check(ctx), "Check created CRC");
	TEST_SUCC(vb2_secdata_firmware_init(ctx), "Init created CRC");
	TEST_NEQ(sd->status & VB2_SD_STATUS_SECDATA_FIRMWARE_INIT, 0,
		 "Init set SD status");
	sd->status &= ~VB2_SD_STATUS_SECDATA_FIRMWARE_INIT;
	test_changed(ctx, 1, "Create changes data");

	/* Now corrupt it */
	ctx->secdata_firmware[2]++;
	TEST_EQ(vb2api_secdata_firmware_check(ctx),
		VB2_ERROR_SECDATA_FIRMWARE_CRC, "Check invalid CRC");
	TEST_EQ(vb2_secdata_firmware_init(ctx),
		VB2_ERROR_SECDATA_FIRMWARE_CRC, "Init invalid CRC");

	/* Read/write flags */
	vb2api_secdata_firmware_create(ctx);
	vb2_secdata_firmware_init(ctx);
	ctx->flags = 0;
	v = vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_FLAGS);
	TEST_EQ(v, 0, "Flags created 0");
	test_changed(ctx, 0, "Get doesn't change data");
	vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_FLAGS, 0x12);
	test_changed(ctx, 1, "Set changes data");
	vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_FLAGS, 0x12);
	test_changed(ctx, 0, "Set again doesn't change data");
	v = vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_FLAGS);
	TEST_EQ(v, 0x12, "Flags changed");
	TEST_ABORT(vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_FLAGS,
					    0x100),
		   "Bad flags");

	/* Read/write versions */
	v = vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_VERSIONS);
	TEST_EQ(v, 0, "Versions created 0");
	test_changed(ctx, 0, "Get doesn't change data");
	vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_VERSIONS,
				 0x123456ff);
	test_changed(ctx, 1, "Set changes data");
	vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_VERSIONS,
				 0x123456ff);
	test_changed(ctx, 0, "Set again doesn't change data");
	v = vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_VERSIONS);
	TEST_EQ(v, 0x123456ff, "Versions changed");

	/* Invalid field fails */
	TEST_ABORT(vb2_secdata_firmware_get(ctx, -1), "Get invalid");
	TEST_ABORT(vb2_secdata_firmware_set(ctx, -1, 456), "Set invalid");
	test_changed(ctx, 0, "Set invalid field doesn't change data");

	/* Read/write uninitialized data fails */
	sd->status &= ~VB2_SD_STATUS_SECDATA_FIRMWARE_INIT;
	TEST_ABORT(vb2_secdata_firmware_get(ctx,
					    VB2_SECDATA_FIRMWARE_VERSIONS),
		   "Get uninitialized");
	test_changed(ctx, 0, "Get uninitialized doesn't change data");
	TEST_ABORT(vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_VERSIONS,
					    0x123456ff),
		   "Set uninitialized");
	test_changed(ctx, 0, "Set uninitialized doesn't change data");

	/* Read/write uninitialized in recovery mode */
	ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
	TEST_EQ(vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_VERSIONS), 0,
		"Get uninitialized (recmode)");
	test_changed(ctx, 0, "Get uninitialized (recmode) doesn't change data");
	vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_VERSIONS,
				 0x123456ff);
	test_changed(ctx, 0, "Set uninitialized (recmode) doesn't change data");

	/* Read/write early in fw_phase1 */
	ctx->flags &= ~VB2_CONTEXT_RECOVERY_MODE;
	sd->status &= ~VB2_SD_STATUS_RECOVERY_DECIDED;
	TEST_EQ(vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_VERSIONS), 0,
		"Get uninitialized (phase1)");
	test_changed(ctx, 0, "Get uninitialized (phase1) doesn't change data");
	vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_VERSIONS,
				 0x123456ff);
	test_changed(ctx, 0, "Set uninitialized (phase1) doesn't change data");
}

int main(int argc, char* argv[])
{
	secdata_firmware_test();

	return gTestSuccess ? 0 : 255;
}
