summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/include/gbb_header.h7
-rw-r--r--firmware/lib/vboot_api_init.c4
-rw-r--r--firmware/lib/vboot_api_kernel.c4
-rw-r--r--firmware/lib/vboot_firmware.c27
-rw-r--r--tests/vboot_api_init_tests.c15
-rw-r--r--tests/vboot_firmware_tests.c19
6 files changed, 62 insertions, 14 deletions
diff --git a/firmware/include/gbb_header.h b/firmware/include/gbb_header.h
index 7f9b0005..a3204e32 100644
--- a/firmware/include/gbb_header.h
+++ b/firmware/include/gbb_header.h
@@ -43,6 +43,13 @@
/* The factory flow may need the BIOS to boot a non-ChromeOS kernel if the
* dev-switch is on. This flag allows that. */
#define GBB_FLAG_ENABLE_ALTERNATE_OS 0x00000004
+/* Force dev switch on, regardless of physical/keyboard dev switch position. */
+#define GBB_FLAG_FORCE_DEV_SWITCH_ON 0x00000008
+/* Allow booting from USB in dev mode even if dev_boot_usb=0. */
+#define GBB_FLAG_FORCE_DEV_BOOT_USB 0x00000010
+/* Disable firmware rollback protection. */
+#define GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK 0x00000020
+
#ifdef __cplusplus
extern "C" {
diff --git a/firmware/lib/vboot_api_init.c b/firmware/lib/vboot_api_init.c
index bff57bd5..78f451fd 100644
--- a/firmware/lib/vboot_api_init.c
+++ b/firmware/lib/vboot_api_init.c
@@ -127,7 +127,9 @@ VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) {
/* We may be asked to clear the virtual dev-switch at boot. */
VbNvGet(&vnc, VBNV_DISABLE_DEV_REQUEST, &disable_dev_request);
- /* FIXME: How about a GBB flag to force dev-switch on? */
+ /* Allow GBB flag to override dev switch */
+ if (gbb->flags & GBB_FLAG_FORCE_DEV_SWITCH_ON)
+ is_hw_dev = 1;
VBPERFSTART("VB_TPMI");
/* Initialize the TPM. If the developer mode state has changed since the
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index b0a04ac4..6e02380e 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -116,6 +116,7 @@ VbError_t VbBootNormal(VbCommonParams* cparams, LoadKernelParams* p) {
/* Handle a developer-mode boot */
VbError_t VbBootDeveloper(VbCommonParams* cparams, LoadKernelParams* p) {
+ GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)cparams->gbb_data;
uint32_t allow_usb = 0;
VbAudioContext* audio = 0;
@@ -123,6 +124,9 @@ VbError_t VbBootDeveloper(VbCommonParams* cparams, LoadKernelParams* p) {
/* Check if USB booting is allowed */
VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &allow_usb);
+ /* Handle GBB flag override */
+ if (gbb->flags & GBB_FLAG_FORCE_DEV_BOOT_USB)
+ allow_usb = 1;
/* Show the dev mode warning screen */
VbDisplayScreen(cparams, VB_SCREEN_DEVELOPER_WARNING, 0, &vnc);
diff --git a/firmware/lib/vboot_firmware.c b/firmware/lib/vboot_firmware.c
index 3f9f64fc..ed9d3bc0 100644
--- a/firmware/lib/vboot_firmware.c
+++ b/firmware/lib/vboot_firmware.c
@@ -131,17 +131,19 @@ int LoadFirmware(VbCommonParams* cparams, VbSelectFirmwareParams* fparams,
/* Check for rollback of key version. */
key_version = key_block->data_key.key_version;
- if (key_version < (shared->fw_version_tpm >> 16)) {
- VBDEBUG(("Key rollback detected.\n"));
- *check_result = VBSD_LF_CHECK_KEY_ROLLBACK;
- continue;
- }
- if (key_version > 0xFFFF) {
- /* Key version is stored in 16 bits in the TPM, so key versions greater
- * than 0xFFFF can't be stored properly. */
- VBDEBUG(("Key version > 0xFFFF.\n"));
- *check_result = VBSD_LF_CHECK_KEY_ROLLBACK;
- continue;
+ if (!(gbb->flags & GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)) {
+ if (key_version < (shared->fw_version_tpm >> 16)) {
+ VBDEBUG(("Key rollback detected.\n"));
+ *check_result = VBSD_LF_CHECK_KEY_ROLLBACK;
+ continue;
+ }
+ if (key_version > 0xFFFF) {
+ /* Key version is stored in 16 bits in the TPM, so key versions greater
+ * than 0xFFFF can't be stored properly. */
+ VBDEBUG(("Key version > 0xFFFF.\n"));
+ *check_result = VBSD_LF_CHECK_KEY_ROLLBACK;
+ continue;
+ }
}
/* Get the key for preamble/data verification from the key block. */
@@ -170,7 +172,8 @@ int LoadFirmware(VbCommonParams* cparams, VbSelectFirmwareParams* fparams,
/* Check for rollback of firmware version. */
combined_version = (uint32_t)((key_version << 16) |
(preamble->firmware_version & 0xFFFF));
- if (combined_version < shared->fw_version_tpm) {
+ if (combined_version < shared->fw_version_tpm &&
+ !(gbb->flags & GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)) {
VBDEBUG(("Firmware version rollback detected.\n"));
*check_result = VBSD_LF_CHECK_FW_ROLLBACK;
RSAPublicKeyFree(data_key);
diff --git a/tests/vboot_api_init_tests.c b/tests/vboot_api_init_tests.c
index ec1e7fa9..28a43d88 100644
--- a/tests/vboot_api_init_tests.c
+++ b/tests/vboot_api_init_tests.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2012 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.
*
@@ -211,6 +211,19 @@ static void VbInitTest(void) {
VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags");
TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags");
+ /* Developer mode forced by GBB flag */
+ ResetMocks();
+ iparams.flags = 0;
+ gbb.flags = GBB_FLAG_FORCE_DEV_SWITCH_ON;
+ TestVbInit(0, 0, "Dev mode via GBB");
+ TEST_EQ(shared->recovery_reason, 0, " recovery reason");
+ TEST_EQ(iparams.out_flags,
+ VB_INIT_OUT_CLEAR_RAM |
+ VB_INIT_OUT_ENABLE_DISPLAY |
+ VB_INIT_OUT_ENABLE_USB_STORAGE |
+ VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags");
+ TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags");
+
/* Recovery mode from NV storage */
ResetMocks();
VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, 123);
diff --git a/tests/vboot_firmware_tests.c b/tests/vboot_firmware_tests.c
index 7a023226..0443b061 100644
--- a/tests/vboot_firmware_tests.c
+++ b/tests/vboot_firmware_tests.c
@@ -253,6 +253,14 @@ static void LoadFirmwareTest(void) {
TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_DATA_KEY_PARSE,
"Data key invalid");
+ /* Test invalid key version with GBB bypass-rollback flag */
+ ResetMocks();
+ vblock[0].data_key.key_version = 1; /* Simulate rollback */
+ gbb->flags = GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK;
+ TestLoadFirmware(VBERROR_SUCCESS, 0, "Key version check + GBB override");
+ TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID,
+ "Key version rollback + GBB override");
+
/* Test invalid preamble with A */
ResetMocks();
mpreamble[0].header_version_major = 1; /* Simulate failure */
@@ -277,6 +285,17 @@ static void LoadFirmwareTest(void) {
TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_FW_ROLLBACK,
"Firmware version overflow");
+ /* Test invalid firmware versions with GBB bypass-rollback flag */
+ ResetMocks();
+ mpreamble[0].firmware_version = 3; /* Simulate rollback */
+ mpreamble[1].firmware_version = 0x10001; /* Check overflow */
+ gbb->flags = GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK;
+ TestLoadFirmware(VBERROR_SUCCESS, 0, "Firmware version check + GBB bypass");
+ TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID,
+ "Firmware version rollback + GBB override");
+ TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_HEADER_VALID,
+ "Firmware version overflow + GBB override");
+
/* Test RO normal with A */
ResetMocks();
mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL;