Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Unified Diff: firmware/lib/rollback_index.c

Issue 2869022: New rollback_index API. (Closed) Base URL: ssh://git@chromiumos-git/vboot_reference.git
Patch Set: small API change Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « firmware/lib/include/rollback_index.h ('k') | firmware/lib/vboot_firmware.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: firmware/lib/rollback_index.c
diff --git a/firmware/lib/rollback_index.c b/firmware/lib/rollback_index.c
index 4fb7ec97e2c7980e04071df48ee3f6525023c2e4..4629e6e4810de9b8c551e2ee72e9756312fa3a0c 100644
--- a/firmware/lib/rollback_index.c
+++ b/firmware/lib/rollback_index.c
@@ -12,10 +12,7 @@
#include "tss_constants.h"
#include "utility.h"
-uint16_t g_firmware_key_version = 0;
-uint16_t g_firmware_version = 0;
-uint16_t g_kernel_key_version = 0;
-uint16_t g_kernel_version = 0;
+static int g_rollback_recovery_mode = 0;
/* disable MSVC warning on const logical expression (as in } while(0);) */
__pragma(warning (disable: 4127))
@@ -133,34 +130,6 @@ static uint32_t SetDistrustKernelSpaceAtNextBoot(uint32_t distrust) {
return TPM_SUCCESS;
}
-static uint32_t GetTPMRollbackIndices(int type) {
- uint32_t firmware_versions;
- uint32_t kernel_versions;
-
- /* We perform the reads, making sure they succeed. A failure means that the
- * rollback index locations are missing or somehow messed up. We let the
- * caller deal with that.
- */
- switch (type) {
- case FIRMWARE_VERSIONS:
- RETURN_ON_FAILURE(TlclRead(FIRMWARE_VERSIONS_NV_INDEX,
- (uint8_t*) &firmware_versions,
- sizeof(firmware_versions)));
- g_firmware_key_version = (uint16_t) (firmware_versions >> 16);
- g_firmware_version = (uint16_t) (firmware_versions & 0xffff);
- break;
- case KERNEL_VERSIONS:
- RETURN_ON_FAILURE(TlclRead(KERNEL_VERSIONS_NV_INDEX,
- (uint8_t*) &kernel_versions,
- sizeof(kernel_versions)));
- g_kernel_key_version = (uint16_t) (kernel_versions >> 16);
- g_kernel_version = (uint16_t) (kernel_versions & 0xffff);
- break;
- }
-
- return TPM_SUCCESS;
-}
-
/* Checks if the kernel version space has been mucked with. If it has,
* reconstructs it using the backup value.
*/
@@ -244,9 +213,30 @@ static uint32_t CheckDeveloperModeTransition(uint32_t current_developer) {
return TPM_SUCCESS;
}
-static uint32_t SetupTPM_(int mode, int developer_flag) {
+/* SetupTPM starts the TPM and establishes the root of trust for the
+ * anti-rollback mechanism. SetupTPM can fail for three reasons. 1 A bug. 2 a
+ * TPM hardware failure. 3 An unexpected TPM state due to some attack. In
+ * general we cannot easily distinguish the kind of failure, so our strategy is
+ * to reboot in recovery mode in all cases. The recovery mode calls SetupTPM
+ * again, which executes (almost) the same sequence of operations. There is a
+ * good chance that, if recovery mode was entered because of a TPM failure, the
+ * failure will repeat itself. (In general this is impossible to guarantee
+ * because we have no way of creating the exact TPM initial state at the
+ * previous boot.) In recovery mode, we ignore the failure and continue, thus
+ * giving the recovery kernel a chance to fix things (that's why we don't set
+ * bGlobalLock). The choice is between a knowingly insecure device and a
+ * bricked device.
+ *
+ * As a side note, observe that we go through considerable hoops to avoid using
+ * the STCLEAR permissions for the index spaces. We do this to avoid writing
+ * to the TPM flashram at every reboot or wake-up, because of concerns about
+ * the durability of the NVRAM.
+ */
+static uint32_t SetupTPM(int recovery_mode,
+ int developer_mode) {
uint8_t disable;
uint8_t deactivated;
+
TlclLibInit();
RETURN_ON_FAILURE(TlclStartup());
RETURN_ON_FAILURE(TlclContinueSelfTest());
@@ -272,136 +262,83 @@ static uint32_t SetupTPM_(int mode, int developer_flag) {
}
}
RETURN_ON_FAILURE(BackupKernelSpace());
- RETURN_ON_FAILURE(SetDistrustKernelSpaceAtNextBoot(mode == RO_RECOVERY_MODE));
- RETURN_ON_FAILURE(GetTPMRollbackIndices(FIRMWARE_VERSIONS));
- RETURN_ON_FAILURE(GetTPMRollbackIndices(KERNEL_VERSIONS));
-
- RETURN_ON_FAILURE(CheckDeveloperModeTransition(developer_flag));
-
- /* As a courtesy (I hope) to the caller, lock the firmware versions if we are
- * in recovery mode. The normal mode may need to update the firmware
- * versions, so they cannot be locked here.
- */
- if (mode == RO_RECOVERY_MODE) {
- RETURN_ON_FAILURE(LockFirmwareVersions());
- }
- return TPM_SUCCESS;
-}
-
-/* SetupTPM starts the TPM and establishes the root of trust for the
- * anti-rollback mechanism. SetupTPM can fail for three reasons. 1 A bug. 2 a
- * TPM hardware failure. 3 An unexpected TPM state due to some attack. In
- * general we cannot easily distinguish the kind of failure, so our strategy is
- * to reboot in recovery mode in all cases. The recovery mode calls SetupTPM
- * again, which executes (almost) the same sequence of operations. There is a
- * good chance that, if recovery mode was entered because of a TPM failure, the
- * failure will repeat itself. (In general this is impossible to guarantee
- * because we have no way of creating the exact TPM initial state at the
- * previous boot.) In recovery mode, we ignore the failure and continue, thus
- * giving the recovery kernel a chance to fix things (that's why we don't set
- * bGlobalLock). The choice is between a knowingly insecure device and a
- * bricked device.
- *
- * As a side note, observe that we go through considerable hoops to avoid using
- * the STCLEAR permissions for the index spaces. We do this to avoid writing
- * to the TPM flashram at every reboot or wake-up, because of concerns about
- * the durability of the NVRAM.
- */
-uint32_t SetupTPM(int mode, int developer_flag) {
- switch (mode) {
- case RO_RECOVERY_MODE:
- case RO_NORMAL_MODE: {
- uint32_t result = SetupTPM_(mode, developer_flag);
- if (mode == RO_NORMAL_MODE) {
- return result;
- } else {
- /* In recovery mode we want to keep going even if there are errors. */
- return TPM_SUCCESS;
- }
- }
- case RW_NORMAL_MODE:
- RETURN_ON_FAILURE(GetTPMRollbackIndices(KERNEL_VERSIONS));
- default:
- return TPM_E_INTERNAL_INCONSISTENCY;
- }
-}
-
-uint32_t GetStoredVersions(int type, uint16_t* key_version, uint16_t* version) {
- /* TODO: should verify that SetupTPM() has been called.
- *
- * Note that SetupTPM() does hardware setup AND sets global variables. When
- * we get down into kernel verification, the hardware setup persists, but we
- * lose the global variables.
- */
- switch (type) {
- case FIRMWARE_VERSIONS:
- *key_version = g_firmware_key_version;
- *version = g_firmware_version;
- break;
- case KERNEL_VERSIONS:
- *key_version = g_kernel_key_version;
- *version = g_kernel_version;
- break;
- }
-
- return TPM_SUCCESS;
-}
+ RETURN_ON_FAILURE(SetDistrustKernelSpaceAtNextBoot(recovery_mode));
+ RETURN_ON_FAILURE(CheckDeveloperModeTransition(developer_mode));
-uint32_t WriteStoredVersions(int type, uint16_t key_version, uint16_t version) {
- uint32_t combined_version = (key_version << 16) & version;
- switch (type) {
- case FIRMWARE_VERSIONS:
- RETURN_ON_FAILURE(SafeWrite(FIRMWARE_VERSIONS_NV_INDEX,
- (uint8_t*) &combined_version,
- sizeof(uint32_t)));
- break;
-
- case KERNEL_VERSIONS:
- RETURN_ON_FAILURE(SafeWrite(KERNEL_VERSIONS_NV_INDEX,
- (uint8_t*) &combined_version,
- sizeof(uint32_t)));
+ if (recovery_mode) {
+ /* In recovery mode global variables are usable. */
+ g_rollback_recovery_mode = 1;
}
return TPM_SUCCESS;
}
-uint32_t LockFirmwareVersions() {
- return TlclSetGlobalLock();
-}
-
-uint32_t LockKernelVersionsByLockingPP() {
- return TlclLockPhysicalPresence();
-}
-
/* disable MSVC warnings on unused arguments */
__pragma(warning (disable: 4100))
-/* NEW APIS! HELP ME LUIGI, YOU'RE MY ONLY HOPE! */
+uint32_t RollbackFirmwareSetup(int developer_mode) {
+ return SetupTPM(0, developer_mode);
+}
-uint32_t RollbackFirmwareSetup(int developer_mode,
- uint16_t* key_version, uint16_t* version) {
+uint32_t RollbackFirmwareRead(uint16_t* key_version, uint16_t* version) {
+ uint32_t firmware_versions;
+ /* Gets firmware versions. */
+ RETURN_ON_FAILURE(TlclRead(FIRMWARE_VERSIONS_NV_INDEX,
+ (uint8_t*) &firmware_versions,
+ sizeof(firmware_versions)));
+ *key_version = (uint16_t) (firmware_versions >> 16);
+ *version = (uint16_t) (firmware_versions & 0xffff);
return TPM_SUCCESS;
}
uint32_t RollbackFirmwareWrite(uint16_t key_version, uint16_t version) {
- return TPM_SUCCESS;
+ uint32_t combined_version = (key_version << 16) & version;
+ return SafeWrite(FIRMWARE_VERSIONS_NV_INDEX,
+ (uint8_t*) &combined_version,
+ sizeof(uint32_t));
}
uint32_t RollbackFirmwareLock(void) {
- return TPM_SUCCESS;
+ return TlclSetGlobalLock();
}
uint32_t RollbackKernelRecovery(int developer_mode) {
+ uint32_t result = SetupTPM(1, developer_mode);
+ if (result == TPM_SUCCESS) {
+ RETURN_ON_FAILURE(TlclSetGlobalLock());
+ }
return TPM_SUCCESS;
}
uint32_t RollbackKernelRead(uint16_t* key_version, uint16_t* version) {
+ uint32_t kernel_versions;
+ if (g_rollback_recovery_mode) {
+ *key_version = 0;
+ *version = 0;
+ } else {
+ /* Reads kernel versions from TPM. */
+ RETURN_ON_FAILURE(TlclRead(KERNEL_VERSIONS_NV_INDEX,
+ (uint8_t*) &kernel_versions,
+ sizeof(kernel_versions)));
+ *key_version = (uint16_t) (kernel_versions >> 16);
+ *version = (uint16_t) (kernel_versions & 0xffff);
+ }
return TPM_SUCCESS;
}
uint32_t RollbackKernelWrite(uint16_t key_version, uint16_t version) {
+ if (!g_rollback_recovery_mode) {
+ uint32_t combined_version = (key_version << 16) & version;
+ return SafeWrite(KERNEL_VERSIONS_NV_INDEX,
+ (uint8_t*) &combined_version,
+ sizeof(uint32_t));
+ }
return TPM_SUCCESS;
}
uint32_t RollbackKernelLock(void) {
- return TPM_SUCCESS;
+ if (!g_rollback_recovery_mode) {
+ return TlclLockPhysicalPresence();
+ } else {
+ return TPM_SUCCESS;
+ }
}
« no previous file with comments | « firmware/lib/include/rollback_index.h ('k') | firmware/lib/vboot_firmware.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698