VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c

最後變更 在這個檔案是 105670,由 vboxsync 提交於 7 月 前

Devices/EFI/FirmwareNew: Merge edk2-stable-202405 and make it build on aarch64, bugref:4643

  • 屬性 svn:eol-style 設為 native
檔案大小: 78.0 KB
 
1/** @file
2 This module implements EFI TD Protocol.
3
4 Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7**/
8
9#include <PiDxe.h>
10#include <IndustryStandard/Acpi.h>
11#include <IndustryStandard/PeImage.h>
12#include <IndustryStandard/TcpaAcpi.h>
13
14#include <Guid/GlobalVariable.h>
15#include <Guid/HobList.h>
16#include <Guid/EventGroup.h>
17#include <Guid/EventExitBootServiceFailed.h>
18#include <Guid/ImageAuthentication.h>
19#include <Guid/TpmInstance.h>
20
21#include <Protocol/DevicePath.h>
22#include <Protocol/MpService.h>
23#include <Protocol/VariableWrite.h>
24#include <Protocol/Tcg2Protocol.h>
25#include <Protocol/TrEEProtocol.h>
26#include <Protocol/ResetNotification.h>
27#include <Protocol/AcpiTable.h>
28
29#include <Library/DebugLib.h>
30#include <Library/BaseMemoryLib.h>
31#include <Library/UefiRuntimeServicesTableLib.h>
32#include <Library/UefiDriverEntryPoint.h>
33#include <Library/HobLib.h>
34#include <Library/UefiBootServicesTableLib.h>
35#include <Library/BaseLib.h>
36#include <Library/MemoryAllocationLib.h>
37#include <Library/PrintLib.h>
38#include <Library/PcdLib.h>
39#include <Library/UefiLib.h>
40#include <Library/HashLib.h>
41#include <Library/PerformanceLib.h>
42#include <Library/ReportStatusCodeLib.h>
43#include <Library/TpmMeasurementLib.h>
44
45#include <Protocol/CcMeasurement.h>
46#include <Guid/CcEventHob.h>
47#include <Library/TdxLib.h>
48
49#define PERF_ID_CC_TCG2_DXE 0x3130
50
51#define CC_EVENT_LOG_AREA_COUNT_MAX 1
52#define CC_MR_INDEX_0_MRTD 0
53#define CC_MR_INDEX_1_RTMR0 1
54#define CC_MR_INDEX_2_RTMR1 2
55#define CC_MR_INDEX_3_RTMR2 3
56#define CC_MR_INDEX_INVALID 4
57
58typedef struct {
59 CHAR16 *VariableName;
60 EFI_GUID *VendorGuid;
61} VARIABLE_TYPE;
62
63typedef struct {
64 EFI_GUID *EventGuid;
65 EFI_CC_EVENT_LOG_FORMAT LogFormat;
66} CC_EVENT_INFO_STRUCT;
67
68typedef struct {
69 EFI_CC_EVENT_LOG_FORMAT EventLogFormat;
70 EFI_PHYSICAL_ADDRESS Lasa;
71 UINT64 Laml;
72 UINTN EventLogSize;
73 UINT8 *LastEvent;
74 BOOLEAN EventLogStarted;
75 BOOLEAN EventLogTruncated;
76 UINTN Next800155EventOffset;
77} CC_EVENT_LOG_AREA_STRUCT;
78
79typedef struct _TDX_DXE_DATA {
80 EFI_CC_BOOT_SERVICE_CAPABILITY BsCap;
81 CC_EVENT_LOG_AREA_STRUCT EventLogAreaStruct[CC_EVENT_LOG_AREA_COUNT_MAX];
82 BOOLEAN GetEventLogCalled[CC_EVENT_LOG_AREA_COUNT_MAX];
83 CC_EVENT_LOG_AREA_STRUCT FinalEventLogAreaStruct[CC_EVENT_LOG_AREA_COUNT_MAX];
84 EFI_CC_FINAL_EVENTS_TABLE *FinalEventsTable[CC_EVENT_LOG_AREA_COUNT_MAX];
85} TDX_DXE_DATA;
86
87typedef struct {
88 TPMI_ALG_HASH HashAlgo;
89 UINT16 HashSize;
90 UINT32 HashMask;
91} TDX_HASH_INFO;
92
93//
94//
95CC_EVENT_INFO_STRUCT mCcEventInfo[] = {
96 { &gCcEventEntryHobGuid, EFI_CC_EVENT_LOG_FORMAT_TCG_2 },
97};
98
99TDX_DXE_DATA mTdxDxeData = {
100 {
101 sizeof (EFI_CC_BOOT_SERVICE_CAPABILITY), // Size
102 { 1, 1 }, // StructureVersion
103 { 1, 1 }, // ProtocolVersion
104 EFI_CC_BOOT_HASH_ALG_SHA384, // HashAlgorithmBitmap
105 EFI_CC_EVENT_LOG_FORMAT_TCG_2, // SupportedEventLogs
106 { 2, 0 } // {CC_TYPE, CC_SUBTYPE}
107 },
108};
109
110UINTN mBootAttempts = 0;
111CHAR16 mBootVarName[] = L"BootOrder";
112
113VARIABLE_TYPE mVariableType[] = {
114 { EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid },
115 { EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid },
116 { EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid },
117 { EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid },
118 { EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid },
119};
120
121EFI_CC_EVENTLOG_ACPI_TABLE mTdxEventlogAcpiTemplate = {
122 {
123 EFI_CC_EVENTLOG_ACPI_TABLE_SIGNATURE,
124 sizeof (mTdxEventlogAcpiTemplate),
125 EFI_CC_EVENTLOG_ACPI_TABLE_REVISION,
126 //
127 // Compiler initializes the remaining bytes to 0
128 // These fields should be filled in production
129 //
130 },
131 { EFI_CC_TYPE_TDX, 0 }, // CcType
132 0, // rsvd
133 0, // laml
134 0, // lasa
135};
136
137//
138// Supported Hash list in Td guest.
139// Currently SHA384 is supported.
140//
141TDX_HASH_INFO mHashInfo[] = {
142 { TPM_ALG_SHA384, SHA384_DIGEST_SIZE, HASH_ALG_SHA384 }
143};
144
145/**
146 Get hash size based on Algo
147
148 @param[in] HashAlgo Hash Algorithm Id.
149
150 @return Size of the hash.
151**/
152UINT16
153GetHashSizeFromAlgo (
154 IN TPMI_ALG_HASH HashAlgo
155 )
156{
157 UINTN Index;
158
159 for (Index = 0; Index < sizeof (mHashInfo)/sizeof (mHashInfo[0]); Index++) {
160 if (mHashInfo[Index].HashAlgo == HashAlgo) {
161 return mHashInfo[Index].HashSize;
162 }
163 }
164
165 return 0;
166}
167
168/**
169 Get hash mask based on Algo
170
171 @param[in] HashAlgo Hash Algorithm Id.
172
173 @return Hash mask.
174**/
175UINT32
176GetHashMaskFromAlgo (
177 IN TPMI_ALG_HASH HashAlgo
178 )
179{
180 UINTN Index;
181
182 for (Index = 0; Index < ARRAY_SIZE (mHashInfo); Index++) {
183 if (mHashInfo[Index].HashAlgo == HashAlgo) {
184 return mHashInfo[Index].HashMask;
185 }
186 }
187
188 ASSERT (FALSE);
189 return 0;
190}
191
192/**
193 Copy TPML_DIGEST_VALUES into a buffer
194
195 @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.
196 @param[in] DigestList TPML_DIGEST_VALUES to be copied.
197 @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.
198
199 @return The end of buffer to hold TPML_DIGEST_VALUES.
200**/
201VOID *
202CopyDigestListToBuffer (
203 IN OUT VOID *Buffer,
204 IN TPML_DIGEST_VALUES *DigestList,
205 IN UINT32 HashAlgorithmMask
206 )
207{
208 UINTN Index;
209 UINT16 DigestSize;
210 UINT32 DigestListCount;
211 UINT32 *DigestListCountPtr;
212
213 DigestListCountPtr = (UINT32 *)Buffer;
214 DigestListCount = 0;
215 Buffer = (UINT8 *)Buffer + sizeof (DigestList->count);
216 for (Index = 0; Index < DigestList->count; Index++) {
217 if ((DigestList->digests[Index].hashAlg & HashAlgorithmMask) == 0) {
218 DEBUG ((DEBUG_ERROR, "WARNING: TD Event log has HashAlg unsupported (0x%x)\n", DigestList->digests[Index].hashAlg));
219 continue;
220 }
221
222 CopyMem (Buffer, &DigestList->digests[Index].hashAlg, sizeof (DigestList->digests[Index].hashAlg));
223 Buffer = (UINT8 *)Buffer + sizeof (DigestList->digests[Index].hashAlg);
224 DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);
225 CopyMem (Buffer, &DigestList->digests[Index].digest, DigestSize);
226 Buffer = (UINT8 *)Buffer + DigestSize;
227 DigestListCount++;
228 }
229
230 WriteUnaligned32 (DigestListCountPtr, DigestListCount);
231
232 return Buffer;
233}
234
235EFI_HANDLE mImageHandle;
236
237/**
238 Measure PE image into TPM log based on the authenticode image hashing in
239 PE/COFF Specification 8.0 Appendix A.
240
241 Caution: This function may receive untrusted input.
242 PE/COFF image is external input, so this function will validate its data structure
243 within this image buffer before use.
244
245 Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().
246
247 @param[in] RtmrIndex RTMR index
248 @param[in] ImageAddress Start address of image buffer.
249 @param[in] ImageSize Image size
250 @param[out] DigestList Digest list of this image.
251
252 @retval EFI_SUCCESS Successfully measure image.
253 @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
254 @retval other error value
255**/
256EFI_STATUS
257MeasurePeImageAndExtend (
258 IN UINT32 RtmrIndex,
259 IN EFI_PHYSICAL_ADDRESS ImageAddress,
260 IN UINTN ImageSize,
261 OUT TPML_DIGEST_VALUES *DigestList
262 );
263
264#define COLUME_SIZE (16 * 2)
265
266/**
267
268 This function dump raw data.
269
270 @param Data raw data
271 @param Size raw data size
272
273**/
274VOID
275InternalDumpData (
276 IN UINT8 *Data,
277 IN UINTN Size
278 )
279{
280 UINTN Index;
281
282 for (Index = 0; Index < Size; Index++) {
283 DEBUG ((DEBUG_INFO, Index == COLUME_SIZE/2 ? " | %02x" : " %02x", (UINTN)Data[Index]));
284 }
285}
286
287/**
288
289 This function dump raw data with colume format.
290
291 @param Data raw data
292 @param Size raw data size
293
294**/
295VOID
296InternalDumpHex (
297 IN UINT8 *Data,
298 IN UINTN Size
299 )
300{
301 UINTN Index;
302 UINTN Count;
303 UINTN Left;
304
305 Count = Size / COLUME_SIZE;
306 Left = Size % COLUME_SIZE;
307 for (Index = 0; Index < Count; Index++) {
308 DEBUG ((DEBUG_INFO, "%04x: ", Index * COLUME_SIZE));
309 InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);
310 DEBUG ((DEBUG_INFO, "\n"));
311 }
312
313 if (Left != 0) {
314 DEBUG ((DEBUG_INFO, "%04x: ", Index * COLUME_SIZE));
315 InternalDumpData (Data + Index * COLUME_SIZE, Left);
316 DEBUG ((DEBUG_INFO, "\n"));
317 }
318}
319
320/**
321
322 This function initialize TD_EVENT_HDR for EV_NO_ACTION
323 Event Type other than EFI Specification ID event. The behavior is defined
324 by TCG PC Client PFP Spec. Section 9.3.4 EV_NO_ACTION Event Types
325
326 @param[in, out] NoActionEvent Event Header of EV_NO_ACTION Event
327 @param[in] EventSize Event Size of the EV_NO_ACTION Event
328
329**/
330VOID
331InitNoActionEvent (
332 IN OUT CC_EVENT_HDR *NoActionEvent,
333 IN UINT32 EventSize
334 )
335{
336 UINT32 DigestListCount;
337 TPMI_ALG_HASH HashAlgId;
338 UINT8 *DigestBuffer;
339
340 DigestBuffer = (UINT8 *)NoActionEvent->Digests.digests;
341 DigestListCount = 0;
342
343 NoActionEvent->MrIndex = 0;
344 NoActionEvent->EventType = EV_NO_ACTION;
345
346 //
347 // Set Hash count & hashAlg accordingly, while Digest.digests[n].digest to all 0
348 //
349 ZeroMem (&NoActionEvent->Digests, sizeof (NoActionEvent->Digests));
350
351 if ((mTdxDxeData.BsCap.HashAlgorithmBitmap & EFI_CC_BOOT_HASH_ALG_SHA384) != 0) {
352 HashAlgId = TPM_ALG_SHA384;
353 CopyMem (DigestBuffer, &HashAlgId, sizeof (TPMI_ALG_HASH));
354 DigestBuffer += sizeof (TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);
355 DigestListCount++;
356 }
357
358 //
359 // Set Digests Count
360 //
361 WriteUnaligned32 ((UINT32 *)&NoActionEvent->Digests.count, DigestListCount);
362
363 //
364 // Set Event Size
365 //
366 WriteUnaligned32 ((UINT32 *)DigestBuffer, EventSize);
367}
368
369/**
370 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
371 Caller is responsible to free LocationBuf.
372
373 @param[out] LocationBuf Returns Processor Location Buffer.
374 @param[out] Num Returns processor number.
375
376 @retval EFI_SUCCESS Operation completed successfully.
377 @retval EFI_UNSUPPORTED MpService protocol not found.
378
379**/
380EFI_STATUS
381GetProcessorsCpuLocation (
382 OUT EFI_CPU_PHYSICAL_LOCATION **LocationBuf,
383 OUT UINTN *Num
384 )
385{
386 EFI_STATUS Status;
387 EFI_MP_SERVICES_PROTOCOL *MpProtocol;
388 UINTN ProcessorNum;
389 UINTN EnabledProcessorNum;
390 EFI_PROCESSOR_INFORMATION ProcessorInfo;
391 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
392 UINTN Index;
393
394 Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpProtocol);
395 if (EFI_ERROR (Status)) {
396 //
397 // MP protocol is not installed
398 //
399 return EFI_UNSUPPORTED;
400 }
401
402 Status = MpProtocol->GetNumberOfProcessors (
403 MpProtocol,
404 &ProcessorNum,
405 &EnabledProcessorNum
406 );
407 if (EFI_ERROR (Status)) {
408 return Status;
409 }
410
411 Status = gBS->AllocatePool (
412 EfiBootServicesData,
413 sizeof (EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
414 (VOID **)&ProcessorLocBuf
415 );
416 if (EFI_ERROR (Status)) {
417 return Status;
418 }
419
420 //
421 // Get each processor Location info
422 //
423 for (Index = 0; Index < ProcessorNum; Index++) {
424 Status = MpProtocol->GetProcessorInfo (
425 MpProtocol,
426 Index,
427 &ProcessorInfo
428 );
429 if (EFI_ERROR (Status)) {
430 FreePool (ProcessorLocBuf);
431 return Status;
432 }
433
434 //
435 // Get all Processor Location info & measure
436 //
437 CopyMem (
438 &ProcessorLocBuf[Index],
439 &ProcessorInfo.Location,
440 sizeof (EFI_CPU_PHYSICAL_LOCATION)
441 );
442 }
443
444 *LocationBuf = ProcessorLocBuf;
445 *Num = ProcessorNum;
446
447 return Status;
448}
449
450/**
451 The EFI_CC_MEASUREMENT_PROTOCOL GetCapability function call provides protocol
452 capability information and state information.
453
454 @param[in] This Indicates the calling context
455 @param[in, out] ProtocolCapability The caller allocates memory for a EFI_CC_BOOT_SERVICE_CAPABILITY
456 structure and sets the size field to the size of the structure allocated.
457 The callee fills in the fields with the EFI protocol capability information
458 and the current EFI TCG2 state information up to the number of fields which
459 fit within the size of the structure passed in.
460
461 @retval EFI_SUCCESS Operation completed successfully.
462 @retval EFI_DEVICE_ERROR The command was unsuccessful.
463 The ProtocolCapability variable will not be populated.
464 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
465 The ProtocolCapability variable will not be populated.
466 @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.
467 It will be partially populated (required Size field will be set).
468**/
469EFI_STATUS
470EFIAPI
471TdGetCapability (
472 IN EFI_CC_MEASUREMENT_PROTOCOL *This,
473 IN OUT EFI_CC_BOOT_SERVICE_CAPABILITY *ProtocolCapability
474 )
475{
476 DEBUG ((DEBUG_VERBOSE, "TdGetCapability\n"));
477
478 if ((This == NULL) || (ProtocolCapability == NULL)) {
479 return EFI_INVALID_PARAMETER;
480 }
481
482 CopyMem (ProtocolCapability, &mTdxDxeData.BsCap, sizeof (EFI_CC_BOOT_SERVICE_CAPABILITY));
483
484 return EFI_SUCCESS;
485}
486
487/**
488 This function dump PCR event.
489 TD Event log reuse the TCG PCR Event spec.
490 The first event in the event log is the SHA1 log format.
491 There is only ONE TCG_PCR_EVENT in TD Event log.
492
493 @param[in] EventHdr TCG PCR event structure.
494**/
495VOID
496DumpPcrEvent (
497 IN TCG_PCR_EVENT_HDR *EventHdr
498 )
499{
500 UINTN Index;
501
502 DEBUG ((DEBUG_INFO, " Event:\n"));
503 DEBUG ((DEBUG_INFO, " MrIndex - %d\n", EventHdr->PCRIndex));
504 DEBUG ((DEBUG_INFO, " EventType - 0x%08x\n", EventHdr->EventType));
505 DEBUG ((DEBUG_INFO, " Digest - "));
506 for (Index = 0; Index < sizeof (TCG_DIGEST); Index++) {
507 DEBUG ((DEBUG_INFO, "%02x ", EventHdr->Digest.digest[Index]));
508 }
509
510 DEBUG ((DEBUG_INFO, "\n"));
511 DEBUG ((DEBUG_INFO, " EventSize - 0x%08x\n", EventHdr->EventSize));
512 InternalDumpHex ((UINT8 *)(EventHdr + 1), EventHdr->EventSize);
513}
514
515/**
516 This function dump TCG_EfiSpecIDEventStruct.
517
518 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
519**/
520VOID
521DumpTcgEfiSpecIdEventStruct (
522 IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct
523 )
524{
525 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
526 UINTN Index;
527 UINT8 *VendorInfoSize;
528 UINT8 *VendorInfo;
529 UINT32 NumberOfAlgorithms;
530
531 DEBUG ((DEBUG_INFO, " TCG_EfiSpecIDEventStruct:\n"));
532 DEBUG ((DEBUG_INFO, " signature - '"));
533 for (Index = 0; Index < sizeof (TcgEfiSpecIdEventStruct->signature); Index++) {
534 DEBUG ((DEBUG_INFO, "%c", TcgEfiSpecIdEventStruct->signature[Index]));
535 }
536
537 DEBUG ((DEBUG_INFO, "'\n"));
538 DEBUG ((DEBUG_INFO, " platformClass - 0x%08x\n", TcgEfiSpecIdEventStruct->platformClass));
539 DEBUG ((DEBUG_INFO, " specVersion - %d.%d%d\n", TcgEfiSpecIdEventStruct->specVersionMajor, TcgEfiSpecIdEventStruct->specVersionMinor, TcgEfiSpecIdEventStruct->specErrata));
540 DEBUG ((DEBUG_INFO, " uintnSize - 0x%02x\n", TcgEfiSpecIdEventStruct->uintnSize));
541
542 CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof (NumberOfAlgorithms));
543 DEBUG ((DEBUG_INFO, " NumberOfAlgorithms - 0x%08x\n", NumberOfAlgorithms));
544
545 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof (*TcgEfiSpecIdEventStruct) + sizeof (NumberOfAlgorithms));
546 for (Index = 0; Index < NumberOfAlgorithms; Index++) {
547 DEBUG ((DEBUG_INFO, " digest(%d)\n", Index));
548 DEBUG ((DEBUG_INFO, " algorithmId - 0x%04x\n", DigestSize[Index].algorithmId));
549 DEBUG ((DEBUG_INFO, " digestSize - 0x%04x\n", DigestSize[Index].digestSize));
550 }
551
552 VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms];
553 DEBUG ((DEBUG_INFO, " VendorInfoSize - 0x%02x\n", *VendorInfoSize));
554 VendorInfo = VendorInfoSize + 1;
555 DEBUG ((DEBUG_INFO, " VendorInfo - "));
556 for (Index = 0; Index < *VendorInfoSize; Index++) {
557 DEBUG ((DEBUG_INFO, "%02x ", VendorInfo[Index]));
558 }
559
560 DEBUG ((DEBUG_INFO, "\n"));
561}
562
563/**
564 This function get size of TCG_EfiSpecIDEventStruct.
565
566 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
567**/
568UINTN
569GetTcgEfiSpecIdEventStructSize (
570 IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct
571 )
572{
573 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
574 UINT8 *VendorInfoSize;
575 UINT32 NumberOfAlgorithms;
576
577 CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof (NumberOfAlgorithms));
578
579 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof (*TcgEfiSpecIdEventStruct) + sizeof (NumberOfAlgorithms));
580 VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms];
581 return sizeof (TCG_EfiSpecIDEventStruct) + sizeof (UINT32) + (NumberOfAlgorithms * sizeof (TCG_EfiSpecIdEventAlgorithmSize)) + sizeof (UINT8) + (*VendorInfoSize);
582}
583
584/**
585 This function dump TD Event (including the Digests).
586
587 @param[in] CcEvent TD Event structure.
588**/
589VOID
590DumpCcEvent (
591 IN CC_EVENT *CcEvent
592 )
593{
594 UINT32 DigestIndex;
595 UINT32 DigestCount;
596 TPMI_ALG_HASH HashAlgo;
597 UINT32 DigestSize;
598 UINT8 *DigestBuffer;
599 UINT32 EventSize;
600 UINT8 *EventBuffer;
601
602 DEBUG ((DEBUG_INFO, "Cc Event:\n"));
603 DEBUG ((DEBUG_INFO, " MrIndex - %d\n", CcEvent->MrIndex));
604 DEBUG ((DEBUG_INFO, " EventType - 0x%08x\n", CcEvent->EventType));
605 DEBUG ((DEBUG_INFO, " DigestCount: 0x%08x\n", CcEvent->Digests.count));
606
607 DigestCount = CcEvent->Digests.count;
608 HashAlgo = CcEvent->Digests.digests[0].hashAlg;
609 DigestBuffer = (UINT8 *)&CcEvent->Digests.digests[0].digest;
610 for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {
611 DEBUG ((DEBUG_INFO, " HashAlgo : 0x%04x\n", HashAlgo));
612 DEBUG ((DEBUG_INFO, " Digest(%d): \n", DigestIndex));
613 DigestSize = GetHashSizeFromAlgo (HashAlgo);
614 InternalDumpHex (DigestBuffer, DigestSize);
615 //
616 // Prepare next
617 //
618 CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof (TPMI_ALG_HASH));
619 DigestBuffer = DigestBuffer + DigestSize + sizeof (TPMI_ALG_HASH);
620 }
621
622 DigestBuffer = DigestBuffer - sizeof (TPMI_ALG_HASH);
623
624 CopyMem (&EventSize, DigestBuffer, sizeof (CcEvent->EventSize));
625 DEBUG ((DEBUG_INFO, " EventSize - 0x%08x\n", EventSize));
626 EventBuffer = DigestBuffer + sizeof (CcEvent->EventSize);
627 InternalDumpHex (EventBuffer, EventSize);
628 DEBUG ((DEBUG_INFO, "\n"));
629}
630
631/**
632 This function returns size of Td Table event.
633
634 @param[in] CcEvent Td Table event structure.
635
636 @return size of Td event.
637**/
638UINTN
639GetCcEventSize (
640 IN CC_EVENT *CcEvent
641 )
642{
643 UINT32 DigestIndex;
644 UINT32 DigestCount;
645 TPMI_ALG_HASH HashAlgo;
646 UINT32 DigestSize;
647 UINT8 *DigestBuffer;
648 UINT32 EventSize;
649 UINT8 *EventBuffer;
650
651 DigestCount = CcEvent->Digests.count;
652 HashAlgo = CcEvent->Digests.digests[0].hashAlg;
653 DigestBuffer = (UINT8 *)&CcEvent->Digests.digests[0].digest;
654 for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {
655 DigestSize = GetHashSizeFromAlgo (HashAlgo);
656 //
657 // Prepare next
658 //
659 CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof (TPMI_ALG_HASH));
660 DigestBuffer = DigestBuffer + DigestSize + sizeof (TPMI_ALG_HASH);
661 }
662
663 DigestBuffer = DigestBuffer - sizeof (TPMI_ALG_HASH);
664
665 CopyMem (&EventSize, DigestBuffer, sizeof (CcEvent->EventSize));
666 EventBuffer = DigestBuffer + sizeof (CcEvent->EventSize);
667
668 return (UINTN)EventBuffer + EventSize - (UINTN)CcEvent;
669}
670
671/**
672 This function dump CC event log.
673 TDVF only supports EFI_CC_EVENT_LOG_FORMAT_TCG_2
674
675 @param[in] EventLogFormat The type of the event log for which the information is requested.
676 @param[in] EventLogLocation A pointer to the memory address of the event log.
677 @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
678 address of the start of the last entry in the event log in memory.
679 @param[in] FinalEventsTable A pointer to the memory address of the final event table.
680**/
681VOID
682DumpCcEventLog (
683 IN EFI_CC_EVENT_LOG_FORMAT EventLogFormat,
684 IN EFI_PHYSICAL_ADDRESS EventLogLocation,
685 IN EFI_PHYSICAL_ADDRESS EventLogLastEntry,
686 IN EFI_CC_FINAL_EVENTS_TABLE *FinalEventsTable
687 )
688{
689 TCG_PCR_EVENT_HDR *EventHdr;
690 CC_EVENT *CcEvent;
691 TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;
692 UINTN NumberOfEvents;
693
694 DEBUG ((DEBUG_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));
695 ASSERT (EventLogFormat == EFI_CC_EVENT_LOG_FORMAT_TCG_2);
696
697 //
698 // Dump first event.
699 // The first event is always the TCG_PCR_EVENT_HDR
700 // After this event is a TCG_EfiSpecIDEventStruct
701 //
702 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;
703 DumpPcrEvent (EventHdr);
704
705 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)(EventHdr + 1);
706 DumpTcgEfiSpecIdEventStruct (TcgEfiSpecIdEventStruct);
707
708 //
709 // Then the CcEvent (Its structure is similar to TCG_PCR_EVENT2)
710 //
711 CcEvent = (CC_EVENT *)((UINTN)TcgEfiSpecIdEventStruct + GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct));
712 while ((UINTN)CcEvent <= EventLogLastEntry) {
713 DumpCcEvent (CcEvent);
714 CcEvent = (CC_EVENT *)((UINTN)CcEvent + GetCcEventSize (CcEvent));
715 }
716
717 if (FinalEventsTable == NULL) {
718 DEBUG ((DEBUG_INFO, "FinalEventsTable: NOT FOUND\n"));
719 } else {
720 DEBUG ((DEBUG_INFO, "FinalEventsTable: (0x%x)\n", FinalEventsTable));
721 DEBUG ((DEBUG_INFO, " Version: (0x%x)\n", FinalEventsTable->Version));
722 DEBUG ((DEBUG_INFO, " NumberOfEvents: (0x%x)\n", FinalEventsTable->NumberOfEvents));
723
724 CcEvent = (CC_EVENT *)(UINTN)(FinalEventsTable + 1);
725 for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) {
726 DumpCcEvent (CcEvent);
727 CcEvent = (CC_EVENT *)((UINTN)CcEvent + GetCcEventSize (CcEvent));
728 }
729 }
730
731 return;
732}
733
734/**
735 The EFI_CC_MEASUREMENT_PROTOCOL Get Event Log function call allows a caller to
736 retrieve the address of a given event log and its last entry.
737
738 @param[in] This Indicates the calling context
739 @param[in] EventLogFormat The type of the event log for which the information is requested.
740 @param[out] EventLogLocation A pointer to the memory address of the event log.
741 @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
742 address of the start of the last entry in the event log in memory.
743 @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would
744 have exceeded the area allocated for events, this value is set to TRUE.
745 Otherwise, the value will be FALSE and the Event Log will be complete.
746
747 @retval EFI_SUCCESS Operation completed successfully.
748 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect
749 (e.g. asking for an event log whose format is not supported).
750**/
751EFI_STATUS
752EFIAPI
753TdGetEventLog (
754 IN EFI_CC_MEASUREMENT_PROTOCOL *This,
755 IN EFI_CC_EVENT_LOG_FORMAT EventLogFormat,
756 OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
757 OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry,
758 OUT BOOLEAN *EventLogTruncated
759 )
760{
761 UINTN Index = 0;
762
763 DEBUG ((DEBUG_INFO, "TdGetEventLog ... (0x%x)\n", EventLogFormat));
764 ASSERT (EventLogFormat == EFI_CC_EVENT_LOG_FORMAT_TCG_2);
765
766 if (EventLogLocation != NULL) {
767 *EventLogLocation = mTdxDxeData.EventLogAreaStruct[Index].Lasa;
768 DEBUG ((DEBUG_INFO, "TdGetEventLog (EventLogLocation - %x)\n", *EventLogLocation));
769 }
770
771 if (EventLogLastEntry != NULL) {
772 if (!mTdxDxeData.EventLogAreaStruct[Index].EventLogStarted) {
773 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0;
774 } else {
775 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)mTdxDxeData.EventLogAreaStruct[Index].LastEvent;
776 }
777
778 DEBUG ((DEBUG_INFO, "TdGetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry));
779 }
780
781 if (EventLogTruncated != NULL) {
782 *EventLogTruncated = mTdxDxeData.EventLogAreaStruct[Index].EventLogTruncated;
783 DEBUG ((DEBUG_INFO, "TdGetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated));
784 }
785
786 DEBUG ((DEBUG_INFO, "TdGetEventLog - %r\n", EFI_SUCCESS));
787
788 // Dump Event Log for debug purpose
789 if ((EventLogLocation != NULL) && (EventLogLastEntry != NULL)) {
790 DumpCcEventLog (EventLogFormat, *EventLogLocation, *EventLogLastEntry, mTdxDxeData.FinalEventsTable[Index]);
791 }
792
793 //
794 // All events generated after the invocation of EFI_TCG2_GET_EVENT_LOG SHALL be stored
795 // in an instance of an EFI_CONFIGURATION_TABLE named by the VendorGuid of EFI_TCG2_FINAL_EVENTS_TABLE_GUID.
796 //
797 mTdxDxeData.GetEventLogCalled[Index] = TRUE;
798
799 return EFI_SUCCESS;
800}
801
802/**
803 Return if this is a Tcg800155PlatformIdEvent.
804
805 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
806 @param[in] NewEventHdrSize New event header size.
807 @param[in] NewEventData Pointer to the new event data.
808 @param[in] NewEventSize New event data size.
809
810 @retval TRUE This is a Tcg800155PlatformIdEvent.
811 @retval FALSE This is NOT a Tcg800155PlatformIdEvent.
812
813**/
814BOOLEAN
815Is800155Event (
816 IN VOID *NewEventHdr,
817 IN UINT32 NewEventHdrSize,
818 IN UINT8 *NewEventData,
819 IN UINT32 NewEventSize
820 )
821{
822 if ((((TCG_PCR_EVENT2_HDR *)NewEventHdr)->EventType == EV_NO_ACTION) &&
823 (NewEventSize >= sizeof (TCG_Sp800_155_PlatformId_Event2)) &&
824 ((CompareMem (
825 NewEventData,
826 TCG_Sp800_155_PlatformId_Event2_SIGNATURE,
827 sizeof (TCG_Sp800_155_PlatformId_Event2_SIGNATURE) - 1
828 ) == 0) ||
829 (CompareMem (
830 NewEventData,
831 TCG_Sp800_155_PlatformId_Event3_SIGNATURE,
832 sizeof (TCG_Sp800_155_PlatformId_Event3_SIGNATURE) - 1
833 ) == 0)))
834 {
835 return TRUE;
836 }
837
838 return FALSE;
839}
840
841/**
842 Add a new entry to the Event Log.
843
844 @param[in, out] EventLogAreaStruct The event log area data structure
845 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
846 @param[in] NewEventHdrSize New event header size.
847 @param[in] NewEventData Pointer to the new event data.
848 @param[in] NewEventSize New event data size.
849
850 @retval EFI_SUCCESS The new event log entry was added.
851 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
852
853**/
854EFI_STATUS
855TcgCommLogEvent (
856 IN OUT CC_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct,
857 IN VOID *NewEventHdr,
858 IN UINT32 NewEventHdrSize,
859 IN UINT8 *NewEventData,
860 IN UINT32 NewEventSize
861 )
862{
863 UINTN NewLogSize;
864 BOOLEAN Record800155Event;
865 CC_EVENT_HDR *CcEventHdr;
866
867 CcEventHdr = (CC_EVENT_HDR *)NewEventHdr;
868 DEBUG ((DEBUG_VERBOSE, "Td: Try to log event. Index = %d, EventType = 0x%x\n", CcEventHdr->MrIndex, CcEventHdr->EventType));
869
870 if (NewEventSize > MAX_ADDRESS - NewEventHdrSize) {
871 return EFI_OUT_OF_RESOURCES;
872 }
873
874 NewLogSize = NewEventHdrSize + NewEventSize;
875
876 if (NewLogSize > MAX_ADDRESS - EventLogAreaStruct->EventLogSize) {
877 return EFI_OUT_OF_RESOURCES;
878 }
879
880 if (NewLogSize + EventLogAreaStruct->EventLogSize > EventLogAreaStruct->Laml) {
881 DEBUG ((DEBUG_INFO, " Laml - 0x%x\n", EventLogAreaStruct->Laml));
882 DEBUG ((DEBUG_INFO, " NewLogSize - 0x%x\n", NewLogSize));
883 DEBUG ((DEBUG_INFO, " LogSize - 0x%x\n", EventLogAreaStruct->EventLogSize));
884 DEBUG ((DEBUG_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));
885 return EFI_OUT_OF_RESOURCES;
886 }
887
888 //
889 // Check 800-155 event
890 // Record to 800-155 event offset only.
891 // If the offset is 0, no need to record.
892 //
893 Record800155Event = Is800155Event (NewEventHdr, NewEventHdrSize, NewEventData, NewEventSize);
894 if (Record800155Event) {
895 DEBUG ((DEBUG_INFO, "It is 800155Event.\n"));
896
897 if (EventLogAreaStruct->Next800155EventOffset != 0) {
898 CopyMem (
899 (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset + NewLogSize,
900 (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset,
901 EventLogAreaStruct->EventLogSize - EventLogAreaStruct->Next800155EventOffset
902 );
903
904 CopyMem (
905 (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset,
906 NewEventHdr,
907 NewEventHdrSize
908 );
909 CopyMem (
910 (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset + NewEventHdrSize,
911 NewEventData,
912 NewEventSize
913 );
914
915 EventLogAreaStruct->Next800155EventOffset += NewLogSize;
916 EventLogAreaStruct->LastEvent += NewLogSize;
917 EventLogAreaStruct->EventLogSize += NewLogSize;
918 }
919
920 return EFI_SUCCESS;
921 }
922
923 EventLogAreaStruct->LastEvent = (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->EventLogSize;
924 EventLogAreaStruct->EventLogSize += NewLogSize;
925
926 CopyMem (EventLogAreaStruct->LastEvent, NewEventHdr, NewEventHdrSize);
927 CopyMem (
928 EventLogAreaStruct->LastEvent + NewEventHdrSize,
929 NewEventData,
930 NewEventSize
931 );
932
933 return EFI_SUCCESS;
934}
935
936/**
937 According to UEFI Spec 2.10 Section 38.4.1:
938 The following table shows the TPM PCR index mapping and CC event log measurement
939 register index interpretation for Intel TDX, where MRTD means Trust Domain Measurement
940 Register and RTMR means Runtime Measurement Register
941
942 // TPM PCR Index | CC Measurement Register Index | TDX-measurement register
943 // ------------------------------------------------------------------------
944 // 0 | 0 | MRTD
945 // 1, 7 | 1 | RTMR[0]
946 // 2~6 | 2 | RTMR[1]
947 // 8~15 | 3 | RTMR[2]
948
949 @param[in] PCRIndex Index of the TPM PCR
950
951 @retval UINT32 Index of the CC Event Log Measurement Register Index
952 @retval CC_MR_INDEX_INVALID Invalid MR Index
953**/
954UINT32
955EFIAPI
956MapPcrToMrIndex (
957 IN UINT32 PCRIndex
958 )
959{
960 UINT32 MrIndex;
961
962 if (PCRIndex > 15) {
963 ASSERT (FALSE);
964 return CC_MR_INDEX_INVALID;
965 }
966
967 MrIndex = 0;
968 if (PCRIndex == 0) {
969 MrIndex = CC_MR_INDEX_0_MRTD;
970 } else if ((PCRIndex == 1) || (PCRIndex == 7)) {
971 MrIndex = CC_MR_INDEX_1_RTMR0;
972 } else if ((PCRIndex >= 2) && (PCRIndex <= 6)) {
973 MrIndex = CC_MR_INDEX_2_RTMR1;
974 } else if ((PCRIndex >= 8) && (PCRIndex <= 15)) {
975 MrIndex = CC_MR_INDEX_3_RTMR2;
976 }
977
978 return MrIndex;
979}
980
981EFI_STATUS
982EFIAPI
983TdMapPcrToMrIndex (
984 IN EFI_CC_MEASUREMENT_PROTOCOL *This,
985 IN UINT32 PCRIndex,
986 OUT UINT32 *MrIndex
987 )
988{
989 if (MrIndex == NULL) {
990 return EFI_INVALID_PARAMETER;
991 }
992
993 *MrIndex = MapPcrToMrIndex (PCRIndex);
994
995 return *MrIndex == CC_MR_INDEX_INVALID ? EFI_INVALID_PARAMETER : EFI_SUCCESS;
996}
997
998/**
999 Add a new entry to the Event Log.
1000
1001 @param[in] EventLogFormat The type of the event log for which the information is requested.
1002 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
1003 @param[in] NewEventHdrSize New event header size.
1004 @param[in] NewEventData Pointer to the new event data.
1005 @param[in] NewEventSize New event data size.
1006
1007 @retval EFI_SUCCESS The new event log entry was added.
1008 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1009
1010**/
1011EFI_STATUS
1012TdxDxeLogEvent (
1013 IN EFI_CC_EVENT_LOG_FORMAT EventLogFormat,
1014 IN VOID *NewEventHdr,
1015 IN UINT32 NewEventHdrSize,
1016 IN UINT8 *NewEventData,
1017 IN UINT32 NewEventSize
1018 )
1019{
1020 EFI_STATUS Status;
1021 UINTN Index;
1022 CC_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct;
1023
1024 if (EventLogFormat != EFI_CC_EVENT_LOG_FORMAT_TCG_2) {
1025 ASSERT (FALSE);
1026 return EFI_INVALID_PARAMETER;
1027 }
1028
1029 Index = 0;
1030
1031 //
1032 // Record to normal event log
1033 //
1034 EventLogAreaStruct = &mTdxDxeData.EventLogAreaStruct[Index];
1035
1036 if (EventLogAreaStruct->EventLogTruncated) {
1037 return EFI_VOLUME_FULL;
1038 }
1039
1040 Status = TcgCommLogEvent (
1041 EventLogAreaStruct,
1042 NewEventHdr,
1043 NewEventHdrSize,
1044 NewEventData,
1045 NewEventSize
1046 );
1047
1048 if (Status == EFI_OUT_OF_RESOURCES) {
1049 EventLogAreaStruct->EventLogTruncated = TRUE;
1050 return EFI_VOLUME_FULL;
1051 } else if (Status == EFI_SUCCESS) {
1052 EventLogAreaStruct->EventLogStarted = TRUE;
1053 }
1054
1055 //
1056 // If GetEventLog is called, record to FinalEventsTable, too.
1057 //
1058 if (mTdxDxeData.GetEventLogCalled[Index]) {
1059 if (mTdxDxeData.FinalEventsTable[Index] == NULL) {
1060 //
1061 // no need for FinalEventsTable
1062 //
1063 return EFI_SUCCESS;
1064 }
1065
1066 EventLogAreaStruct = &mTdxDxeData.FinalEventLogAreaStruct[Index];
1067
1068 if (EventLogAreaStruct->EventLogTruncated) {
1069 return EFI_VOLUME_FULL;
1070 }
1071
1072 Status = TcgCommLogEvent (
1073 EventLogAreaStruct,
1074 NewEventHdr,
1075 NewEventHdrSize,
1076 NewEventData,
1077 NewEventSize
1078 );
1079 if (Status == EFI_OUT_OF_RESOURCES) {
1080 EventLogAreaStruct->EventLogTruncated = TRUE;
1081 return EFI_VOLUME_FULL;
1082 } else if (Status == EFI_SUCCESS) {
1083 EventLogAreaStruct->EventLogStarted = TRUE;
1084 //
1085 // Increase the NumberOfEvents in FinalEventsTable
1086 //
1087 (mTdxDxeData.FinalEventsTable[Index])->NumberOfEvents++;
1088 DEBUG ((DEBUG_INFO, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTdxDxeData.FinalEventsTable[Index])->NumberOfEvents));
1089 DEBUG ((DEBUG_INFO, " Size - 0x%x\n", (UINTN)EventLogAreaStruct->EventLogSize));
1090 }
1091 }
1092
1093 return Status;
1094}
1095
1096/**
1097 Get TPML_DIGEST_VALUES compact binary buffer size.
1098
1099 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
1100
1101 @return TPML_DIGEST_VALUES compact binary buffer size.
1102**/
1103UINT32
1104GetDigestListBinSize (
1105 IN VOID *DigestListBin
1106 )
1107{
1108 UINTN Index;
1109 UINT16 DigestSize;
1110 UINT32 TotalSize;
1111 UINT32 Count;
1112 TPMI_ALG_HASH HashAlg;
1113
1114 Count = ReadUnaligned32 (DigestListBin);
1115 TotalSize = sizeof (Count);
1116 DigestListBin = (UINT8 *)DigestListBin + sizeof (Count);
1117 for (Index = 0; Index < Count; Index++) {
1118 HashAlg = ReadUnaligned16 (DigestListBin);
1119 TotalSize += sizeof (HashAlg);
1120 DigestListBin = (UINT8 *)DigestListBin + sizeof (HashAlg);
1121
1122 DigestSize = GetHashSizeFromAlgo (HashAlg);
1123 TotalSize += DigestSize;
1124 DigestListBin = (UINT8 *)DigestListBin + DigestSize;
1125 }
1126
1127 return TotalSize;
1128}
1129
1130/**
1131 Copy TPML_DIGEST_VALUES compact binary into a buffer
1132
1133 @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.
1134 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
1135 @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.
1136 @param[out] HashAlgorithmMaskCopied Pointer to HASH bits corresponding to the digests copied.
1137
1138 @return The end of buffer to hold TPML_DIGEST_VALUES compact binary.
1139**/
1140VOID *
1141CopyDigestListBinToBuffer (
1142 IN OUT VOID *Buffer,
1143 IN VOID *DigestListBin,
1144 IN UINT32 HashAlgorithmMask,
1145 OUT UINT32 *HashAlgorithmMaskCopied
1146 )
1147{
1148 UINTN Index;
1149 UINT16 DigestSize;
1150 UINT32 Count;
1151 TPMI_ALG_HASH HashAlg;
1152 UINT32 DigestListCount;
1153 UINT32 *DigestListCountPtr;
1154
1155 DigestListCountPtr = (UINT32 *)Buffer;
1156 DigestListCount = 0;
1157 *HashAlgorithmMaskCopied = 0;
1158
1159 Count = ReadUnaligned32 (DigestListBin);
1160 Buffer = (UINT8 *)Buffer + sizeof (Count);
1161 DigestListBin = (UINT8 *)DigestListBin + sizeof (Count);
1162 for (Index = 0; Index < Count; Index++) {
1163 HashAlg = ReadUnaligned16 (DigestListBin);
1164 DigestListBin = (UINT8 *)DigestListBin + sizeof (HashAlg);
1165 DigestSize = GetHashSizeFromAlgo (HashAlg);
1166
1167 if ((HashAlg & HashAlgorithmMask) != 0) {
1168 CopyMem (Buffer, &HashAlg, sizeof (HashAlg));
1169 Buffer = (UINT8 *)Buffer + sizeof (HashAlg);
1170 CopyMem (Buffer, DigestListBin, DigestSize);
1171 Buffer = (UINT8 *)Buffer + DigestSize;
1172 DigestListCount++;
1173 (*HashAlgorithmMaskCopied) |= GetHashMaskFromAlgo (HashAlg);
1174 } else {
1175 DEBUG ((DEBUG_ERROR, "WARNING: CopyDigestListBinToBuffer Event log has HashAlg unsupported by PCR bank (0x%x)\n", HashAlg));
1176 }
1177
1178 DigestListBin = (UINT8 *)DigestListBin + DigestSize;
1179 }
1180
1181 WriteUnaligned32 (DigestListCountPtr, DigestListCount);
1182
1183 return Buffer;
1184}
1185
1186/**
1187 Add a new entry to the Event Log. The call chain is like below:
1188 TdxDxeLogHashEvent -> TdxDxeLogEvent -> TcgCommonLogEvent
1189
1190 Before this function is called, the event information (including the digest)
1191 is ready.
1192
1193 @param[in] DigestList A list of digest.
1194 @param[in,out] NewEventHdr Pointer to a TD_EVENT_HDR data structure.
1195 @param[in] NewEventData Pointer to the new event data.
1196
1197 @retval EFI_SUCCESS The new event log entry was added.
1198 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1199**/
1200EFI_STATUS
1201TdxDxeLogHashEvent (
1202 IN TPML_DIGEST_VALUES *DigestList,
1203 IN OUT CC_EVENT_HDR *NewEventHdr,
1204 IN UINT8 *NewEventData
1205 )
1206{
1207 EFI_STATUS Status;
1208 EFI_TPL OldTpl;
1209 EFI_STATUS RetStatus;
1210 CC_EVENT CcEvent;
1211 UINT8 *DigestBuffer;
1212 UINT32 *EventSizePtr;
1213 EFI_CC_EVENT_LOG_FORMAT LogFormat;
1214
1215 RetStatus = EFI_SUCCESS;
1216 LogFormat = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
1217
1218 ZeroMem (&CcEvent, sizeof (CcEvent));
1219 CcEvent.MrIndex = NewEventHdr->MrIndex;
1220 CcEvent.EventType = NewEventHdr->EventType;
1221 DigestBuffer = (UINT8 *)&CcEvent.Digests;
1222 EventSizePtr = CopyDigestListToBuffer (DigestBuffer, DigestList, HASH_ALG_SHA384);
1223 CopyMem (EventSizePtr, &NewEventHdr->EventSize, sizeof (NewEventHdr->EventSize));
1224
1225 //
1226 // Enter critical region
1227 //
1228 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
1229 Status = TdxDxeLogEvent (
1230 LogFormat,
1231 &CcEvent,
1232 sizeof (CcEvent.MrIndex) + sizeof (CcEvent.EventType) + GetDigestListBinSize (DigestBuffer) + sizeof (CcEvent.EventSize),
1233 NewEventData,
1234 NewEventHdr->EventSize
1235 );
1236 if (Status != EFI_SUCCESS) {
1237 RetStatus = Status;
1238 }
1239
1240 gBS->RestoreTPL (OldTpl);
1241
1242 return RetStatus;
1243}
1244
1245/**
1246 Do a hash operation on a data buffer, extend a specific RTMR with the hash result,
1247 and add an entry to the Event Log.
1248
1249 @param[in] Flags Bitmap providing additional information.
1250 @param[in] HashData Physical address of the start of the data buffer
1251 to be hashed, extended, and logged.
1252 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
1253 @param[in, out] NewEventHdr Pointer to a TD_EVENT_HDR data structure.
1254 @param[in] NewEventData Pointer to the new event data.
1255
1256 @retval EFI_SUCCESS Operation completed successfully.
1257 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1258 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1259
1260**/
1261EFI_STATUS
1262TdxDxeHashLogExtendEvent (
1263 IN UINT64 Flags,
1264 IN UINT8 *HashData,
1265 IN UINT64 HashDataLen,
1266 IN OUT CC_EVENT_HDR *NewEventHdr,
1267 IN UINT8 *NewEventData
1268 )
1269{
1270 EFI_STATUS Status;
1271 TPML_DIGEST_VALUES DigestList;
1272 CC_EVENT_HDR NoActionEvent;
1273
1274 if (NewEventHdr->EventType == EV_NO_ACTION) {
1275 //
1276 // Do not do RTMR extend for EV_NO_ACTION
1277 //
1278 Status = EFI_SUCCESS;
1279 InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);
1280 if ((Flags & EFI_CC_FLAG_EXTEND_ONLY) == 0) {
1281 Status = TdxDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr, NewEventData);
1282 }
1283
1284 return Status;
1285 }
1286
1287 //
1288 // According to UEFI Spec 2.10 Section 38.4.1 the mapping between MrIndex and Intel
1289 // TDX Measurement Register is:
1290 // MrIndex 0 <--> MRTD
1291 // MrIndex 1-3 <--> RTMR[0-2]
1292 // Only the RMTR registers can be extended in TDVF by HashAndExtend. So MrIndex will
1293 // decreased by 1 before it is sent to HashAndExtend.
1294 //
1295 Status = HashAndExtend (
1296 NewEventHdr->MrIndex - 1,
1297 HashData,
1298 (UINTN)HashDataLen,
1299 &DigestList
1300 );
1301 if (!EFI_ERROR (Status)) {
1302 if ((Flags & EFI_CC_FLAG_EXTEND_ONLY) == 0) {
1303 Status = TdxDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);
1304 }
1305 }
1306
1307 return Status;
1308}
1309
1310/**
1311 The EFI_CC_MEASUREMENT_PROTOCOL HashLogExtendEvent function call provides callers with
1312 an opportunity to extend and optionally log events without requiring
1313 knowledge of actual TPM commands.
1314 The extend operation will occur even if this function cannot create an event
1315 log entry (e.g. due to the event log being full).
1316
1317 @param[in] This Indicates the calling context
1318 @param[in] Flags Bitmap providing additional information.
1319 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
1320 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
1321 @param[in] Event Pointer to data buffer containing information about the event.
1322
1323 @retval EFI_SUCCESS Operation completed successfully.
1324 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1325 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
1326 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1327 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
1328**/
1329EFI_STATUS
1330EFIAPI
1331TdHashLogExtendEvent (
1332 IN EFI_CC_MEASUREMENT_PROTOCOL *This,
1333 IN UINT64 Flags,
1334 IN EFI_PHYSICAL_ADDRESS DataToHash,
1335 IN UINT64 DataToHashLen,
1336 IN EFI_CC_EVENT *CcEvent
1337 )
1338{
1339 EFI_STATUS Status;
1340 CC_EVENT_HDR NewEventHdr;
1341 TPML_DIGEST_VALUES DigestList;
1342
1343 DEBUG ((DEBUG_VERBOSE, "TdHashLogExtendEvent ...\n"));
1344
1345 if ((This == NULL) || (CcEvent == NULL)) {
1346 return EFI_INVALID_PARAMETER;
1347 }
1348
1349 //
1350 // Do not check hash data size for EV_NO_ACTION event.
1351 //
1352 if ((CcEvent->Header.EventType != EV_NO_ACTION) && (DataToHash == 0)) {
1353 return EFI_INVALID_PARAMETER;
1354 }
1355
1356 if (CcEvent->Size < CcEvent->Header.HeaderSize + sizeof (UINT32)) {
1357 return EFI_INVALID_PARAMETER;
1358 }
1359
1360 if (CcEvent->Header.MrIndex == CC_MR_INDEX_0_MRTD) {
1361 DEBUG ((DEBUG_ERROR, "%a: MRTD cannot be extended in TDVF.\n", __func__));
1362 return EFI_INVALID_PARAMETER;
1363 }
1364
1365 if (CcEvent->Header.MrIndex >= CC_MR_INDEX_INVALID) {
1366 DEBUG ((DEBUG_ERROR, "%a: MrIndex is invalid. (%d)\n", __func__, CcEvent->Header.MrIndex));
1367 return EFI_INVALID_PARAMETER;
1368 }
1369
1370 NewEventHdr.MrIndex = CcEvent->Header.MrIndex;
1371 NewEventHdr.EventType = CcEvent->Header.EventType;
1372 NewEventHdr.EventSize = CcEvent->Size - sizeof (UINT32) - CcEvent->Header.HeaderSize;
1373 if ((Flags & EFI_CC_FLAG_PE_COFF_IMAGE) != 0) {
1374 //
1375 // According to UEFI Spec 2.10 Section 38.4.1 the mapping between MrIndex and Intel
1376 // TDX Measurement Register is:
1377 // MrIndex 0 <--> MRTD
1378 // MrIndex 1-3 <--> RTMR[0-2]
1379 // Only the RMTR registers can be extended in TDVF by HashAndExtend. So MrIndex will
1380 // decreased by 1 before it is sent to MeasurePeImageAndExtend.
1381 //
1382 Status = MeasurePeImageAndExtend (
1383 NewEventHdr.MrIndex - 1,
1384 DataToHash,
1385 (UINTN)DataToHashLen,
1386 &DigestList
1387 );
1388 if (!EFI_ERROR (Status)) {
1389 if ((Flags & EFI_CC_FLAG_EXTEND_ONLY) == 0) {
1390 Status = TdxDxeLogHashEvent (&DigestList, &NewEventHdr, CcEvent->Event);
1391 }
1392 }
1393 } else {
1394 Status = TdxDxeHashLogExtendEvent (
1395 Flags,
1396 (UINT8 *)(UINTN)DataToHash,
1397 DataToHashLen,
1398 &NewEventHdr,
1399 CcEvent->Event
1400 );
1401 }
1402
1403 DEBUG ((DEBUG_VERBOSE, "TdHashLogExtendEvent - %r\n", Status));
1404 return Status;
1405}
1406
1407EFI_CC_MEASUREMENT_PROTOCOL mTdProtocol = {
1408 TdGetCapability,
1409 TdGetEventLog,
1410 TdHashLogExtendEvent,
1411 TdMapPcrToMrIndex,
1412};
1413
1414#define TD_HASH_COUNT 1
1415#define TEMP_BUF_LEN (sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) \
1416 + (TD_HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8))
1417
1418/**
1419 Initialize the TD Event Log and log events passed from the PEI phase.
1420
1421 @retval EFI_SUCCESS Operation completed successfully.
1422 @retval EFI_OUT_OF_RESOURCES Out of memory.
1423
1424**/
1425EFI_STATUS
1426SetupCcEventLog (
1427 VOID
1428 )
1429{
1430 EFI_STATUS Status;
1431 EFI_PHYSICAL_ADDRESS Lasa;
1432 UINTN Index;
1433 TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;
1434 UINT8 TempBuf[TEMP_BUF_LEN];
1435 TCG_PCR_EVENT_HDR SpecIdEvent;
1436 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
1437 TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;
1438 UINT8 *VendorInfoSize;
1439 UINT32 NumberOfAlgorithms;
1440 EFI_CC_EVENT_LOG_FORMAT LogFormat;
1441 EFI_PEI_HOB_POINTERS GuidHob;
1442 CC_EVENT_HDR NoActionEvent;
1443
1444 Status = EFI_SUCCESS;
1445 DEBUG ((DEBUG_INFO, "SetupCcEventLog\n"));
1446
1447 Index = 0;
1448 LogFormat = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
1449
1450 //
1451 // 1. Create Log Area
1452 //
1453 mTdxDxeData.EventLogAreaStruct[Index].EventLogFormat = LogFormat;
1454
1455 // allocate pages for TD Event log
1456 Status = gBS->AllocatePages (
1457 AllocateAnyPages,
1458 EfiACPIMemoryNVS,
1459 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
1460 &Lasa
1461 );
1462 if (EFI_ERROR (Status)) {
1463 return Status;
1464 }
1465
1466 mTdxDxeData.EventLogAreaStruct[Index].Lasa = Lasa;
1467 mTdxDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);
1468 mTdxDxeData.EventLogAreaStruct[Index].Next800155EventOffset = 0;
1469
1470 //
1471 // Report TD event log address and length, so that they can be reported in
1472 // TD ACPI table. Ignore the return status, because those fields are optional.
1473 //
1474 PcdSet32S (PcdCcEventlogAcpiTableLaml, (UINT32)mTdxDxeData.EventLogAreaStruct[Index].Laml);
1475 PcdSet64S (PcdCcEventlogAcpiTableLasa, mTdxDxeData.EventLogAreaStruct[Index].Lasa);
1476
1477 //
1478 // To initialize them as 0xFF is recommended
1479 // because the OS can know the last entry for that.
1480 //
1481 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);
1482
1483 //
1484 // Create first entry for Log Header Entry Data
1485 //
1486
1487 //
1488 // TcgEfiSpecIdEventStruct
1489 //
1490 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)TempBuf;
1491 CopyMem (TcgEfiSpecIdEventStruct->signature, TCG_EfiSpecIDEventStruct_SIGNATURE_03, sizeof (TcgEfiSpecIdEventStruct->signature));
1492
1493 TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);
1494
1495 TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;
1496 TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;
1497 TcgEfiSpecIdEventStruct->specErrata = TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2;
1498 TcgEfiSpecIdEventStruct->uintnSize = sizeof (UINTN)/sizeof (UINT32);
1499 NumberOfAlgorithms = 0;
1500 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct
1501 + sizeof (*TcgEfiSpecIdEventStruct)
1502 + sizeof (NumberOfAlgorithms));
1503
1504 TempDigestSize = DigestSize;
1505 TempDigestSize += NumberOfAlgorithms;
1506 TempDigestSize->algorithmId = TPM_ALG_SHA384;
1507 TempDigestSize->digestSize = SHA384_DIGEST_SIZE;
1508 NumberOfAlgorithms++;
1509
1510 CopyMem (TcgEfiSpecIdEventStruct + 1, &NumberOfAlgorithms, sizeof (NumberOfAlgorithms));
1511 TempDigestSize = DigestSize;
1512 TempDigestSize += NumberOfAlgorithms;
1513 VendorInfoSize = (UINT8 *)TempDigestSize;
1514 *VendorInfoSize = 0;
1515
1516 SpecIdEvent.PCRIndex = 1; // PCRIndex 0 maps to MrIndex 1
1517 SpecIdEvent.EventType = EV_NO_ACTION;
1518 ZeroMem (&SpecIdEvent.Digest, sizeof (SpecIdEvent.Digest));
1519 SpecIdEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);
1520
1521 //
1522 // TD Event log re-use the spec of TCG2 Event log.
1523 // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.
1524 // TCG EFI Protocol Spec. Section 5.3 Event Log Header
1525 // TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log
1526 //
1527 Status = TdxDxeLogEvent (
1528 LogFormat,
1529 &SpecIdEvent,
1530 sizeof (SpecIdEvent),
1531 (UINT8 *)TcgEfiSpecIdEventStruct,
1532 SpecIdEvent.EventSize
1533 );
1534 //
1535 // record the offset at the end of 800-155 event.
1536 // the future 800-155 event can be inserted here.
1537 //
1538 mTdxDxeData.EventLogAreaStruct[Index].Next800155EventOffset = mTdxDxeData.EventLogAreaStruct[Index].EventLogSize;
1539
1540 //
1541 // Tcg800155PlatformIdEvent. Event format is TCG_PCR_EVENT2
1542 //
1543 GuidHob.Guid = GetFirstGuidHob (&gTcg800155PlatformIdEventHobGuid);
1544 while (GuidHob.Guid != NULL) {
1545 InitNoActionEvent (&NoActionEvent, GET_GUID_HOB_DATA_SIZE (GuidHob.Guid));
1546
1547 Status = TdxDxeLogEvent (
1548 LogFormat,
1549 &NoActionEvent,
1550 sizeof (NoActionEvent.MrIndex) + sizeof (NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof (NoActionEvent.EventSize),
1551 GET_GUID_HOB_DATA (GuidHob.Guid),
1552 GET_GUID_HOB_DATA_SIZE (GuidHob.Guid)
1553 );
1554
1555 GuidHob.Guid = GET_NEXT_HOB (GuidHob);
1556 GuidHob.Guid = GetNextGuidHob (&gTcg800155PlatformIdEventHobGuid, GuidHob.Guid);
1557 }
1558
1559 //
1560 // 2. Create Final Log Area
1561 //
1562 Status = gBS->AllocatePages (
1563 AllocateAnyPages,
1564 EfiACPIMemoryNVS,
1565 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),
1566 &Lasa
1567 );
1568 if (EFI_ERROR (Status)) {
1569 return Status;
1570 }
1571
1572 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcg2FinalLogAreaLen), 0xFF);
1573
1574 //
1575 // Initialize
1576 //
1577 mTdxDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;
1578 (mTdxDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;
1579 (mTdxDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;
1580
1581 mTdxDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = LogFormat;
1582 mTdxDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof (EFI_CC_FINAL_EVENTS_TABLE);
1583 mTdxDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof (EFI_CC_FINAL_EVENTS_TABLE);
1584 mTdxDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
1585 mTdxDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTdxDxeData.FinalEventLogAreaStruct[Index].Lasa;
1586 mTdxDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
1587 mTdxDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
1588 mTdxDxeData.FinalEventLogAreaStruct[Index].Next800155EventOffset = 0;
1589
1590 //
1591 // Install to configuration table for EFI_CC_EVENT_LOG_FORMAT_TCG_2
1592 //
1593 Status = gBS->InstallConfigurationTable (&gEfiCcFinalEventsTableGuid, (VOID *)mTdxDxeData.FinalEventsTable[Index]);
1594 if (EFI_ERROR (Status)) {
1595 return Status;
1596 }
1597
1598 return Status;
1599}
1600
1601/**
1602 Measure and log an action string, and extend the measurement result into RTMR.
1603
1604 @param[in] MrIndex MrIndex to extend
1605 @param[in] String A specific string that indicates an Action event.
1606
1607 @retval EFI_SUCCESS Operation completed successfully.
1608 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1609
1610**/
1611EFI_STATUS
1612TdMeasureAction (
1613 IN UINT32 MrIndex,
1614 IN CHAR8 *String
1615 )
1616{
1617 CC_EVENT_HDR CcEvent;
1618
1619 CcEvent.MrIndex = MrIndex;
1620 CcEvent.EventType = EV_EFI_ACTION;
1621 CcEvent.EventSize = (UINT32)AsciiStrLen (String);
1622 return TdxDxeHashLogExtendEvent (
1623 0,
1624 (UINT8 *)String,
1625 CcEvent.EventSize,
1626 &CcEvent,
1627 (UINT8 *)String
1628 );
1629}
1630
1631/**
1632 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1633
1634 @retval EFI_SUCCESS Operation completed successfully.
1635 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1636
1637**/
1638EFI_STATUS
1639MeasureHandoffTables (
1640 VOID
1641 )
1642{
1643 EFI_STATUS Status;
1644 CC_EVENT_HDR CcEvent;
1645 EFI_HANDOFF_TABLE_POINTERS HandoffTables;
1646 UINTN ProcessorNum;
1647 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
1648
1649 ProcessorLocBuf = NULL;
1650 Status = EFI_SUCCESS;
1651
1652 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
1653 //
1654 // Tcg Server spec.
1655 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1656 //
1657 Status = GetProcessorsCpuLocation (&ProcessorLocBuf, &ProcessorNum);
1658
1659 if (!EFI_ERROR (Status)) {
1660 CcEvent.MrIndex = MapPcrToMrIndex (1);
1661 CcEvent.EventType = EV_TABLE_OF_DEVICES;
1662 CcEvent.EventSize = sizeof (HandoffTables);
1663
1664 HandoffTables.NumberOfTables = 1;
1665 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;
1666 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;
1667
1668 Status = TdxDxeHashLogExtendEvent (
1669 0,
1670 (UINT8 *)(UINTN)ProcessorLocBuf,
1671 sizeof (EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
1672 &CcEvent,
1673 (UINT8 *)&HandoffTables
1674 );
1675
1676 FreePool (ProcessorLocBuf);
1677 }
1678 }
1679
1680 return Status;
1681}
1682
1683/**
1684 Measure and log Separator event, and extend the measurement result into a specific PCR.
1685
1686 @param[in] PCRIndex PCR index.
1687
1688 @retval EFI_SUCCESS Operation completed successfully.
1689 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1690
1691**/
1692EFI_STATUS
1693MeasureSeparatorEvent (
1694 IN UINT32 MrIndex
1695 )
1696{
1697 CC_EVENT_HDR CcEvent;
1698 UINT32 EventData;
1699
1700 DEBUG ((DEBUG_INFO, "MeasureSeparatorEvent to Rtmr - %d\n", MrIndex));
1701
1702 EventData = 0;
1703 CcEvent.MrIndex = MrIndex;
1704 CcEvent.EventType = EV_SEPARATOR;
1705 CcEvent.EventSize = (UINT32)sizeof (EventData);
1706
1707 return TdxDxeHashLogExtendEvent (
1708 0,
1709 (UINT8 *)&EventData,
1710 sizeof (EventData),
1711 &CcEvent,
1712 (UINT8 *)&EventData
1713 );
1714}
1715
1716/**
1717 Measure and log an EFI variable, and extend the measurement result into a specific RTMR.
1718
1719 @param[in] MrIndex RTMR Index.
1720 @param[in] EventType Event type.
1721 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1722 @param[in] VendorGuid A unique identifier for the vendor.
1723 @param[in] VarData The content of the variable data.
1724 @param[in] VarSize The size of the variable data.
1725
1726 @retval EFI_SUCCESS Operation completed successfully.
1727 @retval EFI_OUT_OF_RESOURCES Out of memory.
1728 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1729
1730**/
1731EFI_STATUS
1732MeasureVariable (
1733 IN UINT32 MrIndex,
1734 IN TCG_EVENTTYPE EventType,
1735 IN CHAR16 *VarName,
1736 IN EFI_GUID *VendorGuid,
1737 IN VOID *VarData,
1738 IN UINTN VarSize
1739 )
1740{
1741 EFI_STATUS Status;
1742 CC_EVENT_HDR CcEvent;
1743 UINTN VarNameLength;
1744 UEFI_VARIABLE_DATA *VarLog;
1745
1746 DEBUG ((DEBUG_INFO, "TdTcg2Dxe: MeasureVariable (Rtmr - %x, EventType - %x, ", (UINTN)MrIndex, (UINTN)EventType));
1747 DEBUG ((DEBUG_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
1748
1749 VarNameLength = StrLen (VarName);
1750 CcEvent.MrIndex = MrIndex;
1751 CcEvent.EventType = EventType;
1752
1753 CcEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
1754 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
1755
1756 VarLog = (UEFI_VARIABLE_DATA *)AllocatePool (CcEvent.EventSize);
1757 if (VarLog == NULL) {
1758 return EFI_OUT_OF_RESOURCES;
1759 }
1760
1761 VarLog->VariableName = *VendorGuid;
1762 VarLog->UnicodeNameLength = VarNameLength;
1763 VarLog->VariableDataLength = VarSize;
1764 CopyMem (
1765 VarLog->UnicodeName,
1766 VarName,
1767 VarNameLength * sizeof (*VarName)
1768 );
1769 if ((VarSize != 0) && (VarData != NULL)) {
1770 CopyMem (
1771 (CHAR16 *)VarLog->UnicodeName + VarNameLength,
1772 VarData,
1773 VarSize
1774 );
1775 }
1776
1777 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
1778 //
1779 // Digest is the event data (UEFI_VARIABLE_DATA)
1780 //
1781 Status = TdxDxeHashLogExtendEvent (
1782 0,
1783 (UINT8 *)VarLog,
1784 CcEvent.EventSize,
1785 &CcEvent,
1786 (UINT8 *)VarLog
1787 );
1788 } else {
1789 ASSERT (VarData != NULL);
1790 Status = TdxDxeHashLogExtendEvent (
1791 0,
1792 (UINT8 *)VarData,
1793 VarSize,
1794 &CcEvent,
1795 (UINT8 *)VarLog
1796 );
1797 }
1798
1799 FreePool (VarLog);
1800 return Status;
1801}
1802
1803/**
1804 Read then Measure and log an EFI variable, and extend the measurement result into a specific RTMR.
1805
1806 @param[in] MrIndex RTMR Index.
1807 @param[in] EventType Event type.
1808 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1809 @param[in] VendorGuid A unique identifier for the vendor.
1810 @param[out] VarSize The size of the variable data.
1811 @param[out] VarData Pointer to the content of the variable.
1812
1813 @retval EFI_SUCCESS Operation completed successfully.
1814 @retval EFI_OUT_OF_RESOURCES Out of memory.
1815 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1816
1817**/
1818EFI_STATUS
1819ReadAndMeasureVariable (
1820 IN UINT32 MrIndex,
1821 IN TCG_EVENTTYPE EventType,
1822 IN CHAR16 *VarName,
1823 IN EFI_GUID *VendorGuid,
1824 OUT UINTN *VarSize,
1825 OUT VOID **VarData
1826 )
1827{
1828 EFI_STATUS Status;
1829
1830 Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);
1831 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
1832 if (EFI_ERROR (Status)) {
1833 //
1834 // It is valid case, so we need handle it.
1835 //
1836 *VarData = NULL;
1837 *VarSize = 0;
1838 }
1839 } else {
1840 //
1841 // if status error, VarData is freed and set NULL by GetVariable2
1842 //
1843 if (EFI_ERROR (Status)) {
1844 return EFI_NOT_FOUND;
1845 }
1846 }
1847
1848 Status = MeasureVariable (
1849 MrIndex,
1850 EventType,
1851 VarName,
1852 VendorGuid,
1853 *VarData,
1854 *VarSize
1855 );
1856 return Status;
1857}
1858
1859/**
1860 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].
1861according to TCG PC Client PFP spec 0021 Section 2.4.4.2
1862
1863 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1864 @param[in] VendorGuid A unique identifier for the vendor.
1865 @param[out] VarSize The size of the variable data.
1866 @param[out] VarData Pointer to the content of the variable.
1867
1868 @retval EFI_SUCCESS Operation completed successfully.
1869 @retval EFI_OUT_OF_RESOURCES Out of memory.
1870 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1871
1872**/
1873EFI_STATUS
1874ReadAndMeasureBootVariable (
1875 IN CHAR16 *VarName,
1876 IN EFI_GUID *VendorGuid,
1877 OUT UINTN *VarSize,
1878 OUT VOID **VarData
1879 )
1880{
1881 return ReadAndMeasureVariable (
1882 MapPcrToMrIndex (1),
1883 EV_EFI_VARIABLE_BOOT,
1884 VarName,
1885 VendorGuid,
1886 VarSize,
1887 VarData
1888 );
1889}
1890
1891/**
1892 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
1893
1894 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1895 @param[in] VendorGuid A unique identifier for the vendor.
1896 @param[out] VarSize The size of the variable data.
1897 @param[out] VarData Pointer to the content of the variable.
1898
1899 @retval EFI_SUCCESS Operation completed successfully.
1900 @retval EFI_OUT_OF_RESOURCES Out of memory.
1901 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1902
1903**/
1904EFI_STATUS
1905ReadAndMeasureSecureVariable (
1906 IN CHAR16 *VarName,
1907 IN EFI_GUID *VendorGuid,
1908 OUT UINTN *VarSize,
1909 OUT VOID **VarData
1910 )
1911{
1912 return ReadAndMeasureVariable (
1913 MapPcrToMrIndex (7),
1914 EV_EFI_VARIABLE_DRIVER_CONFIG,
1915 VarName,
1916 VendorGuid,
1917 VarSize,
1918 VarData
1919 );
1920}
1921
1922/**
1923 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
1924
1925 The EFI boot variables are BootOrder and Boot#### variables.
1926
1927 @retval EFI_SUCCESS Operation completed successfully.
1928 @retval EFI_OUT_OF_RESOURCES Out of memory.
1929 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1930
1931**/
1932EFI_STATUS
1933MeasureAllBootVariables (
1934 VOID
1935 )
1936{
1937 EFI_STATUS Status;
1938 UINT16 *BootOrder;
1939 UINTN BootCount;
1940 UINTN Index;
1941 VOID *BootVarData;
1942 UINTN Size;
1943
1944 Status = ReadAndMeasureBootVariable (
1945 mBootVarName,
1946 &gEfiGlobalVariableGuid,
1947 &BootCount,
1948 (VOID **)&BootOrder
1949 );
1950 if ((Status == EFI_NOT_FOUND) || (BootOrder == NULL)) {
1951 return EFI_SUCCESS;
1952 }
1953
1954 if (EFI_ERROR (Status)) {
1955 //
1956 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
1957 //
1958 FreePool (BootOrder);
1959 return Status;
1960 }
1961
1962 BootCount /= sizeof (*BootOrder);
1963 for (Index = 0; Index < BootCount; Index++) {
1964 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);
1965 Status = ReadAndMeasureBootVariable (
1966 mBootVarName,
1967 &gEfiGlobalVariableGuid,
1968 &Size,
1969 &BootVarData
1970 );
1971 if (!EFI_ERROR (Status)) {
1972 FreePool (BootVarData);
1973 }
1974 }
1975
1976 FreePool (BootOrder);
1977 return EFI_SUCCESS;
1978}
1979
1980/**
1981 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
1982
1983 The EFI boot variables are BootOrder and Boot#### variables.
1984
1985 @retval EFI_SUCCESS Operation completed successfully.
1986 @retval EFI_OUT_OF_RESOURCES Out of memory.
1987 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1988
1989**/
1990EFI_STATUS
1991MeasureAllSecureVariables (
1992 VOID
1993 )
1994{
1995 EFI_STATUS Status;
1996 VOID *Data;
1997 UINTN DataSize;
1998 UINTN Index;
1999
2000 Status = EFI_NOT_FOUND;
2001 for (Index = 0; Index < sizeof (mVariableType)/sizeof (mVariableType[0]); Index++) {
2002 Status = ReadAndMeasureSecureVariable (
2003 mVariableType[Index].VariableName,
2004 mVariableType[Index].VendorGuid,
2005 &DataSize,
2006 &Data
2007 );
2008 if (!EFI_ERROR (Status)) {
2009 if (Data != NULL) {
2010 FreePool (Data);
2011 }
2012 }
2013 }
2014
2015 //
2016 // Measure DBT if present and not empty
2017 //
2018 Status = GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, &Data, &DataSize);
2019 if (!EFI_ERROR (Status)) {
2020 Status = MeasureVariable (
2021 MapPcrToMrIndex (7),
2022 EV_EFI_VARIABLE_DRIVER_CONFIG,
2023 EFI_IMAGE_SECURITY_DATABASE2,
2024 &gEfiImageSecurityDatabaseGuid,
2025 Data,
2026 DataSize
2027 );
2028 FreePool (Data);
2029 } else {
2030 DEBUG ((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2));
2031 }
2032
2033 return EFI_SUCCESS;
2034}
2035
2036/**
2037 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
2038
2039 @retval EFI_SUCCESS Operation completed successfully.
2040 @retval EFI_OUT_OF_RESOURCES Out of memory.
2041 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2042
2043**/
2044EFI_STATUS
2045MeasureLaunchOfFirmwareDebugger (
2046 VOID
2047 )
2048{
2049 CC_EVENT_HDR CcEvent;
2050
2051 CcEvent.MrIndex = MapPcrToMrIndex (7);
2052 CcEvent.EventType = EV_EFI_ACTION;
2053 CcEvent.EventSize = sizeof (FIRMWARE_DEBUGGER_EVENT_STRING) - 1;
2054 return TdxDxeHashLogExtendEvent (
2055 0,
2056 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,
2057 sizeof (FIRMWARE_DEBUGGER_EVENT_STRING) - 1,
2058 &CcEvent,
2059 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING
2060 );
2061}
2062
2063/**
2064 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
2065
2066 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
2067 - The contents of the SecureBoot variable
2068 - The contents of the PK variable
2069 - The contents of the KEK variable
2070 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
2071 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
2072 - Separator
2073 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
2074
2075 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
2076 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
2077
2078 @param[in] Event Event whose notification function is being invoked
2079 @param[in] Context Pointer to the notification function's context
2080**/
2081VOID
2082EFIAPI
2083MeasureSecureBootPolicy (
2084 IN EFI_EVENT Event,
2085 IN VOID *Context
2086 )
2087{
2088 EFI_STATUS Status;
2089 VOID *Protocol;
2090
2091 Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);
2092 if (EFI_ERROR (Status)) {
2093 return;
2094 }
2095
2096 if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {
2097 Status = MeasureLaunchOfFirmwareDebugger ();
2098 DEBUG ((DEBUG_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));
2099 }
2100
2101 Status = MeasureAllSecureVariables ();
2102 DEBUG ((DEBUG_INFO, "MeasureAllSecureVariables - %r\n", Status));
2103
2104 //
2105 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
2106 // and ImageVerification (Authority)
2107 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
2108 // the Authority measurement happen before ReadToBoot event.
2109 //
2110 Status = MeasureSeparatorEvent (MapPcrToMrIndex (7));
2111 DEBUG ((DEBUG_INFO, "MeasureSeparatorEvent - %r\n", Status));
2112 return;
2113}
2114
2115/**
2116 Ready to Boot Event notification handler.
2117
2118 Sequence of OS boot events is measured in this event notification handler.
2119
2120 @param[in] Event Event whose notification function is being invoked
2121 @param[in] Context Pointer to the notification function's context
2122
2123**/
2124VOID
2125EFIAPI
2126OnReadyToBoot (
2127 IN EFI_EVENT Event,
2128 IN VOID *Context
2129 )
2130{
2131 EFI_STATUS Status;
2132
2133 PERF_START_EX (mImageHandle, "EventRec", "TdTcg2Dxe", 0, PERF_ID_CC_TCG2_DXE);
2134 if (mBootAttempts == 0) {
2135 //
2136 // Measure handoff tables.
2137 //
2138 Status = MeasureHandoffTables ();
2139 if (EFI_ERROR (Status)) {
2140 DEBUG ((DEBUG_ERROR, "HOBs not Measured. Error!\n"));
2141 }
2142
2143 //
2144 // Measure BootOrder & Boot#### variables.
2145 //
2146 Status = MeasureAllBootVariables ();
2147 if (EFI_ERROR (Status)) {
2148 DEBUG ((DEBUG_ERROR, "Boot Variables not Measured. Error!\n"));
2149 }
2150
2151 //
2152 // 1. This is the first boot attempt.
2153 //
2154 Status = TdMeasureAction (
2155 MapPcrToMrIndex (4),
2156 EFI_CALLING_EFI_APPLICATION
2157 );
2158 if (EFI_ERROR (Status)) {
2159 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
2160 }
2161
2162 //
2163 // 2. Draw a line between pre-boot env and entering post-boot env.
2164 // PCR[7] (is RTMR[0]) is already done.
2165 //
2166 Status = MeasureSeparatorEvent (1);
2167 if (EFI_ERROR (Status)) {
2168 DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n"));
2169 }
2170
2171 //
2172 // 3. Measure GPT. It would be done in SAP driver.
2173 //
2174
2175 //
2176 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
2177 //
2178
2179 //
2180 // 5. Read & Measure variable. BootOrder already measured.
2181 //
2182 } else {
2183 //
2184 // 6. Not first attempt, meaning a return from last attempt
2185 //
2186 Status = TdMeasureAction (
2187 MapPcrToMrIndex (4),
2188 EFI_RETURNING_FROM_EFI_APPLICATION
2189 );
2190 if (EFI_ERROR (Status)) {
2191 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATION));
2192 }
2193
2194 //
2195 // 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again
2196 // TCG PC Client PFP spec Section 2.4.4.5 Step 4
2197 //
2198 Status = TdMeasureAction (
2199 MapPcrToMrIndex (4),
2200 EFI_CALLING_EFI_APPLICATION
2201 );
2202 if (EFI_ERROR (Status)) {
2203 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
2204 }
2205 }
2206
2207 DEBUG ((DEBUG_INFO, "TdTcg2Dxe Measure Data when ReadyToBoot\n"));
2208 //
2209 // Increase boot attempt counter.
2210 //
2211 mBootAttempts++;
2212 PERF_END_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_CC_TCG2_DXE + 1);
2213}
2214
2215/**
2216 Exit Boot Services Event notification handler.
2217
2218 Measure invocation and success of ExitBootServices.
2219
2220 @param[in] Event Event whose notification function is being invoked
2221 @param[in] Context Pointer to the notification function's context
2222
2223**/
2224VOID
2225EFIAPI
2226OnExitBootServices (
2227 IN EFI_EVENT Event,
2228 IN VOID *Context
2229 )
2230{
2231 EFI_STATUS Status;
2232
2233 //
2234 // Measure invocation of ExitBootServices,
2235 //
2236 Status = TdMeasureAction (
2237 MapPcrToMrIndex (5),
2238 EFI_EXIT_BOOT_SERVICES_INVOCATION
2239 );
2240 if (EFI_ERROR (Status)) {
2241 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));
2242 }
2243
2244 //
2245 // Measure success of ExitBootServices
2246 //
2247 Status = TdMeasureAction (
2248 MapPcrToMrIndex (5),
2249 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
2250 );
2251 if (EFI_ERROR (Status)) {
2252 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));
2253 }
2254}
2255
2256/**
2257 Exit Boot Services Failed Event notification handler.
2258
2259 Measure Failure of ExitBootServices.
2260
2261 @param[in] Event Event whose notification function is being invoked
2262 @param[in] Context Pointer to the notification function's context
2263
2264**/
2265VOID
2266EFIAPI
2267OnExitBootServicesFailed (
2268 IN EFI_EVENT Event,
2269 IN VOID *Context
2270 )
2271{
2272 EFI_STATUS Status;
2273
2274 //
2275 // Measure Failure of ExitBootServices,
2276 //
2277 Status = TdMeasureAction (
2278 MapPcrToMrIndex (5),
2279 EFI_EXIT_BOOT_SERVICES_FAILED
2280 );
2281 if (EFI_ERROR (Status)) {
2282 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));
2283 }
2284}
2285
2286EFI_STATUS
2287SyncCcEvent (
2288 VOID
2289 )
2290{
2291 EFI_STATUS Status;
2292 EFI_PEI_HOB_POINTERS GuidHob;
2293 VOID *CcEvent;
2294 VOID *DigestListBin;
2295 UINT32 DigestListBinSize;
2296 UINT8 *Event;
2297 UINT32 EventSize;
2298 EFI_CC_EVENT_LOG_FORMAT LogFormat;
2299
2300 DEBUG ((DEBUG_INFO, "Sync Cc event from SEC\n"));
2301
2302 Status = EFI_SUCCESS;
2303 LogFormat = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
2304 GuidHob.Guid = GetFirstGuidHob (&gCcEventEntryHobGuid);
2305
2306 while (!EFI_ERROR (Status) && GuidHob.Guid != NULL) {
2307 CcEvent = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));
2308 if (CcEvent == NULL) {
2309 return EFI_OUT_OF_RESOURCES;
2310 }
2311
2312 GuidHob.Guid = GET_NEXT_HOB (GuidHob);
2313 GuidHob.Guid = GetNextGuidHob (&gCcEventEntryHobGuid, GuidHob.Guid);
2314
2315 DigestListBin = (UINT8 *)CcEvent + sizeof (UINT32) + sizeof (TCG_EVENTTYPE);
2316 DigestListBinSize = GetDigestListBinSize (DigestListBin);
2317
2318 //
2319 // Event size.
2320 //
2321 EventSize = *(UINT32 *)((UINT8 *)DigestListBin + DigestListBinSize);
2322 Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof (UINT32);
2323
2324 //
2325 // Log the event
2326 //
2327 Status = TdxDxeLogEvent (
2328 LogFormat,
2329 CcEvent,
2330 sizeof (UINT32) + sizeof (TCG_EVENTTYPE) + DigestListBinSize + sizeof (UINT32),
2331 Event,
2332 EventSize
2333 );
2334
2335 DumpCcEvent ((CC_EVENT *)CcEvent);
2336 FreePool (CcEvent);
2337 }
2338
2339 return Status;
2340}
2341
2342/**
2343 Install TDVF ACPI Table when ACPI Table Protocol is available.
2344
2345 @param[in] Event Event whose notification function is being invoked
2346 @param[in] Context Pointer to the notification function's context
2347**/
2348VOID
2349EFIAPI
2350InstallAcpiTable (
2351 IN EFI_EVENT Event,
2352 IN VOID *Context
2353 )
2354{
2355 UINTN TableKey;
2356 EFI_STATUS Status;
2357 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
2358 UINT64 OemTableId;
2359
2360 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);
2361 if (EFI_ERROR (Status)) {
2362 DEBUG ((DEBUG_ERROR, "TD: AcpiTableProtocol is not installed. %r\n", Status));
2363 return;
2364 }
2365
2366 mTdxEventlogAcpiTemplate.Laml = (UINT64)PcdGet32 (PcdCcEventlogAcpiTableLaml);
2367 mTdxEventlogAcpiTemplate.Lasa = PcdGet64 (PcdCcEventlogAcpiTableLasa);
2368 CopyMem (mTdxEventlogAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTdxEventlogAcpiTemplate.Header.OemId));
2369 OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
2370 CopyMem (&mTdxEventlogAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
2371 mTdxEventlogAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
2372 mTdxEventlogAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
2373 mTdxEventlogAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
2374
2375 //
2376 // Construct ACPI Table
2377 Status = AcpiTable->InstallAcpiTable (
2378 AcpiTable,
2379 &mTdxEventlogAcpiTemplate,
2380 mTdxEventlogAcpiTemplate.Header.Length,
2381 &TableKey
2382 );
2383 ASSERT_EFI_ERROR (Status);
2384
2385 DEBUG ((DEBUG_INFO, "TDVF Eventlog ACPI Table is installed.\n"));
2386}
2387
2388/**
2389 The function install TdTcg2 protocol.
2390
2391 @retval EFI_SUCCESS TdTcg2 protocol is installed.
2392 @retval other Some error occurs.
2393**/
2394EFI_STATUS
2395InstallCcMeasurementProtocol (
2396 VOID
2397 )
2398{
2399 EFI_STATUS Status;
2400 EFI_HANDLE Handle;
2401
2402 Handle = NULL;
2403 Status = gBS->InstallMultipleProtocolInterfaces (
2404 &Handle,
2405 &gEfiCcMeasurementProtocolGuid,
2406 &mTdProtocol,
2407 NULL
2408 );
2409 DEBUG ((DEBUG_INFO, "CcProtocol: Install %r\n", Status));
2410 return Status;
2411}
2412
2413/**
2414 The driver's entry point. It publishes EFI Tcg2 Protocol.
2415
2416 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2417 @param[in] SystemTable A pointer to the EFI System Table.
2418
2419 @retval EFI_SUCCESS The entry point is executed successfully.
2420 @retval other Some error occurs when executing this entry point.
2421**/
2422EFI_STATUS
2423EFIAPI
2424DriverEntry (
2425 IN EFI_HANDLE ImageHandle,
2426 IN EFI_SYSTEM_TABLE *SystemTable
2427 )
2428{
2429 EFI_STATUS Status;
2430 EFI_EVENT Event;
2431 VOID *Registration;
2432
2433 if (!TdIsEnabled ()) {
2434 return EFI_UNSUPPORTED;
2435 }
2436
2437 mImageHandle = ImageHandle;
2438
2439 //
2440 // Fill information
2441 //
2442 // ASSERT (TD_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTEventInfo)/sizeof(mTcg2EventInfo[0]));
2443
2444 mTdxDxeData.BsCap.Size = sizeof (EFI_CC_BOOT_SERVICE_CAPABILITY);
2445 mTdxDxeData.BsCap.ProtocolVersion.Major = 1;
2446 mTdxDxeData.BsCap.ProtocolVersion.Minor = 0;
2447 mTdxDxeData.BsCap.StructureVersion.Major = 1;
2448 mTdxDxeData.BsCap.StructureVersion.Minor = 0;
2449
2450 //
2451 // Get supported PCR and current Active PCRs
2452 // For TD gueset HA384 is supported.
2453 //
2454 mTdxDxeData.BsCap.HashAlgorithmBitmap = HASH_ALG_SHA384;
2455
2456 // TD guest only supports EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
2457 mTdxDxeData.BsCap.SupportedEventLogs = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
2458
2459 //
2460 // Setup the log area and copy event log from hob list to it
2461 //
2462 Status = SetupCcEventLog ();
2463 ASSERT_EFI_ERROR (Status);
2464
2465 if (!EFI_ERROR (Status)) {
2466 Status = SyncCcEvent ();
2467 ASSERT_EFI_ERROR (Status);
2468 }
2469
2470 //
2471 // Measure handoff tables, Boot#### variables etc.
2472 //
2473 Status = EfiCreateEventReadyToBootEx (
2474 TPL_CALLBACK,
2475 OnReadyToBoot,
2476 NULL,
2477 &Event
2478 );
2479
2480 Status = gBS->CreateEventEx (
2481 EVT_NOTIFY_SIGNAL,
2482 TPL_NOTIFY,
2483 OnExitBootServices,
2484 NULL,
2485 &gEfiEventExitBootServicesGuid,
2486 &Event
2487 );
2488
2489 //
2490 // Measure Exit Boot Service failed
2491 //
2492 Status = gBS->CreateEventEx (
2493 EVT_NOTIFY_SIGNAL,
2494 TPL_NOTIFY,
2495 OnExitBootServicesFailed,
2496 NULL,
2497 &gEventExitBootServicesFailedGuid,
2498 &Event
2499 );
2500
2501 //
2502 // Create event callback, because we need access variable on SecureBootPolicyVariable
2503 // We should use VariableWriteArch instead of VariableArch, because Variable driver
2504 // may update SecureBoot value based on last setting.
2505 //
2506 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);
2507
2508 //
2509 // Install CcMeasurementProtocol
2510 //
2511 Status = InstallCcMeasurementProtocol ();
2512 DEBUG ((DEBUG_INFO, "InstallCcMeasurementProtocol - %r\n", Status));
2513
2514 if (Status == EFI_SUCCESS) {
2515 //
2516 // Create event callback to install CC EventLog ACPI Table
2517 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration);
2518 } else {
2519 //
2520 // Cc measurement feature is crucial to a td-guest and it shall stop running immediately
2521 // when it is failed to be installed.
2522 DEBUG ((DEBUG_ERROR, "%a: CcMeasurement protocol failed to be installed - %r\n", __func__, Status));
2523 CpuDeadLoop ();
2524 }
2525
2526 return Status;
2527}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette