#include <Protocol/VariableWrite.h>\r
#include <Protocol/Tcg2Protocol.h>\r
#include <Protocol/TrEEProtocol.h>\r
+#include <Protocol/ResetNotification.h>\r
\r
#include <Library/DebugLib.h>\r
#include <Library/BaseMemoryLib.h>\r
{EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid},\r
{EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid},\r
{EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid},\r
- {EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid},\r
};\r
\r
EFI_HANDLE mImageHandle;\r
}\r
}\r
\r
+/**\r
+\r
+ This function initialize TCG_PCR_EVENT2_HDR for EV_NO_ACTION Event Type other than EFI Specification ID event\r
+ The behavior is defined by TCG PC Client PFP Spec. Section 9.3.4 EV_NO_ACTION Event Types\r
+\r
+ @param[in, out] NoActionEvent Event Header of EV_NO_ACTION Event\r
+ @param[in] EventSize Event Size of the EV_NO_ACTION Event\r
+\r
+**/\r
+VOID\r
+InitNoActionEvent (\r
+ IN OUT TCG_PCR_EVENT2_HDR *NoActionEvent,\r
+ IN UINT32 EventSize\r
+ )\r
+{\r
+ UINT32 DigestListCount;\r
+ TPMI_ALG_HASH HashAlgId;\r
+ UINT8 *DigestBuffer;\r
+\r
+ DigestBuffer = (UINT8 *)NoActionEvent->Digests.digests;\r
+ DigestListCount = 0;\r
+\r
+ NoActionEvent->PCRIndex = 0;\r
+ NoActionEvent->EventType = EV_NO_ACTION;\r
+\r
+ //\r
+ // Set Hash count & hashAlg accordingly, while Digest.digests[n].digest to all 0\r
+ //\r
+ ZeroMem (&NoActionEvent->Digests, sizeof(NoActionEvent->Digests));\r
+\r
+ if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
+ HashAlgId = TPM_ALG_SHA1;\r
+ CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+ DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+ DigestListCount++;\r
+ }\r
+\r
+ if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
+ HashAlgId = TPM_ALG_SHA256;\r
+ CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+ DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+ DigestListCount++;\r
+ }\r
+\r
+ if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
+ HashAlgId = TPM_ALG_SHA384;\r
+ CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+ DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+ DigestListCount++;\r
+ }\r
+\r
+ if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
+ HashAlgId = TPM_ALG_SHA512;\r
+ CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+ DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+ DigestListCount++;\r
+ }\r
+\r
+ if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
+ HashAlgId = TPM_ALG_SM3_256;\r
+ CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+ DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+ DigestListCount++;\r
+ }\r
+\r
+ //\r
+ // Set Digests Count\r
+ //\r
+ WriteUnaligned32 ((UINT32 *)&NoActionEvent->Digests.count, DigestListCount);\r
+\r
+ //\r
+ // Set Event Size\r
+ //\r
+ WriteUnaligned32((UINT32 *)DigestBuffer, EventSize);\r
+}\r
+\r
/**\r
\r
This function dump raw data with colume format.\r
UINT32 HashAlgorithmMaskCopied;\r
TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;\r
UINT8 TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];\r
- TCG_PCR_EVENT_HDR NoActionEvent;\r
+ TCG_PCR_EVENT_HDR SpecIdEvent;\r
+ TCG_PCR_EVENT2_HDR NoActionEvent;\r
TCG_EfiSpecIdEventAlgorithmSize *DigestSize;\r
TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;\r
UINT8 *VendorInfoSize;\r
VendorInfoSize = (UINT8 *)TempDigestSize;\r
*VendorInfoSize = 0;\r
\r
- NoActionEvent.PCRIndex = 0;\r
- NoActionEvent.EventType = EV_NO_ACTION;\r
- ZeroMem (&NoActionEvent.Digest, sizeof(NoActionEvent.Digest));\r
- NoActionEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);\r
+ SpecIdEvent.PCRIndex = 0;\r
+ SpecIdEvent.EventType = EV_NO_ACTION;\r
+ ZeroMem (&SpecIdEvent.Digest, sizeof(SpecIdEvent.Digest));\r
+ SpecIdEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);\r
\r
//\r
- // Log TcgEfiSpecIdEventStruct as the first Event\r
+ // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.\r
+ // TCG EFI Protocol Spec. Section 5.3 Event Log Header\r
// TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log\r
//\r
Status = TcgDxeLogEvent (\r
mTcg2EventInfo[Index].LogFormat,\r
- &NoActionEvent,\r
- sizeof(NoActionEvent),\r
+ &SpecIdEvent,\r
+ sizeof(SpecIdEvent),\r
(UINT8 *)TcgEfiSpecIdEventStruct,\r
- NoActionEvent.EventSize\r
+ SpecIdEvent.EventSize\r
);\r
\r
//\r
- // EfiStartupLocalityEvent\r
+ // EfiStartupLocalityEvent. Event format is TCG_PCR_EVENT2\r
//\r
GuidHob.Guid = GetFirstGuidHob (&gTpm2StartupLocalityHobGuid);\r
if (GuidHob.Guid != NULL) {\r
//\r
StartupLocalityEvent.StartupLocality = *(UINT8 *)(GET_GUID_HOB_DATA (GuidHob.Guid));\r
CopyMem (StartupLocalityEvent.Signature, TCG_EfiStartupLocalityEvent_SIGNATURE, sizeof(StartupLocalityEvent.Signature));\r
-\r
- NoActionEvent.PCRIndex = 0;\r
- NoActionEvent.EventType = EV_NO_ACTION;\r
- ZeroMem (&NoActionEvent.Digest, sizeof(NoActionEvent.Digest));\r
- NoActionEvent.EventSize = sizeof(StartupLocalityEvent);\r
-\r
DEBUG ((DEBUG_INFO, "SetupEventLog: Set Locality from HOB into StartupLocalityEvent 0x%02x\n", StartupLocalityEvent.StartupLocality));\r
\r
+ //\r
+ // Initialize StartupLocalityEvent\r
+ //\r
+ InitNoActionEvent(&NoActionEvent, sizeof(StartupLocalityEvent));\r
+\r
//\r
// Log EfiStartupLocalityEvent as the second Event\r
// TCG PC Client PFP spec. Section 9.3.4.3 Startup Locality Event\r
Status = TcgDxeLogEvent (\r
mTcg2EventInfo[Index].LogFormat,\r
&NoActionEvent,\r
- sizeof(NoActionEvent),\r
+ sizeof(NoActionEvent.PCRIndex) + sizeof(NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof(NoActionEvent.EventSize),\r
(UINT8 *)&StartupLocalityEvent,\r
- NoActionEvent.EventSize\r
+ sizeof(StartupLocalityEvent)\r
);\r
+\r
}\r
}\r
}\r
}\r
\r
/**\r
- Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].\r
+ Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].\r
+according to TCG PC Client PFP spec 0021 Section 2.4.4.2\r
\r
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
@param[in] VendorGuid A unique identifier for the vendor.\r
)\r
{\r
return ReadAndMeasureVariable (\r
- 5,\r
+ 1,\r
EV_EFI_VARIABLE_BOOT,\r
VarName,\r
VendorGuid,\r
}\r
}\r
\r
+ //\r
+ // Measure DBT if present and not empty\r
+ //\r
+ Status = GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, &Data, &DataSize);\r
+ if (!EFI_ERROR(Status)) {\r
+ Status = MeasureVariable (\r
+ 7,\r
+ EV_EFI_VARIABLE_DRIVER_CONFIG,\r
+ EFI_IMAGE_SECURITY_DATABASE2,\r
+ &gEfiImageSecurityDatabaseGuid,\r
+ Data,\r
+ DataSize\r
+ );\r
+ FreePool(Data);\r
+ } else {\r
+ DEBUG((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2));\r
+ }\r
+\r
return EFI_SUCCESS;\r
}\r
\r
\r
}\r
\r
+/**\r
+ This routine is called to properly shutdown the TPM before system reset.\r
+ It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
+ Part 1: Architecture, Revision 01.16.\r
+\r
+ @param[in] ResetType The type of reset to perform.\r
+ @param[in] ResetStatus The status code for the reset.\r
+ @param[in] DataSize The size, in bytes, of ResetData.\r
+ @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or\r
+ EfiResetShutdown the data buffer starts with a Null-terminated\r
+ string, optionally followed by additional binary data.\r
+ The string is a description that the caller may use to further\r
+ indicate the reason for the system reset. ResetData is only\r
+ valid if ResetStatus is something other than EFI_SUCCESS\r
+ unless the ResetType is EfiResetPlatformSpecific\r
+ where a minimum amount of ResetData is always required.\r
+ For a ResetType of EfiResetPlatformSpecific the data buffer\r
+ also starts with a Null-terminated string that is followed\r
+ by an EFI_GUID that describes the specific type of reset to perform.\r
+**/\r
+VOID\r
+EFIAPI\r
+ShutdownTpmOnReset (\r
+ IN EFI_RESET_TYPE ResetType,\r
+ IN EFI_STATUS ResetStatus,\r
+ IN UINTN DataSize,\r
+ IN VOID *ResetData OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ Status = Tpm2Shutdown (TPM_SU_CLEAR);\r
+ DEBUG ((DEBUG_VERBOSE, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status));\r
+}\r
+\r
+/**\r
+ Hook the system reset to properly shutdown TPM.\r
+ It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
+ Part 1: Architecture, Revision 01.16.\r
+\r
+ @param[in] Event Event whose notification function is being invoked\r
+ @param[in] Context Pointer to the notification function's context\r
+**/\r
+VOID\r
+EFIAPI\r
+OnResetNotificationInstall (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_RESET_NOTIFICATION_PROTOCOL *ResetNotify;\r
+\r
+ Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **) &ResetNotify);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = ResetNotify->RegisterResetNotify (ResetNotify, ShutdownTpmOnReset);\r
+ ASSERT_EFI_ERROR (Status);\r
+ DEBUG ((DEBUG_VERBOSE, "TCG2: Hook system reset to properly shutdown TPM.\n"));\r
+\r
+ gBS->CloseEvent (Event);\r
+ }\r
+}\r
+\r
/**\r
The function install Tcg2 protocol.\r
\r
\r
if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
- DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));\r
+ DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n"));\r
return EFI_UNSUPPORTED;\r
}\r
\r
// may update SecureBoot value based on last setting.\r
//\r
EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);\r
+\r
+ //\r
+ // Hook the system reset to properly shutdown TPM.\r
+ //\r
+ EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid, TPL_CALLBACK, OnResetNotificationInstall, NULL, &Registration);\r
}\r
\r
//\r