diff options
Diffstat (limited to 'tests/vboot_api_kernel4_tests.c')
-rw-r--r-- | tests/vboot_api_kernel4_tests.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/tests/vboot_api_kernel4_tests.c b/tests/vboot_api_kernel4_tests.c new file mode 100644 index 00000000..414279e5 --- /dev/null +++ b/tests/vboot_api_kernel4_tests.c @@ -0,0 +1,241 @@ +/* Copyright (c) 2013 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 vboot_api_kernel, part 4 - select and load kernel + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "gbb_header.h" +#include "host_common.h" +#include "load_kernel_fw.h" +#include "rollback_index.h" +#include "test_common.h" +#include "vboot_audio.h" +#include "vboot_common.h" +#include "vboot_kernel.h" +#include "vboot_nvstorage.h" +#include "vboot_struct.h" + +/* Mock data */ +static VbCommonParams cparams; +static VbSelectAndLoadKernelParams kparams; +static VbNvContext vnc; +static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE]; +static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data; +static GoogleBinaryBlockHeader gbb; + +static int ecsync_retval; +static uint32_t rkr_version; +static uint32_t new_version; +static int rkr_retval, rkw_retval, rkl_retval; +static VbError_t vbboot_retval; + +/* Reset mock data (for use before each test) */ +static void ResetMocks(void) +{ + Memset(&cparams, 0, sizeof(cparams)); + cparams.shared_data_size = sizeof(shared_data); + cparams.shared_data_blob = shared_data; + cparams.gbb_data = &gbb; + + Memset(&kparams, 0, sizeof(kparams)); + + Memset(&gbb, 0, sizeof(gbb)); + gbb.major_version = GBB_MAJOR_VER; + gbb.minor_version = GBB_MINOR_VER; + gbb.flags = 0; + + Memset(&vnc, 0, sizeof(vnc)); + VbNvSetup(&vnc); + VbNvTeardown(&vnc); /* So CRC gets generated */ + + Memset(&shared_data, 0, sizeof(shared_data)); + VbSharedDataInit(shared, sizeof(shared_data)); + + ecsync_retval = VBERROR_SUCCESS; + rkr_version = new_version = 0x10002; + rkr_retval = rkw_retval = rkl_retval = VBERROR_SUCCESS; + vbboot_retval = VBERROR_SUCCESS; +} + +/* Mock functions */ + +VbError_t VbExNvStorageRead(uint8_t *buf) +{ + Memcpy(buf, vnc.raw, sizeof(vnc.raw)); + return VBERROR_SUCCESS; +} + +VbError_t VbExNvStorageWrite(const uint8_t *buf) +{ + Memcpy(vnc.raw, buf, sizeof(vnc.raw)); + return VBERROR_SUCCESS; +} + +VbError_t VbEcSoftwareSync(VbCommonParams *cparams) +{ + return ecsync_retval; +} + +uint32_t RollbackKernelRead(uint32_t *version) +{ + *version = rkr_version; + return rkr_retval; +} + +uint32_t RollbackKernelWrite(uint32_t version) +{ + TEST_EQ(version, new_version, "RollbackKernelWrite new version"); + rkr_version = version; + return rkw_retval; +} + +uint32_t RollbackKernelLock(void) +{ + return rkl_retval; +} + +VbError_t VbBootNormal(VbCommonParams *cparams, LoadKernelParams *p) +{ + shared->kernel_version_tpm = new_version; + + if (vbboot_retval == -1) + return VBERROR_SIMULATED; + + return vbboot_retval; +} + +VbError_t VbBootDeveloper(VbCommonParams *cparams, LoadKernelParams *p) +{ + shared->kernel_version_tpm = new_version; + + if (vbboot_retval == -2) + return VBERROR_SIMULATED; + + return vbboot_retval; +} + +VbError_t VbBootRecovery(VbCommonParams *cparams, LoadKernelParams *p) +{ + shared->kernel_version_tpm = new_version; + + if (vbboot_retval == -3) + return VBERROR_SIMULATED; + + return vbboot_retval; +} + +static void test_slk(VbError_t retval, int recovery_reason, const char *desc) +{ + uint32_t u; + + TEST_EQ(VbSelectAndLoadKernel(&cparams, &kparams), retval, desc); + VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u); + TEST_EQ(u, recovery_reason, " recovery reason"); +} + +/* Tests */ + +static void VbSlkTest(void) +{ + ResetMocks(); + test_slk(0, 0, "Normal"); + + /* Software sync */ + ResetMocks(); + shared->flags |= VBSD_EC_SOFTWARE_SYNC; + ecsync_retval = VBERROR_SIMULATED; + test_slk(VBERROR_SIMULATED, 0, "EC sync bad"); + + ResetMocks(); + ecsync_retval = VBERROR_SIMULATED; + test_slk(0, 0, "EC sync not done"); + + /* Rollback kernel version */ + ResetMocks(); + rkr_retval = 123; + test_slk(VBERROR_TPM_READ_KERNEL, + VBNV_RECOVERY_RW_TPM_R_ERROR, "Read kernel rollback"); + + ResetMocks(); + new_version = 0x20003; + test_slk(0, 0, "Roll forward"); + TEST_EQ(rkr_version, 0x20003, " version"); + + ResetMocks(); + new_version = 0x20003; + shared->flags |= VBSD_FWB_TRIED; + shared->firmware_index = 1; + test_slk(0, 0, "Don't roll forward during try B"); + TEST_EQ(rkr_version, 0x10002, " version"); + + ResetMocks(); + vbboot_retval = VBERROR_INVALID_KERNEL_FOUND; + VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, 123); + VbNvTeardown(&vnc); + shared->flags |= VBSD_FWB_TRIED; + shared->firmware_index = 1; + test_slk(VBERROR_INVALID_KERNEL_FOUND, + 0, "Don't go to recovery if try b fails to find a kernel"); + + ResetMocks(); + new_version = 0x20003; + rkw_retval = 123; + test_slk(VBERROR_TPM_WRITE_KERNEL, + VBNV_RECOVERY_RW_TPM_W_ERROR, "Write kernel rollback"); + + ResetMocks(); + rkl_retval = 123; + test_slk(VBERROR_TPM_LOCK_KERNEL, + VBNV_RECOVERY_RW_TPM_L_ERROR, "Lock kernel rollback"); + + /* Boot normal */ + ResetMocks(); + vbboot_retval = -1; + test_slk(VBERROR_SIMULATED, 0, "Normal boot bad"); + + /* Boot dev */ + ResetMocks(); + shared->flags |= VBSD_BOOT_DEV_SWITCH_ON; + vbboot_retval = -2; + test_slk(VBERROR_SIMULATED, 0, "Dev boot bad"); + + ResetMocks(); + shared->flags |= VBSD_BOOT_DEV_SWITCH_ON; + new_version = 0x20003; + test_slk(0, 0, "Dev doesn't roll forward"); + TEST_EQ(rkr_version, 0x10002, " version"); + + /* Boot recovery */ + ResetMocks(); + shared->recovery_reason = 123; + vbboot_retval = -3; + test_slk(VBERROR_SIMULATED, 0, "Recovery boot bad"); + + ResetMocks(); + shared->recovery_reason = 123; + new_version = 0x20003; + test_slk(0, 0, "Recovery doesn't roll forward"); + TEST_EQ(rkr_version, 0x10002, " version"); + + ResetMocks(); + shared->recovery_reason = 123; + rkr_retval = rkw_retval = rkl_retval = VBERROR_SIMULATED; + test_slk(0, 0, "Recovery ignore TPM errors"); + + + + // todo: rkr/w/l fail ignored if recovery + + +} + +int main(void) +{ + VbSlkTest(); + + return gTestSuccess ? 0 : 255; +} |