summaryrefslogtreecommitdiff
path: root/tests/vb20_api_kernel_tests.c
diff options
context:
space:
mode:
authorJoel Kitching <kitching@google.com>2019-06-09 12:37:55 +0800
committerCommit Bot <commit-bot@chromium.org>2020-02-09 11:59:26 +0000
commita32d8d67587ec2cfdb4598ef69d8d8763b34f6e8 (patch)
tree29a65094ffea26d52ffa73a67fb4fd4d2156bad6 /tests/vb20_api_kernel_tests.c
parent58229e2c77f949976d051387fe17f572802fd708 (diff)
downloadvboot-a32d8d67587ec2cfdb4598ef69d8d8763b34f6e8.tar.gz
vboot: update vb2api_kernel_phase1 to use GBB interface
vb2api_kernel_phase1 was previously written to read the GBB headers, locate the recovery key, and then load it. GBB headers are now saved directly on workbuf in firmware phase. Simply use the vb2_gbb_read_recovery_key function to retrieve the key. Update LoadKernel to read kernel subkey from vboot2 workbuf. Update tests/verify_kernel.c to write subkey to vboot2 workbuf. BUG=b:124141368, chromium:954774, chromium:1038260 TEST=make clean && make runtests BRANCH=none Change-Id: Ia85013da34bdab68bf486014a3401d48c95b3472 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1651221 Tested-by: Joel Kitching <kitching@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org> Commit-Queue: Joel Kitching <kitching@chromium.org>
Diffstat (limited to 'tests/vb20_api_kernel_tests.c')
-rw-r--r--tests/vb20_api_kernel_tests.c99
1 files changed, 67 insertions, 32 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);