Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 51 additions & 11 deletions SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ typedef struct {

typedef struct _TCG_DXE_DATA {
EFI_TCG2_BOOT_SERVICE_CAPABILITY BsCap;
BOOLEAN TpmUpdateFlag;
TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX];
BOOLEAN GetEventLogCalled[TCG_EVENT_LOG_AREA_COUNT_MAX];
TCG_EVENT_LOG_AREA_STRUCT FinalEventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX];
Expand All @@ -101,6 +102,7 @@ TCG_DXE_DATA mTcgDxeData = {
0, // NumberOfPCRBanks
0, // ActivePcrBanks
},
FALSE,
};

UINTN mBootAttempts = 0;
Expand Down Expand Up @@ -1407,6 +1409,8 @@ Tcg2SubmitCommand (
)
{
EFI_STATUS Status;
TPM_RC ResponseCode;
UINT32 CurrentOutputBlockSize;

if ((This == NULL) ||
(InputParameterBlockSize == 0) || (InputParameterBlock == NULL) ||
Expand All @@ -1415,10 +1419,6 @@ Tcg2SubmitCommand (
return EFI_INVALID_PARAMETER;
}

if (!mTcgDxeData.BsCap.TPMPresentFlag) {
return EFI_DEVICE_ERROR;
}

if (InputParameterBlockSize > mTcgDxeData.BsCap.MaxCommandSize) {
return EFI_INVALID_PARAMETER;
}
Expand All @@ -1427,13 +1427,53 @@ Tcg2SubmitCommand (
return EFI_INVALID_PARAMETER;
}

Status = Tpm2SubmitCommand (
InputParameterBlockSize,
InputParameterBlock,
&OutputParameterBlockSize,
OutputParameterBlock
);
return Status;
//
// Always attempt to submit the command, but if the TPM is already flagged
// as not present, we expect it to fail other than the capsule update scenario.
//
CurrentOutputBlockSize = OutputParameterBlockSize;
Status = Tpm2SubmitCommand (
InputParameterBlockSize,
InputParameterBlock,
&CurrentOutputBlockSize,
OutputParameterBlock
);
if (EFI_ERROR (Status)) {
return mTcgDxeData.BsCap.TPMPresentFlag ? Status : EFI_DEVICE_ERROR;
}

if (CurrentOutputBlockSize < sizeof (TPM2_RESPONSE_HEADER)) {
DEBUG ((DEBUG_ERROR, "%a: Response buffer too small!\n", __func__));
return EFI_DEVICE_ERROR;
}

//
// Correctly read the response code and swap bytes from Big-Endian to Host order.
// The responseCode field is at offset 6 of the response header.
//
ResponseCode = SwapBytes32 (ReadUnaligned32 ((UINT32 *)(OutputParameterBlock + 6)));
DEBUG ((DEBUG_ERROR, "Response code is %x", ResponseCode));
// If the response code ever equals to TPM_RC_UPGRADE, it means the TPM is in field
// upgrade mode, we set both flags to TRUE.
if (ResponseCode == TPM_RC_UPGRADE) {
DEBUG ((DEBUG_INFO, "TPM response code TPM_RC_UPDATE received. Setting flag.\n"));
mTcgDxeData.TpmUpdateFlag = TRUE;
mTcgDxeData.BsCap.TPMPresentFlag = TRUE;
}

// Now that we have set the TPMPresentFlag, it should be able to reflect the actual TPM presence.
if (!mTcgDxeData.BsCap.TPMPresentFlag) {
DEBUG ((DEBUG_WARN, "%a: TPMPresentFlag is FALSE. Expecting command to fail.\n", __func__));
return EFI_DEVICE_ERROR;
}

// If the response code is not TPM_RC_SUCCESS and the device is not in field update mode, return error.
if ((ResponseCode != TPM_RC_SUCCESS) && (mTcgDxeData.TpmUpdateFlag == FALSE)) {
DEBUG ((DEBUG_ERROR, "%a: Command failed with response code 0x%x\n", __func__, ResponseCode));
return EFI_DEVICE_ERROR;
}

return EFI_SUCCESS;
}

/**
Expand Down
Loading