summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2011-02-14 11:12:09 -0800
committerRandall Spangler <rspangler@chromium.org>2011-02-14 11:12:09 -0800
commita8e0f94b94c2181a95a984fbcd8de80c3ca1b8c9 (patch)
tree8443735374d04604a006d8561b770e1fd900e982
parent61362d65fcdd6f6aff90fc5be51237b39cfeb9ae (diff)
downloadvboot-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.h12
-rw-r--r--firmware/lib/vboot_firmware.c20
-rw-r--r--firmware/lib/vboot_kernel.c10
-rw-r--r--firmware/stub/load_firmware_stub.c3
-rw-r--r--utility/load_kernel_test.c9
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 */