/* 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.
 *
 * Unit tests
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>

#include "2sha.h"
#include "2hmac.h"
#include "bdb.h"
#include "bdb_api.h"
#include "bdb_struct.h"
#include "host.h"
#include "test_common.h"
#include "vboot_register.h"
#include "secrets.h"

static struct bdb_header *bdb, *bdb0, *bdb1;
static uint32_t vboot_register;
static uint32_t vboot_register_persist;
static char slot_selected;
static uint8_t aprw_digest[BDB_SHA256_DIGEST_SIZE];
static uint8_t reset_count;

/* NVM-RW image in storage (e.g. EEPROM) */
static uint8_t nvmrw1[NVM_RW_MAX_STRUCT_SIZE];
static uint8_t nvmrw2[NVM_RW_MAX_STRUCT_SIZE];

static struct bdb_secrets secrets = {
	.nvm_wp = {0x00, },
	.nvm_rw = {0x00, },
	.bdb = {0x00, },
	.boot_verified = {0x00, },
	.boot_path = {0x00, },
	.buc = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
		0xff, 0xff},
};

static int vbe_write_nvm_failure = 0;

static struct bdb_header *create_bdb(const char *key_dir,
				     struct bdb_hash *hash, int num_hashes)
{
	struct bdb_header *b;
	uint8_t oem_area_0[32] = "Some OEM area.";
	uint8_t oem_area_1[64] = "Some other OEM area.";
	char filename[1024];

	struct bdb_create_params p = {
		.bdb_load_address = 0x11223344,
		.oem_area_0 = oem_area_0,
		.oem_area_0_size = sizeof(oem_area_0),
		.oem_area_1 = oem_area_1,
		.oem_area_1_size = sizeof(oem_area_1),
		.header_sig_description = "The header sig",
		.data_sig_description = "The data sig",
		.data_description = "Test BDB data",
		.data_version = 3,
		.hash = hash,
		.num_hashes = num_hashes,
	};

	uint8_t bdbkey_digest[BDB_SHA256_DIGEST_SIZE];

	/* Load keys */
	snprintf(filename, sizeof(filename), "%s/bdbkey.keyb", key_dir);
	p.bdbkey = bdb_create_key(filename, 100, "BDB key");
	snprintf(filename, sizeof(filename), "%s/datakey.keyb", key_dir);
	p.datakey = bdb_create_key(filename, 200, "datakey");
	snprintf(filename, sizeof(filename), "%s/bdbkey.pem", key_dir);
	p.private_bdbkey = read_pem(filename);
	snprintf(filename, sizeof(filename), "%s/datakey.pem", key_dir);
	p.private_datakey = read_pem(filename);
	if (!p.bdbkey || !p.datakey || !p.private_bdbkey || !p.private_datakey) {
		fprintf(stderr, "Unable to load test keys\n");
		exit(2);
	}

	vb2_digest_buffer((uint8_t *)p.bdbkey, p.bdbkey->struct_size,
			  VB2_HASH_SHA256,
			  bdbkey_digest, BDB_SHA256_DIGEST_SIZE);

	b = bdb_create(&p);
	if (!b) {
		fprintf(stderr, "Unable to create test BDB\n");
		exit(2);
	}

	/* Free keys and buffers */
	free(p.bdbkey);
	free(p.datakey);
	RSA_free(p.private_bdbkey);
	RSA_free(p.private_datakey);

	return b;
}

static void calculate_aprw_digest(const struct bdb_hash *hash, uint8_t *digest)
{
	/* Locate AP-RW */
	/* Calculate digest as loading AP-RW */
	memcpy(digest, aprw_digest, sizeof(aprw_digest));
}

static void verstage_main(void)
{
	struct vba_context ctx;
	const struct bdb_hash *hash;
	uint8_t digest[BDB_SHA256_DIGEST_SIZE];
	int rv;

	rv = vba_bdb_init(&ctx);
	if (rv) {
		fprintf(stderr, "Initializing context failed for (%d)\n", rv);
		vba_bdb_fail(&ctx);
		/* This return is needed for unit test. vba_bdb_fail calls
		 * vbe_reset, which calls verstage_main. If verstage_main
		 * successfully returns, we return here as well. */
		return;
	}
	fprintf(stderr, "Initialized context. Trying slot %c\n",
		ctx.slot ? 'B' : 'A');

	/* 1. Locate BDB */

	/* 2. Get bdb_hash structure for AP-RW */
	hash = bdb_get_hash_by_type(bdb, BDB_DATA_AP_RW);
	fprintf(stderr, "Got hash of AP-RW\n");

	/* 3. Load & calculate digest of AP-RW */
	calculate_aprw_digest(hash, digest);
	fprintf(stderr, "Calculated digest\n");

	/* 4. Compare digests */
	if (memcmp(hash->digest, digest, BDB_SHA256_DIGEST_SIZE)) {
		fprintf(stderr, "Digests do not match\n");
		vba_bdb_fail(&ctx);
		/* This return is needed for unit test. vba_bdb_fail calls
		 * vbe_reset, which calls verstage_main. If verstage_main
		 * successfully returns, we return here as well. */
		return;
	}

	/* 5. Record selected slot. This depends on the firmware */
	slot_selected = ctx.slot ? 'B' : 'A';
	fprintf(stderr, "Selected AP-RW in slot %c\n", slot_selected);

	/* X. This should be done upon AP-RW's request after everything is
	 * successful. We do it here for the unit test. */
	vba_bdb_finalize(&ctx);
}

uint32_t vbe_get_vboot_register(enum vboot_register type)
{
	switch (type) {
	case VBOOT_REGISTER:
		return vboot_register;
	case VBOOT_REGISTER_PERSIST:
		return vboot_register_persist;
	default:
		fprintf(stderr, "Invalid vboot register type (%d)\n", type);
		exit(2);
	}
}

void vbe_set_vboot_register(enum vboot_register type, uint32_t val)
{
	switch (type) {
	case VBOOT_REGISTER:
		vboot_register = val;
		break;
	case VBOOT_REGISTER_PERSIST:
		vboot_register_persist = val;
		break;
	default:
		fprintf(stderr, "Invalid vboot register type (%d)\n", type);
		exit(2);
	}
}

void vbe_reset(void)
{
	uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST);

	fprintf(stderr, "Booting ...\n");

	if (++reset_count > 5) {
		fprintf(stderr, "Reset counter exceeded maximum value\n");
		exit(2);
	}

	/* Emulate warm reset */
	vboot_register = 0;
	if (val & VBOOT_REGISTER_RECOVERY_REQUEST) {
		fprintf(stderr, "Recovery requested\n");
		return;
	}
	/* Selected by SP-RO */
	bdb = (val & VBOOT_REGISTER_TRY_SECONDARY_BDB) ? bdb1 : bdb0;
	verstage_main();
}

static void test_verify_aprw(const char *key_dir)
{
	struct bdb_hash hash0 = {
		.offset = 0x28000,
		.size = 0x20000,
		.partition = 1,
		.type = BDB_DATA_AP_RW,
		.load_address = 0x200000,
		.digest = {0x11, 0x11, 0x11, 0x11},
	};
	struct bdb_hash hash1 = {
		.offset = 0x28000,
		.size = 0x20000,
		.partition = 1,
		.type = BDB_DATA_AP_RW,
		.load_address = 0x200000,
		.digest = {0x22, 0x22, 0x22, 0x22},
	};

	bdb0 = create_bdb(key_dir, &hash0, 1);
	bdb1 = create_bdb(key_dir, &hash1, 1);
	memset(aprw_digest, 0, BDB_SHA256_DIGEST_SIZE);

	/* (slotA, slotB) = (good, bad) */
	reset_count = 0;
	vboot_register_persist = 0;
	slot_selected = 'X';
	memcpy(aprw_digest, hash0.digest, 4);
	vbe_reset();
	TEST_EQ(reset_count, 1, NULL);
	TEST_EQ(slot_selected, 'A', NULL);
	TEST_FALSE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_PRIMARY,
		   NULL);
	TEST_FALSE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_SECONDARY,
		   NULL);

	/* (slotA, slotB) = (bad, good) */
	reset_count = 0;
	vboot_register_persist = 0;
	slot_selected = 'X';
	memcpy(aprw_digest, hash1.digest, 4);
	vbe_reset();
	TEST_EQ(reset_count, 3, NULL);
	TEST_EQ(slot_selected, 'B', NULL);
	TEST_TRUE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_PRIMARY,
		  NULL);
	TEST_FALSE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_SECONDARY,
		   NULL);

	/* (slotA, slotB) = (bad, bad) */
	reset_count = 0;
	vboot_register_persist = 0;
	slot_selected = 'X';
	memset(aprw_digest, 0, BDB_SHA256_DIGEST_SIZE);
	vbe_reset();
	TEST_EQ(reset_count, 5, NULL);
	TEST_EQ(slot_selected, 'X', NULL);
	TEST_TRUE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_PRIMARY,
		  NULL);
	TEST_TRUE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_SECONDARY,
		  NULL);
	TEST_TRUE(vboot_register_persist & VBOOT_REGISTER_RECOVERY_REQUEST,
		  NULL);

	/* Clean up */
	free(bdb0);
	free(bdb1);
}

int vbe_read_nvm(enum nvm_type type, uint8_t *buf, uint32_t size)
{
	/* Read NVM-RW contents (from EEPROM for example) */
	switch (type) {
	case NVM_TYPE_RW_PRIMARY:
		if (sizeof(nvmrw1) < size)
			return -1;
		memcpy(buf, nvmrw1, size);
		break;
	case NVM_TYPE_RW_SECONDARY:
		if (sizeof(nvmrw2) < size)
			return -1;
		memcpy(buf, nvmrw2, size);
		break;
	default:
		return -1;
	}
	return 0;
}

int vbe_write_nvm(enum nvm_type type, void *buf, uint32_t size)
{
	if (vbe_write_nvm_failure > 0) {
		fprintf(stderr, "Failed to write NVM (type=%d failure=%d)\n",
			type, vbe_write_nvm_failure);
		vbe_write_nvm_failure--;
		return -1;
	}

	/* Write NVM-RW contents (to EEPROM for example) */
	switch (type) {
	case NVM_TYPE_RW_PRIMARY:
		memcpy(nvmrw1, buf, size);
		break;
	case NVM_TYPE_RW_SECONDARY:
		memcpy(nvmrw2, buf, size);
		break;
	default:
		return -1;
	}
	return 0;
}

static void install_nvm(enum nvm_type type,
			uint32_t min_kernel_data_key_version,
			uint32_t min_kernel_version,
			uint32_t update_count)
{
	struct nvmrw nvm = {
		.struct_magic = NVM_RW_MAGIC,
		.struct_major_version = NVM_HEADER_VERSION_MAJOR,
		.struct_minor_version = NVM_HEADER_VERSION_MINOR,
		.struct_size = sizeof(struct nvmrw),
		.min_kernel_data_key_version = min_kernel_data_key_version,
		.min_kernel_version = min_kernel_version,
		.update_count = update_count,
	};

	/* Compute HMAC */
	hmac(VB2_HASH_SHA256, secrets.nvm_rw, BDB_SECRET_SIZE,
	     &nvm, nvm.struct_size - sizeof(nvm.hmac),
	     nvm.hmac, sizeof(nvm.hmac));

	/* Install NVM-RWs (in EEPROM for example) */
	switch (type) {
	case NVM_TYPE_RW_PRIMARY:
		memset(nvmrw1, 0, sizeof(nvmrw1));
		memcpy(nvmrw1, &nvm, sizeof(nvm));
		break;
	case NVM_TYPE_RW_SECONDARY:
		memset(nvmrw2, 0, sizeof(nvmrw2));
		memcpy(nvmrw2, &nvm, sizeof(nvm));
		break;
	default:
		fprintf(stderr, "Unsupported NVM type (%d)\n", type);
		exit(2);
		return;
	}
}

static void test_nvm_read(void)
{
	struct vba_context ctx = {
		.bdb = NULL,
		.secrets = &secrets,
	};
	struct nvmrw *nvm;
	uint8_t nvmrw1_copy[NVM_RW_MAX_STRUCT_SIZE];
	uint8_t nvmrw2_copy[NVM_RW_MAX_STRUCT_SIZE];

	install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0);
	install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 0);
	memcpy(nvmrw1_copy, nvmrw1, sizeof(nvmrw1));
	memcpy(nvmrw2_copy, nvmrw2, sizeof(nvmrw2));

	/* Test nvm_read: both good -> pick primary, no sync */
	memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw));
	TEST_SUCC(nvmrw_read(&ctx), NULL);
	TEST_SUCC(memcmp(&ctx.nvmrw, nvmrw1, sizeof(*nvm)), NULL);
	TEST_SUCC(memcmp(nvmrw1, nvmrw1_copy, sizeof(nvmrw1)), NULL);
	TEST_SUCC(memcmp(nvmrw2, nvmrw2_copy, sizeof(nvmrw2)), NULL);

	/* Test nvm_read: primary bad -> pick secondary */
	install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0);
	install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 0);
	memcpy(nvmrw2_copy, nvmrw2, sizeof(*nvm));
	nvm = (struct nvmrw *)nvmrw1;
	nvm->hmac[0] ^= 0xff;
	memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw));
	TEST_SUCC(nvmrw_read(&ctx), NULL);
	TEST_SUCC(memcmp(&ctx.nvmrw, nvmrw2, sizeof(*nvm)), NULL);
	TEST_SUCC(memcmp(nvmrw1, nvmrw2_copy, sizeof(nvmrw2)), NULL);
	TEST_SUCC(memcmp(nvmrw2, nvmrw2_copy, sizeof(nvmrw2)), NULL);

	/* Test nvm_read: secondary bad -> pick primary */
	install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0);
	install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 0);
	memcpy(nvmrw1_copy, nvmrw1, sizeof(*nvm));
	nvm = (struct nvmrw *)nvmrw2;
	nvm->hmac[0] ^= 0xff;
	memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw));
	TEST_SUCC(nvmrw_read(&ctx), NULL);
	TEST_SUCC(memcmp(&ctx.nvmrw, nvmrw1, sizeof(*nvm)), NULL);
	TEST_SUCC(memcmp(nvmrw1, nvmrw1_copy, sizeof(nvmrw1)), NULL);
	TEST_SUCC(memcmp(nvmrw2, nvmrw1_copy, sizeof(nvmrw1)), NULL);

	/* Test nvm_read: both bad */
	nvm = (struct nvmrw *)nvmrw1;
	nvm->hmac[0] ^= 0xff;
	nvm = (struct nvmrw *)nvmrw2;
	nvm->hmac[0] ^= 0xff;
	memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw));
	TEST_EQ(nvmrw_read(&ctx), BDB_ERROR_NVM_RW_INVALID_HMAC, NULL);

	/* Test update count: secondary new -> pick secondary */
	install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0);
	install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 1);
	memcpy(nvmrw2_copy, nvmrw2, sizeof(*nvm));
	memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw));
	TEST_SUCC(nvmrw_read(&ctx), NULL);
	TEST_SUCC(memcmp(&ctx.nvmrw, nvmrw2, sizeof(*nvm)), NULL);
	TEST_SUCC(memcmp(nvmrw1, nvmrw2_copy, sizeof(nvmrw1)), NULL);
	TEST_SUCC(memcmp(nvmrw2, nvmrw2_copy, sizeof(nvmrw2)), NULL);

	/* Test old reader -> minor version downgrade */
	install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0);
	install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 1);
	memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw));
	nvm = (struct nvmrw *)nvmrw1;
	nvm->struct_minor_version++;
	nvm->struct_size++;
	TEST_SUCC(nvmrw_read(&ctx), NULL);
	TEST_EQ(ctx.nvmrw.struct_minor_version, NVM_HEADER_VERSION_MINOR, NULL);
	TEST_EQ(ctx.nvmrw.struct_size, sizeof(*nvm), NULL);
}

static void verify_nvm_write(struct vba_context *ctx,
			     int expected_result)
{
	struct nvmrw *nvmrw;
	struct nvmrw *nvm = &ctx->nvmrw;

	TEST_EQ(nvmrw_write(ctx, NVM_TYPE_RW_PRIMARY), expected_result, NULL);

	if (expected_result != BDB_SUCCESS)
		return;

	nvmrw = (struct nvmrw *)nvmrw1;
	TEST_EQ(nvmrw->min_kernel_data_key_version,
		nvm->min_kernel_data_key_version, NULL);
	TEST_EQ(nvmrw->min_kernel_version, nvm->min_kernel_version, NULL);
	TEST_EQ(nvmrw->update_count, nvm->update_count, NULL);
}

static void test_nvm_write(void)
{
	struct vba_context ctx = {
		.bdb = NULL,
		.secrets = &secrets,
	};
	struct nvmrw nvm = {
		.struct_magic = NVM_RW_MAGIC,
		.struct_major_version = NVM_HEADER_VERSION_MAJOR,
		.struct_minor_version = NVM_HEADER_VERSION_MINOR,
		.struct_size = sizeof(struct nvmrw),
		.min_kernel_data_key_version = 1,
		.min_kernel_version = 2,
		.update_count = 3,
	};

	/* Test normal case */
	memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
	vbe_write_nvm_failure = 0;
	verify_nvm_write(&ctx, BDB_SUCCESS);

	/* Test write failure: once */
	memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
	vbe_write_nvm_failure = 1;
	verify_nvm_write(&ctx, BDB_SUCCESS);

	/* Test write failure: twice */
	memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
	vbe_write_nvm_failure = 2;
	verify_nvm_write(&ctx, BDB_ERROR_NVM_WRITE);

	/* Test invalid struct magic */
	memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
	ctx.nvmrw.struct_magic ^= 0xff;
	verify_nvm_write(&ctx, BDB_ERROR_NVM_RW_MAGIC);

	/* Test struct size too small */
	memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
	ctx.nvmrw.struct_size = NVM_RW_MIN_STRUCT_SIZE - 1;
	verify_nvm_write(&ctx, BDB_ERROR_NVM_STRUCT_SIZE);

	/* Test struct size too large */
	memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
	ctx.nvmrw.struct_size = NVM_RW_MAX_STRUCT_SIZE + 1;
	verify_nvm_write(&ctx, BDB_ERROR_NVM_STRUCT_SIZE);

	/* Test invalid struct version */
	memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
	ctx.nvmrw.struct_major_version = NVM_HEADER_VERSION_MAJOR - 1;
	verify_nvm_write(&ctx, BDB_ERROR_NVM_STRUCT_VERSION);

	vbe_write_nvm_failure = 0;
}

static void verify_kernel_version(uint32_t min_kernel_data_key_version,
				  uint32_t new_kernel_data_key_version,
				  uint32_t min_kernel_version,
				  uint32_t new_kernel_version,
				  int expected_result)
{
	struct vba_context ctx = {
		.bdb = NULL,
		.secrets = &secrets,
	};
	struct nvmrw *nvm = (struct nvmrw *)nvmrw1;
	uint32_t expected_kernel_data_key_version = min_kernel_data_key_version;
	uint32_t expected_kernel_version = min_kernel_version;
	int should_update = 0;

	if (min_kernel_data_key_version < new_kernel_data_key_version) {
		expected_kernel_data_key_version = new_kernel_data_key_version;
		should_update = 1;
	}
	if (min_kernel_version < new_kernel_version) {
		expected_kernel_version = new_kernel_version;
		should_update = 1;
	}

	install_nvm(NVM_TYPE_RW_PRIMARY, min_kernel_data_key_version,
		    min_kernel_version, 0);
	install_nvm(NVM_TYPE_RW_SECONDARY, 0, 0, 0);

	TEST_EQ(vba_update_kernel_version(&ctx, new_kernel_data_key_version,
					  new_kernel_version),
		expected_result, NULL);

	if (expected_result != BDB_SUCCESS)
		return;

	/* Check data key version */
	TEST_EQ(nvm->min_kernel_data_key_version,
		expected_kernel_data_key_version, NULL);
	/* Check kernel version */
	TEST_EQ(nvm->min_kernel_version, expected_kernel_version, NULL);
	/* Check update_count */
	TEST_EQ(nvm->update_count, 0 + should_update, NULL);
	/* Check sync if update is expected */
	if (should_update)
		TEST_SUCC(memcmp(nvmrw2, nvmrw1, sizeof(nvmrw1)), NULL);
}

static void test_update_kernel_version(void)
{
	/* Test update: data key version */
	verify_kernel_version(0, 1, 0, 0, BDB_SUCCESS);
	/* Test update: kernel version */
	verify_kernel_version(0, 0, 0, 1, BDB_SUCCESS);
	/* Test no update: data key version */
	verify_kernel_version(1, 0, 0, 0, BDB_SUCCESS);
	/* Test no update: kernel version */
	verify_kernel_version(0, 0, 1, 0, BDB_SUCCESS);
}

int vbe_aes256_encrypt(const uint8_t *msg, uint32_t len, const uint8_t *key,
		       uint8_t *out)
{
	int i;

	for (i = 0; i < len; i++)
		out[i] = msg[i] ^ key[i % 256/8];

	return BDB_SUCCESS;
}

int vbe_aes256_decrypt(const uint8_t *msg, uint32_t len, const uint8_t *key,
		       uint8_t *out)
{
	int i;

	for (i = 0; i < len; i++)
		out[i] = msg[i] ^ key[i % 256/8];

	return BDB_SUCCESS;
}

static void test_update_buc(void)
{
	uint8_t new_buc[BUC_ENC_DIGEST_SIZE];
	uint8_t enc_buc[BUC_ENC_DIGEST_SIZE];
	struct nvmrw *nvm = (struct nvmrw *)nvmrw1;
	struct vba_context ctx = {
		.bdb = NULL,
		.secrets = &secrets,
	};

	install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0);
	install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 0);

	TEST_SUCC(vba_update_buc(&ctx, new_buc), NULL);
	vbe_aes256_encrypt(new_buc, sizeof(new_buc), ctx.secrets->buc,
			   enc_buc);
	TEST_SUCC(memcmp(nvm->buc_enc_digest, enc_buc, sizeof(new_buc)), NULL);
}

static void test_derive_secrets(void)
{
	uint8_t test_key[sizeof(struct bdb_key) + BDB_RSA4096_KEY_DATA_SIZE];
	struct bdb_key *key = (struct bdb_key *)test_key;
	struct vba_context ctx = {
		.bdb = NULL,
		.secrets = &secrets,
	};
	const struct bdb_secrets expected = {
		.bdb = {
			0x75, 0xb6, 0x24, 0xaa, 0x72, 0x50, 0xf9, 0x33,
			0x59, 0x45, 0x8d, 0xbf, 0xfa, 0x42, 0xc4, 0xb7,
			0x1b, 0xff, 0xc6, 0x02, 0x02, 0x35, 0xc5, 0x1a,
			0x6c, 0xdc, 0x3a, 0x63, 0xfb, 0x8b, 0xac, 0x53},
		.boot_verified = {
			0x40, 0xf3, 0x9b, 0xdc, 0xf6, 0xb4, 0xe8, 0xdf,
			0x48, 0xc4, 0xfe, 0x02, 0xdd, 0x34, 0x06, 0xd9,
			0xed, 0xd9, 0x55, 0x79, 0xf4, 0x48, 0x58, 0xbf,
			0x32, 0x55, 0xba, 0x21, 0xca, 0xcc, 0x8c, 0xd1},
		.boot_path = {
			0xfb, 0x58, 0x89, 0x58, 0x2f, 0x54, 0xa2, 0xf7,
			0x96, 0x5b, 0x69, 0x77, 0x9b, 0x67, 0x80, 0x39,
			0x7a, 0xd4, 0xc5, 0x3b, 0xcf, 0x95, 0x3f, 0xec,
			0x28, 0x49, 0x55, 0x49, 0x38, 0x27, 0x5d, 0x3c},
		.buc = {
			0x63, 0xa5, 0x30, 0xd7, 0xca, 0xe1, 0x3e, 0x2e,
			0x72, 0x7e, 0x29, 0xc9, 0x37, 0x66, 0x6a, 0x63,
			0x91, 0xd4, 0x8e, 0x8b, 0xbc, 0x1a, 0x7a, 0xcf,
			0xc3, 0x19, 0xa0, 0x87, 0xfc, 0x4d, 0xe1, 0xe8},
	};

	memset(test_key, 0, sizeof(test_key));
	key->struct_magic = BDB_KEY_MAGIC;
	key->struct_major_version = BDB_KEY_VERSION_MAJOR;
	key->struct_minor_version = BDB_KEY_VERSION_MINOR;
	key->struct_size = sizeof(test_key);
	key->hash_alg = BDB_HASH_ALG_SHA256;
	key->sig_alg = BDB_SIG_ALG_RSA4096;
	key->key_version = 1;

	TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BDB, NULL,
				    test_key, sizeof(test_key)), NULL);
	TEST_SUCC(memcmp(ctx.secrets->bdb, expected.bdb, BDB_SECRET_SIZE),
		  NULL);

	TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BOOT_VERIFIED, NULL,
				    NULL, 0), NULL);
	TEST_SUCC(memcmp(ctx.secrets->boot_verified, expected.boot_verified,
			 BDB_SECRET_SIZE), NULL);

	TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BOOT_PATH, NULL,
				    test_key, sizeof(test_key)), NULL);
	TEST_SUCC(memcmp(ctx.secrets->boot_path, expected.boot_path,
			 BDB_SECRET_SIZE), NULL);

	TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BUC, NULL, NULL, 0),
		  NULL);
	TEST_SUCC(memcmp(ctx.secrets->buc, expected.buc,
			 BDB_SECRET_SIZE), NULL);
}

int main(int argc, char *argv[])
{
	if (argc != 2) {
		fprintf(stderr, "Usage: %s <keys_dir>", argv[0]);
		return -1;
	}
	printf("Running BDB SP-RW tests...\n");

	test_verify_aprw(argv[1]);
	test_nvm_read();
	test_nvm_write();
	test_update_kernel_version();
	test_update_buc();
	test_derive_secrets();

	return gTestSuccess ? 0 : 255;
}
