| Index: firmware/lib/rollback_index.c | 
| diff --git a/firmware/lib/rollback_index.c b/firmware/lib/rollback_index.c | 
| index a81bb9b86cea59f7ab4437684f14ae9257eec80c..944104b112788124b41026a5155445dc4755534d 100644 | 
| --- a/firmware/lib/rollback_index.c | 
| +++ b/firmware/lib/rollback_index.c | 
| @@ -24,7 +24,7 @@ __pragma(warning (disable: 4127)) | 
| }                                                   \ | 
| } while (0) | 
|  | 
| -static uint32_t TPMClearAndReenable() { | 
| +uint32_t TPMClearAndReenable(void) { | 
| RETURN_ON_FAILURE(TlclForceClear()); | 
| RETURN_ON_FAILURE(TlclSetEnable()); | 
| RETURN_ON_FAILURE(TlclSetDeactivated(0)); | 
| @@ -58,7 +58,7 @@ static uint32_t InitializeKernelVersionsSpaces(void) { | 
| * if the spaces have been fully initialized, to 0 if not.  Otherwise | 
| * *|initialized| is not changed. | 
| */ | 
| -static uint32_t GetSpacesInitialized(int* initialized) { | 
| +uint32_t GetSpacesInitialized(int* initialized) { | 
| uint32_t space_holder; | 
| uint32_t result; | 
| result = TlclRead(TPM_IS_INITIALIZED_NV_INDEX, | 
| @@ -154,8 +154,8 @@ uint32_t RecoverKernelSpace(void) { | 
| KERNEL_SPACE_SIZE)); | 
| RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_VERSIONS_NV_INDEX, &perms)); | 
| if (perms != TPM_NV_PER_PPWRITE || | 
| -      !Memcmp(buffer + sizeof(uint32_t), KERNEL_SPACE_UID, | 
| -              KERNEL_SPACE_UID_SIZE)) { | 
| +      Memcmp(buffer + sizeof(uint32_t), KERNEL_SPACE_UID, | 
| +              KERNEL_SPACE_UID_SIZE) != 0) { | 
| return TPM_E_CORRUPTED_STATE; | 
| } | 
|  | 
| @@ -233,6 +233,7 @@ static uint32_t SetupTPM(int recovery_mode, | 
| int developer_mode) { | 
| uint8_t disable; | 
| uint8_t deactivated; | 
| +  uint32_t result; | 
|  | 
| TlclLibInit(); | 
| RETURN_ON_FAILURE(TlclStartup()); | 
| @@ -245,14 +246,15 @@ static uint32_t SetupTPM(int recovery_mode, | 
| RETURN_ON_FAILURE(TlclSetDeactivated(0)); | 
| return TPM_E_MUST_REBOOT; | 
| } | 
| -  /* We expect this to fail the first time we run on a device, because the TPM | 
| -   * has not been initialized yet. | 
| -   */ | 
| -  if (RecoverKernelSpace() != TPM_SUCCESS) { | 
| +  result = RecoverKernelSpace(); | 
| +  if (result != TPM_SUCCESS) { | 
| +     /* Check if this is the first time we run and the TPM has not been | 
| +      * initialized yet. | 
| +      */ | 
| int initialized = 0; | 
| RETURN_ON_FAILURE(GetSpacesInitialized(&initialized)); | 
| if (initialized) { | 
| -      return TPM_E_ALREADY_INITIALIZED; | 
| +      return result; | 
| } else { | 
| RETURN_ON_FAILURE(InitializeSpaces()); | 
| RETURN_ON_FAILURE(RecoverKernelSpace()); | 
| @@ -299,7 +301,7 @@ uint32_t RollbackFirmwareLock(void) { | 
| } | 
|  | 
| uint32_t RollbackKernelRecovery(int developer_mode) { | 
| -  (void) SetupTPM(1, developer_mode); | 
| +  uint32_t result = SetupTPM(1, developer_mode); | 
| /* In recovery mode we ignore TPM malfunctions or corruptions, and leave the | 
| * TPM completely unlocked if and only if the dev mode switch is ON.  The | 
| * recovery kernel will fix the TPM (if needed) and lock it ASAP.  We leave | 
| @@ -308,7 +310,10 @@ uint32_t RollbackKernelRecovery(int developer_mode) { | 
| if (!developer_mode) { | 
| RETURN_ON_FAILURE(TlclSetGlobalLock()); | 
| } | 
| -  return TPM_SUCCESS; | 
| +  /* We still return the result of SetupTPM even though we expect the caller to | 
| +   * ignore it.  It's useful in unit testing. | 
| +   */ | 
| +  return result; | 
| } | 
|  | 
| uint32_t RollbackKernelRead(uint16_t* key_version, uint16_t* version) { | 
|  |