summaryrefslogtreecommitdiff
path: root/tests/vboot_kernel_tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/vboot_kernel_tests.c')
-rw-r--r--tests/vboot_kernel_tests.c140
1 files changed, 78 insertions, 62 deletions
diff --git a/tests/vboot_kernel_tests.c b/tests/vboot_kernel_tests.c
index d3a25d58..2a472d38 100644
--- a/tests/vboot_kernel_tests.c
+++ b/tests/vboot_kernel_tests.c
@@ -11,7 +11,9 @@
#include <string.h>
#include "2sysincludes.h"
+#include "2api.h"
#include "2common.h"
+#include "2misc.h"
#include "2sha.h"
#include "cgptlib.h"
#include "cgptlib_internal.h"
@@ -74,6 +76,8 @@ static GptHeader *mock_gpt_primary =
static GptHeader *mock_gpt_secondary =
(GptHeader*)&mock_disk[MOCK_SECTOR_SIZE * (MOCK_SECTOR_COUNT - 1)];
static uint8_t mock_digest[VB2_SHA256_DIGEST_SIZE] = {12, 34, 56, 78};
+static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE];
+static struct vb2_context ctx;
/**
* Prepare a valid GPT header that will pass CheckHeader() tests
@@ -182,6 +186,12 @@ static void ResetMocks(void)
mock_parts[0].start = 100;
mock_parts[0].size = 150; /* 75 KB */
mock_part_next = 0;
+
+ memset(&ctx, 0, sizeof(ctx));
+ memcpy(ctx.nvdata, vnc.raw, VB2_NVDATA_SIZE);
+ ctx.workbuf = workbuf;
+ ctx.workbuf_size = sizeof(workbuf);
+ // TODO: more workbuf fields - flags, secdata, secdatak
}
/* Mocks */
@@ -564,6 +574,23 @@ static void ReadWriteGptTest(void)
}
+static void TestLoadKernel(int expect_retval, char *test_name)
+{
+ memcpy(ctx.nvdata, vnc.raw, VB2_NVDATA_SIZE);
+ if (lkp.boot_flags & BOOT_FLAG_RECOVERY)
+ ctx.flags |= VB2_CONTEXT_RECOVERY_MODE;
+ if (lkp.boot_flags & BOOT_FLAG_DEVELOPER)
+ ctx.flags |= VB2_CONTEXT_DEVELOPER_MODE;
+
+ TEST_EQ(LoadKernel(&ctx, &lkp, &cparams), expect_retval, test_name);
+
+ if (ctx.flags & VB2_CONTEXT_NVDATA_CHANGED) {
+ memcpy(vnc.raw, ctx.nvdata, VB2_NVDATA_SIZE);
+ vnc.raw_changed = 1;
+ ctx.flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
+ }
+}
+
/**
* Trivial invalid calls to LoadKernel()
*/
@@ -571,14 +598,12 @@ static void InvalidParamsTest(void)
{
ResetMocks();
gpt_init_fail = 1;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND,
- "Bad GPT");
+ TestLoadKernel(VBERROR_NO_KERNEL_FOUND, "Bad GPT");
/* This causes the stream open call to fail */
ResetMocks();
lkp.disk_handle = NULL;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Bad disk handle");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND, "Bad disk handle");
}
static void LoadKernelTest(void)
@@ -587,8 +612,7 @@ static void LoadKernelTest(void)
ResetMocks();
- u = LoadKernel(&lkp, &cparams);
- TEST_EQ(u, 0, "First kernel good");
+ TestLoadKernel(0, "First kernel good");
TEST_EQ(lkp.partition_number, 1, " part num");
TEST_EQ(lkp.bootloader_address, 0xbeadd008, " bootloader addr");
TEST_EQ(lkp.bootloader_size, 0x1234, " bootloader size");
@@ -600,46 +624,44 @@ static void LoadKernelTest(void)
ResetMocks();
mock_parts[1].start = 300;
mock_parts[1].size = 150;
- TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Two good kernels");
+ TestLoadKernel(0, "Two good kernels");
TEST_EQ(lkp.partition_number, 1, " part num");
TEST_EQ(mock_part_next, 1, " didn't read second one");
/* Fail if no kernels found */
ResetMocks();
mock_parts[0].size = 0;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND, "No kernels");
+ TestLoadKernel(VBERROR_NO_KERNEL_FOUND, "No kernels");
VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
TEST_EQ(u, VBNV_RECOVERY_RW_NO_OS, " recovery request");
/* Skip kernels which are too small */
ResetMocks();
mock_parts[0].size = 10;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND, "Too small");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND, "Too small");
VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
TEST_EQ(u, VBNV_RECOVERY_RW_INVALID_OS, " recovery request");
ResetMocks();
disk_read_to_fail = 100;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Fail reading kernel start");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
+ "Fail reading kernel start");
ResetMocks();
key_block_verify_fail = 1;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Fail key block sig");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND, "Fail key block sig");
/* In dev mode, fail if hash is bad too */
ResetMocks();
lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
key_block_verify_fail = 2;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Fail key block dev hash");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND, "Fail key block dev hash");
/* But just bad sig is ok */
ResetMocks();
lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
key_block_verify_fail = 1;
- TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Succeed key block dev sig");
+ TestLoadKernel(0, "Succeed key block dev sig");
/* In dev mode and requiring signed kernel, fail if sig is bad */
ResetMocks();
@@ -647,101 +669,97 @@ static void LoadKernelTest(void)
VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1);
VbNvTeardown(&vnc);
key_block_verify_fail = 1;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Fail key block dev sig");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND, "Fail key block dev sig");
ResetMocks();
lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
lkp.fwmp = &fwmp;
fwmp.flags |= FWMP_DEV_ENABLE_OFFICIAL_ONLY;
key_block_verify_fail = 1;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Fail key block dev sig fwmp");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
+ "Fail key block dev sig fwmp");
/* Check key block flag mismatches */
ResetMocks();
kbh.key_block_flags =
KEY_BLOCK_FLAG_RECOVERY_0 | KEY_BLOCK_FLAG_DEVELOPER_1;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Key block dev flag mismatch");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
+ "Key block dev flag mismatch");
ResetMocks();
kbh.key_block_flags =
KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_0;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Key block rec flag mismatch");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
+ "Key block rec flag mismatch");
ResetMocks();
lkp.boot_flags |= BOOT_FLAG_RECOVERY;
kbh.key_block_flags =
KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_1;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Key block recdev flag mismatch");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
+ "Key block recdev flag mismatch");
ResetMocks();
lkp.boot_flags |= BOOT_FLAG_RECOVERY | BOOT_FLAG_DEVELOPER;
kbh.key_block_flags =
KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_0;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Key block rec!dev flag mismatch");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
+ "Key block rec!dev flag mismatch");
ResetMocks();
kbh.data_key.key_version = 1;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Key block kernel key rollback");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
+ "Key block kernel key rollback");
ResetMocks();
kbh.data_key.key_version = 0x10000;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Key block kernel key version too big");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
+ "Key block kernel key version too big");
ResetMocks();
kbh.data_key.key_version = 3;
- TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key block version roll forward");
+ TestLoadKernel(0, "Key block version roll forward");
TEST_EQ(shared->kernel_version_tpm, 0x30001, " shared version");
ResetMocks();
kbh.data_key.key_version = 3;
mock_parts[1].start = 300;
mock_parts[1].size = 150;
- TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Two kernels roll forward");
+ TestLoadKernel(0, "Two kernels roll forward");
TEST_EQ(mock_part_next, 2, " read both");
TEST_EQ(shared->kernel_version_tpm, 0x30001, " shared version");
ResetMocks();
kbh.data_key.key_version = 1;
lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
- TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key version ignored in dev mode");
+ TestLoadKernel(0, "Key version ignored in dev mode");
ResetMocks();
kbh.data_key.key_version = 1;
lkp.boot_flags |= BOOT_FLAG_RECOVERY;
- TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key version ignored in rec mode");
+ TestLoadKernel(0, "Key version ignored in rec mode");
ResetMocks();
unpack_key_fail = 2;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Bad data key");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND, "Bad data key");
ResetMocks();
preamble_verify_fail = 1;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Bad preamble");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND, "Bad preamble");
ResetMocks();
kph.kernel_version = 0;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Kernel version rollback");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND, "Kernel version rollback");
ResetMocks();
kph.kernel_version = 0;
lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
- TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel version ignored in dev mode");
+ TestLoadKernel(0, "Kernel version ignored in dev mode");
ResetMocks();
kph.kernel_version = 0;
lkp.boot_flags |= BOOT_FLAG_RECOVERY;
- TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel version ignored in rec mode");
+ TestLoadKernel(0, "Kernel version ignored in rec mode");
/* Check developer key hash - bad */
ResetMocks();
@@ -749,68 +767,66 @@ static void LoadKernelTest(void)
lkp.fwmp = &fwmp;
fwmp.flags |= FWMP_DEV_USE_KEY_HASH;
fwmp.dev_key_hash[0]++;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Fail key block dev fwmp hash");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
+ "Fail key block dev fwmp hash");
/* Check developer key hash - good */
ResetMocks();
lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
lkp.fwmp = &fwmp;
fwmp.flags |= FWMP_DEV_USE_KEY_HASH;
- TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Good key block dev fwmp hash");
+ TestLoadKernel(0, "Good key block dev fwmp hash");
ResetMocks();
kph.preamble_size |= 0x07;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Kernel body offset");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND, "Kernel body offset");
ResetMocks();
kph.preamble_size += 65536;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Kernel body offset huge");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND, "Kernel body offset huge");
/* Check getting kernel load address from header */
ResetMocks();
kph.body_load_address = (size_t)kernel_buffer;
lkp.kernel_buffer = NULL;
- TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Get load address from preamble");
+ TestLoadKernel(0, "Get load address from preamble");
TEST_PTR_EQ(lkp.kernel_buffer, kernel_buffer, " address");
/* Size is rounded up to nearest sector */
TEST_EQ(lkp.kernel_buffer_size, 70144, " size");
ResetMocks();
lkp.kernel_buffer_size = 8192;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Kernel too big for buffer");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
+ "Kernel too big for buffer");
ResetMocks();
mock_parts[0].size = 130;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Kernel too big for partition");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
+ "Kernel too big for partition");
ResetMocks();
kph.body_signature.data_size = 8192;
- TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel tiny");
+ TestLoadKernel(0, "Kernel tiny");
ResetMocks();
disk_read_to_fail = 228;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
- "Fail reading kernel data");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
+ "Fail reading kernel data");
ResetMocks();
verify_data_fail = 1;
- TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND, "Bad data");
+ TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND, "Bad data");
/* Check that EXTERNAL_GPT flag makes it down */
ResetMocks();
lkp.boot_flags |= BOOT_FLAG_EXTERNAL_GPT;
- TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Succeed external GPT");
+ TestLoadKernel(0, "Succeed external GPT");
TEST_EQ(gpt_flag_external, 1, "GPT was external");
/* Check recovery from unreadble primary GPT */
ResetMocks();
disk_read_to_fail = 1;
- TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Can't read disk");
+ TestLoadKernel(0, "Can't read disk");
}
int main(void)