diff --git a/MdePkg/Include/Protocol/Tdx.h b/MdePkg/Include/Protocol/Tdx.h index 1dc427253add..0c09feb6fd4d 100644 --- a/MdePkg/Include/Protocol/Tdx.h +++ b/MdePkg/Include/Protocol/Tdx.h @@ -19,22 +19,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include -#define REG_TYPE_NA 0 -#define REG_TYPE_MRTD 1 -#define REG_TYPE_RTMR 2 -#define PCR_COUNT 16 - -typedef struct { - UINT8 Pcr; // PCR index - UINT8 RegType; // RTMR or MRTD - UINT8 Index; // index in RTMR/MRTD - UINT8 EventlogIndex;// index in EventLog -} PCR_TDX_EXTEND_MAP; - #define EFI_TD_PROTOCOL_GUID \ {0x96751a3d, 0x72f4, 0x41a6, { 0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b }} extern EFI_GUID gTdTcg2ProtocolGuid; -#endif \ No newline at end of file +#endif diff --git a/OvmfPkg/Include/Library/TdxStartupLib.h b/OvmfPkg/Include/Library/TdxStartupLib.h index 7419cc1c4413..03d85fc8b82d 100644 --- a/OvmfPkg/Include/Library/TdxStartupLib.h +++ b/OvmfPkg/Include/Library/TdxStartupLib.h @@ -7,6 +7,24 @@ #include #include #include +#include + +#pragma pack(1) + +typedef struct { + UINT32 count; + TPMI_ALG_HASH hashAlg; + BYTE sha384[SHA384_DIGEST_SIZE]; +} TDX_DIGEST_VALUE; + +typedef struct { + UINT32 Signature; + UINT64 HashDataPtr; + UINT64 HashDataLen; +} TDX_EVENT; + +#pragma pack() + typedef VOID diff --git a/OvmfPkg/Library/HashLibBaseCryptoRouterTdx/HashLibBaseCryptoRouterDxe.c b/OvmfPkg/Library/HashLibBaseCryptoRouterTdx/HashLibBaseCryptoRouterDxe.c index 577645b69457..8aedb5aefb99 100644 --- a/OvmfPkg/Library/HashLibBaseCryptoRouterTdx/HashLibBaseCryptoRouterDxe.c +++ b/OvmfPkg/Library/HashLibBaseCryptoRouterTdx/HashLibBaseCryptoRouterDxe.c @@ -18,10 +18,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include "HashLibBaseCryptoRouterCommon.h" -extern PCR_TDX_EXTEND_MAP mPcrTdxExtendMaps[PCR_COUNT]; - HASH_INTERFACE mHashInterface[HASH_COUNT] = {{{0}, NULL, NULL, NULL}}; UINTN mHashInterfaceCount = 0; @@ -127,6 +126,31 @@ HashUpdate ( return EFI_SUCCESS; } +/** + MRTD => PCR[0] + RTMR[0] => PCR[1,7] + RTMR[1] => PCR[2,3,4,5,6] + RTMR[2] => PCR[8~15] + RTMR[3] => NA + +**/ +UINT8 GetMappedRtmrIndex(UINT32 PCRIndex) +{ + UINT8 RtmrIndex; + + ASSERT (PCRIndex <= 16 && PCRIndex >= 0); + RtmrIndex = 0; + if (PCRIndex == 1 || PCRIndex == 7) { + RtmrIndex = 0; + } else if (PCRIndex >= 2 && PCRIndex <= 6) { + RtmrIndex = 1; + } else if (PCRIndex >= 8 && PCRIndex <= 15) { + RtmrIndex = 2; + } + + return RtmrIndex; +} + /** Hash sequence complete and extend to PCR. @@ -153,15 +177,11 @@ HashCompleteAndExtend ( UINTN Index; EFI_STATUS Status; UINT32 HashMask; - PCR_TDX_EXTEND_MAP PcrTdxExtendMap; if (mHashInterfaceCount == 0) { return EFI_UNSUPPORTED; } - PcrTdxExtendMap = mPcrTdxExtendMaps[PcrIndex]; - ASSERT(PcrTdxExtendMap.Pcr == PcrIndex); - CheckSupportedHashMaskMismatch (); HashCtx = (HASH_HANDLE *)HashHandle; @@ -183,7 +203,7 @@ HashCompleteAndExtend ( Status = TdExtendRtmr ( (UINT32*)DigestList->digests[0].digest.sha384, SHA384_DIGEST_SIZE, - (UINT8)PcrTdxExtendMap.Index + GetMappedRtmrIndex(PcrIndex) ); return Status; } diff --git a/OvmfPkg/Library/TdxStartupLib/Tcg.c b/OvmfPkg/Library/TdxStartupLib/Tcg.c index a97cdcea75de..12c103393cc2 100644 --- a/OvmfPkg/Library/TdxStartupLib/Tcg.c +++ b/OvmfPkg/Library/TdxStartupLib/Tcg.c @@ -29,7 +29,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include - +#include #include "TdxStartupInternal.h" #pragma pack (1) @@ -70,6 +70,7 @@ CreateTdxExtendEvent ( TDX_EVENT *TdxEvent; UINT8 *DigestBuffer; TDX_DIGEST_VALUE *TdxDigest; + UINT8 *Ptr; DEBUG ((EFI_D_INFO, "Creating Tcg2PcrEvent PCR %d EventType 0x%x\n", PCRIndex, EventType)); @@ -91,40 +92,43 @@ CreateTdxExtendEvent ( DEBUG ((EFI_D_INFO, " Tcg2PcrEvent - data %p\n", EventHobData)); + Ptr = (UINT8*)EventHobData; // // Initialize PcrEvent data now // - TcgPcrEvent2 = EventHobData; - TcgPcrEvent2->PCRIndex = PCRIndex; - TcgPcrEvent2->EventType = EventType; + CopyMem(Ptr, &PCRIndex, sizeof(TCG_PCRINDEX)); + Ptr += sizeof(TCG_PCRINDEX); + CopyMem(Ptr, &EventType, sizeof(TCG_EVENTTYPE)); + Ptr += sizeof(TCG_EVENTTYPE); // // We don't have a digest to copy yet, but we can to copy the eventsize/data now // - DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest; + DigestBuffer = Ptr; DEBUG ((EFI_D_INFO, " Tcg2PcrEvent - digest %p\n", DigestBuffer)); TdxDigest = (TDX_DIGEST_VALUE *)DigestBuffer; TdxDigest->count = 1; TdxDigest->hashAlg = TPM_ALG_SHA384; + ZeroMem(TdxDigest->sha384, SHA384_DIGEST_SIZE); - DigestBuffer = DigestBuffer + sizeof(TDX_DIGEST_VALUE); + Ptr += sizeof(TDX_DIGEST_VALUE); DEBUG ((EFI_D_INFO, " Tcg2PcrEvent - eventdata %p\n", DigestBuffer)); - CopyMem (DigestBuffer, &EventSize, sizeof(TcgPcrEvent2->EventSize)); - DigestBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize); - CopyMem (DigestBuffer, EventData, EventSize); - DigestBuffer = DigestBuffer + EventSize; - TdxEvent = (TDX_EVENT *)DigestBuffer; + CopyMem (Ptr, &EventSize, sizeof(UINT32)); + Ptr += sizeof(UINT32); + CopyMem (Ptr, EventData, EventSize); + Ptr += EventSize; + TdxEvent = (TDX_EVENT *)Ptr; // // Initialize the TdxEvent so we can perform measurement in DXE. // During early DXE, the gTcgEvent2EntryHobGuid will be parsed, the data hashed, and TcgEvent2 hobs // updated with the updated hash // - //TdxEvent->Signature = TCG_TDX_EVENT_DATA_SIGNATURE; - TdxEvent->HashData = HashData; - TdxEvent->HashDataLen = HashDataLen; + TdxEvent->Signature = SIGNATURE_32('T', 'D', 'E', 'T'); + TdxEvent->HashDataPtr = (UINT64)(UINTN)HashData; + TdxEvent->HashDataLen = (UINT64)HashDataLen; Status = EFI_SUCCESS; return Status; diff --git a/OvmfPkg/Library/TdxStartupLib/TdxStartupInternal.h b/OvmfPkg/Library/TdxStartupLib/TdxStartupInternal.h index e652de76555c..9e2db4e0f3d3 100644 --- a/OvmfPkg/Library/TdxStartupLib/TdxStartupInternal.h +++ b/OvmfPkg/Library/TdxStartupLib/TdxStartupInternal.h @@ -56,25 +56,12 @@ } MP_RELOCATION_MAP; #define HANDOFF_TABLE_DESC "TdxTable" - typedef struct { - UINT8 TableDescriptionSize; - UINT8 TableDescription[sizeof(HANDOFF_TABLE_DESC)]; - UINT64 NumberOfTables; - EFI_CONFIGURATION_TABLE TableEntry[1]; - } TDX_HANDOFF_TABLE_POINTERS2; - - typedef struct { - UINT32 count; - TPMI_ALG_HASH hashAlg; - BYTE sha384[SHA384_DIGEST_SIZE]; - } TDX_DIGEST_VALUE; - - typedef struct { - UINT32 Signature; - UINT8 *HashData; - UINTN HashDataLen; - } TDX_EVENT; - +typedef struct { + UINT8 TableDescriptionSize; + UINT8 TableDescription[sizeof (HANDOFF_TABLE_DESC)]; + UINT64 NumberOfTables; + EFI_CONFIGURATION_TABLE TableEntry[1]; +} TDX_HANDOFF_TABLE_POINTERS2; #pragma pack() #define LOOPIT(X) do { \ diff --git a/OvmfPkg/Tcg/Tcg2Dxe/TdTcg2Dxe.c b/OvmfPkg/Tcg/Tcg2Dxe/TdTcg2Dxe.c index 33151729af31..b22a5744f31d 100644 --- a/OvmfPkg/Tcg/Tcg2Dxe/TdTcg2Dxe.c +++ b/OvmfPkg/Tcg/Tcg2Dxe/TdTcg2Dxe.c @@ -45,50 +45,17 @@ #include #include +#include #include #include -/** - If TD guest firmware supports measurement and an event is created, - TD guest firmware is designed to report the event log with the same - data structure in TCG-Platform-Firmware-Profile spec with - EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 format. - - So there is map between the TDX MRTD/RTMR registers and TPM PCRs. - MRTD => PCR[0] - RTMR[0] => PCR[1,7] - RTMR[1] => PCR[2,3,4,5,6] - RTMR[2] => PCR[8~15] - RTMR[3] => NA - **/ -PCR_TDX_EXTEND_MAP mPcrTdxExtendMaps[PCR_COUNT] = { - {0 , REG_TYPE_MRTD, 0, 0}, - {1 , REG_TYPE_RTMR, 0, 1}, - {2 , REG_TYPE_RTMR, 1, 2}, - {3 , REG_TYPE_RTMR, 1, 2}, - {4 , REG_TYPE_RTMR, 1, 2}, - {5 , REG_TYPE_RTMR, 1, 2}, - {6 , REG_TYPE_RTMR, 1, 2}, - {7 , REG_TYPE_RTMR, 0, 1}, - {8 , REG_TYPE_RTMR, 2, 3}, - {9 , REG_TYPE_RTMR, 2, 3}, - {10, REG_TYPE_RTMR, 2, 3}, - {11, REG_TYPE_RTMR, 2, 3}, - {12, REG_TYPE_RTMR, 2, 3}, - {13, REG_TYPE_RTMR, 2, 3}, - {14, REG_TYPE_RTMR, 2, 3}, - {15, REG_TYPE_RTMR, 2, 3}, -}; #define PERF_ID_TD_TCG2_DXE 0x3130 // TODO TDX command/response size #define TCG2_DEFAULT_MAX_COMMAND_SIZE 0x1000 #define TCG2_DEFAULT_MAX_RESPONSE_SIZE 0x1000 -#define HANDOFF_TABLE_DESC "TdxTable" #define TCG_EVENT_LOG_AREA_COUNT_MAX 1 -#pragma pack(1) - typedef struct { CHAR16 *VariableName; EFI_GUID *VendorGuid; @@ -110,25 +77,6 @@ typedef struct { UINTN Next800155EventOffset; } TCG_EVENT_LOG_AREA_STRUCT; -typedef struct { - UINT8 TableDescriptionSize; - UINT8 TableDescription[sizeof(HANDOFF_TABLE_DESC)]; - UINT64 NumberOfTables; - EFI_CONFIGURATION_TABLE TableEntry[1]; -} TDX_HANDOFF_TABLE_POINTERS2; - -typedef struct { - UINT32 count; - TPMI_ALG_HASH hashAlg; - BYTE sha384[SHA384_DIGEST_SIZE]; -} TDX_DIGEST_VALUE; - -typedef struct { - UINT32 Signature; - UINT8 *HashData; - UINTN HashDataLen; -} TDX_EVENT; - typedef struct _TCG_DXE_DATA { EFI_TCG2_BOOT_SERVICE_CAPABILITY BsCap; TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX]; @@ -143,8 +91,6 @@ typedef struct{ UINT32 HashMask; }TDX_HASH_INFO; -#pragma pack() - TCG2_EVENT_INFO_STRUCT mTcg2EventInfo[] = { {&gTcgEvent2EntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_2}, }; @@ -191,7 +137,7 @@ EFI_TDX_EVENTLOG_ACPI_TABLE mTdxEventlogAcpiTemplate = { 0, // lasa }; -static TDX_HASH_INFO mHashInfo[] = { +TDX_HASH_INFO mHashInfo[] = { {TPM_ALG_SHA384, SHA384_DIGEST_SIZE, HASH_ALG_SHA384} }; @@ -973,13 +919,29 @@ TcgCommLogEvent ( return EFI_SUCCESS; } +/** + MRTD => PCR[0] + RTMR[0] => PCR[1,7] + RTMR[1] => PCR[2,3,4,5,6] + RTMR[2] => PCR[8~15] + RTMR[3] => NA + +**/ UINT32 GetMappedIndexInEventLog(UINT32 PCRIndex) { - PCR_TDX_EXTEND_MAP *PcrTdxMap; + UINT32 RtmrIndex; + + ASSERT (PCRIndex <= 16 && PCRIndex >= 0); + RtmrIndex = 0; + if (PCRIndex == 1 || PCRIndex == 7) { + RtmrIndex = 0; + } else if (PCRIndex >= 2 && PCRIndex <= 6) { + RtmrIndex = 1; + } else if (PCRIndex >= 8 && PCRIndex <= 15) { + RtmrIndex = 2; + } - ASSERT(PCRIndex >= 0 && PCRIndex < PCR_COUNT); - PcrTdxMap = (PCR_TDX_EXTEND_MAP*)&mPcrTdxExtendMaps[PCRIndex]; - return PcrTdxMap->EventlogIndex; + return RtmrIndex + 1; } /** @@ -1535,14 +1497,9 @@ SetupEventLog ( ) { EFI_STATUS Status; - VOID *TcgEvent; EFI_PEI_HOB_POINTERS GuidHob; EFI_PHYSICAL_ADDRESS Lasa; UINTN Index; - VOID *DigestListBin; - UINT32 DigestListBinSize; - UINT8 *Event; - UINT32 EventSize; TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct; UINT8 TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) @@ -1554,11 +1511,8 @@ SetupEventLog ( TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize; UINT8 *VendorInfoSize; UINT32 NumberOfAlgorithms; - TDX_EVENT *TdxEvent; - TCG_PCR_EVENT2 *TcgPcrEvent2; - TPML_DIGEST_VALUES DigestList; - DEBUG ((EFI_D_INFO, "SetupEventLog\n")); + DEBUG ((EFI_D_INFO, "Td: SetupEventLog\n")); // // 1. Create Log Area @@ -1719,101 +1673,6 @@ SetupEventLog ( } } - // - // 3. Sync data from PEI to DXE - // - Status = EFI_SUCCESS; - for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) { - if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) { - GuidHob.Raw = GetHobList (); - Status = EFI_SUCCESS; - while (!EFI_ERROR (Status) && (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) { - // - // TcgEvent points to TCG_PCR_EVENT2 + TDX_EVENT - // The Digest field in TCG_PCR_EVENT2 is not populated at this moment - // Instead its value should be calculated here by hashing the DATA designated by TDX_EVENT - // - // typedef struct tdTCG_PCR_EVENT2 { - // TCG_PCRINDEX PCRIndex; - // TCG_EVENTTYPE EventType; - // TPML_DIGEST_VALUES Digest; // In TDVF this field is TDX_DIGEST_VALUE which is same as TPML_DIGEST_VALUES - // UINT32 EventSize; - // UINT8 Event[1]; - // } TCG_PCR_EVENT2; - // - // typedef struct { - // UINT32 Signature; - // UINT8 *HashData; - // UINTN HashDataLen; - // }TDX_EVENT - - TcgEvent = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid)); - DEBUG((DEBUG_INFO, "GuidHob size = 0x%x\n", GET_GUID_HOB_DATA_SIZE (GuidHob.Guid))); - ASSERT (TcgEvent != NULL); - TcgPcrEvent2 = (TCG_PCR_EVENT2*)TcgEvent; - - // This is for next iteration - GuidHob.Raw = GET_NEXT_HOB (GuidHob); - - // - // TDVF only supports EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 - if(mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { - - // - // PCRIndex + EventType + Digest + EventSize + Event - // - DigestListBin = (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE); - DigestListBinSize = GetDigestListBinSize (DigestListBin); - - // - // Event size. - // - CopyMem (&EventSize, (UINT8 *)DigestListBin + DigestListBinSize, sizeof(UINT32)); - Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof(UINT32); - - // - // TdxEvent - // - TdxEvent = (TDX_EVENT*)((UINT8 *)DigestListBin + DigestListBinSize + sizeof(UINT32) + EventSize); - DEBUG((DEBUG_INFO, "DigestListBinSize=0x%x, EventSize=0x%x\n", - DigestListBinSize, EventSize)); - DEBUG((DEBUG_INFO, "HashData: %p, HashDataLen=0x%x\n", - TdxEvent->HashData, TdxEvent->HashDataLen)); - - - ZeroMem((UINT8*)&DigestList, sizeof(DigestList)); - // - // Calculate the Digest by hashing(SHA384) the DATA designated by TdxEvent - // - Status = HashAndExtend(TcgPcrEvent2->PCRIndex, - TdxEvent->HashData, - TdxEvent->HashDataLen, - &DigestList); - DEBUG((DEBUG_INFO, "Digest count=%d, hashAlg=0x%x\n", DigestList.count, DigestList.digests[0].hashAlg)); - - ASSERT(Status == EFI_SUCCESS); - ASSERT(DigestList.count == 1 && DigestList.digests[0].hashAlg == TPM_ALG_SHA384); - TcgPcrEvent2->Digest.count = 1; - CopyMem((UINT8*)&TcgPcrEvent2->Digest + sizeof(UINT32), (UINT8*)&DigestList.digests[0], sizeof(TPMI_ALG_HASH) + SHA384_DIGEST_SIZE); - DumpEvent2(TcgPcrEvent2); - - // - // Log the event - // - Status = TcgDxeLogEvent ( - mTcg2EventInfo[Index].LogFormat, - TcgEvent, - sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32), - Event, - EventSize - ); - } - - FreePool (TcgEvent); - } - } - } - return Status; } @@ -2505,6 +2364,73 @@ OnExitBootServicesFailed ( } +EFI_STATUS +SyncTdTcgEvent() +{ + EFI_STATUS Status; + EFI_PEI_HOB_POINTERS GuidHob; + VOID *TcgEvent; + VOID *DigestListBin; + UINT32 DigestListBinSize; + UINT8 *Event; + UINT32 EventSize; + TDX_EVENT *TdxEvent; + TPML_DIGEST_VALUES DigestList; + + DEBUG ((DEBUG_INFO, "Sync Tdx event from SEC\n")); + + Status = EFI_SUCCESS; + GuidHob.Guid = GetFirstGuidHob (&gTcgEvent2EntryHobGuid); + + while (!EFI_ERROR(Status) && GuidHob.Guid != NULL) { + TcgEvent = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid)); + + GuidHob.Guid = GET_NEXT_HOB (GuidHob); + GuidHob.Guid = GetNextGuidHob (&gTcgEvent2EntryHobGuid, GuidHob.Guid); + + DigestListBin = (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE); + DigestListBinSize = GetDigestListBinSize(DigestListBin); + + // + // Event size. + // + EventSize = *(UINT32*)((UINT8 *) DigestListBin + DigestListBinSize); + Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof(UINT32); + // + // Hash and extend the data from SEC + // + TdxEvent = (TDX_EVENT*)((UINT8 *)DigestListBin + DigestListBinSize + sizeof(UINT32) + EventSize); + Status = HashAndExtend (*(UINT32*)(TcgEvent), + (VOID*)(UINTN)TdxEvent->HashDataPtr, + TdxEvent->HashDataLen, + &DigestList); + + // + // Copy the hash data to TcgEvent + // + CopyMem ((UINT8*)DigestListBin + sizeof (UINT32) + sizeof (TPMI_ALG_HASH), + DigestList.digests[0].digest.sha384, + SHA384_DIGEST_SIZE); + + // + // Log the event + // + Status = TcgDxeLogEvent ( + mTcg2EventInfo[0].LogFormat, + TcgEvent, + sizeof (TCG_PCRINDEX) + sizeof (TCG_EVENTTYPE) + DigestListBinSize + sizeof (UINT32), + Event, + EventSize + ); + + DumpEvent2 ((TCG_PCR_EVENT2*) TcgEvent); + FreePool (TcgEvent); + } + + return Status; +} + + /** Install TDVF ACPI Table when ACPI Table Protocol is available. @@ -2561,7 +2487,6 @@ InstallAcpiTable ( ASSERT_EFI_ERROR (Status); DEBUG((DEBUG_INFO, "TDX Eventlog ACPI Table is measured and logged\n")); - } /** @@ -2648,6 +2573,9 @@ DriverEntry ( Status = SetupEventLog (); ASSERT_EFI_ERROR (Status); + Status = SyncTdTcgEvent(); + ASSERT_EFI_ERROR (Status); + // // Measure handoff tables, Boot#### variables etc. //