summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/include/load_firmware_fw.h1
-rw-r--r--firmware/include/load_kernel_fw.h2
-rw-r--r--firmware/lib/include/rollback_index.h1
-rw-r--r--firmware/lib/rollback_index.c1
-rw-r--r--firmware/lib/vboot_firmware.c29
-rw-r--r--firmware/lib/vboot_kernel.c22
-rw-r--r--firmware/version.c2
7 files changed, 41 insertions, 17 deletions
diff --git a/firmware/include/load_firmware_fw.h b/firmware/include/load_firmware_fw.h
index 2332564b..6bdcc6a9 100644
--- a/firmware/include/load_firmware_fw.h
+++ b/firmware/include/load_firmware_fw.h
@@ -19,6 +19,7 @@
/* Return codes for LoadFirmware() */
#define LOAD_FIRMWARE_SUCCESS 0 /* Success */
#define LOAD_FIRMWARE_RECOVERY 1 /* Reboot to recovery mode */
+#define LOAD_FIRMWARE_REBOOT 2 /* Reboot to same mode as current boot */
/* Boot flags for LoadFirmware().boot_flags */
#define BOOT_FLAG_DEVELOPER UINT64_C(0x01) /* Developer switch is on */
diff --git a/firmware/include/load_kernel_fw.h b/firmware/include/load_kernel_fw.h
index 4f86b403..31c30818 100644
--- a/firmware/include/load_kernel_fw.h
+++ b/firmware/include/load_kernel_fw.h
@@ -18,6 +18,8 @@
#define LOAD_KERNEL_NOT_FOUND 1 /* No kernel found on device */
#define LOAD_KERNEL_INVALID 2 /* Only invalid kernels found on device */
#define LOAD_KERNEL_RECOVERY 3 /* Internal error; reboot to recovery mode */
+#define LOAD_KERNEL_REBOOT 4 /* Internal error; reboot to current mode */
+
/* Boot flags for LoadKernel().boot_flags */
#define BOOT_FLAG_DEVELOPER UINT64_C(0x01) /* Developer switch is on */
diff --git a/firmware/lib/include/rollback_index.h b/firmware/lib/include/rollback_index.h
index fd5f72a2..513454b2 100644
--- a/firmware/lib/include/rollback_index.h
+++ b/firmware/lib/include/rollback_index.h
@@ -10,6 +10,7 @@
#define VBOOT_REFERENCE_ROLLBACK_INDEX_H_
#include "sysincludes.h"
+#include "tss_constants.h"
/* Rollback version types. */
#define FIRMWARE_VERSIONS 0
diff --git a/firmware/lib/rollback_index.c b/firmware/lib/rollback_index.c
index 944104b1..02fcee58 100644
--- a/firmware/lib/rollback_index.c
+++ b/firmware/lib/rollback_index.c
@@ -20,6 +20,7 @@ __pragma(warning (disable: 4127))
#define RETURN_ON_FAILURE(tpm_command) do { \
uint32_t result; \
if ((result = (tpm_command)) != TPM_SUCCESS) { \
+ VBDEBUG(("Rollback: %08x returned by " #tpm_command "\n", (int)result)); \
return result; \
} \
} while (0)
diff --git a/firmware/lib/vboot_firmware.c b/firmware/lib/vboot_firmware.c
index c445a819..b88dc209 100644
--- a/firmware/lib/vboot_firmware.c
+++ b/firmware/lib/vboot_firmware.c
@@ -40,6 +40,7 @@ int LoadFirmware(LoadFirmwareParams* params) {
uint16_t tpm_fw_version = 0;
uint64_t lowest_key_version = 0xFFFF;
uint64_t lowest_fw_version = 0xFFFF;
+ uint32_t status;
int good_index = -1;
int index;
@@ -60,13 +61,17 @@ int LoadFirmware(LoadFirmwareParams* params) {
}
/* Initialize the TPM and read rollback indices. */
- if (0 != RollbackFirmwareSetup(params->boot_flags & BOOT_FLAG_DEVELOPER)) {
+ status = RollbackFirmwareSetup(params->boot_flags & BOOT_FLAG_DEVELOPER);
+ if (0 != status) {
VBDEBUG(("Unable to setup TPM.\n"));
- return LOAD_FIRMWARE_RECOVERY;
+ return (status == TPM_E_MUST_REBOOT ?
+ LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY);
}
- if (0 != RollbackFirmwareRead(&tpm_key_version, &tpm_fw_version)) {
+ status = RollbackFirmwareRead(&tpm_key_version, &tpm_fw_version);
+ if (0 != status) {
VBDEBUG(("Unable to read stored versions.\n"));
- return LOAD_FIRMWARE_RECOVERY;
+ return (status == TPM_E_MUST_REBOOT ?
+ LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY);
}
/* Allocate our internal data */
@@ -219,17 +224,23 @@ int LoadFirmware(LoadFirmwareParams* params) {
if ((lowest_key_version > tpm_key_version) ||
(lowest_key_version == tpm_key_version &&
lowest_fw_version > tpm_fw_version)) {
- if (0 != RollbackFirmwareWrite((uint16_t)lowest_key_version,
- (uint16_t)lowest_fw_version)) {
+
+
+ status = RollbackFirmwareWrite((uint16_t)lowest_key_version,
+ (uint16_t)lowest_fw_version);
+ if (0 != status) {
VBDEBUG(("Unable to write stored versions.\n"));
- return LOAD_FIRMWARE_RECOVERY;
+ return (status == TPM_E_MUST_REBOOT ?
+ LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY);
}
}
/* Lock firmware versions in TPM */
- if (0 != RollbackFirmwareLock()) {
+ status = RollbackFirmwareLock();
+ if (0 != status) {
VBDEBUG(("Unable to lock firmware versions.\n"));
- return LOAD_FIRMWARE_RECOVERY;
+ return (status == TPM_E_MUST_REBOOT ?
+ LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY);
}
/* Success */
diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c
index 23ea9136..ddbceed6 100644
--- a/firmware/lib/vboot_kernel.c
+++ b/firmware/lib/vboot_kernel.c
@@ -129,6 +129,7 @@ int LoadKernel(LoadKernelParams* params) {
int is_dev = (BOOT_FLAG_DEVELOPER & params->boot_flags ? 1 : 0);
int is_rec = (BOOT_FLAG_RECOVERY & params->boot_flags ? 1 : 0);
int is_normal = (!is_dev && !is_rec);
+ uint32_t status;
/* Clear output params in case we fail */
params->partition_number = 0;
@@ -147,9 +148,11 @@ int LoadKernel(LoadKernelParams* params) {
if (is_normal) {
/* Read current kernel key index from TPM. Assumes TPM is already
* initialized. */
- if (0 != RollbackKernelRead(&tpm_key_version, &tpm_kernel_version)) {
+ status = RollbackKernelRead(&tpm_key_version, &tpm_kernel_version);
+ if (0 != status) {
VBDEBUG(("Unable to get kernel versions from TPM\n"));
- return LOAD_KERNEL_RECOVERY;
+ return (status == TPM_E_MUST_REBOOT ?
+ LOAD_KERNEL_REBOOT : LOAD_KERNEL_RECOVERY);
}
} else if (is_dev && !is_rec) {
/* In developer mode, we ignore the kernel subkey, and just use
@@ -367,20 +370,25 @@ int LoadKernel(LoadKernelParams* params) {
if ((lowest_key_version > tpm_key_version) ||
(lowest_key_version == tpm_key_version &&
lowest_kernel_version > tpm_kernel_version)) {
- if (0 != RollbackKernelWrite((uint16_t)lowest_key_version,
- (uint16_t)lowest_kernel_version)) {
+
+ status = RollbackKernelWrite((uint16_t)lowest_key_version,
+ (uint16_t)lowest_kernel_version);
+ if (0 != status) {
VBDEBUG(("Error writing kernel versions to TPM.\n"));
- return LOAD_KERNEL_RECOVERY;
+ return (status == TPM_E_MUST_REBOOT ?
+ LOAD_KERNEL_REBOOT : LOAD_KERNEL_RECOVERY);
}
}
}
/* Lock the kernel versions */
- if (0 != RollbackKernelLock()) {
+ status = RollbackKernelLock();
+ if (0 != status) {
VBDEBUG(("Error locking kernel versions.\n"));
/* Don't reboot to recovery mode if we're already there */
if (!is_rec)
- return LOAD_KERNEL_RECOVERY;
+ return (status == TPM_E_MUST_REBOOT ?
+ LOAD_KERNEL_REBOOT : LOAD_KERNEL_RECOVERY);
}
/* Success! */
diff --git a/firmware/version.c b/firmware/version.c
index 2d4dc147..a9136bb3 100644
--- a/firmware/version.c
+++ b/firmware/version.c
@@ -1 +1 @@
-char* VbootVersion = "VBOOv=983af25b";
+char* VbootVersion = "VBOOv=ba8bd4f8";