summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/vb20_api_kernel_tests.c99
-rw-r--r--tests/vboot_api_kernel4_tests.c41
-rw-r--r--tests/verify_kernel.c22
3 files changed, 105 insertions, 57 deletions
diff --git a/tests/vb20_api_kernel_tests.c b/tests/vb20_api_kernel_tests.c
index 646f8ec4..5fba07e4 100644
--- a/tests/vb20_api_kernel_tests.c
+++ b/tests/vb20_api_kernel_tests.c
@@ -16,12 +16,15 @@
#include "2sysincludes.h"
#include "test_common.h"
#include "vb2_common.h"
+#include "vboot_struct.h"
/* Common context for tests */
static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]
__attribute__((aligned(VB2_WORKBUF_ALIGN)));
static struct vb2_context *ctx;
static struct vb2_shared_data *sd;
+static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
+static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
static struct vb2_fw_preamble *fwpre;
static struct vb2_kernel_preamble *kpre;
static struct vb2_packed_key *kdkey;
@@ -38,9 +41,9 @@ static struct {
static int mock_read_res_fail_on_call;
static int mock_unpack_key_retval;
-static int mock_read_gbb_header_retval;
static int mock_load_kernel_keyblock_retval;
static int mock_load_kernel_preamble_retval;
+static int mock_secdata_fwmp_check_retval;
/* Type of test to reset for */
enum reset_type {
@@ -59,6 +62,8 @@ static void reset_common_data(enum reset_type t)
"vb2api_init failed");
sd = vb2_get_sd(ctx);
+ memset(&shared_data, 0, sizeof(shared_data));
+ sd->vbsd = shared;
vb2_nv_init(ctx);
@@ -68,11 +73,12 @@ static void reset_common_data(enum reset_type t)
mock_read_res_fail_on_call = 0;
mock_unpack_key_retval = VB2_SUCCESS;
- mock_read_gbb_header_retval = VB2_SUCCESS;
mock_load_kernel_keyblock_retval = VB2_SUCCESS;
mock_load_kernel_preamble_retval = VB2_SUCCESS;
+ mock_secdata_fwmp_check_retval = VB2_SUCCESS;
/* Recovery key in mock GBB */
+ memset(&mock_gbb, 0, sizeof(mock_gbb));
mock_gbb.recovery_key.algorithm = 11;
mock_gbb.recovery_key.key_offset =
vb2_offset_of(&mock_gbb.recovery_key,
@@ -154,6 +160,16 @@ static void reset_common_data(enum reset_type t)
/* Mocked functions */
+vb2_error_t vb2api_secdata_fwmp_check(struct vb2_context *c, uint8_t *size)
+{
+ return mock_secdata_fwmp_check_retval;
+}
+
+struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c)
+{
+ return &mock_gbb.h;
+}
+
vb2_error_t vb2ex_read_resource(struct vb2_context *c,
enum vb2_resource_index index, uint32_t offset,
void *buf, uint32_t size)
@@ -180,13 +196,6 @@ vb2_error_t vb2ex_read_resource(struct vb2_context *c,
return VB2_SUCCESS;
}
-vb2_error_t vb2_read_gbb_header(struct vb2_context *c,
- struct vb2_gbb_header *gbb)
-{
- memcpy(gbb, &mock_gbb.h, sizeof(*gbb));
- return mock_read_gbb_header_retval;
-}
-
vb2_error_t vb2_load_kernel_keyblock(struct vb2_context *c)
{
return mock_load_kernel_keyblock_retval;
@@ -222,15 +231,14 @@ vb2_error_t vb2_verify_digest(const struct vb2_public_key *key,
static void phase1_tests(void)
{
struct vb2_packed_key *k;
- uint32_t old_preamble_offset;
+ uint32_t wb_used_before;
/* Test successful call */
reset_common_data(FOR_PHASE1);
- old_preamble_offset = sd->preamble_offset;
TEST_SUCC(vb2api_kernel_phase1(ctx), "phase1 good");
- TEST_EQ(sd->preamble_size, 0, " no more fw preamble");
/* Make sure normal key was loaded */
- TEST_EQ(sd->kernel_key_offset, old_preamble_offset,
+ TEST_EQ(sd->kernel_key_offset, sd->preamble_offset +
+ offsetof(struct vb2_fw_preamble, kernel_subkey),
" workbuf key offset");
k = vb2_member_of(sd, sd->kernel_key_offset);
TEST_EQ(sd->kernel_key_size, k->key_offset + k->key_size,
@@ -245,18 +253,21 @@ static void phase1_tests(void)
k->key_size), 0, " key data");
TEST_EQ(sd->kernel_version_secdata, 0x20002,
" secdata_kernel version");
+ TEST_EQ(sd->vbsd->kernel_version_tpm, 0x20002,
+ " secdata_kernel version (vboot1)");
+ TEST_EQ(sd->vbsd->kernel_version_tpm_start, 0x20002,
+ " secdata_kernel version (vboot1)");
/* Test successful call in recovery mode */
reset_common_data(FOR_PHASE1);
ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
- /* No preamble loaded in recovery mode */
- old_preamble_offset = sd->preamble_offset;
+ /* No preamble needed in recovery mode */
sd->workbuf_used = sd->preamble_offset;
sd->preamble_offset = sd->preamble_size = 0;
+ wb_used_before = sd->workbuf_used;
TEST_SUCC(vb2api_kernel_phase1(ctx), "phase1 rec good");
- TEST_EQ(sd->preamble_size, 0, "no more fw preamble");
/* Make sure recovery key was loaded */
- TEST_EQ(sd->kernel_key_offset, old_preamble_offset,
+ TEST_EQ(sd->kernel_key_offset, wb_used_before,
" workbuf key offset");
k = vb2_member_of(sd, sd->kernel_key_offset);
TEST_EQ(sd->kernel_key_size, k->key_offset + k->key_size,
@@ -272,45 +283,69 @@ static void phase1_tests(void)
" key data");
TEST_EQ(sd->kernel_version_secdata, 0x20002,
" secdata_kernel version");
+ TEST_EQ(sd->vbsd->kernel_version_tpm, 0x20002,
+ " secdata_kernel version (vboot1)");
+ TEST_EQ(sd->vbsd->kernel_version_tpm_start, 0x20002,
+ " secdata_kernel version (vboot1)");
/* Bad secdata_kernel causes failure in normal mode only */
reset_common_data(FOR_PHASE1);
ctx->secdata_kernel[0] ^= 0x33;
TEST_EQ(vb2api_kernel_phase1(ctx), VB2_ERROR_SECDATA_KERNEL_CRC,
- "phase1 bad secdata");
+ "phase1 bad secdata_kernel");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
+ VB2_RECOVERY_SECDATA_KERNEL_INIT, " recovery reason");
reset_common_data(FOR_PHASE1);
ctx->secdata_kernel[0] ^= 0x33;
ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
- TEST_SUCC(vb2api_kernel_phase1(ctx), "phase1 bad secdata rec");
+ TEST_SUCC(vb2api_kernel_phase1(ctx), "phase1 bad secdata_kernel rec");
TEST_EQ(sd->kernel_version_secdata, 0, " secdata_kernel version");
-
- /* Failures while reading recovery key */
+ TEST_EQ(sd->vbsd->kernel_version_tpm, 0,
+ " secdata_kernel version (vboot1)");
+ TEST_EQ(sd->vbsd->kernel_version_tpm_start, 0,
+ " secdata_kernel version (vboot1)");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
+ VB2_RECOVERY_NOT_REQUESTED, " no recovery");
+
+ /* Bad secdata_fwmp causes failure in normal mode only */
reset_common_data(FOR_PHASE1);
- ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
- sd->workbuf_used = sd->workbuf_size + VB2_WORKBUF_ALIGN -
- vb2_wb_round_up(sizeof(struct vb2_gbb_header));
- TEST_EQ(vb2api_kernel_phase1(ctx), VB2_ERROR_GBB_WORKBUF,
- "phase1 rec workbuf gbb header");
+ mock_secdata_fwmp_check_retval = VB2_ERROR_SECDATA_FWMP_CRC;
+ TEST_EQ(vb2api_kernel_phase1(ctx), mock_secdata_fwmp_check_retval,
+ "phase1 bad secdata_fwmp");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
+ VB2_RECOVERY_SECDATA_FWMP_INIT, " recovery reason");
reset_common_data(FOR_PHASE1);
+ mock_secdata_fwmp_check_retval = VB2_ERROR_SECDATA_FWMP_CRC;
ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
- mock_read_gbb_header_retval = VB2_ERROR_MOCK;
- TEST_EQ(vb2api_kernel_phase1(ctx), VB2_ERROR_MOCK,
- "phase1 rec gbb read header");
+ TEST_SUCC(vb2api_kernel_phase1(ctx), "phase1 bad secdata_fwmp rec");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
+ VB2_RECOVERY_NOT_REQUESTED, " no recovery");
+ /* Failures while reading recovery key */
reset_common_data(FOR_PHASE1);
ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
mock_gbb.h.recovery_key_size = sd->workbuf_size - 1;
- TEST_EQ(vb2api_kernel_phase1(ctx),
- VB2_ERROR_API_KPHASE1_WORKBUF_REC_KEY,
+ mock_gbb.recovery_key.key_size =
+ mock_gbb.h.recovery_key_size - sizeof(mock_gbb.recovery_key);
+ TEST_EQ(vb2api_kernel_phase1(ctx), VB2_SUCCESS,
"phase1 rec workbuf key");
+ TEST_EQ(sd->kernel_key_offset, 0, " workbuf key offset");
+ TEST_EQ(sd->kernel_key_size, 0, " workbuf key size");
+ mock_gbb.h.flags |= VB2_GBB_FLAG_FORCE_MANUAL_RECOVERY;
+ TEST_ABORT(vb2api_kernel_phase1(ctx), " fatal for manual recovery");
reset_common_data(FOR_PHASE1);
ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
mock_read_res_fail_on_call = 1;
- TEST_EQ(vb2api_kernel_phase1(ctx), VB2_ERROR_MOCK,
+ TEST_EQ(vb2api_kernel_phase1(ctx), VB2_SUCCESS,
"phase1 rec gbb read key");
+ TEST_EQ(sd->kernel_key_offset, 0, " workbuf key offset");
+ TEST_EQ(sd->kernel_key_size, 0, " workbuf key size");
+ mock_gbb.h.flags |= VB2_GBB_FLAG_FORCE_MANUAL_RECOVERY;
+ mock_read_res_fail_on_call = 1;
+ TEST_ABORT(vb2api_kernel_phase1(ctx), " fatal for manual recovery");
/* Failures while parsing subkey from firmware preamble */
reset_common_data(FOR_PHASE1);
diff --git a/tests/vboot_api_kernel4_tests.c b/tests/vboot_api_kernel4_tests.c
index 97a6b1d2..a376be09 100644
--- a/tests/vboot_api_kernel4_tests.c
+++ b/tests/vboot_api_kernel4_tests.c
@@ -38,6 +38,7 @@ static vb2_error_t commit_data_retval;
static int commit_data_called;
static vb2_error_t secdata_kernel_init_retval;
static vb2_error_t secdata_fwmp_init_retval;
+static vb2_error_t kernel_phase1_retval;
static uint32_t mock_switches[8];
static uint32_t mock_switches_count;
@@ -58,6 +59,7 @@ static void ResetMocks(void)
sd = vb2_get_sd(ctx);
sd->flags |= VB2_SD_FLAG_DISPLAY_AVAILABLE;
ctx->flags |= VB2_CONTEXT_NO_SECDATA_FWMP;
+ sd->preamble_size = 1;
vb2_nv_init(ctx);
vb2_nv_set(ctx, VB2_NV_KERNEL_MAX_ROLLFORWARD, 0xffffffff);
@@ -70,6 +72,7 @@ static void ResetMocks(void)
vbboot_retval = VB2_SUCCESS;
secdata_kernel_init_retval = VB2_SUCCESS;
secdata_fwmp_init_retval = VB2_SUCCESS;
+ kernel_phase1_retval = VB2_SUCCESS;
memset(mock_switches, 0, sizeof(mock_switches));
mock_switches_count = 0;
@@ -78,6 +81,14 @@ static void ResetMocks(void)
/* Mock functions */
+vb2_error_t vb2api_kernel_phase1(struct vb2_context *c)
+{
+ sd->kernel_version_secdata = kernel_version;
+ shared->kernel_version_tpm_start = kernel_version;
+ shared->kernel_version_tpm = kernel_version;
+ return kernel_phase1_retval;
+}
+
vb2_error_t vb2ex_commit_data(struct vb2_context *c)
{
commit_data_called = 1;
@@ -89,12 +100,6 @@ vb2_error_t vb2_secdata_kernel_init(struct vb2_context *c)
return secdata_kernel_init_retval;
}
-uint32_t vb2_secdata_kernel_get(struct vb2_context *c,
- enum vb2_secdata_kernel_param param)
-{
- return kernel_version;
-}
-
vb2_error_t vb2_secdata_fwmp_init(struct vb2_context *c)
{
return secdata_fwmp_init_retval;
@@ -239,16 +244,10 @@ static void VbSlkTest(void)
" didn't commit nvdata");
}
- /* Boot normal - secdata init failures */
- ResetMocks();
- secdata_kernel_init_retval = VB2_ERROR_UNKNOWN;
- test_slk(secdata_kernel_init_retval, VB2_RECOVERY_SECDATA_KERNEL_INIT,
- "Normal secdata_kernel init error triggers recovery");
-
+ /* Boot normal - phase1 failure */
ResetMocks();
- secdata_fwmp_init_retval = VB2_ERROR_UNKNOWN;
- test_slk(secdata_fwmp_init_retval, VB2_RECOVERY_SECDATA_FWMP_INIT,
- "Normal secdata_fwmp init error triggers recovery");
+ kernel_phase1_retval = VB2_ERROR_MOCK;
+ test_slk(VB2_ERROR_MOCK, 0, "Normal phase1 failure");
/* Boot normal - commit data failures */
ResetMocks();
@@ -277,6 +276,12 @@ static void VbSlkTest(void)
test_slk(0, 0, "Dev doesn't roll forward");
TEST_EQ(kernel_version, 0x10002, " version");
+ /* Boot dev - phase1 failure */
+ ResetMocks();
+ sd->flags |= VB2_SD_FLAG_DEV_MODE_ENABLED;
+ kernel_phase1_retval = VB2_ERROR_MOCK;
+ test_slk(VB2_ERROR_MOCK, 0, "Dev phase1 failure");
+
/* Boot recovery */
ResetMocks();
sd->recovery_reason = 123;
@@ -289,6 +294,12 @@ static void VbSlkTest(void)
test_slk(0, 0, "Recovery doesn't roll forward");
TEST_EQ(kernel_version, 0x10002, " version");
+ /* Boot recovery - phase1 failure */
+ ResetMocks();
+ sd->recovery_reason = 123;
+ kernel_phase1_retval = VB2_ERROR_MOCK;
+ test_slk(VB2_ERROR_MOCK, 0, "Recovery phase1 failure");
+
/* Boot recovery - commit data failures */
ResetMocks();
sd->recovery_reason = 123;
diff --git a/tests/verify_kernel.c b/tests/verify_kernel.c
index 1a4831d5..ac4b45e6 100644
--- a/tests/verify_kernel.c
+++ b/tests/verify_kernel.c
@@ -115,16 +115,18 @@ int main(int argc, char *argv[])
sd = vb2_get_sd(ctx);
sd->vbsd = shared;
- /* Copy kernel subkey to VBSD */
- struct vb2_packed_key *dst = (struct vb2_packed_key *)
- (shared_data + vb2_wb_round_up(sizeof(VbSharedDataHeader)));
- shared->kernel_subkey.key_offset =
- (uintptr_t)dst - (uintptr_t)&shared->kernel_subkey;
- shared->kernel_subkey.key_size = kernkey->key_size;
- shared->kernel_subkey.algorithm = kernkey->algorithm;
- shared->kernel_subkey.key_version = kernkey->key_version;
- memcpy(vb2_packed_key_data_mutable(dst), vb2_packed_key_data(kernkey),
- kernkey->key_size);
+ /* Copy kernel subkey to workbuf */
+ {
+ struct vb2_workbuf wb;
+ struct vb2_packed_key *dst;
+ uint32_t kernkey_size = kernkey->key_offset + kernkey->key_size;
+ vb2_workbuf_from_ctx(ctx, &wb);
+ dst = vb2_workbuf_alloc(&wb, kernkey_size);
+ memcpy(dst, kernkey, kernkey_size);
+ vb2_set_workbuf_used(ctx, vb2_offset_of(sd, wb.buf));
+ sd->kernel_key_offset = vb2_offset_of(sd, dst);
+ sd->kernel_key_size = kernkey_size;
+ }
/*
* LoadKernel() cares only about VBNV_DEV_BOOT_SIGNED_ONLY, and only in