TBR: reviewed in person with semenzato
diff --git a/firmware/include/load_firmware_fw.h b/firmware/include/load_firmware_fw.h
index 6bdcc6a..e377766 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 @@
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 f8f78a1..0e630db 100644
--- a/firmware/lib/include/rollback_index.h
+++ b/firmware/lib/include/rollback_index.h
@@ -83,6 +83,10 @@
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 0d9b23c..931e819 100644
--- a/firmware/lib/rollback_index.c
+++ b/firmware/lib/rollback_index.c
@@ -256,6 +256,17 @@
/* 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 @@
}
#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 @@
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 6475adb..d1d2f22 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 39c92e6..cc0c373 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 ac16246..4a0c74a 100644
--- a/firmware/lib/vboot_firmware.c
+++ b/firmware/lib/vboot_firmware.c
@@ -64,7 +64,7 @@
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 @@
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 @@
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 @@
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 daa4247..fbf4a2f 100644
--- a/firmware/linktest/main.c
+++ b/firmware/linktest/main.c
@@ -27,6 +27,7 @@
LoadKernel(0);
/* rollback_index.h */
+ RollbackS3Resume();
RollbackFirmwareSetup(0, 0);
RollbackFirmwareWrite(0);
RollbackFirmwareLock();
@@ -40,6 +41,7 @@
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 6df8464..a302dcc 100644
--- a/firmware/stub/tpm_lite_stub.c
+++ b/firmware/stub/tpm_lite_stub.c
@@ -22,7 +22,6 @@
#include <sys/stat.h>
#include <unistd.h>
-#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 85a841d..551bdcf 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