X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=SecurityPkg%2FTcg%2FTcg2Dxe%2FTcg2Dxe.c;h=85f2e0ae3809efd6ba412061b18db619aca7f997;hb=a7e2d20193e853020a1415c25b53280955055394;hp=f0dbbac5b1dd5fb7ce12936803e4c37ef2324c4a;hpb=91e914f5876f35317638771103f64baf903a9bfc;p=mirror_edk2.git
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
index f0dbbac5b1..85f2e0ae38 100644
--- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
+++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
@@ -1,14 +1,9 @@
/** @file
This module implements Tcg2 Protocol.
-
-Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -30,6 +25,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include
#include
#include
+#include
#include
#include
@@ -126,6 +122,8 @@ EFI_HANDLE mImageHandle;
PE/COFF image is external input, so this function will validate its data structure
within this image buffer before use.
+ Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().
+
@param[in] PCRIndex TPM PCR index
@param[in] ImageAddress Start address of image buffer.
@param[in] ImageSize Image size
@@ -163,6 +161,82 @@ InternalDumpData (
}
}
+/**
+
+ This function initialize TCG_PCR_EVENT2_HDR for EV_NO_ACTION Event Type other than EFI Specification ID event
+ The behavior is defined by TCG PC Client PFP Spec. Section 9.3.4 EV_NO_ACTION Event Types
+
+ @param[in, out] NoActionEvent Event Header of EV_NO_ACTION Event
+ @param[in] EventSize Event Size of the EV_NO_ACTION Event
+
+**/
+VOID
+InitNoActionEvent (
+ IN OUT TCG_PCR_EVENT2_HDR *NoActionEvent,
+ IN UINT32 EventSize
+ )
+{
+ UINT32 DigestListCount;
+ TPMI_ALG_HASH HashAlgId;
+ UINT8 *DigestBuffer;
+
+ DigestBuffer = (UINT8 *)NoActionEvent->Digests.digests;
+ DigestListCount = 0;
+
+ NoActionEvent->PCRIndex = 0;
+ NoActionEvent->EventType = EV_NO_ACTION;
+
+ //
+ // Set Hash count & hashAlg accordingly, while Digest.digests[n].digest to all 0
+ //
+ ZeroMem (&NoActionEvent->Digests, sizeof(NoActionEvent->Digests));
+
+ if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {
+ HashAlgId = TPM_ALG_SHA1;
+ CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));
+ DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);
+ DigestListCount++;
+ }
+
+ if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {
+ HashAlgId = TPM_ALG_SHA256;
+ CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));
+ DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);
+ DigestListCount++;
+ }
+
+ if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {
+ HashAlgId = TPM_ALG_SHA384;
+ CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));
+ DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);
+ DigestListCount++;
+ }
+
+ if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {
+ HashAlgId = TPM_ALG_SHA512;
+ CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));
+ DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);
+ DigestListCount++;
+ }
+
+ if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {
+ HashAlgId = TPM_ALG_SM3_256;
+ CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));
+ DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);
+ DigestListCount++;
+ }
+
+ //
+ // Set Digests Count
+ //
+ WriteUnaligned32 ((UINT32 *)&NoActionEvent->Digests.count, DigestListCount);
+
+ //
+ // Set Event Size
+ //
+ WriteUnaligned32((UINT32 *)DigestBuffer, EventSize);
+}
+
/**
This function dump raw data with colume format.
@@ -198,33 +272,6 @@ InternalDumpHex (
}
}
-/**
- Check if buffer is all zero.
-
- @param[in] Buffer Buffer to be checked.
- @param[in] BufferSize Size of buffer to be checked.
-
- @retval TRUE Buffer is all zero.
- @retval FALSE Buffer is not all zero.
-**/
-BOOLEAN
-IsZeroBuffer (
- IN VOID *Buffer,
- IN UINTN BufferSize
- )
-{
- UINT8 *BufferData;
- UINTN Index;
-
- BufferData = Buffer;
- for (Index = 0; Index < BufferSize; Index++) {
- if (BufferData[Index] != 0) {
- return FALSE;
- }
- }
- return TRUE;
-}
-
/**
Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
Caller is responsible to free LocationBuf.
@@ -319,11 +366,11 @@ GetProcessorsCpuLocation (
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
- The ProtocolCapability variable will not be populated.
+ The ProtocolCapability variable will not be populated.
@retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
The ProtocolCapability variable will not be populated.
@retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.
- It will be partially populated (required Size field will be set).
+ It will be partially populated (required Size field will be set).
**/
EFI_STATUS
EFIAPI
@@ -332,20 +379,20 @@ Tcg2GetCapability (
IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability
)
{
- DEBUG ((EFI_D_INFO, "Tcg2GetCapability ...\n"));
+ DEBUG ((DEBUG_VERBOSE, "Tcg2GetCapability ...\n"));
if ((This == NULL) || (ProtocolCapability == NULL)) {
return EFI_INVALID_PARAMETER;
}
-
- DEBUG ((EFI_D_INFO, "Size - 0x%x\n", ProtocolCapability->Size));
- DEBUG ((EFI_D_INFO, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY), sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)));
+
+ DEBUG ((DEBUG_VERBOSE, "Size - 0x%x\n", ProtocolCapability->Size));
+ DEBUG ((DEBUG_VERBOSE, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY), sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)));
if (ProtocolCapability->Size < mTcgDxeData.BsCap.Size) {
//
// Handle the case that firmware support 1.1 but OS only support 1.0.
//
- if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) ||
+ if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) ||
((mTcgDxeData.BsCap.ProtocolVersion.Major == 0x01) && ((mTcgDxeData.BsCap.ProtocolVersion.Minor > 0x00)))) {
if (ProtocolCapability->Size >= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)) {
CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0));
@@ -363,7 +410,7 @@ Tcg2GetCapability (
}
CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, mTcgDxeData.BsCap.Size);
- DEBUG ((EFI_D_INFO, "Tcg2GetCapability - %r\n", EFI_SUCCESS));
+ DEBUG ((DEBUG_VERBOSE, "Tcg2GetCapability - %r\n", EFI_SUCCESS));
return EFI_SUCCESS;
}
@@ -510,7 +557,7 @@ DumpEvent2 (
/**
This function returns size of TCG PCR event 2.
-
+
@param[in] TcgPcrEvent2 TCG PCR event 2 structure.
@return size of TCG PCR event 2.
@@ -570,7 +617,7 @@ DumpEventLog (
UINTN NumberOfEvents;
DEBUG ((EFI_D_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));
-
+
switch (EventLogFormat) {
case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;
@@ -594,7 +641,7 @@ DumpEventLog (
break;
case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:
//
- // Dump first event
+ // Dump first event
//
EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;
DumpEvent (EventHdr);
@@ -629,7 +676,7 @@ DumpEventLog (
/**
The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to
- retrieve the address of a given event log and its last entry.
+ retrieve the address of a given event log and its last entry.
@param[in] This Indicates the calling context
@param[in] EventLogFormat The type of the event log for which the information is requested.
@@ -727,14 +774,14 @@ Tcg2GetEventLog (
/**
Add a new entry to the Event Log.
- @param[in, out] EventLogPtr Pointer to the Event Log data.
- @param[in, out] LogSize Size of the Event Log.
+ @param[in, out] EventLogPtr Pointer to the Event Log data.
+ @param[in, out] LogSize Size of the Event Log.
@param[in] MaxSize Maximum size of the Event Log.
- @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
+ @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
@param[in] NewEventHdrSize New event header size.
- @param[in] NewEventData Pointer to the new event data.
+ @param[in] NewEventData Pointer to the new event data.
@param[in] NewEventSize New event data size.
-
+
@retval EFI_SUCCESS The new event log entry was added.
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
@@ -785,9 +832,9 @@ TcgCommLogEvent (
Add a new entry to the Event Log.
@param[in] EventLogFormat The type of the event log for which the information is requested.
- @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
+ @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
@param[in] NewEventHdrSize New event header size.
- @param[in] NewEventData Pointer to the new event data.
+ @param[in] NewEventData Pointer to the new event data.
@param[in] NewEventSize New event data size.
@retval EFI_SUCCESS The new event log entry was added.
@@ -806,7 +853,7 @@ TcgDxeLogEvent (
EFI_STATUS Status;
UINTN Index;
TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct;
-
+
for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {
break;
@@ -817,11 +864,10 @@ TcgDxeLogEvent (
return EFI_INVALID_PARAMETER;
}
- if (!mTcgDxeData.GetEventLogCalled[Index]) {
- EventLogAreaStruct = &mTcgDxeData.EventLogAreaStruct[Index];
- } else {
- EventLogAreaStruct = &mTcgDxeData.FinalEventLogAreaStruct[Index];
- }
+ //
+ // Record to normal event log
+ //
+ EventLogAreaStruct = &mTcgDxeData.EventLogAreaStruct[Index];
if (EventLogAreaStruct->EventLogTruncated) {
return EFI_VOLUME_FULL;
@@ -837,80 +883,55 @@ TcgDxeLogEvent (
NewEventData,
NewEventSize
);
-
- if (Status == EFI_DEVICE_ERROR) {
- return EFI_DEVICE_ERROR;
- } else if (Status == EFI_OUT_OF_RESOURCES) {
+
+ if (Status == EFI_OUT_OF_RESOURCES) {
EventLogAreaStruct->EventLogTruncated = TRUE;
return EFI_VOLUME_FULL;
} else if (Status == EFI_SUCCESS) {
EventLogAreaStruct->EventLogStarted = TRUE;
- if (mTcgDxeData.GetEventLogCalled[Index]) {
- (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents ++;
- }
}
- return Status;
-}
-
-/**
- This function get digest from digest list.
-
- @param HashAlg digest algorithm
- @param DigestList digest list
- @param Digest digest
-
- @retval EFI_SUCCESS Sha1Digest is found and returned.
- @retval EFI_NOT_FOUND Sha1Digest is not found.
-**/
-EFI_STATUS
-Tpm2GetDigestFromDigestList (
- IN TPMI_ALG_HASH HashAlg,
- IN TPML_DIGEST_VALUES *DigestList,
- IN VOID *Digest
- )
-{
- UINTN Index;
- UINT16 DigestSize;
-
- DigestSize = GetHashSizeFromAlgo (HashAlg);
- for (Index = 0; Index < DigestList->count; Index++) {
- if (DigestList->digests[Index].hashAlg == HashAlg) {
- CopyMem (
- Digest,
- &DigestList->digests[Index].digest,
- DigestSize
- );
+ //
+ // If GetEventLog is called, record to FinalEventsTable, too.
+ //
+ if (mTcgDxeData.GetEventLogCalled[Index]) {
+ if (mTcgDxeData.FinalEventsTable[Index] == NULL) {
+ //
+ // no need for FinalEventsTable
+ //
return EFI_SUCCESS;
}
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Get TPML_DIGEST_VALUES data size.
-
- @param[in] DigestList TPML_DIGEST_VALUES data.
+ EventLogAreaStruct = &mTcgDxeData.FinalEventLogAreaStruct[Index];
- @return TPML_DIGEST_VALUES data size.
-**/
-UINT32
-GetDigestListSize (
- IN TPML_DIGEST_VALUES *DigestList
- )
-{
- UINTN Index;
- UINT16 DigestSize;
- UINT32 TotalSize;
+ if (EventLogAreaStruct->EventLogTruncated) {
+ return EFI_VOLUME_FULL;
+ }
- TotalSize = sizeof(DigestList->count);
- for (Index = 0; Index < DigestList->count; Index++) {
- DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);
- TotalSize += sizeof(DigestList->digests[Index].hashAlg) + DigestSize;
+ EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;
+ Status = TcgCommLogEvent (
+ &EventLogAreaStruct->LastEvent,
+ &EventLogAreaStruct->EventLogSize,
+ (UINTN)EventLogAreaStruct->Laml,
+ NewEventHdr,
+ NewEventHdrSize,
+ NewEventData,
+ NewEventSize
+ );
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ EventLogAreaStruct->EventLogTruncated = TRUE;
+ return EFI_VOLUME_FULL;
+ } else if (Status == EFI_SUCCESS) {
+ EventLogAreaStruct->EventLogStarted = TRUE;
+ //
+ // Increase the NumberOfEvents in FinalEventsTable
+ //
+ (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents ++;
+ DEBUG ((EFI_D_INFO, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents));
+ DEBUG ((EFI_D_INFO, " Size - 0x%x\n", (UINTN)EventLogAreaStruct->EventLogSize));
+ }
}
- return TotalSize;
+ return Status;
}
/**
@@ -948,79 +969,55 @@ GetDigestListBinSize (
}
/**
- Return if hash alg is supported in TPM PCR bank.
+ Copy TPML_DIGEST_VALUES compact binary into a buffer
- @param HashAlg Hash algorithm to be checked.
+ @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.
+ @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
+ @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.
+ @param[out] HashAlgorithmMaskCopied Pointer to HASH bits corresponding to the digests copied.
- @retval TRUE Hash algorithm is supported.
- @retval FALSE Hash algorithm is not supported.
+ @return The end of buffer to hold TPML_DIGEST_VALUES compact binary.
**/
-BOOLEAN
-IsHashAlgSupportedInPcrBank (
- IN TPMI_ALG_HASH HashAlg
+VOID *
+CopyDigestListBinToBuffer (
+ IN OUT VOID *Buffer,
+ IN VOID *DigestListBin,
+ IN UINT32 HashAlgorithmMask,
+ OUT UINT32 *HashAlgorithmMaskCopied
)
{
- switch (HashAlg) {
- case TPM_ALG_SHA1:
- if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {
- return TRUE;
- }
- break;
- case TPM_ALG_SHA256:
- if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {
- return TRUE;
- }
- break;
- case TPM_ALG_SHA384:
- if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {
- return TRUE;
- }
- break;
- case TPM_ALG_SHA512:
- if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {
- return TRUE;
- }
- break;
- case TPM_ALG_SM3_256:
- if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {
- return TRUE;
- }
- break;
- }
-
- return FALSE;
-}
+ UINTN Index;
+ UINT16 DigestSize;
+ UINT32 Count;
+ TPMI_ALG_HASH HashAlg;
+ UINT32 DigestListCount;
+ UINT32 *DigestListCountPtr;
-/**
- Copy TPML_DIGEST_VALUES into a buffer
+ DigestListCountPtr = (UINT32 *) Buffer;
+ DigestListCount = 0;
+ (*HashAlgorithmMaskCopied) = 0;
- @param[in,out] Buffer Buffer to hold TPML_DIGEST_VALUES.
- @param[in] DigestList TPML_DIGEST_VALUES to be copied.
+ Count = ReadUnaligned32 (DigestListBin);
+ Buffer = (UINT8 *)Buffer + sizeof(Count);
+ DigestListBin = (UINT8 *)DigestListBin + sizeof(Count);
+ for (Index = 0; Index < Count; Index++) {
+ HashAlg = ReadUnaligned16 (DigestListBin);
+ DigestListBin = (UINT8 *)DigestListBin + sizeof(HashAlg);
+ DigestSize = GetHashSizeFromAlgo (HashAlg);
- @return The end of buffer to hold TPML_DIGEST_VALUES.
-**/
-VOID *
-CopyDigestListToBuffer (
- IN OUT VOID *Buffer,
- IN TPML_DIGEST_VALUES *DigestList
- )
-{
- UINTN Index;
- UINT16 DigestSize;
-
- CopyMem (Buffer, &DigestList->count, sizeof(DigestList->count));
- Buffer = (UINT8 *)Buffer + sizeof(DigestList->count);
- for (Index = 0; Index < DigestList->count; Index++) {
- if (!IsHashAlgSupportedInPcrBank (DigestList->digests[Index].hashAlg)) {
- DEBUG ((EFI_D_ERROR, "WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0x%x)\n", DigestList->digests[Index].hashAlg));
- continue;
+ if (IsHashAlgSupportedInHashAlgorithmMask(HashAlg, HashAlgorithmMask)) {
+ CopyMem (Buffer, &HashAlg, sizeof(HashAlg));
+ Buffer = (UINT8 *)Buffer + sizeof(HashAlg);
+ CopyMem (Buffer, DigestListBin, DigestSize);
+ Buffer = (UINT8 *)Buffer + DigestSize;
+ DigestListCount++;
+ (*HashAlgorithmMaskCopied) |= GetHashMaskFromAlgo (HashAlg);
+ } else {
+ DEBUG ((DEBUG_ERROR, "WARNING: CopyDigestListBinToBuffer Event log has HashAlg unsupported by PCR bank (0x%x)\n", HashAlg));
}
- CopyMem (Buffer, &DigestList->digests[Index].hashAlg, sizeof(DigestList->digests[Index].hashAlg));
- Buffer = (UINT8 *)Buffer + sizeof(DigestList->digests[Index].hashAlg);
- DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);
- CopyMem (Buffer, &DigestList->digests[Index].digest, DigestSize);
- Buffer = (UINT8 *)Buffer + DigestSize;
+ DigestListBin = (UINT8 *)DigestListBin + DigestSize;
}
+ WriteUnaligned32 (DigestListCountPtr, DigestListCount);
return Buffer;
}
@@ -1048,6 +1045,7 @@ TcgDxeLogHashEvent (
EFI_STATUS RetStatus;
TCG_PCR_EVENT2 TcgPcrEvent2;
UINT8 *DigestBuffer;
+ UINT32 *EventSizePtr;
DEBUG ((EFI_D_INFO, "SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));
@@ -1057,7 +1055,7 @@ TcgDxeLogHashEvent (
DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));
switch (mTcg2EventInfo[Index].LogFormat) {
case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
- Status = Tpm2GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);
+ Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);
if (!EFI_ERROR (Status)) {
//
// Enter critical region
@@ -1084,9 +1082,8 @@ TcgDxeLogHashEvent (
TcgPcrEvent2.PCRIndex = NewEventHdr->PCRIndex;
TcgPcrEvent2.EventType = NewEventHdr->EventType;
DigestBuffer = (UINT8 *)&TcgPcrEvent2.Digest;
- DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList);
- CopyMem (DigestBuffer, &NewEventHdr->EventSize, sizeof(NewEventHdr->EventSize));
- DigestBuffer = DigestBuffer + sizeof(NewEventHdr->EventSize);
+ EventSizePtr = CopyDigestListToBuffer (DigestBuffer, DigestList, mTcgDxeData.BsCap.ActivePcrBanks);
+ CopyMem (EventSizePtr, &NewEventHdr->EventSize, sizeof(NewEventHdr->EventSize));
//
// Enter critical region
@@ -1095,7 +1092,7 @@ TcgDxeLogHashEvent (
Status = TcgDxeLogEvent (
mTcg2EventInfo[Index].LogFormat,
&TcgPcrEvent2,
- sizeof(TcgPcrEvent2.PCRIndex) + sizeof(TcgPcrEvent2.EventType) + GetDigestListSize (DigestList) + sizeof(TcgPcrEvent2.EventSize),
+ sizeof(TcgPcrEvent2.PCRIndex) + sizeof(TcgPcrEvent2.EventType) + GetDigestListBinSize (DigestBuffer) + sizeof(TcgPcrEvent2.EventSize),
NewEventData,
NewEventHdr->EventSize
);
@@ -1119,11 +1116,11 @@ TcgDxeLogHashEvent (
and add an entry to the Event Log.
@param[in] Flags Bitmap providing additional information.
- @param[in] HashData Physical address of the start of the data buffer
+ @param[in] HashData Physical address of the start of the data buffer
to be hashed, extended, and logged.
@param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
- @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
- @param[in] NewEventData Pointer to the new event data.
+ @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
+ @param[in] NewEventData Pointer to the new event data.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
@@ -1173,13 +1170,13 @@ TcgDxeHashLogExtendEvent (
/**
The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with
an opportunity to extend and optionally log events without requiring
- knowledge of actual TPM commands.
+ knowledge of actual TPM commands.
The extend operation will occur even if this function cannot create an event
- log entry (e.g. due to the event log being full).
+ log entry (e.g. due to the event log being full).
@param[in] This Indicates the calling context
@param[in] Flags Bitmap providing additional information.
- @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
+ @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
@param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
@param[in] Event Pointer to data buffer containing information about the event.
@@ -1203,7 +1200,7 @@ Tcg2HashLogExtendEvent (
TCG_PCR_EVENT_HDR NewEventHdr;
TPML_DIGEST_VALUES DigestList;
- DEBUG ((EFI_D_INFO, "Tcg2HashLogExtendEvent ...\n"));
+ DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent ...\n"));
if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) {
return EFI_INVALID_PARAMETER;
@@ -1253,7 +1250,7 @@ Tcg2HashLogExtendEvent (
Event->Event
);
}
- DEBUG ((EFI_D_INFO, "Tcg2HashLogExtendEvent - %r\n", Status));
+ DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent - %r\n", Status));
return Status;
}
@@ -1269,7 +1266,7 @@ Tcg2HashLogExtendEvent (
@retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
@retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
@retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
- @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
+ @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
**/
EFI_STATUS
EFIAPI
@@ -1295,10 +1292,10 @@ Tcg2SubmitCommand (
return EFI_DEVICE_ERROR;
}
- if (InputParameterBlockSize >= mTcgDxeData.BsCap.MaxCommandSize) {
+ if (InputParameterBlockSize > mTcgDxeData.BsCap.MaxCommandSize) {
return EFI_INVALID_PARAMETER;
}
- if (OutputParameterBlockSize >= mTcgDxeData.BsCap.MaxResponseSize) {
+ if (OutputParameterBlockSize > mTcgDxeData.BsCap.MaxResponseSize) {
return EFI_INVALID_PARAMETER;
}
@@ -1319,7 +1316,7 @@ Tcg2SubmitCommand (
@param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks.
@retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.
- @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
**/
EFI_STATUS
EFIAPI
@@ -1409,7 +1406,7 @@ Tcg2GetResultOfSetActivePcrBanks (
if ((OperationPresent == NULL) || (Response == NULL)) {
return EFI_INVALID_PARAMETER;
}
-
+
ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response);
if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) {
return EFI_SUCCESS;
@@ -1445,15 +1442,22 @@ SetupEventLog (
EFI_PEI_HOB_POINTERS GuidHob;
EFI_PHYSICAL_ADDRESS Lasa;
UINTN Index;
+ VOID *DigestListBin;
+ TPML_DIGEST_VALUES TempDigestListBin;
UINT32 DigestListBinSize;
+ UINT8 *Event;
UINT32 EventSize;
+ UINT32 *EventSizePtr;
+ UINT32 HashAlgorithmMaskCopied;
TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;
- UINT8 TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];
- TCG_PCR_EVENT_HDR FirstPcrEvent;
+ UINT8 TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];
+ TCG_PCR_EVENT_HDR SpecIdEvent;
+ TCG_PCR_EVENT2_HDR NoActionEvent;
TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;
UINT8 *VendorInfoSize;
UINT32 NumberOfAlgorithms;
+ TCG_EfiStartupLocalityEvent StartupLocalityEvent;
DEBUG ((EFI_D_INFO, "SetupEventLog\n"));
@@ -1463,20 +1467,39 @@ SetupEventLog (
for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
- Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiACPIMemoryNVS,
- EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
- &Lasa
- );
+ if (PcdGet8(PcdTpm2AcpiTableRev) >= 4) {
+ Status = gBS->AllocatePages (
+ AllocateAnyPages,
+ EfiACPIMemoryNVS,
+ EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
+ &Lasa
+ );
+ } else {
+ Status = gBS->AllocatePages (
+ AllocateAnyPages,
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
+ &Lasa
+ );
+ }
if (EFI_ERROR (Status)) {
return Status;
}
mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;
mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);
+
+ if ((PcdGet8(PcdTpm2AcpiTableRev) >= 4) ||
+ (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)) {
+ //
+ // Report TCG2 event log address and length, so that they can be reported in TPM2 ACPI table.
+ // Ignore the return status, because those fields are optional.
+ //
+ PcdSet32S(PcdTpm2AcpiTableLaml, (UINT32)mTcgDxeData.EventLogAreaStruct[Index].Laml);
+ PcdSet64S(PcdTpm2AcpiTableLasa, mTcgDxeData.EventLogAreaStruct[Index].Lasa);
+ }
+
//
- // To initialize them as 0xFF is recommended
+ // To initialize them as 0xFF is recommended
// because the OS can know the last entry for that.
//
SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);
@@ -1537,24 +1560,54 @@ SetupEventLog (
VendorInfoSize = (UINT8 *)TempDigestSize;
*VendorInfoSize = 0;
- //
- // FirstPcrEvent
- //
- FirstPcrEvent.PCRIndex = 0;
- FirstPcrEvent.EventType = EV_NO_ACTION;
- ZeroMem (&FirstPcrEvent.Digest, sizeof(FirstPcrEvent.Digest));
- FirstPcrEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);
+ SpecIdEvent.PCRIndex = 0;
+ SpecIdEvent.EventType = EV_NO_ACTION;
+ ZeroMem (&SpecIdEvent.Digest, sizeof(SpecIdEvent.Digest));
+ SpecIdEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);
//
- // Record
+ // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.
+ // TCG EFI Protocol Spec. Section 5.3 Event Log Header
+ // TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log
//
Status = TcgDxeLogEvent (
mTcg2EventInfo[Index].LogFormat,
- &FirstPcrEvent,
- sizeof(FirstPcrEvent),
+ &SpecIdEvent,
+ sizeof(SpecIdEvent),
(UINT8 *)TcgEfiSpecIdEventStruct,
- FirstPcrEvent.EventSize
+ SpecIdEvent.EventSize
);
+
+ //
+ // EfiStartupLocalityEvent. Event format is TCG_PCR_EVENT2
+ //
+ GuidHob.Guid = GetFirstGuidHob (&gTpm2StartupLocalityHobGuid);
+ if (GuidHob.Guid != NULL) {
+ //
+ // Get Locality Indicator from StartupLocality HOB
+ //
+ StartupLocalityEvent.StartupLocality = *(UINT8 *)(GET_GUID_HOB_DATA (GuidHob.Guid));
+ CopyMem (StartupLocalityEvent.Signature, TCG_EfiStartupLocalityEvent_SIGNATURE, sizeof(StartupLocalityEvent.Signature));
+ DEBUG ((DEBUG_INFO, "SetupEventLog: Set Locality from HOB into StartupLocalityEvent 0x%02x\n", StartupLocalityEvent.StartupLocality));
+
+ //
+ // Initialize StartupLocalityEvent
+ //
+ InitNoActionEvent(&NoActionEvent, sizeof(StartupLocalityEvent));
+
+ //
+ // Log EfiStartupLocalityEvent as the second Event
+ // TCG PC Client PFP spec. Section 9.3.4.3 Startup Locality Event
+ //
+ Status = TcgDxeLogEvent (
+ mTcg2EventInfo[Index].LogFormat,
+ &NoActionEvent,
+ sizeof(NoActionEvent.PCRIndex) + sizeof(NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof(NoActionEvent.EventSize),
+ (UINT8 *)&StartupLocalityEvent,
+ sizeof(StartupLocalityEvent)
+ );
+
+ }
}
}
}
@@ -1564,45 +1617,56 @@ SetupEventLog (
//
for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
- Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiACPIMemoryNVS,
- EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),
- &Lasa
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcg2FinalLogAreaLen), 0xFF);
+ if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {
+ Status = gBS->AllocatePages (
+ AllocateAnyPages,
+ EfiACPIMemoryNVS,
+ EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),
+ &Lasa
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcg2FinalLogAreaLen), 0xFF);
- //
- // Initialize
- //
- mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;
- (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;
- (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;
-
- mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
- mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);
- mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);
- mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
- mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;
- mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
- mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
+ //
+ // Initialize
+ //
+ mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;
+ (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;
+ (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;
+
+ mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
+ mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);
+ mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);
+ mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
+ mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;
+ mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
+ mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
- if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {
//
- // Install to configuration table
+ // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
//
- Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[1]);
+ Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);
if (EFI_ERROR (Status)) {
return Status;
}
+ } else {
+ //
+ // No need to handle EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
+ //
+ mTcgDxeData.FinalEventsTable[Index] = NULL;
+ mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
+ mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = 0;
+ mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = 0;
+ mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
+ mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = 0;
+ mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
+ mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
}
}
}
-
+
//
// 3. Sync data from PEI to DXE
//
@@ -1611,9 +1675,10 @@ SetupEventLog (
if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
GuidHob.Raw = GetHobList ();
Status = EFI_SUCCESS;
- while (!EFI_ERROR (Status) &&
+ while (!EFI_ERROR (Status) &&
(GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {
- TcgEvent = GET_GUID_HOB_DATA (GuidHob.Guid);
+ TcgEvent = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));
+ ASSERT (TcgEvent != NULL);
GuidHob.Raw = GET_NEXT_HOB (GuidHob);
switch (mTcg2EventInfo[Index].LogFormat) {
case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
@@ -1626,17 +1691,47 @@ SetupEventLog (
);
break;
case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:
- DigestListBinSize = GetDigestListBinSize ((UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE));
- CopyMem (&EventSize, (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize, sizeof(UINT32));
+ DigestListBin = (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE);
+ DigestListBinSize = GetDigestListBinSize (DigestListBin);
+ //
+ // Save event size.
+ //
+ CopyMem (&EventSize, (UINT8 *)DigestListBin + DigestListBinSize, sizeof(UINT32));
+ Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof(UINT32);
+ //
+ // Filter inactive digest in the event2 log from PEI HOB.
+ //
+ CopyMem (&TempDigestListBin, DigestListBin, GetDigestListBinSize (DigestListBin));
+ EventSizePtr = CopyDigestListBinToBuffer (
+ DigestListBin,
+ &TempDigestListBin,
+ mTcgDxeData.BsCap.ActivePcrBanks,
+ &HashAlgorithmMaskCopied
+ );
+ if (HashAlgorithmMaskCopied != mTcgDxeData.BsCap.ActivePcrBanks) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: The event2 log includes digest hash mask 0x%x, but required digest hash mask is 0x%x\n",
+ HashAlgorithmMaskCopied,
+ mTcgDxeData.BsCap.ActivePcrBanks
+ ));
+ }
+ //
+ // Restore event size.
+ //
+ CopyMem (EventSizePtr, &EventSize, sizeof(UINT32));
+ DigestListBinSize = GetDigestListBinSize (DigestListBin);
+
Status = TcgDxeLogEvent (
mTcg2EventInfo[Index].LogFormat,
TcgEvent,
sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),
- (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),
+ Event,
EventSize
);
break;
}
+ FreePool (TcgEvent);
}
}
}
@@ -1645,22 +1740,24 @@ SetupEventLog (
}
/**
- Measure and log an action string, and extend the measurement result into PCR[5].
+ Measure and log an action string, and extend the measurement result into PCR[PCRIndex].
+
+ @param[in] PCRIndex PCRIndex to extend
+ @param[in] String A specific string that indicates an Action event.
- @param[in] String A specific string that indicates an Action event.
-
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
**/
EFI_STATUS
TcgMeasureAction (
- IN CHAR8 *String
+ IN TPM_PCRINDEX PCRIndex,
+ IN CHAR8 *String
)
{
TCG_PCR_EVENT_HDR TcgEvent;
- TcgEvent.PCRIndex = 5;
+ TcgEvent.PCRIndex = PCRIndex;
TcgEvent.EventType = EV_EFI_ACTION;
TcgEvent.EventSize = (UINT32)AsciiStrLen (String);
return TcgDxeHashLogExtendEvent (
@@ -1695,7 +1792,7 @@ MeasureHandoffTables (
if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
//
- // Tcg Server spec.
+ // Tcg Server spec.
// Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
//
Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);
@@ -1727,7 +1824,7 @@ MeasureHandoffTables (
/**
Measure and log Separator event, and extend the measurement result into a specific PCR.
- @param[in] PCRIndex PCR index.
+ @param[in] PCRIndex PCR index.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
@@ -1759,13 +1856,13 @@ MeasureSeparatorEvent (
/**
Measure and log an EFI variable, and extend the measurement result into a specific PCR.
- @param[in] PCRIndex PCR Index.
- @param[in] EventType Event type.
+ @param[in] PCRIndex PCR Index.
+ @param[in] EventType Event type.
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.
@param[in] VendorGuid A unique identifier for the vendor.
- @param[in] VarData The content of the variable data.
- @param[in] VarSize The size of the variable data.
-
+ @param[in] VarData The content of the variable data.
+ @param[in] VarSize The size of the variable data.
+
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_OUT_OF_RESOURCES Out of memory.
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
@@ -1784,7 +1881,7 @@ MeasureVariable (
EFI_STATUS Status;
TCG_PCR_EVENT_HDR TcgEvent;
UINTN VarNameLength;
- EFI_VARIABLE_DATA_TREE *VarLog;
+ UEFI_VARIABLE_DATA *VarLog;
DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));
DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
@@ -1796,7 +1893,7 @@ MeasureVariable (
TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
- sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
- VarLog = (EFI_VARIABLE_DATA_TREE *)AllocatePool (TcgEvent.EventSize);
+ VarLog = (UEFI_VARIABLE_DATA *)AllocatePool (TcgEvent.EventSize);
if (VarLog == NULL) {
return EFI_OUT_OF_RESOURCES;
}
@@ -1819,7 +1916,7 @@ MeasureVariable (
if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
//
- // Digest is the event data (EFI_VARIABLE_DATA)
+ // Digest is the event data (UEFI_VARIABLE_DATA)
//
Status = TcgDxeHashLogExtendEvent (
0,
@@ -1829,6 +1926,7 @@ MeasureVariable (
(UINT8*)VarLog
);
} else {
+ ASSERT (VarData != NULL);
Status = TcgDxeHashLogExtendEvent (
0,
(UINT8*)VarData,
@@ -1844,13 +1942,13 @@ MeasureVariable (
/**
Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.
- @param[in] PCRIndex PCR Index.
- @param[in] EventType Event type.
+ @param[in] PCRIndex PCR Index.
+ @param[in] EventType Event type.
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.
@param[in] VendorGuid A unique identifier for the vendor.
- @param[out] VarSize The size of the variable data.
- @param[out] VarData Pointer to the content of the variable.
-
+ @param[out] VarSize The size of the variable data.
+ @param[out] VarData Pointer to the content of the variable.
+
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_OUT_OF_RESOURCES Out of memory.
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
@@ -1898,13 +1996,14 @@ ReadAndMeasureVariable (
}
/**
- Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
+ Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].
+according to TCG PC Client PFP spec 0021 Section 2.4.4.2
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.
@param[in] VendorGuid A unique identifier for the vendor.
- @param[out] VarSize The size of the variable data.
- @param[out] VarData Pointer to the content of the variable.
-
+ @param[out] VarSize The size of the variable data.
+ @param[out] VarData Pointer to the content of the variable.
+
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_OUT_OF_RESOURCES Out of memory.
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
@@ -1919,7 +2018,7 @@ ReadAndMeasureBootVariable (
)
{
return ReadAndMeasureVariable (
- 5,
+ 1,
EV_EFI_VARIABLE_BOOT,
VarName,
VendorGuid,
@@ -1933,9 +2032,9 @@ ReadAndMeasureBootVariable (
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.
@param[in] VendorGuid A unique identifier for the vendor.
- @param[out] VarSize The size of the variable data.
- @param[out] VarData Pointer to the content of the variable.
-
+ @param[out] VarSize The size of the variable data.
+ @param[out] VarData Pointer to the content of the variable.
+
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_OUT_OF_RESOURCES Out of memory.
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
@@ -2052,6 +2151,24 @@ MeasureAllSecureVariables (
}
}
+ //
+ // Measure DBT if present and not empty
+ //
+ Status = GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, &Data, &DataSize);
+ if (!EFI_ERROR(Status)) {
+ Status = MeasureVariable (
+ 7,
+ EV_EFI_VARIABLE_DRIVER_CONFIG,
+ EFI_IMAGE_SECURITY_DATABASE2,
+ &gEfiImageSecurityDatabaseGuid,
+ Data,
+ DataSize
+ );
+ FreePool(Data);
+ } else {
+ DEBUG((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2));
+ }
+
return EFI_SUCCESS;
}
@@ -2176,6 +2293,7 @@ OnReadyToBoot (
// 1. This is the first boot attempt.
//
Status = TcgMeasureAction (
+ 4,
EFI_CALLING_EFI_APPLICATION
);
if (EFI_ERROR (Status)) {
@@ -2189,7 +2307,7 @@ OnReadyToBoot (
for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {
Status = MeasureSeparatorEvent (PcrIndex);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Seperator Event not Measured. Error!\n"));
+ DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n"));
}
}
@@ -2209,10 +2327,23 @@ OnReadyToBoot (
// 6. Not first attempt, meaning a return from last attempt
//
Status = TcgMeasureAction (
- EFI_RETURNING_FROM_EFI_APPLICATOIN
+ 4,
+ EFI_RETURNING_FROM_EFI_APPLICATION
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));
+ DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATION));
+ }
+
+ //
+ // 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again
+ // TCG PC Client PFP spec Section 2.4.4.5 Step 4
+ //
+ Status = TcgMeasureAction (
+ 4,
+ EFI_CALLING_EFI_APPLICATION
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
}
}
@@ -2246,6 +2377,7 @@ OnExitBootServices (
// Measure invocation of ExitBootServices,
//
Status = TcgMeasureAction (
+ 5,
EFI_EXIT_BOOT_SERVICES_INVOCATION
);
if (EFI_ERROR (Status)) {
@@ -2256,6 +2388,7 @@ OnExitBootServices (
// Measure success of ExitBootServices
//
Status = TcgMeasureAction (
+ 5,
EFI_EXIT_BOOT_SERVICES_SUCCEEDED
);
if (EFI_ERROR (Status)) {
@@ -2285,6 +2418,7 @@ OnExitBootServicesFailed (
// Measure Failure of ExitBootServices,
//
Status = TcgMeasureAction (
+ 5,
EFI_EXIT_BOOT_SERVICES_FAILED
);
if (EFI_ERROR (Status)) {
@@ -2293,9 +2427,68 @@ OnExitBootServicesFailed (
}
+/**
+ This routine is called to properly shutdown the TPM before system reset.
+ It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library
+ Part 1: Architecture, Revision 01.16.
+
+ @param[in] ResetType The type of reset to perform.
+ @param[in] ResetStatus The status code for the reset.
+ @param[in] DataSize The size, in bytes, of ResetData.
+ @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
+ EfiResetShutdown the data buffer starts with a Null-terminated
+ string, optionally followed by additional binary data.
+ The string is a description that the caller may use to further
+ indicate the reason for the system reset.
+ For a ResetType of EfiResetPlatformSpecific the data buffer
+ also starts with a Null-terminated string that is followed
+ by an EFI_GUID that describes the specific type of reset to perform.
+**/
+VOID
+EFIAPI
+ShutdownTpmOnReset (
+ IN EFI_RESET_TYPE ResetType,
+ IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize,
+ IN VOID *ResetData OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ Status = Tpm2Shutdown (TPM_SU_CLEAR);
+ DEBUG ((DEBUG_VERBOSE, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status));
+}
+
+/**
+ Hook the system reset to properly shutdown TPM.
+ It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library
+ Part 1: Architecture, Revision 01.16.
+
+ @param[in] Event Event whose notification function is being invoked
+ @param[in] Context Pointer to the notification function's context
+**/
+VOID
+EFIAPI
+OnResetNotificationInstall (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_RESET_NOTIFICATION_PROTOCOL *ResetNotify;
+
+ Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **) &ResetNotify);
+ if (!EFI_ERROR (Status)) {
+ Status = ResetNotify->RegisterResetNotify (ResetNotify, ShutdownTpmOnReset);
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_VERBOSE, "TCG2: Hook system reset to properly shutdown TPM.\n"));
+
+ gBS->CloseEvent (Event);
+ }
+}
+
/**
The function install Tcg2 protocol.
-
+
@retval EFI_SUCCESS Tcg2 protocol is installed.
@retval other Some error occurs.
**/
@@ -2320,9 +2513,9 @@ InstallTcg2 (
/**
The driver's entry point. It publishes EFI Tcg2 Protocol.
- @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
-
+
@retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point.
**/
@@ -2338,7 +2531,6 @@ DriverEntry (
VOID *Registration;
UINT32 MaxCommandSize;
UINT32 MaxResponseSize;
- TPML_PCR_SELECTION Pcrs;
UINTN Index;
EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;
UINT32 ActivePCRBanks;
@@ -2348,7 +2540,7 @@ DriverEntry (
if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||
CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
- DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));
+ DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n"));
return EFI_UNSUPPORTED;
}
@@ -2356,18 +2548,18 @@ DriverEntry (
DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
return EFI_DEVICE_ERROR;
}
-
+
Status = Tpm2RequestUseTpm ();
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));
return Status;
}
-
+
//
// Fill information
//
ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]));
-
+
mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);
mTcgDxeData.BsCap.ProtocolVersion.Major = 1;
mTcgDxeData.BsCap.ProtocolVersion.Minor = 1;
@@ -2408,61 +2600,22 @@ DriverEntry (
//
// Get supported PCR and current Active PCRs
//
- Status = Tpm2GetCapabilityPcrs (&Pcrs);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityPcrs fail!\n"));
- TpmHashAlgorithmBitmap = EFI_TCG2_BOOT_HASH_ALG_SHA1;
- NumberOfPCRBanks = 1;
- ActivePCRBanks = EFI_TCG2_BOOT_HASH_ALG_SHA1;
- } else {
- DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs.count));
- NumberOfPCRBanks = 0;
- TpmHashAlgorithmBitmap = 0;
- ActivePCRBanks = 0;
- for (Index = 0; Index < Pcrs.count; Index++) {
- DEBUG ((EFI_D_INFO, "hash - %x\n", Pcrs.pcrSelections[Index].hash));
- switch (Pcrs.pcrSelections[Index].hash) {
- case TPM_ALG_SHA1:
- TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA1;
- NumberOfPCRBanks ++;
- if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {
- ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA1;
- }
- break;
- case TPM_ALG_SHA256:
- TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA256;
- NumberOfPCRBanks ++;
- if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {
- ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA256;
- }
- break;
- case TPM_ALG_SHA384:
- TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA384;
- NumberOfPCRBanks ++;
- if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {
- ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA384;
- }
- break;
- case TPM_ALG_SHA512:
- TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA512;
- NumberOfPCRBanks ++;
- if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {
- ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA512;
- }
- break;
- case TPM_ALG_SM3_256:
- TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;
- NumberOfPCRBanks ++;
- if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {
- ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;
- }
- break;
- }
- }
- }
+ Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePCRBanks);
+ ASSERT_EFI_ERROR (Status);
+
mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap & PcdGet32 (PcdTcg2HashAlgorithmBitmap);
mTcgDxeData.BsCap.ActivePcrBanks = ActivePCRBanks & PcdGet32 (PcdTcg2HashAlgorithmBitmap);
+ //
+ // Need calculate NumberOfPCRBanks here, because HashAlgorithmBitmap might be removed by PCD.
+ //
+ NumberOfPCRBanks = 0;
+ for (Index = 0; Index < 32; Index++) {
+ if ((mTcgDxeData.BsCap.HashAlgorithmBitmap & (1u << Index)) != 0) {
+ NumberOfPCRBanks++;
+ }
+ }
+
if (PcdGet32 (PcdTcg2NumberOfPCRBanks) == 0) {
mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;
} else {
@@ -2474,11 +2627,11 @@ DriverEntry (
}
mTcgDxeData.BsCap.SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
- if ((mTcgDxeData.BsCap.ActivePcrBanks & TREE_BOOT_HASH_ALG_SHA1) == 0) {
+ if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) == 0) {
//
// No need to expose TCG1.2 event log if SHA1 bank does not exist.
//
- mTcgDxeData.BsCap.SupportedEventLogs &= ~TREE_EVENT_LOG_FORMAT_TCG_1_2;
+ mTcgDxeData.BsCap.SupportedEventLogs &= ~EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
}
DEBUG ((EFI_D_INFO, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));
@@ -2513,7 +2666,7 @@ DriverEntry (
);
//
- // Measure Exit Boot Service failed
+ // Measure Exit Boot Service failed
//
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
@@ -2530,6 +2683,11 @@ DriverEntry (
// may update SecureBoot value based on last setting.
//
EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);
+
+ //
+ // Hook the system reset to properly shutdown TPM.
+ //
+ EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid, TPL_CALLBACK, OnResetNotificationInstall, NULL, &Registration);
}
//