diff options
author | Randall Spangler <rspangler@chromium.org> | 2011-02-14 11:12:09 -0800 |
---|---|---|
committer | Randall Spangler <rspangler@chromium.org> | 2011-02-14 11:12:09 -0800 |
commit | a8e0f94b94c2181a95a984fbcd8de80c3ca1b8c9 (patch) | |
tree | 8443735374d04604a006d8561b770e1fd900e982 | |
parent | 61362d65fcdd6f6aff90fc5be51237b39cfeb9ae (diff) | |
download | vboot-a8e0f94b94c2181a95a984fbcd8de80c3ca1b8c9.tar.gz |
Support dev vs consumer firmware in vboot_reference
Change-Id: I5a42ba017974b3d591abc574ef7b9b7c9ac579e8
BUG=chrome-os-partner:1824
TEST=make && make runtests
Review URL: http://codereview.chromium.org/6462010
-rw-r--r-- | firmware/include/load_kernel_fw.h | 12 | ||||
-rw-r--r-- | firmware/lib/vboot_firmware.c | 20 | ||||
-rw-r--r-- | firmware/lib/vboot_kernel.c | 10 | ||||
-rw-r--r-- | firmware/stub/load_firmware_stub.c | 3 | ||||
-rw-r--r-- | utility/load_kernel_test.c | 9 |
5 files changed, 47 insertions, 7 deletions
diff --git a/firmware/include/load_kernel_fw.h b/firmware/include/load_kernel_fw.h index 4cca8bd5..16dade1f 100644 --- a/firmware/include/load_kernel_fw.h +++ b/firmware/include/load_kernel_fw.h @@ -22,10 +22,14 @@ /* Boot flags for LoadKernel().boot_flags */ -#define BOOT_FLAG_DEVELOPER UINT64_C(0x01) /* Developer switch is on */ -#define BOOT_FLAG_RECOVERY UINT64_C(0x02) /* In recovery mode */ -#define BOOT_FLAG_SKIP_ADDR_CHECK UINT64_C(0x04) /* Skip check of kernel - * buffer address */ +/* Developer switch is on */ +#define BOOT_FLAG_DEVELOPER UINT64_C(0x01) +/* In recovery mode */ +#define BOOT_FLAG_RECOVERY UINT64_C(0x02) +/* Skip check of kernel buffer address */ +#define BOOT_FLAG_SKIP_ADDR_CHECK UINT64_C(0x04) +/* Active main firmware is developer-type, not normal-type or recovery-type. */ +#define BOOT_FLAG_DEV_FIRMWARE UINT64_C(0x08) typedef struct LoadKernelParams { /* Inputs to LoadKernel() */ diff --git a/firmware/lib/vboot_firmware.c b/firmware/lib/vboot_firmware.c index 019c0bc6..97494333 100644 --- a/firmware/lib/vboot_firmware.c +++ b/firmware/lib/vboot_firmware.c @@ -40,6 +40,7 @@ int LoadFirmware(LoadFirmwareParams* params) { uint64_t lowest_version = 0xFFFFFFFF; uint32_t status; int good_index = -1; + int is_dev; int index; /* Clear output params in case we fail */ @@ -58,10 +59,12 @@ int LoadFirmware(LoadFirmwareParams* params) { return LOAD_FIRMWARE_RECOVERY; } + /* Parse flags */ + is_dev = (params->boot_flags & BOOT_FLAG_DEVELOPER ? 1 : 0); + /* Initialize the TPM and read rollback indices. */ VBPERFSTART("VB_TPMI"); - status = RollbackFirmwareSetup(params->boot_flags & BOOT_FLAG_DEVELOPER, - &tpm_version); + status = RollbackFirmwareSetup(is_dev, &tpm_version); if (0 != status) { VBDEBUG(("Unable to setup TPM and read stored versions.\n")); VBPERFEND("VB_TPMI"); @@ -103,6 +106,19 @@ int LoadFirmware(LoadFirmwareParams* params) { } VBPERFEND("VB_VKB"); + /* Check the key block flags against the current boot mode. */ + if (!(key_block->key_block_flags & + (is_dev ? KEY_BLOCK_FLAG_DEVELOPER_1 : + KEY_BLOCK_FLAG_DEVELOPER_0))) { + VBDEBUG(("Developer flag mismatch.\n")); + continue; + } + /* RW firmware never runs in recovery mode. */ + if (!(key_block->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_0)) { + VBDEBUG(("Recovery flag mismatch.\n")); + continue; + } + /* Check for rollback of key version. */ key_version = key_block->data_key.key_version; if (key_version < (tpm_version >> 16)) { diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c index 8ee45a7e..bd8865bd 100644 --- a/firmware/lib/vboot_kernel.c +++ b/firmware/lib/vboot_kernel.c @@ -146,8 +146,16 @@ int LoadKernel(LoadKernelParams* params) { return LOAD_KERNEL_INVALID; } - is_dev = (BOOT_FLAG_DEVELOPER & params->boot_flags ? 1 : 0); is_rec = (BOOT_FLAG_RECOVERY & params->boot_flags ? 1 : 0); + if (is_rec || (BOOT_FLAG_DEV_FIRMWARE & params->boot_flags)) { + /* Recovery or developer firmware, so accurately represent the + * state of the developer switch for the purposes of verified boot. */ + is_dev = (BOOT_FLAG_DEVELOPER & params->boot_flags ? 1 : 0); + } else { + /* Normal firmware always does a fully verified boot regardless of + * the state of the developer switch. */ + is_dev = 0; + } is_normal = (!is_dev && !is_rec); /* Clear output params in case we fail */ diff --git a/firmware/stub/load_firmware_stub.c b/firmware/stub/load_firmware_stub.c index 9d99b4a0..99ed657f 100644 --- a/firmware/stub/load_firmware_stub.c +++ b/firmware/stub/load_firmware_stub.c @@ -92,6 +92,9 @@ int VerifyFirmwareDriver_stub(uint8_t* root_key_blob, p.kernel_sign_key_blob = Malloc(LOAD_FIRMWARE_KEY_BLOB_REC_SIZE); p.kernel_sign_key_size = LOAD_FIRMWARE_KEY_BLOB_REC_SIZE; + /* TODO: YOU NEED TO SET THE BOOT FLAGS SOMEHOW */ + p.boot_flags = 0; + /* Call LoadFirmware() */ rv = LoadFirmware(&p); if (LOAD_FIRMWARE_SUCCESS == rv) { diff --git a/utility/load_kernel_test.c b/utility/load_kernel_test.c index 9d1f14c3..38e4104f 100644 --- a/utility/load_kernel_test.c +++ b/utility/load_kernel_test.c @@ -144,6 +144,15 @@ int main(int argc, char* argv[]) { * heap instead of its actual target address in the firmware. */ lkp.boot_flags |= BOOT_FLAG_SKIP_ADDR_CHECK; + /* If the boot flags are for developer mode, non-recovery, add the dev-type + * firmware bit. LoadKernel() masks off the developer bit if the dev + * firmware bit is absent, to keep normal firmware from verifying dev + * kernels. */ + if ((lkp.boot_flags & BOOT_FLAG_DEVELOPER) + && !(lkp.boot_flags & BOOT_FLAG_RECOVERY)) { + lkp.boot_flags |= BOOT_FLAG_DEV_FIRMWARE; + } + printf("bootflags = %" PRIu64 "\n", lkp.boot_flags); /* Get image size */ |