diff --git a/firmware/include/load_firmware_fw.h b/firmware/include/load_firmware_fw.h index 6bdcc6a93d..e377766027 100644 --- a/firmware/include/load_firmware_fw.h +++ b/firmware/include/load_firmware_fw.h @@ -16,10 +16,12 @@ * boot phases */ #define LOAD_FIRMWARE_KEY_BLOB_REC_SIZE 2104 -/* Return codes for LoadFirmware() */ +/* Return codes for LoadFirmware() and S3Resume(). */ #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 */ +#define LOAD_FIRMWARE_RECOVERY_TPM 3 /* Reboot to recovery mode due + * to TPM error */ /* Boot flags for LoadFirmware().boot_flags */ #define BOOT_FLAG_DEVELOPER UINT64_C(0x01) /* Developer switch is on */ @@ -85,7 +87,9 @@ int LoadFirmware(LoadFirmwareParams* params); void UpdateFirmwareBodyHash(LoadFirmwareParams* params, uint8_t* data, uint64_t size); - - +/* Handle S3 resume. + * + * Returns LOAD_FIRMWARE_SUCCESS if successful, error code on failure. */ +int S3Resume(void); #endif /* VBOOT_REFERENCE_LOAD_FIRMWARE_FW_H_ */ diff --git a/firmware/lib/include/rollback_index.h b/firmware/lib/include/rollback_index.h index f8f78a185f..0e630dbb8c 100644 --- a/firmware/lib/include/rollback_index.h +++ b/firmware/lib/include/rollback_index.h @@ -83,6 +83,10 @@ Call from LoadKernel() Must send in developer and recovery flags */ +/* These functions are called from S3Resume(). They cannot use + * global variables. */ +uint32_t RollbackS3Resume(void); + /* These functions are callable from LoadFirmware(). They cannot use * global variables. */ diff --git a/firmware/lib/rollback_index.c b/firmware/lib/rollback_index.c index 0d9b23c9ce..931e819eda 100644 --- a/firmware/lib/rollback_index.c +++ b/firmware/lib/rollback_index.c @@ -256,6 +256,17 @@ __pragma(warning (disable: 4100)) /* Dummy implementations which don't support TPM rollback protection */ +uint32_t RollbackS3Resume(void) { +#ifndef CHROMEOS_ENVIRONMENT + /* Initialize the TPM, but ignore return codes. In ChromeOS + * environment, don't even talk to the TPM. */ + TlclLibInit(); + TlclResume(); + TlclSelfTestFull(); +#endif + return TPM_SUCCESS; +} + uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) { #ifndef CHROMEOS_ENVIRONMENT /* Initializes the TPM, but ignores return codes. In ChromeOS @@ -302,6 +313,22 @@ uint32_t RollbackKernelLock(void) { } #else + +uint32_t RollbackS3Resume(void) { + TlclLibInit(); + RETURN_ON_FAILURE(TlclResume()); +#ifdef USE_CONTINUE_SELF_TEST + /* TODO: ContinueSelfTest() should be faster than SelfTestFull, but + * may also not work properly in older TPM firmware. For now, do + * the full self test. */ + RETURN_ON_FAILURE(TlclContinueSelfTest()); +#else + RETURN_ON_FAILURE(TlclSelfTestFull()); +#endif + return TPM_SUCCESS; +} + + uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) { RollbackSpaceFirmware rsf; uint8_t out_digest[20]; /* For PCR extend output */ @@ -316,7 +343,7 @@ uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) { RETURN_ON_FAILURE(TlclExtend(DEV_MODE_PCR, DEV_MODE_OFF_SHA1_DIGEST, out_digest)); VBDEBUG(("TPM: RollbackFirmwareSetup dev mode PCR out_digest %02x %02x %02x " - "%02x", out_digest, out_digest+1, out_digest+2, out_digest+3)); + "%02x\n", out_digest, out_digest+1, out_digest+2, out_digest+3)); return TPM_SUCCESS; } diff --git a/firmware/lib/tpm_lite/include/tss_constants.h b/firmware/lib/tpm_lite/include/tss_constants.h index 6475adb27e..d1d2f22f3d 100644 --- a/firmware/lib/tpm_lite/include/tss_constants.h +++ b/firmware/lib/tpm_lite/include/tss_constants.h @@ -13,6 +13,7 @@ #define TPM_MAX_COMMAND_SIZE 4096 #define TPM_LARGE_ENOUGH_COMMAND_SIZE 256 /* saves space in the firmware */ +#define TPM_PUBEK_SIZE 256 #define TPM_E_NON_FATAL 0x800 diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c index 39c92e6f9b..cc0c373af6 100644 --- a/firmware/lib/tpm_lite/tlcl.c +++ b/firmware/lib/tpm_lite/tlcl.c @@ -18,7 +18,6 @@ #include "tlcl.h" #include "tlcl_internal.h" #include "tlcl_structures.h" -#include "tpmextras.h" #include "utility.h" /* Sets the size field of a TPM command. */ diff --git a/firmware/lib/vboot_firmware.c b/firmware/lib/vboot_firmware.c index ac162467ce..4a0c74a5e4 100644 --- a/firmware/lib/vboot_firmware.c +++ b/firmware/lib/vboot_firmware.c @@ -64,7 +64,7 @@ int LoadFirmware(LoadFirmwareParams* params) { if (0 != status) { VBDEBUG(("Unable to setup TPM and read stored versions.\n")); return (status == TPM_E_MUST_REBOOT ? - LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY); + LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY_TPM); } /* Allocate our internal data */ @@ -214,7 +214,7 @@ int LoadFirmware(LoadFirmwareParams* params) { if (0 != status) { VBDEBUG(("Unable to write stored versions.\n")); return (status == TPM_E_MUST_REBOOT ? - LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY); + LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY_TPM); } } @@ -223,7 +223,7 @@ int LoadFirmware(LoadFirmwareParams* params) { if (0 != status) { VBDEBUG(("Unable to lock firmware versions.\n")); return (status == TPM_E_MUST_REBOOT ? - LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY); + LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY_TPM); } /* Success */ @@ -235,3 +235,16 @@ int LoadFirmware(LoadFirmwareParams* params) { VBDEBUG(("Alas, no good firmware.\n")); return LOAD_FIRMWARE_RECOVERY; } + + +int S3Resume(void) { + /* Resume the TPM */ + uint32_t status = RollbackS3Resume(); + + if (status == TPM_SUCCESS) + return LOAD_FIRMWARE_SUCCESS; + else if (status == TPM_E_MUST_REBOOT) + return LOAD_FIRMWARE_REBOOT; + else + return LOAD_FIRMWARE_RECOVERY_TPM; +} diff --git a/firmware/linktest/main.c b/firmware/linktest/main.c index daa424727c..fbf4a2f56d 100644 --- a/firmware/linktest/main.c +++ b/firmware/linktest/main.c @@ -27,6 +27,7 @@ int main(void) LoadKernel(0); /* rollback_index.h */ + RollbackS3Resume(); RollbackFirmwareSetup(0, 0); RollbackFirmwareWrite(0); RollbackFirmwareLock(); @@ -40,6 +41,7 @@ int main(void) TlclCloseDevice(); TlclOpenDevice(); TlclStartup(); + TlclResume(); TlclSelfTestFull(); TlclContinueSelfTest(); TlclDefineSpace(0, 0, 0); diff --git a/firmware/stub/tpm_lite_stub.c b/firmware/stub/tpm_lite_stub.c index 6df84645b3..a302dccee7 100644 --- a/firmware/stub/tpm_lite_stub.c +++ b/firmware/stub/tpm_lite_stub.c @@ -22,7 +22,6 @@ #include #include -#include "tpmextras.h" #define TPM_DEVICE_PATH "/dev/tpm0" /* TODO: these functions should pass errors back rather than returning void */ diff --git a/firmware/version.c b/firmware/version.c index 85a841d063..551bdcf854 100644 --- a/firmware/version.c +++ b/firmware/version.c @@ -1 +1 @@ -char* VbootVersion = "VBOOv=fc764233"; +char* VbootVersion = "VBOOv=54e1e8b5"; diff --git a/firmware/stub/include/tpmextras.h b/utility/include/tpmextras.h similarity index 100% rename from firmware/stub/include/tpmextras.h rename to utility/include/tpmextras.h