Index: firmware/lib/rollback_index.c |
diff --git a/firmware/lib/rollback_index.c b/firmware/lib/rollback_index.c |
index b63230588666fd64a851965d5f07d334e85129a2..0d9b23c9cefc4ef24d3b064b4ff9806a7b6d7f75 100644 |
--- a/firmware/lib/rollback_index.c |
+++ b/firmware/lib/rollback_index.c |
@@ -98,20 +98,25 @@ static uint32_t WriteSpaceKernel(const RollbackSpaceKernel* rsk) { |
return SafeWrite(KERNEL_NV_INDEX, rsk, sizeof(RollbackSpaceKernel)); |
} |
-/* Creates the NVRAM spaces, and sets their initial values as needed. */ |
-static uint32_t InitializeSpaces(RollbackSpaceFirmware* rsf, |
- RollbackSpaceKernel* rsk) { |
+/* Performs one-time initializations. Creates the NVRAM spaces, and sets their |
+ * initial values as needed. Sets the nvLocked bit and ensures the physical |
+ * presence command is enabled and locked. |
+ */ |
+static uint32_t OneTimeInitializeTPM(RollbackSpaceFirmware* rsf, |
+ RollbackSpaceKernel* rsk) { |
static const RollbackSpaceFirmware rsf_init = { |
ROLLBACK_SPACE_FIRMWARE_VERSION, 0, 0, 0}; |
static const RollbackSpaceKernel rsk_init = { |
ROLLBACK_SPACE_KERNEL_VERSION, ROLLBACK_SPACE_KERNEL_UID, 0, 0}; |
uint8_t nvlocked = 0; |
- VBDEBUG(("TPM: Initializing spaces\n")); |
+ VBDEBUG(("TPM: One-time initialization\n")); |
+ |
+ RETURN_ON_FAILURE(TlclFinalizePhysicalPresence()); |
/* The TPM will not enforce the NV authorization restrictions until the |
* execution of a TPM_NV_DefineSpace with the handle of TPM_NV_INDEX_LOCK. |
- * Create that space if it doesn't already exist. */ |
+ * Here we create that space if it doesn't already exist. */ |
RETURN_ON_FAILURE(TlclGetFlags(NULL, NULL, &nvlocked)); |
VBDEBUG(("TPM: nvlocked=%d\n", nvlocked)); |
if (!nvlocked) { |
@@ -119,11 +124,11 @@ static uint32_t InitializeSpaces(RollbackSpaceFirmware* rsf, |
RETURN_ON_FAILURE(TlclSetNvLocked()); |
} |
- /* Initialize the firmware and kernel spaces */ |
+ /* Initializes the firmware and kernel spaces */ |
Memcpy(rsf, &rsf_init, sizeof(RollbackSpaceFirmware)); |
Memcpy(rsk, &rsk_init, sizeof(RollbackSpaceKernel)); |
- /* Define and set firmware and kernel spaces */ |
+ /* Defines and sets firmware and kernel spaces */ |
RETURN_ON_FAILURE(SafeDefineSpace(FIRMWARE_NV_INDEX, |
TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE, |
sizeof(RollbackSpaceFirmware))); |
@@ -177,9 +182,17 @@ uint32_t SetupTPM(int recovery_mode, int developer_mode, |
#else |
RETURN_ON_FAILURE(TlclSelfTestFull()); |
#endif |
- RETURN_ON_FAILURE(TlclAssertPhysicalPresence()); |
+ result = TlclAssertPhysicalPresence(); |
+ if (result != 0) { |
+ /* It is possible that the TPM was delivered with the physical presence |
+ * command disabled. This tries enabling it, then tries asserting PP |
+ * again. |
+ */ |
+ RETURN_ON_FAILURE(TlclPhysicalPresenceCMDEnable()); |
+ RETURN_ON_FAILURE(TlclAssertPhysicalPresence()); |
+ } |
- /* Check that the TPM is enabled and activated. */ |
+ /* Checks that the TPM is enabled and activated. */ |
RETURN_ON_FAILURE(TlclGetFlags(&disable, &deactivated, NULL)); |
if (disable || deactivated) { |
VBDEBUG(("TPM: disabled (%d) or deactivated (%d). Fixing...\n", |
@@ -190,15 +203,15 @@ uint32_t SetupTPM(int recovery_mode, int developer_mode, |
return TPM_E_MUST_REBOOT; |
} |
- /* Read the firmware space. */ |
+ /* Reads the firmware space. */ |
result = ReadSpaceFirmware(rsf); |
if (TPM_E_BADINDEX == result) { |
RollbackSpaceKernel rsk; |
/* This is the first time we've run, and the TPM has not been |
- * initialized. Initialize it. */ |
+ * initialized. This initializes it. */ |
VBDEBUG(("TPM: Not initialized yet.\n")); |
- RETURN_ON_FAILURE(InitializeSpaces(rsf, &rsk)); |
+ RETURN_ON_FAILURE(OneTimeInitializeTPM(rsf, &rsk)); |
} else if (TPM_SUCCESS != result) { |
VBDEBUG(("TPM: Firmware space in a bad state; giving up.\n")); |
return TPM_E_CORRUPTED_STATE; |
@@ -206,14 +219,14 @@ uint32_t SetupTPM(int recovery_mode, int developer_mode, |
VBDEBUG(("TPM: Firmware space sv%d f%x v%x\n", |
rsf->struct_version, rsf->flags, rsf->fw_versions)); |
- /* Clear ownership if developer flag has toggled */ |
+ /* Clears ownership if developer flag has toggled */ |
if ((developer_mode ? FLAG_LAST_BOOT_DEVELOPER : 0) != |
(rsf->flags & FLAG_LAST_BOOT_DEVELOPER)) { |
VBDEBUG(("TPM: Developer flag changed; clearing owner.\n")); |
RETURN_ON_FAILURE(TPMClearAndReenable()); |
} |
- /* Update flags */ |
+ /* Updates flags */ |
if (developer_mode) |
new_flags |= FLAG_LAST_BOOT_DEVELOPER; |
if (recovery_mode) |
@@ -225,7 +238,7 @@ uint32_t SetupTPM(int recovery_mode, int developer_mode, |
rsf_dirty = 1; |
} |
- /* If firmware space is dirty, flush it back to the TPM */ |
+ /* If firmware space is dirty, this flushes it back to the TPM */ |
if (rsf_dirty) { |
VBDEBUG(("TPM: Updating firmware space.\n")); |
RETURN_ON_FAILURE(WriteSpaceFirmware(rsf)); |
@@ -245,8 +258,8 @@ __pragma(warning (disable: 4100)) |
uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) { |
#ifndef CHROMEOS_ENVIRONMENT |
- /* Initialize the TPM, but ignore return codes. In ChromeOS |
- * environment, don't even talk to the TPM. */ |
+ /* Initializes the TPM, but ignores return codes. In ChromeOS |
+ * environment, doesn't even talk to the TPM. */ |
TlclLibInit(); |
TlclStartup(); |
TlclSelfTestFull(); |
@@ -266,8 +279,8 @@ uint32_t RollbackFirmwareLock(void) { |
uint32_t RollbackKernelRecovery(int developer_mode) { |
#ifndef CHROMEOS_ENVIRONMENT |
- /* Initialize the TPM, but ignore return codes. In ChromeOS |
- * environment, don't even talk to the TPM. */ |
+ /* Initializes the TPM, but ignore return codes. In ChromeOS |
+ * environment, doesn't even talk to the TPM. */ |
TlclLibInit(); |
TlclStartup(); |
TlclSelfTestFull(); |