summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2011-03-01 13:04:22 -0800
committerRandall Spangler <rspangler@chromium.org>2011-03-01 13:04:22 -0800
commitb416714a10cc8b8048009ca2ab0f3fa1dc4ac24b (patch)
treefd71d216ffdc6f15bf146cad0998137b8fe8a1a7
parentdfe4ca5e4057132b634c3df859ddecbdee35cd29 (diff)
downloadvboot-b416714a10cc8b8048009ca2ab0f3fa1dc4ac24b.tar.gz
Add crossystem support for nvram_cleared and kern_nv
Fix try_b processing And move key block flags check up in LoadFirmware(), which speeds up boot when the dev switch is off because it doesn't do a signature check and then throw it out. BUG=12282 TEST=build firmware, try by hand Review URL: http://codereview.chromium.org/6596081 Change-Id: I10474e9e0ae324906dfe02a351347d04ce847f67
-rw-r--r--firmware/lib/vboot_firmware.c24
-rw-r--r--firmware/lib/vboot_nvstorage.c10
-rw-r--r--host/lib/crossystem.c15
-rw-r--r--utility/crossystem_main.c3
4 files changed, 26 insertions, 26 deletions
diff --git a/firmware/lib/vboot_firmware.c b/firmware/lib/vboot_firmware.c
index e8c8a86f..036441fb 100644
--- a/firmware/lib/vboot_firmware.c
+++ b/firmware/lib/vboot_firmware.c
@@ -116,10 +116,7 @@ int LoadFirmware(LoadFirmwareParams* params) {
uint8_t* body_digest;
/* If try B count is non-zero try firmware B first */
- index = (try_b_count ? i : 1 - i);
-
- /* Verify the key block */
- VBPERFSTART("VB_VKB");
+ index = (try_b_count ? 1 - i : i);
if (0 == index) {
key_block = (VbKeyBlockHeader*)params->verification_block_0;
vblock_size = params->verification_size_0;
@@ -127,14 +124,10 @@ int LoadFirmware(LoadFirmwareParams* params) {
key_block = (VbKeyBlockHeader*)params->verification_block_1;
vblock_size = params->verification_size_1;
}
- if ((0 != KeyBlockVerify(key_block, vblock_size, root_key, 0))) {
- VBDEBUG(("Key block verification failed.\n"));
- VBPERFEND("VB_VKB");
- continue;
- }
- VBPERFEND("VB_VKB");
- /* Check the key block flags against the current boot mode. */
+ /* Check the key block flags against the current boot mode. Do this
+ * before verifying the key block, since flags are faster to check than
+ * the RSA signature. */
if (!(key_block->key_block_flags &
(is_dev ? KEY_BLOCK_FLAG_DEVELOPER_1 :
KEY_BLOCK_FLAG_DEVELOPER_0))) {
@@ -147,6 +140,15 @@ int LoadFirmware(LoadFirmwareParams* params) {
continue;
}
+ /* Verify the key block */
+ VBPERFSTART("VB_VKB");
+ if ((0 != KeyBlockVerify(key_block, vblock_size, root_key, 0))) {
+ VBDEBUG(("Key block verification failed.\n"));
+ VBPERFEND("VB_VKB");
+ continue;
+ }
+ VBPERFEND("VB_VKB");
+
/* 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_nvstorage.c b/firmware/lib/vboot_nvstorage.c
index d9158041..419a9fbc 100644
--- a/firmware/lib/vboot_nvstorage.c
+++ b/firmware/lib/vboot_nvstorage.c
@@ -21,7 +21,7 @@
#define BOOT_OFFSET 1
#define BOOT_DEBUG_RESET_MODE 0x80
-#define BOOT_TRY_B_COUNT 0x0F
+#define BOOT_TRY_B_COUNT_MASK 0x0F
#define RECOVERY_OFFSET 2
#define LOCALIZATION_OFFSET 3
@@ -107,7 +107,7 @@ int VbNvGet(VbNvContext* context, VbNvParam param, uint32_t* dest) {
return 0;
case VBNV_TRY_B_COUNT:
- *dest = raw[BOOT_OFFSET] & BOOT_TRY_B_COUNT;
+ *dest = raw[BOOT_OFFSET] & BOOT_TRY_B_COUNT_MASK;
return 0;
case VBNV_RECOVERY_REQUEST:
@@ -172,10 +172,10 @@ int VbNvSet(VbNvContext* context, VbNvParam param, uint32_t value) {
case VBNV_TRY_B_COUNT:
/* Clip to valid range. */
- if (value > BOOT_TRY_B_COUNT)
- value = BOOT_TRY_B_COUNT - 1;
+ if (value > BOOT_TRY_B_COUNT_MASK)
+ value = BOOT_TRY_B_COUNT_MASK;
- raw[BOOT_OFFSET] &= ~BOOT_TRY_B_COUNT;
+ raw[BOOT_OFFSET] &= ~BOOT_TRY_B_COUNT_MASK;
raw[BOOT_OFFSET] |= (uint8_t)value;
break;
diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c
index 8e482d36..5951e10b 100644
--- a/host/lib/crossystem.c
+++ b/host/lib/crossystem.c
@@ -489,6 +489,8 @@ int VbGetSystemPropertyInt(const char* name) {
value = VbGetNvStorage(VBNV_TRIED_FIRMWARE_B);
} else if (!strcasecmp(name,"kern_nv")) {
value = VbGetNvStorage(VBNV_KERNEL_FIELD);
+ } else if (!strcasecmp(name,"nvram_cleared")) {
+ value = VbGetNvStorage(VBNV_KERNEL_SETTINGS_RESET);
}
/* NV storage values. If unable to get from NV storage, fall back to the
* CMOS reboot field used by older BIOS. */
@@ -512,10 +514,6 @@ int VbGetSystemPropertyInt(const char* name) {
value = ReadFileInt(ACPI_FMAP_PATH);
}
- /* TODO: implement the following properties:
- * nvram_cleared
- */
-
return value;
}
@@ -574,7 +572,10 @@ const char* VbGetSystemPropertyString(const char* name, char* dest, int size) {
int VbSetSystemPropertyInt(const char* name, int value) {
/* NV storage values with no defaults for older BIOS. */
- if (!strcasecmp(name,"kern_nv")) {
+ if (!strcasecmp(name,"nvram_cleared")) {
+ /* Can only clear this flag; it's set inside the NV storage library. */
+ return VbSetNvStorage(VBNV_KERNEL_SETTINGS_RESET, 0);
+ } else if (!strcasecmp(name,"kern_nv")) {
return VbSetNvStorage(VBNV_KERNEL_FIELD, value);
}
/* NV storage values. If unable to get from NV storage, fall back to the
@@ -593,10 +594,6 @@ int VbSetSystemPropertyInt(const char* name, int value) {
return VbSetCmosRebootField(CMOSRF_TRY_B, value);
}
- /* TODO: implement the following:
- * nvram_cleared
- */
-
return -1;
}
diff --git a/utility/crossystem_main.c b/utility/crossystem_main.c
index ebd6ed55..35d6ea70 100644
--- a/utility/crossystem_main.c
+++ b/utility/crossystem_main.c
@@ -43,10 +43,11 @@ const Param sys_param_list[] = {
{"ecfw_act", 1, 0, "Active EC firmware"},
{"kernkey_vfy", 1, 0, "Type of verification done on kernel key block"},
/* Writable integers */
+ {"nvram_cleared", 0, 1, "Have NV settings been lost? Write 0 to clear"},
+ {"kern_nv", 0, 1, "Non-volatile field for kernel use", "0x%08x"},
{"recovery_request", 0, 1, "Recovery mode request (writable)"},
{"dbg_reset", 0, 1, "Debug reset mode request (writable)"},
{"fwb_tries", 0, 1, "Try firmware B count (writable)"},
- {"kern_nv", 0, 1, "Non-volatile field for kernel use", "0x%08x"},
/* TODO: implement the following:
* nvram_cleared