Add error handling for TPM in S3 resume failure.

If TPM2_Startup(TPM_SU_STATE) to return an error, the system
 firmware that resumes from S3 MUST deal with a TPM2_Startup
 error appropriately.
For example, issuing a TPM2_Startup(TPM_SU_CLEAR) command and
 configuring the device securely by taking actions like extending
 a separator with an error digest (0x01) into PCRs 0 through 7.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: "Yao, Jiewen" <jiewen.yao@intel.com>
Reviewed-by: "Zhang, Chao B" <chao.b.zhang@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18760 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Yao, Jiewen 2015-11-10 02:03:40 +00:00 committed by jyao1
parent 07c707858d
commit c2fe66bf62
1 changed files with 50 additions and 0 deletions

View File

@ -828,6 +828,33 @@ PeimEntryMP (
return Status; return Status;
} }
/**
Measure and log Separator event with error, and extend the measurement result into a specific PCR.
@param[in] PCRIndex PCR index.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
**/
EFI_STATUS
MeasureSeparatorEventWithError (
IN TPM_PCRINDEX PCRIndex
)
{
TCG_PCR_EVENT_HDR TcgEvent;
UINT32 EventData;
//
// Use EventData 0x1 to indicate there is error.
//
EventData = 0x1;
TcgEvent.PCRIndex = PCRIndex;
TcgEvent.EventType = EV_SEPARATOR;
TcgEvent.EventSize = (UINT32)sizeof (EventData);
return HashLogExtendEvent(0,(UINT8 *)&EventData, TcgEvent.EventSize, &TcgEvent,(UINT8 *)&EventData);
}
/** /**
Entry point of this module. Entry point of this module.
@ -847,6 +874,8 @@ PeimEntryMA (
EFI_STATUS Status; EFI_STATUS Status;
EFI_STATUS Status2; EFI_STATUS Status2;
EFI_BOOT_MODE BootMode; EFI_BOOT_MODE BootMode;
TPM_PCRINDEX PcrIndex;
BOOLEAN S3ErrorReport;
if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) || if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||
CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){ CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
@ -885,11 +914,15 @@ PeimEntryMA (
goto Done; goto Done;
} }
S3ErrorReport = FALSE;
if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) { if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) {
if (BootMode == BOOT_ON_S3_RESUME) { if (BootMode == BOOT_ON_S3_RESUME) {
Status = Tpm2Startup (TPM_SU_STATE); Status = Tpm2Startup (TPM_SU_STATE);
if (EFI_ERROR (Status) ) { if (EFI_ERROR (Status) ) {
Status = Tpm2Startup (TPM_SU_CLEAR); Status = Tpm2Startup (TPM_SU_CLEAR);
if (!EFI_ERROR(Status)) {
S3ErrorReport = TRUE;
}
} }
} else { } else {
Status = Tpm2Startup (TPM_SU_CLEAR); Status = Tpm2Startup (TPM_SU_CLEAR);
@ -903,6 +936,23 @@ PeimEntryMA (
// Update Tpm2HashMask according to PCR bank. // Update Tpm2HashMask according to PCR bank.
// //
SetTpm2HashMask (); SetTpm2HashMask ();
if (S3ErrorReport) {
//
// The system firmware that resumes from S3 MUST deal with a
// TPM2_Startup error appropriately.
// For example, issue a TPM2_Startup(TPM_SU_CLEAR) command and
// configuring the device securely by taking actions like extending a
// separator with an error digest (0x01) into PCRs 0 through 7.
//
for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {
Status = MeasureSeparatorEventWithError (PcrIndex);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "Separator Event with Error not Measured. Error!\n"));
}
}
}
// //
// TpmSelfTest is optional on S3 path, skip it to save S3 time // TpmSelfTest is optional on S3 path, skip it to save S3 time
// //