12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522 |
- /** @file
- This module implements EFI TD Protocol.
- Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <PiDxe.h>
- #include <IndustryStandard/Acpi.h>
- #include <IndustryStandard/PeImage.h>
- #include <IndustryStandard/TcpaAcpi.h>
- #include <Guid/GlobalVariable.h>
- #include <Guid/HobList.h>
- #include <Guid/EventGroup.h>
- #include <Guid/EventExitBootServiceFailed.h>
- #include <Guid/ImageAuthentication.h>
- #include <Guid/TpmInstance.h>
- #include <Protocol/DevicePath.h>
- #include <Protocol/MpService.h>
- #include <Protocol/VariableWrite.h>
- #include <Protocol/Tcg2Protocol.h>
- #include <Protocol/TrEEProtocol.h>
- #include <Protocol/ResetNotification.h>
- #include <Protocol/AcpiTable.h>
- #include <Library/DebugLib.h>
- #include <Library/BaseMemoryLib.h>
- #include <Library/UefiRuntimeServicesTableLib.h>
- #include <Library/UefiDriverEntryPoint.h>
- #include <Library/HobLib.h>
- #include <Library/UefiBootServicesTableLib.h>
- #include <Library/BaseLib.h>
- #include <Library/MemoryAllocationLib.h>
- #include <Library/PrintLib.h>
- #include <Library/PcdLib.h>
- #include <Library/UefiLib.h>
- #include <Library/HashLib.h>
- #include <Library/PerformanceLib.h>
- #include <Library/ReportStatusCodeLib.h>
- #include <Library/TpmMeasurementLib.h>
- #include <Protocol/CcMeasurement.h>
- #include <Guid/CcEventHob.h>
- #include <Library/TdxLib.h>
- #define PERF_ID_CC_TCG2_DXE 0x3130
- #define CC_EVENT_LOG_AREA_COUNT_MAX 1
- #define CC_MR_INDEX_0_MRTD 0
- #define CC_MR_INDEX_1_RTMR0 1
- #define CC_MR_INDEX_2_RTMR1 2
- #define CC_MR_INDEX_3_RTMR2 3
- #define CC_MR_INDEX_INVALID 4
- typedef struct {
- CHAR16 *VariableName;
- EFI_GUID *VendorGuid;
- } VARIABLE_TYPE;
- typedef struct {
- EFI_GUID *EventGuid;
- EFI_CC_EVENT_LOG_FORMAT LogFormat;
- } CC_EVENT_INFO_STRUCT;
- typedef struct {
- EFI_CC_EVENT_LOG_FORMAT EventLogFormat;
- EFI_PHYSICAL_ADDRESS Lasa;
- UINT64 Laml;
- UINTN EventLogSize;
- UINT8 *LastEvent;
- BOOLEAN EventLogStarted;
- BOOLEAN EventLogTruncated;
- UINTN Next800155EventOffset;
- } CC_EVENT_LOG_AREA_STRUCT;
- typedef struct _TDX_DXE_DATA {
- EFI_CC_BOOT_SERVICE_CAPABILITY BsCap;
- CC_EVENT_LOG_AREA_STRUCT EventLogAreaStruct[CC_EVENT_LOG_AREA_COUNT_MAX];
- BOOLEAN GetEventLogCalled[CC_EVENT_LOG_AREA_COUNT_MAX];
- CC_EVENT_LOG_AREA_STRUCT FinalEventLogAreaStruct[CC_EVENT_LOG_AREA_COUNT_MAX];
- EFI_CC_FINAL_EVENTS_TABLE *FinalEventsTable[CC_EVENT_LOG_AREA_COUNT_MAX];
- } TDX_DXE_DATA;
- typedef struct {
- TPMI_ALG_HASH HashAlgo;
- UINT16 HashSize;
- UINT32 HashMask;
- } TDX_HASH_INFO;
- //
- //
- CC_EVENT_INFO_STRUCT mCcEventInfo[] = {
- { &gCcEventEntryHobGuid, EFI_CC_EVENT_LOG_FORMAT_TCG_2 },
- };
- TDX_DXE_DATA mTdxDxeData = {
- {
- sizeof (EFI_CC_BOOT_SERVICE_CAPABILITY), // Size
- { 1, 1 }, // StructureVersion
- { 1, 1 }, // ProtocolVersion
- EFI_CC_BOOT_HASH_ALG_SHA384, // HashAlgorithmBitmap
- EFI_CC_EVENT_LOG_FORMAT_TCG_2, // SupportedEventLogs
- { 2, 0 } // {CC_TYPE, CC_SUBTYPE}
- },
- };
- UINTN mBootAttempts = 0;
- CHAR16 mBootVarName[] = L"BootOrder";
- VARIABLE_TYPE mVariableType[] = {
- { EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid },
- { EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid },
- { EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid },
- { EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid },
- { EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid },
- };
- EFI_CC_EVENTLOG_ACPI_TABLE mTdxEventlogAcpiTemplate = {
- {
- EFI_CC_EVENTLOG_ACPI_TABLE_SIGNATURE,
- sizeof (mTdxEventlogAcpiTemplate),
- EFI_CC_EVENTLOG_ACPI_TABLE_REVISION,
- //
- // Compiler initializes the remaining bytes to 0
- // These fields should be filled in production
- //
- },
- { EFI_CC_TYPE_TDX, 0 }, // CcType
- 0, // rsvd
- 0, // laml
- 0, // lasa
- };
- //
- // Supported Hash list in Td guest.
- // Currently SHA384 is supported.
- //
- TDX_HASH_INFO mHashInfo[] = {
- { TPM_ALG_SHA384, SHA384_DIGEST_SIZE, HASH_ALG_SHA384 }
- };
- /**
- Get hash size based on Algo
- @param[in] HashAlgo Hash Algorithm Id.
- @return Size of the hash.
- **/
- UINT16
- GetHashSizeFromAlgo (
- IN TPMI_ALG_HASH HashAlgo
- )
- {
- UINTN Index;
- for (Index = 0; Index < sizeof (mHashInfo)/sizeof (mHashInfo[0]); Index++) {
- if (mHashInfo[Index].HashAlgo == HashAlgo) {
- return mHashInfo[Index].HashSize;
- }
- }
- return 0;
- }
- /**
- Get hash mask based on Algo
- @param[in] HashAlgo Hash Algorithm Id.
- @return Hash mask.
- **/
- UINT32
- GetHashMaskFromAlgo (
- IN TPMI_ALG_HASH HashAlgo
- )
- {
- UINTN Index;
- for (Index = 0; Index < ARRAY_SIZE (mHashInfo); Index++) {
- if (mHashInfo[Index].HashAlgo == HashAlgo) {
- return mHashInfo[Index].HashMask;
- }
- }
- ASSERT (FALSE);
- return 0;
- }
- /**
- Copy TPML_DIGEST_VALUES into a buffer
- @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.
- @param[in] DigestList TPML_DIGEST_VALUES to be copied.
- @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.
- @return The end of buffer to hold TPML_DIGEST_VALUES.
- **/
- VOID *
- CopyDigestListToBuffer (
- IN OUT VOID *Buffer,
- IN TPML_DIGEST_VALUES *DigestList,
- IN UINT32 HashAlgorithmMask
- )
- {
- UINTN Index;
- UINT16 DigestSize;
- UINT32 DigestListCount;
- UINT32 *DigestListCountPtr;
- DigestListCountPtr = (UINT32 *)Buffer;
- DigestListCount = 0;
- Buffer = (UINT8 *)Buffer + sizeof (DigestList->count);
- for (Index = 0; Index < DigestList->count; Index++) {
- if ((DigestList->digests[Index].hashAlg & HashAlgorithmMask) == 0) {
- DEBUG ((DEBUG_ERROR, "WARNING: TD Event log has HashAlg unsupported (0x%x)\n", DigestList->digests[Index].hashAlg));
- continue;
- }
- 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;
- DigestListCount++;
- }
- WriteUnaligned32 (DigestListCountPtr, DigestListCount);
- return Buffer;
- }
- EFI_HANDLE mImageHandle;
- /**
- Measure PE image into TPM log based on the authenticode image hashing in
- PE/COFF Specification 8.0 Appendix A.
- Caution: This function may receive untrusted input.
- 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] RtmrIndex RTMR index
- @param[in] ImageAddress Start address of image buffer.
- @param[in] ImageSize Image size
- @param[out] DigestList Digest list of this image.
- @retval EFI_SUCCESS Successfully measure image.
- @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
- @retval other error value
- **/
- EFI_STATUS
- MeasurePeImageAndExtend (
- IN UINT32 RtmrIndex,
- IN EFI_PHYSICAL_ADDRESS ImageAddress,
- IN UINTN ImageSize,
- OUT TPML_DIGEST_VALUES *DigestList
- );
- #define COLUME_SIZE (16 * 2)
- /**
- This function dump raw data.
- @param Data raw data
- @param Size raw data size
- **/
- VOID
- InternalDumpData (
- IN UINT8 *Data,
- IN UINTN Size
- )
- {
- UINTN Index;
- for (Index = 0; Index < Size; Index++) {
- DEBUG ((DEBUG_INFO, Index == COLUME_SIZE/2 ? " | %02x" : " %02x", (UINTN)Data[Index]));
- }
- }
- /**
- This function dump raw data with colume format.
- @param Data raw data
- @param Size raw data size
- **/
- VOID
- InternalDumpHex (
- IN UINT8 *Data,
- IN UINTN Size
- )
- {
- UINTN Index;
- UINTN Count;
- UINTN Left;
- Count = Size / COLUME_SIZE;
- Left = Size % COLUME_SIZE;
- for (Index = 0; Index < Count; Index++) {
- DEBUG ((DEBUG_INFO, "%04x: ", Index * COLUME_SIZE));
- InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);
- DEBUG ((DEBUG_INFO, "\n"));
- }
- if (Left != 0) {
- DEBUG ((DEBUG_INFO, "%04x: ", Index * COLUME_SIZE));
- InternalDumpData (Data + Index * COLUME_SIZE, Left);
- DEBUG ((DEBUG_INFO, "\n"));
- }
- }
- /**
- This function initialize TD_EVENT_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 CC_EVENT_HDR *NoActionEvent,
- IN UINT32 EventSize
- )
- {
- UINT32 DigestListCount;
- TPMI_ALG_HASH HashAlgId;
- UINT8 *DigestBuffer;
- DigestBuffer = (UINT8 *)NoActionEvent->Digests.digests;
- DigestListCount = 0;
- NoActionEvent->MrIndex = 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 ((mTdxDxeData.BsCap.HashAlgorithmBitmap & EFI_CC_BOOT_HASH_ALG_SHA384) != 0) {
- HashAlgId = TPM_ALG_SHA384;
- 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);
- }
- /**
- Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
- Caller is responsible to free LocationBuf.
- @param[out] LocationBuf Returns Processor Location Buffer.
- @param[out] Num Returns processor number.
- @retval EFI_SUCCESS Operation completed successfully.
- @retval EFI_UNSUPPORTED MpService protocol not found.
- **/
- EFI_STATUS
- GetProcessorsCpuLocation (
- OUT EFI_CPU_PHYSICAL_LOCATION **LocationBuf,
- OUT UINTN *Num
- )
- {
- EFI_STATUS Status;
- EFI_MP_SERVICES_PROTOCOL *MpProtocol;
- UINTN ProcessorNum;
- UINTN EnabledProcessorNum;
- EFI_PROCESSOR_INFORMATION ProcessorInfo;
- EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
- UINTN Index;
- Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpProtocol);
- if (EFI_ERROR (Status)) {
- //
- // MP protocol is not installed
- //
- return EFI_UNSUPPORTED;
- }
- Status = MpProtocol->GetNumberOfProcessors (
- MpProtocol,
- &ProcessorNum,
- &EnabledProcessorNum
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- Status = gBS->AllocatePool (
- EfiBootServicesData,
- sizeof (EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
- (VOID **)&ProcessorLocBuf
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Get each processor Location info
- //
- for (Index = 0; Index < ProcessorNum; Index++) {
- Status = MpProtocol->GetProcessorInfo (
- MpProtocol,
- Index,
- &ProcessorInfo
- );
- if (EFI_ERROR (Status)) {
- FreePool (ProcessorLocBuf);
- return Status;
- }
- //
- // Get all Processor Location info & measure
- //
- CopyMem (
- &ProcessorLocBuf[Index],
- &ProcessorInfo.Location,
- sizeof (EFI_CPU_PHYSICAL_LOCATION)
- );
- }
- *LocationBuf = ProcessorLocBuf;
- *Num = ProcessorNum;
- return Status;
- }
- /**
- The EFI_CC_MEASUREMENT_PROTOCOL GetCapability function call provides protocol
- capability information and state information.
- @param[in] This Indicates the calling context
- @param[in, out] ProtocolCapability The caller allocates memory for a EFI_CC_BOOT_SERVICE_CAPABILITY
- structure and sets the size field to the size of the structure allocated.
- The callee fills in the fields with the EFI protocol capability information
- and the current EFI TCG2 state information up to the number of fields which
- fit within the size of the structure passed in.
- @retval EFI_SUCCESS Operation completed successfully.
- @retval EFI_DEVICE_ERROR The command was unsuccessful.
- 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).
- **/
- EFI_STATUS
- EFIAPI
- TdGetCapability (
- IN EFI_CC_MEASUREMENT_PROTOCOL *This,
- IN OUT EFI_CC_BOOT_SERVICE_CAPABILITY *ProtocolCapability
- )
- {
- DEBUG ((DEBUG_VERBOSE, "TdGetCapability\n"));
- if ((This == NULL) || (ProtocolCapability == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- CopyMem (ProtocolCapability, &mTdxDxeData.BsCap, sizeof (EFI_CC_BOOT_SERVICE_CAPABILITY));
- return EFI_SUCCESS;
- }
- /**
- This function dump PCR event.
- TD Event log reuse the TCG PCR Event spec.
- The first event in the event log is the SHA1 log format.
- There is only ONE TCG_PCR_EVENT in TD Event log.
- @param[in] EventHdr TCG PCR event structure.
- **/
- VOID
- DumpPcrEvent (
- IN TCG_PCR_EVENT_HDR *EventHdr
- )
- {
- UINTN Index;
- DEBUG ((DEBUG_INFO, " Event:\n"));
- DEBUG ((DEBUG_INFO, " MrIndex - %d\n", EventHdr->PCRIndex));
- DEBUG ((DEBUG_INFO, " EventType - 0x%08x\n", EventHdr->EventType));
- DEBUG ((DEBUG_INFO, " Digest - "));
- for (Index = 0; Index < sizeof (TCG_DIGEST); Index++) {
- DEBUG ((DEBUG_INFO, "%02x ", EventHdr->Digest.digest[Index]));
- }
- DEBUG ((DEBUG_INFO, "\n"));
- DEBUG ((DEBUG_INFO, " EventSize - 0x%08x\n", EventHdr->EventSize));
- InternalDumpHex ((UINT8 *)(EventHdr + 1), EventHdr->EventSize);
- }
- /**
- This function dump TCG_EfiSpecIDEventStruct.
- @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
- **/
- VOID
- DumpTcgEfiSpecIdEventStruct (
- IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct
- )
- {
- TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
- UINTN Index;
- UINT8 *VendorInfoSize;
- UINT8 *VendorInfo;
- UINT32 NumberOfAlgorithms;
- DEBUG ((DEBUG_INFO, " TCG_EfiSpecIDEventStruct:\n"));
- DEBUG ((DEBUG_INFO, " signature - '"));
- for (Index = 0; Index < sizeof (TcgEfiSpecIdEventStruct->signature); Index++) {
- DEBUG ((DEBUG_INFO, "%c", TcgEfiSpecIdEventStruct->signature[Index]));
- }
- DEBUG ((DEBUG_INFO, "'\n"));
- DEBUG ((DEBUG_INFO, " platformClass - 0x%08x\n", TcgEfiSpecIdEventStruct->platformClass));
- DEBUG ((DEBUG_INFO, " specVersion - %d.%d%d\n", TcgEfiSpecIdEventStruct->specVersionMajor, TcgEfiSpecIdEventStruct->specVersionMinor, TcgEfiSpecIdEventStruct->specErrata));
- DEBUG ((DEBUG_INFO, " uintnSize - 0x%02x\n", TcgEfiSpecIdEventStruct->uintnSize));
- CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof (NumberOfAlgorithms));
- DEBUG ((DEBUG_INFO, " NumberOfAlgorithms - 0x%08x\n", NumberOfAlgorithms));
- DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof (*TcgEfiSpecIdEventStruct) + sizeof (NumberOfAlgorithms));
- for (Index = 0; Index < NumberOfAlgorithms; Index++) {
- DEBUG ((DEBUG_INFO, " digest(%d)\n", Index));
- DEBUG ((DEBUG_INFO, " algorithmId - 0x%04x\n", DigestSize[Index].algorithmId));
- DEBUG ((DEBUG_INFO, " digestSize - 0x%04x\n", DigestSize[Index].digestSize));
- }
- VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms];
- DEBUG ((DEBUG_INFO, " VendorInfoSize - 0x%02x\n", *VendorInfoSize));
- VendorInfo = VendorInfoSize + 1;
- DEBUG ((DEBUG_INFO, " VendorInfo - "));
- for (Index = 0; Index < *VendorInfoSize; Index++) {
- DEBUG ((DEBUG_INFO, "%02x ", VendorInfo[Index]));
- }
- DEBUG ((DEBUG_INFO, "\n"));
- }
- /**
- This function get size of TCG_EfiSpecIDEventStruct.
- @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
- **/
- UINTN
- GetTcgEfiSpecIdEventStructSize (
- IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct
- )
- {
- TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
- UINT8 *VendorInfoSize;
- UINT32 NumberOfAlgorithms;
- CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof (NumberOfAlgorithms));
- DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof (*TcgEfiSpecIdEventStruct) + sizeof (NumberOfAlgorithms));
- VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms];
- return sizeof (TCG_EfiSpecIDEventStruct) + sizeof (UINT32) + (NumberOfAlgorithms * sizeof (TCG_EfiSpecIdEventAlgorithmSize)) + sizeof (UINT8) + (*VendorInfoSize);
- }
- /**
- This function dump TD Event (including the Digests).
- @param[in] CcEvent TD Event structure.
- **/
- VOID
- DumpCcEvent (
- IN CC_EVENT *CcEvent
- )
- {
- UINT32 DigestIndex;
- UINT32 DigestCount;
- TPMI_ALG_HASH HashAlgo;
- UINT32 DigestSize;
- UINT8 *DigestBuffer;
- UINT32 EventSize;
- UINT8 *EventBuffer;
- DEBUG ((DEBUG_INFO, "Cc Event:\n"));
- DEBUG ((DEBUG_INFO, " MrIndex - %d\n", CcEvent->MrIndex));
- DEBUG ((DEBUG_INFO, " EventType - 0x%08x\n", CcEvent->EventType));
- DEBUG ((DEBUG_INFO, " DigestCount: 0x%08x\n", CcEvent->Digests.count));
- DigestCount = CcEvent->Digests.count;
- HashAlgo = CcEvent->Digests.digests[0].hashAlg;
- DigestBuffer = (UINT8 *)&CcEvent->Digests.digests[0].digest;
- for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {
- DEBUG ((DEBUG_INFO, " HashAlgo : 0x%04x\n", HashAlgo));
- DEBUG ((DEBUG_INFO, " Digest(%d): \n", DigestIndex));
- DigestSize = GetHashSizeFromAlgo (HashAlgo);
- InternalDumpHex (DigestBuffer, DigestSize);
- //
- // Prepare next
- //
- CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof (TPMI_ALG_HASH));
- DigestBuffer = DigestBuffer + DigestSize + sizeof (TPMI_ALG_HASH);
- }
- DigestBuffer = DigestBuffer - sizeof (TPMI_ALG_HASH);
- CopyMem (&EventSize, DigestBuffer, sizeof (CcEvent->EventSize));
- DEBUG ((DEBUG_INFO, " EventSize - 0x%08x\n", EventSize));
- EventBuffer = DigestBuffer + sizeof (CcEvent->EventSize);
- InternalDumpHex (EventBuffer, EventSize);
- DEBUG ((DEBUG_INFO, "\n"));
- }
- /**
- This function returns size of Td Table event.
- @param[in] CcEvent Td Table event structure.
- @return size of Td event.
- **/
- UINTN
- GetCcEventSize (
- IN CC_EVENT *CcEvent
- )
- {
- UINT32 DigestIndex;
- UINT32 DigestCount;
- TPMI_ALG_HASH HashAlgo;
- UINT32 DigestSize;
- UINT8 *DigestBuffer;
- UINT32 EventSize;
- UINT8 *EventBuffer;
- DigestCount = CcEvent->Digests.count;
- HashAlgo = CcEvent->Digests.digests[0].hashAlg;
- DigestBuffer = (UINT8 *)&CcEvent->Digests.digests[0].digest;
- for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {
- DigestSize = GetHashSizeFromAlgo (HashAlgo);
- //
- // Prepare next
- //
- CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof (TPMI_ALG_HASH));
- DigestBuffer = DigestBuffer + DigestSize + sizeof (TPMI_ALG_HASH);
- }
- DigestBuffer = DigestBuffer - sizeof (TPMI_ALG_HASH);
- CopyMem (&EventSize, DigestBuffer, sizeof (CcEvent->EventSize));
- EventBuffer = DigestBuffer + sizeof (CcEvent->EventSize);
- return (UINTN)EventBuffer + EventSize - (UINTN)CcEvent;
- }
- /**
- This function dump CC event log.
- TDVF only supports EFI_CC_EVENT_LOG_FORMAT_TCG_2
- @param[in] EventLogFormat The type of the event log for which the information is requested.
- @param[in] EventLogLocation A pointer to the memory address of the event log.
- @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
- address of the start of the last entry in the event log in memory.
- @param[in] FinalEventsTable A pointer to the memory address of the final event table.
- **/
- VOID
- DumpCcEventLog (
- IN EFI_CC_EVENT_LOG_FORMAT EventLogFormat,
- IN EFI_PHYSICAL_ADDRESS EventLogLocation,
- IN EFI_PHYSICAL_ADDRESS EventLogLastEntry,
- IN EFI_CC_FINAL_EVENTS_TABLE *FinalEventsTable
- )
- {
- TCG_PCR_EVENT_HDR *EventHdr;
- CC_EVENT *CcEvent;
- TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;
- UINTN NumberOfEvents;
- DEBUG ((DEBUG_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));
- ASSERT (EventLogFormat == EFI_CC_EVENT_LOG_FORMAT_TCG_2);
- //
- // Dump first event.
- // The first event is always the TCG_PCR_EVENT_HDR
- // After this event is a TCG_EfiSpecIDEventStruct
- //
- EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;
- DumpPcrEvent (EventHdr);
- TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)(EventHdr + 1);
- DumpTcgEfiSpecIdEventStruct (TcgEfiSpecIdEventStruct);
- //
- // Then the CcEvent (Its structure is similar to TCG_PCR_EVENT2)
- //
- CcEvent = (CC_EVENT *)((UINTN)TcgEfiSpecIdEventStruct + GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct));
- while ((UINTN)CcEvent <= EventLogLastEntry) {
- DumpCcEvent (CcEvent);
- CcEvent = (CC_EVENT *)((UINTN)CcEvent + GetCcEventSize (CcEvent));
- }
- if (FinalEventsTable == NULL) {
- DEBUG ((DEBUG_INFO, "FinalEventsTable: NOT FOUND\n"));
- } else {
- DEBUG ((DEBUG_INFO, "FinalEventsTable: (0x%x)\n", FinalEventsTable));
- DEBUG ((DEBUG_INFO, " Version: (0x%x)\n", FinalEventsTable->Version));
- DEBUG ((DEBUG_INFO, " NumberOfEvents: (0x%x)\n", FinalEventsTable->NumberOfEvents));
- CcEvent = (CC_EVENT *)(UINTN)(FinalEventsTable + 1);
- for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) {
- DumpCcEvent (CcEvent);
- CcEvent = (CC_EVENT *)((UINTN)CcEvent + GetCcEventSize (CcEvent));
- }
- }
- return;
- }
- /**
- The EFI_CC_MEASUREMENT_PROTOCOL Get Event Log function call allows a caller to
- 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.
- @param[out] EventLogLocation A pointer to the memory address of the event log.
- @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
- address of the start of the last entry in the event log in memory.
- @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would
- have exceeded the area allocated for events, this value is set to TRUE.
- Otherwise, the value will be FALSE and the Event Log will be complete.
- @retval EFI_SUCCESS Operation completed successfully.
- @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect
- (e.g. asking for an event log whose format is not supported).
- **/
- EFI_STATUS
- EFIAPI
- TdGetEventLog (
- IN EFI_CC_MEASUREMENT_PROTOCOL *This,
- IN EFI_CC_EVENT_LOG_FORMAT EventLogFormat,
- OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
- OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry,
- OUT BOOLEAN *EventLogTruncated
- )
- {
- UINTN Index = 0;
- DEBUG ((DEBUG_INFO, "TdGetEventLog ... (0x%x)\n", EventLogFormat));
- ASSERT (EventLogFormat == EFI_CC_EVENT_LOG_FORMAT_TCG_2);
- if (EventLogLocation != NULL) {
- *EventLogLocation = mTdxDxeData.EventLogAreaStruct[Index].Lasa;
- DEBUG ((DEBUG_INFO, "TdGetEventLog (EventLogLocation - %x)\n", *EventLogLocation));
- }
- if (EventLogLastEntry != NULL) {
- if (!mTdxDxeData.EventLogAreaStruct[Index].EventLogStarted) {
- *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0;
- } else {
- *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)mTdxDxeData.EventLogAreaStruct[Index].LastEvent;
- }
- DEBUG ((DEBUG_INFO, "TdGetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry));
- }
- if (EventLogTruncated != NULL) {
- *EventLogTruncated = mTdxDxeData.EventLogAreaStruct[Index].EventLogTruncated;
- DEBUG ((DEBUG_INFO, "TdGetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated));
- }
- DEBUG ((DEBUG_INFO, "TdGetEventLog - %r\n", EFI_SUCCESS));
- // Dump Event Log for debug purpose
- if ((EventLogLocation != NULL) && (EventLogLastEntry != NULL)) {
- DumpCcEventLog (EventLogFormat, *EventLogLocation, *EventLogLastEntry, mTdxDxeData.FinalEventsTable[Index]);
- }
- //
- // All events generated after the invocation of EFI_TCG2_GET_EVENT_LOG SHALL be stored
- // in an instance of an EFI_CONFIGURATION_TABLE named by the VendorGuid of EFI_TCG2_FINAL_EVENTS_TABLE_GUID.
- //
- mTdxDxeData.GetEventLogCalled[Index] = TRUE;
- return EFI_SUCCESS;
- }
- /**
- Return if this is a Tcg800155PlatformIdEvent.
- @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] NewEventSize New event data size.
- @retval TRUE This is a Tcg800155PlatformIdEvent.
- @retval FALSE This is NOT a Tcg800155PlatformIdEvent.
- **/
- BOOLEAN
- Is800155Event (
- IN VOID *NewEventHdr,
- IN UINT32 NewEventHdrSize,
- IN UINT8 *NewEventData,
- IN UINT32 NewEventSize
- )
- {
- if ((((TCG_PCR_EVENT2_HDR *)NewEventHdr)->EventType == EV_NO_ACTION) &&
- (NewEventSize >= sizeof (TCG_Sp800_155_PlatformId_Event2)) &&
- (CompareMem (
- NewEventData,
- TCG_Sp800_155_PlatformId_Event2_SIGNATURE,
- sizeof (TCG_Sp800_155_PlatformId_Event2_SIGNATURE) - 1
- ) == 0))
- {
- return TRUE;
- }
- return FALSE;
- }
- /**
- Add a new entry to the Event Log.
- @param[in, out] EventLogAreaStruct The event log area 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] 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.
- **/
- EFI_STATUS
- TcgCommLogEvent (
- IN OUT CC_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct,
- IN VOID *NewEventHdr,
- IN UINT32 NewEventHdrSize,
- IN UINT8 *NewEventData,
- IN UINT32 NewEventSize
- )
- {
- UINTN NewLogSize;
- BOOLEAN Record800155Event;
- CC_EVENT_HDR *CcEventHdr;
- CcEventHdr = (CC_EVENT_HDR *)NewEventHdr;
- DEBUG ((DEBUG_VERBOSE, "Td: Try to log event. Index = %d, EventType = 0x%x\n", CcEventHdr->MrIndex, CcEventHdr->EventType));
- if (NewEventSize > MAX_ADDRESS - NewEventHdrSize) {
- return EFI_OUT_OF_RESOURCES;
- }
- NewLogSize = NewEventHdrSize + NewEventSize;
- if (NewLogSize > MAX_ADDRESS - EventLogAreaStruct->EventLogSize) {
- return EFI_OUT_OF_RESOURCES;
- }
- if (NewLogSize + EventLogAreaStruct->EventLogSize > EventLogAreaStruct->Laml) {
- DEBUG ((DEBUG_INFO, " Laml - 0x%x\n", EventLogAreaStruct->Laml));
- DEBUG ((DEBUG_INFO, " NewLogSize - 0x%x\n", NewLogSize));
- DEBUG ((DEBUG_INFO, " LogSize - 0x%x\n", EventLogAreaStruct->EventLogSize));
- DEBUG ((DEBUG_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Check 800-155 event
- // Record to 800-155 event offset only.
- // If the offset is 0, no need to record.
- //
- Record800155Event = Is800155Event (NewEventHdr, NewEventHdrSize, NewEventData, NewEventSize);
- if (Record800155Event) {
- DEBUG ((DEBUG_INFO, "It is 800155Event.\n"));
- if (EventLogAreaStruct->Next800155EventOffset != 0) {
- CopyMem (
- (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset + NewLogSize,
- (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset,
- EventLogAreaStruct->EventLogSize - EventLogAreaStruct->Next800155EventOffset
- );
- CopyMem (
- (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset,
- NewEventHdr,
- NewEventHdrSize
- );
- CopyMem (
- (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset + NewEventHdrSize,
- NewEventData,
- NewEventSize
- );
- EventLogAreaStruct->Next800155EventOffset += NewLogSize;
- EventLogAreaStruct->LastEvent += NewLogSize;
- EventLogAreaStruct->EventLogSize += NewLogSize;
- }
- return EFI_SUCCESS;
- }
- EventLogAreaStruct->LastEvent = (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->EventLogSize;
- EventLogAreaStruct->EventLogSize += NewLogSize;
- CopyMem (EventLogAreaStruct->LastEvent, NewEventHdr, NewEventHdrSize);
- CopyMem (
- EventLogAreaStruct->LastEvent + NewEventHdrSize,
- NewEventData,
- NewEventSize
- );
- return EFI_SUCCESS;
- }
- /**
- According to UEFI Spec 2.10 Section 38.4.1:
- The following table shows the TPM PCR index mapping and CC event log measurement
- register index interpretation for Intel TDX, where MRTD means Trust Domain Measurement
- Register and RTMR means Runtime Measurement Register
- // TPM PCR Index | CC Measurement Register Index | TDX-measurement register
- // ------------------------------------------------------------------------
- // 0 | 0 | MRTD
- // 1, 7 | 1 | RTMR[0]
- // 2~6 | 2 | RTMR[1]
- // 8~15 | 3 | RTMR[2]
- @param[in] PCRIndex Index of the TPM PCR
- @retval UINT32 Index of the CC Event Log Measurement Register Index
- @retval CC_MR_INDEX_INVALID Invalid MR Index
- **/
- UINT32
- EFIAPI
- MapPcrToMrIndex (
- IN UINT32 PCRIndex
- )
- {
- UINT32 MrIndex;
- if (PCRIndex > 15) {
- ASSERT (FALSE);
- return CC_MR_INDEX_INVALID;
- }
- MrIndex = 0;
- if (PCRIndex == 0) {
- MrIndex = CC_MR_INDEX_0_MRTD;
- } else if ((PCRIndex == 1) || (PCRIndex == 7)) {
- MrIndex = CC_MR_INDEX_1_RTMR0;
- } else if ((PCRIndex >= 2) && (PCRIndex <= 6)) {
- MrIndex = CC_MR_INDEX_2_RTMR1;
- } else if ((PCRIndex >= 8) && (PCRIndex <= 15)) {
- MrIndex = CC_MR_INDEX_3_RTMR2;
- }
- return MrIndex;
- }
- EFI_STATUS
- EFIAPI
- TdMapPcrToMrIndex (
- IN EFI_CC_MEASUREMENT_PROTOCOL *This,
- IN UINT32 PCRIndex,
- OUT UINT32 *MrIndex
- )
- {
- if (MrIndex == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- *MrIndex = MapPcrToMrIndex (PCRIndex);
- return *MrIndex == CC_MR_INDEX_INVALID ? EFI_INVALID_PARAMETER : EFI_SUCCESS;
- }
- /**
- 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] NewEventHdrSize New event header size.
- @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.
- **/
- EFI_STATUS
- TdxDxeLogEvent (
- IN EFI_CC_EVENT_LOG_FORMAT EventLogFormat,
- IN VOID *NewEventHdr,
- IN UINT32 NewEventHdrSize,
- IN UINT8 *NewEventData,
- IN UINT32 NewEventSize
- )
- {
- EFI_STATUS Status;
- UINTN Index;
- CC_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct;
- if (EventLogFormat != EFI_CC_EVENT_LOG_FORMAT_TCG_2) {
- ASSERT (FALSE);
- return EFI_INVALID_PARAMETER;
- }
- Index = 0;
- //
- // Record to normal event log
- //
- EventLogAreaStruct = &mTdxDxeData.EventLogAreaStruct[Index];
- if (EventLogAreaStruct->EventLogTruncated) {
- return EFI_VOLUME_FULL;
- }
- Status = TcgCommLogEvent (
- EventLogAreaStruct,
- 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;
- }
- //
- // If GetEventLog is called, record to FinalEventsTable, too.
- //
- if (mTdxDxeData.GetEventLogCalled[Index]) {
- if (mTdxDxeData.FinalEventsTable[Index] == NULL) {
- //
- // no need for FinalEventsTable
- //
- return EFI_SUCCESS;
- }
- EventLogAreaStruct = &mTdxDxeData.FinalEventLogAreaStruct[Index];
- if (EventLogAreaStruct->EventLogTruncated) {
- return EFI_VOLUME_FULL;
- }
- Status = TcgCommLogEvent (
- EventLogAreaStruct,
- 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
- //
- (mTdxDxeData.FinalEventsTable[Index])->NumberOfEvents++;
- DEBUG ((DEBUG_INFO, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTdxDxeData.FinalEventsTable[Index])->NumberOfEvents));
- DEBUG ((DEBUG_INFO, " Size - 0x%x\n", (UINTN)EventLogAreaStruct->EventLogSize));
- }
- }
- return Status;
- }
- /**
- Get TPML_DIGEST_VALUES compact binary buffer size.
- @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
- @return TPML_DIGEST_VALUES compact binary buffer size.
- **/
- UINT32
- GetDigestListBinSize (
- IN VOID *DigestListBin
- )
- {
- UINTN Index;
- UINT16 DigestSize;
- UINT32 TotalSize;
- UINT32 Count;
- TPMI_ALG_HASH HashAlg;
- Count = ReadUnaligned32 (DigestListBin);
- TotalSize = sizeof (Count);
- DigestListBin = (UINT8 *)DigestListBin + sizeof (Count);
- for (Index = 0; Index < Count; Index++) {
- HashAlg = ReadUnaligned16 (DigestListBin);
- TotalSize += sizeof (HashAlg);
- DigestListBin = (UINT8 *)DigestListBin + sizeof (HashAlg);
- DigestSize = GetHashSizeFromAlgo (HashAlg);
- TotalSize += DigestSize;
- DigestListBin = (UINT8 *)DigestListBin + DigestSize;
- }
- return TotalSize;
- }
- /**
- Copy TPML_DIGEST_VALUES compact binary into a buffer
- @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.
- @return The end of buffer to hold TPML_DIGEST_VALUES compact binary.
- **/
- VOID *
- CopyDigestListBinToBuffer (
- IN OUT VOID *Buffer,
- IN VOID *DigestListBin,
- IN UINT32 HashAlgorithmMask,
- OUT UINT32 *HashAlgorithmMaskCopied
- )
- {
- UINTN Index;
- UINT16 DigestSize;
- UINT32 Count;
- TPMI_ALG_HASH HashAlg;
- UINT32 DigestListCount;
- UINT32 *DigestListCountPtr;
- DigestListCountPtr = (UINT32 *)Buffer;
- DigestListCount = 0;
- *HashAlgorithmMaskCopied = 0;
- 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);
- if ((HashAlg & HashAlgorithmMask) != 0) {
- 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));
- }
- DigestListBin = (UINT8 *)DigestListBin + DigestSize;
- }
- WriteUnaligned32 (DigestListCountPtr, DigestListCount);
- return Buffer;
- }
- /**
- Add a new entry to the Event Log. The call chain is like below:
- TdxDxeLogHashEvent -> TdxDxeLogEvent -> TcgCommonLogEvent
- Before this function is called, the event information (including the digest)
- is ready.
- @param[in] DigestList A list of digest.
- @param[in,out] NewEventHdr Pointer to a TD_EVENT_HDR data structure.
- @param[in] NewEventData Pointer to the new event data.
- @retval EFI_SUCCESS The new event log entry was added.
- @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
- **/
- EFI_STATUS
- TdxDxeLogHashEvent (
- IN TPML_DIGEST_VALUES *DigestList,
- IN OUT CC_EVENT_HDR *NewEventHdr,
- IN UINT8 *NewEventData
- )
- {
- EFI_STATUS Status;
- EFI_TPL OldTpl;
- EFI_STATUS RetStatus;
- CC_EVENT CcEvent;
- UINT8 *DigestBuffer;
- UINT32 *EventSizePtr;
- EFI_CC_EVENT_LOG_FORMAT LogFormat;
- RetStatus = EFI_SUCCESS;
- LogFormat = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
- ZeroMem (&CcEvent, sizeof (CcEvent));
- CcEvent.MrIndex = NewEventHdr->MrIndex;
- CcEvent.EventType = NewEventHdr->EventType;
- DigestBuffer = (UINT8 *)&CcEvent.Digests;
- EventSizePtr = CopyDigestListToBuffer (DigestBuffer, DigestList, HASH_ALG_SHA384);
- CopyMem (EventSizePtr, &NewEventHdr->EventSize, sizeof (NewEventHdr->EventSize));
- //
- // Enter critical region
- //
- OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
- Status = TdxDxeLogEvent (
- LogFormat,
- &CcEvent,
- sizeof (CcEvent.MrIndex) + sizeof (CcEvent.EventType) + GetDigestListBinSize (DigestBuffer) + sizeof (CcEvent.EventSize),
- NewEventData,
- NewEventHdr->EventSize
- );
- if (Status != EFI_SUCCESS) {
- RetStatus = Status;
- }
- gBS->RestoreTPL (OldTpl);
- return RetStatus;
- }
- /**
- Do a hash operation on a data buffer, extend a specific RTMR with the hash result,
- 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
- 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 TD_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.
- @retval EFI_DEVICE_ERROR The command was unsuccessful.
- **/
- EFI_STATUS
- TdxDxeHashLogExtendEvent (
- IN UINT64 Flags,
- IN UINT8 *HashData,
- IN UINT64 HashDataLen,
- IN OUT CC_EVENT_HDR *NewEventHdr,
- IN UINT8 *NewEventData
- )
- {
- EFI_STATUS Status;
- TPML_DIGEST_VALUES DigestList;
- CC_EVENT_HDR NoActionEvent;
- if (NewEventHdr->EventType == EV_NO_ACTION) {
- //
- // Do not do RTMR extend for EV_NO_ACTION
- //
- Status = EFI_SUCCESS;
- InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);
- if ((Flags & EFI_CC_FLAG_EXTEND_ONLY) == 0) {
- Status = TdxDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr, NewEventData);
- }
- return Status;
- }
- //
- // According to UEFI Spec 2.10 Section 38.4.1 the mapping between MrIndex and Intel
- // TDX Measurement Register is:
- // MrIndex 0 <--> MRTD
- // MrIndex 1-3 <--> RTMR[0-2]
- // Only the RMTR registers can be extended in TDVF by HashAndExtend. So MrIndex will
- // decreased by 1 before it is sent to HashAndExtend.
- //
- Status = HashAndExtend (
- NewEventHdr->MrIndex - 1,
- HashData,
- (UINTN)HashDataLen,
- &DigestList
- );
- if (!EFI_ERROR (Status)) {
- if ((Flags & EFI_CC_FLAG_EXTEND_ONLY) == 0) {
- Status = TdxDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);
- }
- }
- return Status;
- }
- /**
- The EFI_CC_MEASUREMENT_PROTOCOL HashLogExtendEvent function call provides callers with
- an opportunity to extend and optionally log events without requiring
- 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).
- @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] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
- @param[in] Event Pointer to data buffer containing information about the event.
- @retval EFI_SUCCESS Operation completed successfully.
- @retval EFI_DEVICE_ERROR The command was unsuccessful.
- @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
- @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
- @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
- **/
- EFI_STATUS
- EFIAPI
- TdHashLogExtendEvent (
- IN EFI_CC_MEASUREMENT_PROTOCOL *This,
- IN UINT64 Flags,
- IN EFI_PHYSICAL_ADDRESS DataToHash,
- IN UINT64 DataToHashLen,
- IN EFI_CC_EVENT *CcEvent
- )
- {
- EFI_STATUS Status;
- CC_EVENT_HDR NewEventHdr;
- TPML_DIGEST_VALUES DigestList;
- DEBUG ((DEBUG_VERBOSE, "TdHashLogExtendEvent ...\n"));
- if ((This == NULL) || (CcEvent == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Do not check hash data size for EV_NO_ACTION event.
- //
- if ((CcEvent->Header.EventType != EV_NO_ACTION) && (DataToHash == 0)) {
- return EFI_INVALID_PARAMETER;
- }
- if (CcEvent->Size < CcEvent->Header.HeaderSize + sizeof (UINT32)) {
- return EFI_INVALID_PARAMETER;
- }
- if (CcEvent->Header.MrIndex == CC_MR_INDEX_0_MRTD) {
- DEBUG ((DEBUG_ERROR, "%a: MRTD cannot be extended in TDVF.\n", __FUNCTION__));
- return EFI_INVALID_PARAMETER;
- }
- if (CcEvent->Header.MrIndex >= CC_MR_INDEX_INVALID) {
- DEBUG ((DEBUG_ERROR, "%a: MrIndex is invalid. (%d)\n", __FUNCTION__, CcEvent->Header.MrIndex));
- return EFI_INVALID_PARAMETER;
- }
- NewEventHdr.MrIndex = CcEvent->Header.MrIndex;
- NewEventHdr.EventType = CcEvent->Header.EventType;
- NewEventHdr.EventSize = CcEvent->Size - sizeof (UINT32) - CcEvent->Header.HeaderSize;
- if ((Flags & EFI_CC_FLAG_PE_COFF_IMAGE) != 0) {
- //
- // According to UEFI Spec 2.10 Section 38.4.1 the mapping between MrIndex and Intel
- // TDX Measurement Register is:
- // MrIndex 0 <--> MRTD
- // MrIndex 1-3 <--> RTMR[0-2]
- // Only the RMTR registers can be extended in TDVF by HashAndExtend. So MrIndex will
- // decreased by 1 before it is sent to MeasurePeImageAndExtend.
- //
- Status = MeasurePeImageAndExtend (
- NewEventHdr.MrIndex - 1,
- DataToHash,
- (UINTN)DataToHashLen,
- &DigestList
- );
- if (!EFI_ERROR (Status)) {
- if ((Flags & EFI_CC_FLAG_EXTEND_ONLY) == 0) {
- Status = TdxDxeLogHashEvent (&DigestList, &NewEventHdr, CcEvent->Event);
- }
- }
- } else {
- Status = TdxDxeHashLogExtendEvent (
- Flags,
- (UINT8 *)(UINTN)DataToHash,
- DataToHashLen,
- &NewEventHdr,
- CcEvent->Event
- );
- }
- DEBUG ((DEBUG_VERBOSE, "TdHashLogExtendEvent - %r\n", Status));
- return Status;
- }
- EFI_CC_MEASUREMENT_PROTOCOL mTdProtocol = {
- TdGetCapability,
- TdGetEventLog,
- TdHashLogExtendEvent,
- TdMapPcrToMrIndex,
- };
- #define TD_HASH_COUNT 1
- #define TEMP_BUF_LEN (sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) \
- + (TD_HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8))
- /**
- Initialize the TD Event Log and log events passed from the PEI phase.
- @retval EFI_SUCCESS Operation completed successfully.
- @retval EFI_OUT_OF_RESOURCES Out of memory.
- **/
- EFI_STATUS
- SetupCcEventLog (
- VOID
- )
- {
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS Lasa;
- UINTN Index;
- TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;
- UINT8 TempBuf[TEMP_BUF_LEN];
- TCG_PCR_EVENT_HDR SpecIdEvent;
- TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
- TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;
- UINT8 *VendorInfoSize;
- UINT32 NumberOfAlgorithms;
- EFI_CC_EVENT_LOG_FORMAT LogFormat;
- EFI_PEI_HOB_POINTERS GuidHob;
- CC_EVENT_HDR NoActionEvent;
- Status = EFI_SUCCESS;
- DEBUG ((DEBUG_INFO, "SetupCcEventLog\n"));
- Index = 0;
- LogFormat = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
- //
- // 1. Create Log Area
- //
- mTdxDxeData.EventLogAreaStruct[Index].EventLogFormat = LogFormat;
- // allocate pages for TD Event log
- Status = gBS->AllocatePages (
- AllocateAnyPages,
- EfiACPIMemoryNVS,
- EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
- &Lasa
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- mTdxDxeData.EventLogAreaStruct[Index].Lasa = Lasa;
- mTdxDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);
- mTdxDxeData.EventLogAreaStruct[Index].Next800155EventOffset = 0;
- //
- // Report TD event log address and length, so that they can be reported in
- // TD ACPI table. Ignore the return status, because those fields are optional.
- //
- PcdSet32S (PcdCcEventlogAcpiTableLaml, (UINT32)mTdxDxeData.EventLogAreaStruct[Index].Laml);
- PcdSet64S (PcdCcEventlogAcpiTableLasa, mTdxDxeData.EventLogAreaStruct[Index].Lasa);
- //
- // To initialize them as 0xFF is recommended
- // because the OS can know the last entry for that.
- //
- SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);
- //
- // Create first entry for Log Header Entry Data
- //
- //
- // TcgEfiSpecIdEventStruct
- //
- TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)TempBuf;
- CopyMem (TcgEfiSpecIdEventStruct->signature, TCG_EfiSpecIDEventStruct_SIGNATURE_03, sizeof (TcgEfiSpecIdEventStruct->signature));
- TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);
- TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;
- TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;
- TcgEfiSpecIdEventStruct->specErrata = TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2;
- TcgEfiSpecIdEventStruct->uintnSize = sizeof (UINTN)/sizeof (UINT32);
- NumberOfAlgorithms = 0;
- DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct
- + sizeof (*TcgEfiSpecIdEventStruct)
- + sizeof (NumberOfAlgorithms));
- TempDigestSize = DigestSize;
- TempDigestSize += NumberOfAlgorithms;
- TempDigestSize->algorithmId = TPM_ALG_SHA384;
- TempDigestSize->digestSize = SHA384_DIGEST_SIZE;
- NumberOfAlgorithms++;
- CopyMem (TcgEfiSpecIdEventStruct + 1, &NumberOfAlgorithms, sizeof (NumberOfAlgorithms));
- TempDigestSize = DigestSize;
- TempDigestSize += NumberOfAlgorithms;
- VendorInfoSize = (UINT8 *)TempDigestSize;
- *VendorInfoSize = 0;
- SpecIdEvent.PCRIndex = 1; // PCRIndex 0 maps to MrIndex 1
- SpecIdEvent.EventType = EV_NO_ACTION;
- ZeroMem (&SpecIdEvent.Digest, sizeof (SpecIdEvent.Digest));
- SpecIdEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);
- //
- // TD Event log re-use the spec of TCG2 Event log.
- // 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 = TdxDxeLogEvent (
- LogFormat,
- &SpecIdEvent,
- sizeof (SpecIdEvent),
- (UINT8 *)TcgEfiSpecIdEventStruct,
- SpecIdEvent.EventSize
- );
- //
- // record the offset at the end of 800-155 event.
- // the future 800-155 event can be inserted here.
- //
- mTdxDxeData.EventLogAreaStruct[Index].Next800155EventOffset = mTdxDxeData.EventLogAreaStruct[Index].EventLogSize;
- //
- // Tcg800155PlatformIdEvent. Event format is TCG_PCR_EVENT2
- //
- GuidHob.Guid = GetFirstGuidHob (&gTcg800155PlatformIdEventHobGuid);
- while (GuidHob.Guid != NULL) {
- InitNoActionEvent (&NoActionEvent, GET_GUID_HOB_DATA_SIZE (GuidHob.Guid));
- Status = TdxDxeLogEvent (
- LogFormat,
- &NoActionEvent,
- sizeof (NoActionEvent.MrIndex) + sizeof (NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof (NoActionEvent.EventSize),
- GET_GUID_HOB_DATA (GuidHob.Guid),
- GET_GUID_HOB_DATA_SIZE (GuidHob.Guid)
- );
- GuidHob.Guid = GET_NEXT_HOB (GuidHob);
- GuidHob.Guid = GetNextGuidHob (&gTcg800155PlatformIdEventHobGuid, GuidHob.Guid);
- }
- //
- // 2. Create Final Log Area
- //
- 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
- //
- mTdxDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;
- (mTdxDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;
- (mTdxDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;
- mTdxDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = LogFormat;
- mTdxDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof (EFI_CC_FINAL_EVENTS_TABLE);
- mTdxDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof (EFI_CC_FINAL_EVENTS_TABLE);
- mTdxDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
- mTdxDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTdxDxeData.FinalEventLogAreaStruct[Index].Lasa;
- mTdxDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
- mTdxDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
- mTdxDxeData.FinalEventLogAreaStruct[Index].Next800155EventOffset = 0;
- //
- // Install to configuration table for EFI_CC_EVENT_LOG_FORMAT_TCG_2
- //
- Status = gBS->InstallConfigurationTable (&gEfiCcFinalEventsTableGuid, (VOID *)mTdxDxeData.FinalEventsTable[Index]);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- return Status;
- }
- /**
- Measure and log an action string, and extend the measurement result into RTMR.
- @param[in] MrIndex MrIndex to extend
- @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
- TdMeasureAction (
- IN UINT32 MrIndex,
- IN CHAR8 *String
- )
- {
- CC_EVENT_HDR CcEvent;
- CcEvent.MrIndex = MrIndex;
- CcEvent.EventType = EV_EFI_ACTION;
- CcEvent.EventSize = (UINT32)AsciiStrLen (String);
- return TdxDxeHashLogExtendEvent (
- 0,
- (UINT8 *)String,
- CcEvent.EventSize,
- &CcEvent,
- (UINT8 *)String
- );
- }
- /**
- Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
- @retval EFI_SUCCESS Operation completed successfully.
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.
- **/
- EFI_STATUS
- MeasureHandoffTables (
- VOID
- )
- {
- EFI_STATUS Status;
- CC_EVENT_HDR CcEvent;
- EFI_HANDOFF_TABLE_POINTERS HandoffTables;
- UINTN ProcessorNum;
- EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
- ProcessorLocBuf = NULL;
- Status = EFI_SUCCESS;
- if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
- //
- // Tcg Server spec.
- // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
- //
- Status = GetProcessorsCpuLocation (&ProcessorLocBuf, &ProcessorNum);
- if (!EFI_ERROR (Status)) {
- CcEvent.MrIndex = MapPcrToMrIndex (1);
- CcEvent.EventType = EV_TABLE_OF_DEVICES;
- CcEvent.EventSize = sizeof (HandoffTables);
- HandoffTables.NumberOfTables = 1;
- HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;
- HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;
- Status = TdxDxeHashLogExtendEvent (
- 0,
- (UINT8 *)(UINTN)ProcessorLocBuf,
- sizeof (EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
- &CcEvent,
- (UINT8 *)&HandoffTables
- );
- FreePool (ProcessorLocBuf);
- }
- }
- return Status;
- }
- /**
- Measure and log Separator event, 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
- MeasureSeparatorEvent (
- IN UINT32 MrIndex
- )
- {
- CC_EVENT_HDR CcEvent;
- UINT32 EventData;
- DEBUG ((DEBUG_INFO, "MeasureSeparatorEvent to Rtmr - %d\n", MrIndex));
- EventData = 0;
- CcEvent.MrIndex = MrIndex;
- CcEvent.EventType = EV_SEPARATOR;
- CcEvent.EventSize = (UINT32)sizeof (EventData);
- return TdxDxeHashLogExtendEvent (
- 0,
- (UINT8 *)&EventData,
- sizeof (EventData),
- &CcEvent,
- (UINT8 *)&EventData
- );
- }
- /**
- Measure and log an EFI variable, and extend the measurement result into a specific RTMR.
- @param[in] MrIndex RTMR 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.
- @retval EFI_SUCCESS Operation completed successfully.
- @retval EFI_OUT_OF_RESOURCES Out of memory.
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.
- **/
- EFI_STATUS
- MeasureVariable (
- IN UINT32 MrIndex,
- IN TCG_EVENTTYPE EventType,
- IN CHAR16 *VarName,
- IN EFI_GUID *VendorGuid,
- IN VOID *VarData,
- IN UINTN VarSize
- )
- {
- EFI_STATUS Status;
- CC_EVENT_HDR CcEvent;
- UINTN VarNameLength;
- UEFI_VARIABLE_DATA *VarLog;
- DEBUG ((DEBUG_INFO, "TdTcg2Dxe: MeasureVariable (Rtmr - %x, EventType - %x, ", (UINTN)MrIndex, (UINTN)EventType));
- DEBUG ((DEBUG_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
- VarNameLength = StrLen (VarName);
- CcEvent.MrIndex = MrIndex;
- CcEvent.EventType = EventType;
- CcEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
- - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
- VarLog = (UEFI_VARIABLE_DATA *)AllocatePool (CcEvent.EventSize);
- if (VarLog == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- VarLog->VariableName = *VendorGuid;
- VarLog->UnicodeNameLength = VarNameLength;
- VarLog->VariableDataLength = VarSize;
- CopyMem (
- VarLog->UnicodeName,
- VarName,
- VarNameLength * sizeof (*VarName)
- );
- if ((VarSize != 0) && (VarData != NULL)) {
- CopyMem (
- (CHAR16 *)VarLog->UnicodeName + VarNameLength,
- VarData,
- VarSize
- );
- }
- if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
- //
- // Digest is the event data (UEFI_VARIABLE_DATA)
- //
- Status = TdxDxeHashLogExtendEvent (
- 0,
- (UINT8 *)VarLog,
- CcEvent.EventSize,
- &CcEvent,
- (UINT8 *)VarLog
- );
- } else {
- ASSERT (VarData != NULL);
- Status = TdxDxeHashLogExtendEvent (
- 0,
- (UINT8 *)VarData,
- VarSize,
- &CcEvent,
- (UINT8 *)VarLog
- );
- }
- FreePool (VarLog);
- return Status;
- }
- /**
- Read then Measure and log an EFI variable, and extend the measurement result into a specific RTMR.
- @param[in] MrIndex RTMR 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.
- @retval EFI_SUCCESS Operation completed successfully.
- @retval EFI_OUT_OF_RESOURCES Out of memory.
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.
- **/
- EFI_STATUS
- ReadAndMeasureVariable (
- IN UINT32 MrIndex,
- IN TCG_EVENTTYPE EventType,
- IN CHAR16 *VarName,
- IN EFI_GUID *VendorGuid,
- OUT UINTN *VarSize,
- OUT VOID **VarData
- )
- {
- EFI_STATUS Status;
- Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);
- if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
- if (EFI_ERROR (Status)) {
- //
- // It is valid case, so we need handle it.
- //
- *VarData = NULL;
- *VarSize = 0;
- }
- } else {
- //
- // if status error, VarData is freed and set NULL by GetVariable2
- //
- if (EFI_ERROR (Status)) {
- return EFI_NOT_FOUND;
- }
- }
- Status = MeasureVariable (
- MrIndex,
- EventType,
- VarName,
- VendorGuid,
- *VarData,
- *VarSize
- );
- return Status;
- }
- /**
- 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.
- @retval EFI_SUCCESS Operation completed successfully.
- @retval EFI_OUT_OF_RESOURCES Out of memory.
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.
- **/
- EFI_STATUS
- ReadAndMeasureBootVariable (
- IN CHAR16 *VarName,
- IN EFI_GUID *VendorGuid,
- OUT UINTN *VarSize,
- OUT VOID **VarData
- )
- {
- return ReadAndMeasureVariable (
- MapPcrToMrIndex (1),
- EV_EFI_VARIABLE_BOOT,
- VarName,
- VendorGuid,
- VarSize,
- VarData
- );
- }
- /**
- Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
- @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.
- @retval EFI_SUCCESS Operation completed successfully.
- @retval EFI_OUT_OF_RESOURCES Out of memory.
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.
- **/
- EFI_STATUS
- ReadAndMeasureSecureVariable (
- IN CHAR16 *VarName,
- IN EFI_GUID *VendorGuid,
- OUT UINTN *VarSize,
- OUT VOID **VarData
- )
- {
- return ReadAndMeasureVariable (
- MapPcrToMrIndex (7),
- EV_EFI_VARIABLE_DRIVER_CONFIG,
- VarName,
- VendorGuid,
- VarSize,
- VarData
- );
- }
- /**
- Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
- The EFI boot variables are BootOrder and Boot#### variables.
- @retval EFI_SUCCESS Operation completed successfully.
- @retval EFI_OUT_OF_RESOURCES Out of memory.
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.
- **/
- EFI_STATUS
- MeasureAllBootVariables (
- VOID
- )
- {
- EFI_STATUS Status;
- UINT16 *BootOrder;
- UINTN BootCount;
- UINTN Index;
- VOID *BootVarData;
- UINTN Size;
- Status = ReadAndMeasureBootVariable (
- mBootVarName,
- &gEfiGlobalVariableGuid,
- &BootCount,
- (VOID **)&BootOrder
- );
- if ((Status == EFI_NOT_FOUND) || (BootOrder == NULL)) {
- return EFI_SUCCESS;
- }
- if (EFI_ERROR (Status)) {
- //
- // BootOrder can't be NULL if status is not EFI_NOT_FOUND
- //
- FreePool (BootOrder);
- return Status;
- }
- BootCount /= sizeof (*BootOrder);
- for (Index = 0; Index < BootCount; Index++) {
- UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);
- Status = ReadAndMeasureBootVariable (
- mBootVarName,
- &gEfiGlobalVariableGuid,
- &Size,
- &BootVarData
- );
- if (!EFI_ERROR (Status)) {
- FreePool (BootVarData);
- }
- }
- FreePool (BootOrder);
- return EFI_SUCCESS;
- }
- /**
- Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
- The EFI boot variables are BootOrder and Boot#### variables.
- @retval EFI_SUCCESS Operation completed successfully.
- @retval EFI_OUT_OF_RESOURCES Out of memory.
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.
- **/
- EFI_STATUS
- MeasureAllSecureVariables (
- VOID
- )
- {
- EFI_STATUS Status;
- VOID *Data;
- UINTN DataSize;
- UINTN Index;
- Status = EFI_NOT_FOUND;
- for (Index = 0; Index < sizeof (mVariableType)/sizeof (mVariableType[0]); Index++) {
- Status = ReadAndMeasureSecureVariable (
- mVariableType[Index].VariableName,
- mVariableType[Index].VendorGuid,
- &DataSize,
- &Data
- );
- if (!EFI_ERROR (Status)) {
- if (Data != NULL) {
- FreePool (Data);
- }
- }
- }
- //
- // Measure DBT if present and not empty
- //
- Status = GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, &Data, &DataSize);
- if (!EFI_ERROR (Status)) {
- Status = MeasureVariable (
- MapPcrToMrIndex (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;
- }
- /**
- Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
- @retval EFI_SUCCESS Operation completed successfully.
- @retval EFI_OUT_OF_RESOURCES Out of memory.
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.
- **/
- EFI_STATUS
- MeasureLaunchOfFirmwareDebugger (
- VOID
- )
- {
- CC_EVENT_HDR CcEvent;
- CcEvent.MrIndex = MapPcrToMrIndex (7);
- CcEvent.EventType = EV_EFI_ACTION;
- CcEvent.EventSize = sizeof (FIRMWARE_DEBUGGER_EVENT_STRING) - 1;
- return TdxDxeHashLogExtendEvent (
- 0,
- (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,
- sizeof (FIRMWARE_DEBUGGER_EVENT_STRING) - 1,
- &CcEvent,
- (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING
- );
- }
- /**
- Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
- Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
- - The contents of the SecureBoot variable
- - The contents of the PK variable
- - The contents of the KEK variable
- - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
- - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
- - Separator
- - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
- NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
- EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
- @param[in] Event Event whose notification function is being invoked
- @param[in] Context Pointer to the notification function's context
- **/
- VOID
- EFIAPI
- MeasureSecureBootPolicy (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- EFI_STATUS Status;
- VOID *Protocol;
- Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);
- if (EFI_ERROR (Status)) {
- return;
- }
- if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {
- Status = MeasureLaunchOfFirmwareDebugger ();
- DEBUG ((DEBUG_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));
- }
- Status = MeasureAllSecureVariables ();
- DEBUG ((DEBUG_INFO, "MeasureAllSecureVariables - %r\n", Status));
- //
- // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
- // and ImageVerification (Authority)
- // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
- // the Authority measurement happen before ReadToBoot event.
- //
- Status = MeasureSeparatorEvent (MapPcrToMrIndex (7));
- DEBUG ((DEBUG_INFO, "MeasureSeparatorEvent - %r\n", Status));
- return;
- }
- /**
- Ready to Boot Event notification handler.
- Sequence of OS boot events is measured in this event notification handler.
- @param[in] Event Event whose notification function is being invoked
- @param[in] Context Pointer to the notification function's context
- **/
- VOID
- EFIAPI
- OnReadyToBoot (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- EFI_STATUS Status;
- PERF_START_EX (mImageHandle, "EventRec", "TdTcg2Dxe", 0, PERF_ID_CC_TCG2_DXE);
- if (mBootAttempts == 0) {
- //
- // Measure handoff tables.
- //
- Status = MeasureHandoffTables ();
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "HOBs not Measured. Error!\n"));
- }
- //
- // Measure BootOrder & Boot#### variables.
- //
- Status = MeasureAllBootVariables ();
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Boot Variables not Measured. Error!\n"));
- }
- //
- // 1. This is the first boot attempt.
- //
- Status = TdMeasureAction (
- MapPcrToMrIndex (4),
- EFI_CALLING_EFI_APPLICATION
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
- }
- //
- // 2. Draw a line between pre-boot env and entering post-boot env.
- // PCR[7] (is RTMR[0]) is already done.
- //
- Status = MeasureSeparatorEvent (1);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n"));
- }
- //
- // 3. Measure GPT. It would be done in SAP driver.
- //
- //
- // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
- //
- //
- // 5. Read & Measure variable. BootOrder already measured.
- //
- } else {
- //
- // 6. Not first attempt, meaning a return from last attempt
- //
- Status = TdMeasureAction (
- MapPcrToMrIndex (4),
- EFI_RETURNING_FROM_EFI_APPLICATION
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_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 = TdMeasureAction (
- MapPcrToMrIndex (4),
- EFI_CALLING_EFI_APPLICATION
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
- }
- }
- DEBUG ((DEBUG_INFO, "TdTcg2Dxe Measure Data when ReadyToBoot\n"));
- //
- // Increase boot attempt counter.
- //
- mBootAttempts++;
- PERF_END_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_CC_TCG2_DXE + 1);
- }
- /**
- Exit Boot Services Event notification handler.
- Measure invocation and success of ExitBootServices.
- @param[in] Event Event whose notification function is being invoked
- @param[in] Context Pointer to the notification function's context
- **/
- VOID
- EFIAPI
- OnExitBootServices (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- EFI_STATUS Status;
- //
- // Measure invocation of ExitBootServices,
- //
- Status = TdMeasureAction (
- MapPcrToMrIndex (5),
- EFI_EXIT_BOOT_SERVICES_INVOCATION
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));
- }
- //
- // Measure success of ExitBootServices
- //
- Status = TdMeasureAction (
- MapPcrToMrIndex (5),
- EFI_EXIT_BOOT_SERVICES_SUCCEEDED
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));
- }
- }
- /**
- Exit Boot Services Failed Event notification handler.
- Measure Failure of ExitBootServices.
- @param[in] Event Event whose notification function is being invoked
- @param[in] Context Pointer to the notification function's context
- **/
- VOID
- EFIAPI
- OnExitBootServicesFailed (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- EFI_STATUS Status;
- //
- // Measure Failure of ExitBootServices,
- //
- Status = TdMeasureAction (
- MapPcrToMrIndex (5),
- EFI_EXIT_BOOT_SERVICES_FAILED
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));
- }
- }
- EFI_STATUS
- SyncCcEvent (
- VOID
- )
- {
- EFI_STATUS Status;
- EFI_PEI_HOB_POINTERS GuidHob;
- VOID *CcEvent;
- VOID *DigestListBin;
- UINT32 DigestListBinSize;
- UINT8 *Event;
- UINT32 EventSize;
- EFI_CC_EVENT_LOG_FORMAT LogFormat;
- DEBUG ((DEBUG_INFO, "Sync Cc event from SEC\n"));
- Status = EFI_SUCCESS;
- LogFormat = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
- GuidHob.Guid = GetFirstGuidHob (&gCcEventEntryHobGuid);
- while (!EFI_ERROR (Status) && GuidHob.Guid != NULL) {
- CcEvent = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));
- if (CcEvent == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- GuidHob.Guid = GET_NEXT_HOB (GuidHob);
- GuidHob.Guid = GetNextGuidHob (&gCcEventEntryHobGuid, GuidHob.Guid);
- DigestListBin = (UINT8 *)CcEvent + sizeof (UINT32) + sizeof (TCG_EVENTTYPE);
- DigestListBinSize = GetDigestListBinSize (DigestListBin);
- //
- // Event size.
- //
- EventSize = *(UINT32 *)((UINT8 *)DigestListBin + DigestListBinSize);
- Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof (UINT32);
- //
- // Log the event
- //
- Status = TdxDxeLogEvent (
- LogFormat,
- CcEvent,
- sizeof (UINT32) + sizeof (TCG_EVENTTYPE) + DigestListBinSize + sizeof (UINT32),
- Event,
- EventSize
- );
- DumpCcEvent ((CC_EVENT *)CcEvent);
- FreePool (CcEvent);
- }
- return Status;
- }
- /**
- Install TDVF ACPI Table when ACPI Table Protocol is available.
- @param[in] Event Event whose notification function is being invoked
- @param[in] Context Pointer to the notification function's context
- **/
- VOID
- EFIAPI
- InstallAcpiTable (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- UINTN TableKey;
- EFI_STATUS Status;
- EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
- UINT64 OemTableId;
- Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "TD: AcpiTableProtocol is not installed. %r\n", Status));
- return;
- }
- mTdxEventlogAcpiTemplate.Laml = (UINT64)PcdGet32 (PcdCcEventlogAcpiTableLaml);
- mTdxEventlogAcpiTemplate.Lasa = PcdGet64 (PcdCcEventlogAcpiTableLasa);
- CopyMem (mTdxEventlogAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTdxEventlogAcpiTemplate.Header.OemId));
- OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
- CopyMem (&mTdxEventlogAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
- mTdxEventlogAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
- mTdxEventlogAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
- mTdxEventlogAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
- //
- // Construct ACPI Table
- Status = AcpiTable->InstallAcpiTable (
- AcpiTable,
- &mTdxEventlogAcpiTemplate,
- mTdxEventlogAcpiTemplate.Header.Length,
- &TableKey
- );
- ASSERT_EFI_ERROR (Status);
- DEBUG ((DEBUG_INFO, "TDVF Eventlog ACPI Table is installed.\n"));
- }
- /**
- The function install TdTcg2 protocol.
- @retval EFI_SUCCESS TdTcg2 protocol is installed.
- @retval other Some error occurs.
- **/
- EFI_STATUS
- InstallCcMeasurementProtocol (
- VOID
- )
- {
- EFI_STATUS Status;
- EFI_HANDLE Handle;
- Handle = NULL;
- Status = gBS->InstallMultipleProtocolInterfaces (
- &Handle,
- &gEfiCcMeasurementProtocolGuid,
- &mTdProtocol,
- NULL
- );
- DEBUG ((DEBUG_INFO, "CcProtocol: Install %r\n", Status));
- return Status;
- }
- /**
- The driver's entry point. It publishes EFI Tcg2 Protocol.
- @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.
- **/
- EFI_STATUS
- EFIAPI
- DriverEntry (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status;
- EFI_EVENT Event;
- VOID *Registration;
- if (!TdIsEnabled ()) {
- return EFI_UNSUPPORTED;
- }
- mImageHandle = ImageHandle;
- //
- // Fill information
- //
- // ASSERT (TD_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTEventInfo)/sizeof(mTcg2EventInfo[0]));
- mTdxDxeData.BsCap.Size = sizeof (EFI_CC_BOOT_SERVICE_CAPABILITY);
- mTdxDxeData.BsCap.ProtocolVersion.Major = 1;
- mTdxDxeData.BsCap.ProtocolVersion.Minor = 0;
- mTdxDxeData.BsCap.StructureVersion.Major = 1;
- mTdxDxeData.BsCap.StructureVersion.Minor = 0;
- //
- // Get supported PCR and current Active PCRs
- // For TD gueset HA384 is supported.
- //
- mTdxDxeData.BsCap.HashAlgorithmBitmap = HASH_ALG_SHA384;
- // TD guest only supports EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
- mTdxDxeData.BsCap.SupportedEventLogs = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
- //
- // Setup the log area and copy event log from hob list to it
- //
- Status = SetupCcEventLog ();
- ASSERT_EFI_ERROR (Status);
- if (!EFI_ERROR (Status)) {
- Status = SyncCcEvent ();
- ASSERT_EFI_ERROR (Status);
- }
- //
- // Measure handoff tables, Boot#### variables etc.
- //
- Status = EfiCreateEventReadyToBootEx (
- TPL_CALLBACK,
- OnReadyToBoot,
- NULL,
- &Event
- );
- Status = gBS->CreateEventEx (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- OnExitBootServices,
- NULL,
- &gEfiEventExitBootServicesGuid,
- &Event
- );
- //
- // Measure Exit Boot Service failed
- //
- Status = gBS->CreateEventEx (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- OnExitBootServicesFailed,
- NULL,
- &gEventExitBootServicesFailedGuid,
- &Event
- );
- //
- // Create event callback, because we need access variable on SecureBootPolicyVariable
- // We should use VariableWriteArch instead of VariableArch, because Variable driver
- // may update SecureBoot value based on last setting.
- //
- EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);
- //
- // Install CcMeasurementProtocol
- //
- Status = InstallCcMeasurementProtocol ();
- DEBUG ((DEBUG_INFO, "InstallCcMeasurementProtocol - %r\n", Status));
- if (Status == EFI_SUCCESS) {
- //
- // Create event callback to install CC EventLog ACPI Table
- EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration);
- } else {
- //
- // Cc measurement feature is crucial to a td-guest and it shall stop running immediately
- // when it is failed to be installed.
- DEBUG ((DEBUG_ERROR, "%a: CcMeasurement protocol failed to be installed - %r\n", __FUNCTION__, Status));
- CpuDeadLoop ();
- }
- return Status;
- }
|