]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c
SecurityPkg/TdTcg2Dxe: Extend EFI boot variable to PCR[1]
[mirror_edk2.git] / SecurityPkg / Tcg / TdTcg2Dxe / TdTcg2Dxe.c
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
58 typedef struct {
59 CHAR16 *VariableName;
60 EFI_GUID *VendorGuid;
61 } VARIABLE_TYPE;
62
63 typedef struct {
64 EFI_GUID *EventGuid;
65 EFI_CC_EVENT_LOG_FORMAT LogFormat;
66 } CC_EVENT_INFO_STRUCT;
67
68 typedef 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
79 typedef 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
87 typedef struct {
88 TPMI_ALG_HASH HashAlgo;
89 UINT16 HashSize;
90 UINT32 HashMask;
91 } TDX_HASH_INFO;
92
93 //
94 //
95 CC_EVENT_INFO_STRUCT mCcEventInfo[] = {
96 { &gCcEventEntryHobGuid, EFI_CC_EVENT_LOG_FORMAT_TCG_2 },
97 };
98
99 TDX_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
110 UINTN mBootAttempts = 0;
111 CHAR16 mBootVarName[] = L"BootOrder";
112
113 VARIABLE_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
121 EFI_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 //
141 TDX_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 **/
152 UINT16
153 GetHashSizeFromAlgo (
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 **/
175 UINT32
176 GetHashMaskFromAlgo (
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 **/
201 VOID *
202 CopyDigestListToBuffer (
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
235 EFI_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 **/
256 EFI_STATUS
257 MeasurePeImageAndExtend (
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 **/
274 VOID
275 InternalDumpData (
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 **/
295 VOID
296 InternalDumpHex (
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 **/
330 VOID
331 InitNoActionEvent (
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 **/
380 EFI_STATUS
381 GetProcessorsCpuLocation (
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 **/
469 EFI_STATUS
470 EFIAPI
471 TdGetCapability (
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 **/
495 VOID
496 DumpPcrEvent (
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 **/
520 VOID
521 DumpTcgEfiSpecIdEventStruct (
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 **/
568 UINTN
569 GetTcgEfiSpecIdEventStructSize (
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 **/
589 VOID
590 DumpCcEvent (
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 **/
638 UINTN
639 GetCcEventSize (
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 **/
681 VOID
682 DumpCcEventLog (
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 **/
751 EFI_STATUS
752 EFIAPI
753 TdGetEventLog (
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 **/
814 BOOLEAN
815 Is800155Event (
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 {
830 return TRUE;
831 }
832
833 return FALSE;
834 }
835
836 /**
837 Add a new entry to the Event Log.
838
839 @param[in, out] EventLogAreaStruct The event log area data structure
840 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
841 @param[in] NewEventHdrSize New event header size.
842 @param[in] NewEventData Pointer to the new event data.
843 @param[in] NewEventSize New event data size.
844
845 @retval EFI_SUCCESS The new event log entry was added.
846 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
847
848 **/
849 EFI_STATUS
850 TcgCommLogEvent (
851 IN OUT CC_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct,
852 IN VOID *NewEventHdr,
853 IN UINT32 NewEventHdrSize,
854 IN UINT8 *NewEventData,
855 IN UINT32 NewEventSize
856 )
857 {
858 UINTN NewLogSize;
859 BOOLEAN Record800155Event;
860 CC_EVENT_HDR *CcEventHdr;
861
862 CcEventHdr = (CC_EVENT_HDR *)NewEventHdr;
863 DEBUG ((DEBUG_VERBOSE, "Td: Try to log event. Index = %d, EventType = 0x%x\n", CcEventHdr->MrIndex, CcEventHdr->EventType));
864
865 if (NewEventSize > MAX_ADDRESS - NewEventHdrSize) {
866 return EFI_OUT_OF_RESOURCES;
867 }
868
869 NewLogSize = NewEventHdrSize + NewEventSize;
870
871 if (NewLogSize > MAX_ADDRESS - EventLogAreaStruct->EventLogSize) {
872 return EFI_OUT_OF_RESOURCES;
873 }
874
875 if (NewLogSize + EventLogAreaStruct->EventLogSize > EventLogAreaStruct->Laml) {
876 DEBUG ((DEBUG_INFO, " Laml - 0x%x\n", EventLogAreaStruct->Laml));
877 DEBUG ((DEBUG_INFO, " NewLogSize - 0x%x\n", NewLogSize));
878 DEBUG ((DEBUG_INFO, " LogSize - 0x%x\n", EventLogAreaStruct->EventLogSize));
879 DEBUG ((DEBUG_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));
880 return EFI_OUT_OF_RESOURCES;
881 }
882
883 //
884 // Check 800-155 event
885 // Record to 800-155 event offset only.
886 // If the offset is 0, no need to record.
887 //
888 Record800155Event = Is800155Event (NewEventHdr, NewEventHdrSize, NewEventData, NewEventSize);
889 if (Record800155Event) {
890 DEBUG ((DEBUG_INFO, "It is 800155Event.\n"));
891
892 if (EventLogAreaStruct->Next800155EventOffset != 0) {
893 CopyMem (
894 (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset + NewLogSize,
895 (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset,
896 EventLogAreaStruct->EventLogSize - EventLogAreaStruct->Next800155EventOffset
897 );
898
899 CopyMem (
900 (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset,
901 NewEventHdr,
902 NewEventHdrSize
903 );
904 CopyMem (
905 (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset + NewEventHdrSize,
906 NewEventData,
907 NewEventSize
908 );
909
910 EventLogAreaStruct->Next800155EventOffset += NewLogSize;
911 EventLogAreaStruct->LastEvent += NewLogSize;
912 EventLogAreaStruct->EventLogSize += NewLogSize;
913 }
914
915 return EFI_SUCCESS;
916 }
917
918 EventLogAreaStruct->LastEvent = (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->EventLogSize;
919 EventLogAreaStruct->EventLogSize += NewLogSize;
920
921 CopyMem (EventLogAreaStruct->LastEvent, NewEventHdr, NewEventHdrSize);
922 CopyMem (
923 EventLogAreaStruct->LastEvent + NewEventHdrSize,
924 NewEventData,
925 NewEventSize
926 );
927
928 return EFI_SUCCESS;
929 }
930
931 /**
932 According to UEFI Spec 2.10 Section 38.4.1:
933 The following table shows the TPM PCR index mapping and CC event log measurement
934 register index interpretation for Intel TDX, where MRTD means Trust Domain Measurement
935 Register and RTMR means Runtime Measurement Register
936
937 // TPM PCR Index | CC Measurement Register Index | TDX-measurement register
938 // ------------------------------------------------------------------------
939 // 0 | 0 | MRTD
940 // 1, 7 | 1 | RTMR[0]
941 // 2~6 | 2 | RTMR[1]
942 // 8~15 | 3 | RTMR[2]
943
944 @param[in] PCRIndex Index of the TPM PCR
945
946 @retval UINT32 Index of the CC Event Log Measurement Register Index
947 @retval CC_MR_INDEX_INVALID Invalid MR Index
948 **/
949 UINT32
950 EFIAPI
951 MapPcrToMrIndex (
952 IN UINT32 PCRIndex
953 )
954 {
955 UINT32 MrIndex;
956
957 if (PCRIndex > 15) {
958 ASSERT (FALSE);
959 return CC_MR_INDEX_INVALID;
960 }
961
962 MrIndex = 0;
963 if (PCRIndex == 0) {
964 MrIndex = CC_MR_INDEX_0_MRTD;
965 } else if ((PCRIndex == 1) || (PCRIndex == 7)) {
966 MrIndex = CC_MR_INDEX_1_RTMR0;
967 } else if ((PCRIndex >= 2) && (PCRIndex <= 6)) {
968 MrIndex = CC_MR_INDEX_2_RTMR1;
969 } else if ((PCRIndex >= 8) && (PCRIndex <= 15)) {
970 MrIndex = CC_MR_INDEX_3_RTMR2;
971 }
972
973 return MrIndex;
974 }
975
976 EFI_STATUS
977 EFIAPI
978 TdMapPcrToMrIndex (
979 IN EFI_CC_MEASUREMENT_PROTOCOL *This,
980 IN UINT32 PCRIndex,
981 OUT UINT32 *MrIndex
982 )
983 {
984 if (MrIndex == NULL) {
985 return EFI_INVALID_PARAMETER;
986 }
987
988 *MrIndex = MapPcrToMrIndex (PCRIndex);
989
990 return *MrIndex == CC_MR_INDEX_INVALID ? EFI_INVALID_PARAMETER : EFI_SUCCESS;
991 }
992
993 /**
994 Add a new entry to the Event Log.
995
996 @param[in] EventLogFormat The type of the event log for which the information is requested.
997 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
998 @param[in] NewEventHdrSize New event header size.
999 @param[in] NewEventData Pointer to the new event data.
1000 @param[in] NewEventSize New event data size.
1001
1002 @retval EFI_SUCCESS The new event log entry was added.
1003 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1004
1005 **/
1006 EFI_STATUS
1007 TdxDxeLogEvent (
1008 IN EFI_CC_EVENT_LOG_FORMAT EventLogFormat,
1009 IN VOID *NewEventHdr,
1010 IN UINT32 NewEventHdrSize,
1011 IN UINT8 *NewEventData,
1012 IN UINT32 NewEventSize
1013 )
1014 {
1015 EFI_STATUS Status;
1016 UINTN Index;
1017 CC_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct;
1018
1019 if (EventLogFormat != EFI_CC_EVENT_LOG_FORMAT_TCG_2) {
1020 ASSERT (FALSE);
1021 return EFI_INVALID_PARAMETER;
1022 }
1023
1024 Index = 0;
1025
1026 //
1027 // Record to normal event log
1028 //
1029 EventLogAreaStruct = &mTdxDxeData.EventLogAreaStruct[Index];
1030
1031 if (EventLogAreaStruct->EventLogTruncated) {
1032 return EFI_VOLUME_FULL;
1033 }
1034
1035 Status = TcgCommLogEvent (
1036 EventLogAreaStruct,
1037 NewEventHdr,
1038 NewEventHdrSize,
1039 NewEventData,
1040 NewEventSize
1041 );
1042
1043 if (Status == EFI_OUT_OF_RESOURCES) {
1044 EventLogAreaStruct->EventLogTruncated = TRUE;
1045 return EFI_VOLUME_FULL;
1046 } else if (Status == EFI_SUCCESS) {
1047 EventLogAreaStruct->EventLogStarted = TRUE;
1048 }
1049
1050 //
1051 // If GetEventLog is called, record to FinalEventsTable, too.
1052 //
1053 if (mTdxDxeData.GetEventLogCalled[Index]) {
1054 if (mTdxDxeData.FinalEventsTable[Index] == NULL) {
1055 //
1056 // no need for FinalEventsTable
1057 //
1058 return EFI_SUCCESS;
1059 }
1060
1061 EventLogAreaStruct = &mTdxDxeData.FinalEventLogAreaStruct[Index];
1062
1063 if (EventLogAreaStruct->EventLogTruncated) {
1064 return EFI_VOLUME_FULL;
1065 }
1066
1067 Status = TcgCommLogEvent (
1068 EventLogAreaStruct,
1069 NewEventHdr,
1070 NewEventHdrSize,
1071 NewEventData,
1072 NewEventSize
1073 );
1074 if (Status == EFI_OUT_OF_RESOURCES) {
1075 EventLogAreaStruct->EventLogTruncated = TRUE;
1076 return EFI_VOLUME_FULL;
1077 } else if (Status == EFI_SUCCESS) {
1078 EventLogAreaStruct->EventLogStarted = TRUE;
1079 //
1080 // Increase the NumberOfEvents in FinalEventsTable
1081 //
1082 (mTdxDxeData.FinalEventsTable[Index])->NumberOfEvents++;
1083 DEBUG ((DEBUG_INFO, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTdxDxeData.FinalEventsTable[Index])->NumberOfEvents));
1084 DEBUG ((DEBUG_INFO, " Size - 0x%x\n", (UINTN)EventLogAreaStruct->EventLogSize));
1085 }
1086 }
1087
1088 return Status;
1089 }
1090
1091 /**
1092 Get TPML_DIGEST_VALUES compact binary buffer size.
1093
1094 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
1095
1096 @return TPML_DIGEST_VALUES compact binary buffer size.
1097 **/
1098 UINT32
1099 GetDigestListBinSize (
1100 IN VOID *DigestListBin
1101 )
1102 {
1103 UINTN Index;
1104 UINT16 DigestSize;
1105 UINT32 TotalSize;
1106 UINT32 Count;
1107 TPMI_ALG_HASH HashAlg;
1108
1109 Count = ReadUnaligned32 (DigestListBin);
1110 TotalSize = sizeof (Count);
1111 DigestListBin = (UINT8 *)DigestListBin + sizeof (Count);
1112 for (Index = 0; Index < Count; Index++) {
1113 HashAlg = ReadUnaligned16 (DigestListBin);
1114 TotalSize += sizeof (HashAlg);
1115 DigestListBin = (UINT8 *)DigestListBin + sizeof (HashAlg);
1116
1117 DigestSize = GetHashSizeFromAlgo (HashAlg);
1118 TotalSize += DigestSize;
1119 DigestListBin = (UINT8 *)DigestListBin + DigestSize;
1120 }
1121
1122 return TotalSize;
1123 }
1124
1125 /**
1126 Copy TPML_DIGEST_VALUES compact binary into a buffer
1127
1128 @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.
1129 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
1130 @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.
1131 @param[out] HashAlgorithmMaskCopied Pointer to HASH bits corresponding to the digests copied.
1132
1133 @return The end of buffer to hold TPML_DIGEST_VALUES compact binary.
1134 **/
1135 VOID *
1136 CopyDigestListBinToBuffer (
1137 IN OUT VOID *Buffer,
1138 IN VOID *DigestListBin,
1139 IN UINT32 HashAlgorithmMask,
1140 OUT UINT32 *HashAlgorithmMaskCopied
1141 )
1142 {
1143 UINTN Index;
1144 UINT16 DigestSize;
1145 UINT32 Count;
1146 TPMI_ALG_HASH HashAlg;
1147 UINT32 DigestListCount;
1148 UINT32 *DigestListCountPtr;
1149
1150 DigestListCountPtr = (UINT32 *)Buffer;
1151 DigestListCount = 0;
1152 *HashAlgorithmMaskCopied = 0;
1153
1154 Count = ReadUnaligned32 (DigestListBin);
1155 Buffer = (UINT8 *)Buffer + sizeof (Count);
1156 DigestListBin = (UINT8 *)DigestListBin + sizeof (Count);
1157 for (Index = 0; Index < Count; Index++) {
1158 HashAlg = ReadUnaligned16 (DigestListBin);
1159 DigestListBin = (UINT8 *)DigestListBin + sizeof (HashAlg);
1160 DigestSize = GetHashSizeFromAlgo (HashAlg);
1161
1162 if ((HashAlg & HashAlgorithmMask) != 0) {
1163 CopyMem (Buffer, &HashAlg, sizeof (HashAlg));
1164 Buffer = (UINT8 *)Buffer + sizeof (HashAlg);
1165 CopyMem (Buffer, DigestListBin, DigestSize);
1166 Buffer = (UINT8 *)Buffer + DigestSize;
1167 DigestListCount++;
1168 (*HashAlgorithmMaskCopied) |= GetHashMaskFromAlgo (HashAlg);
1169 } else {
1170 DEBUG ((DEBUG_ERROR, "WARNING: CopyDigestListBinToBuffer Event log has HashAlg unsupported by PCR bank (0x%x)\n", HashAlg));
1171 }
1172
1173 DigestListBin = (UINT8 *)DigestListBin + DigestSize;
1174 }
1175
1176 WriteUnaligned32 (DigestListCountPtr, DigestListCount);
1177
1178 return Buffer;
1179 }
1180
1181 /**
1182 Add a new entry to the Event Log. The call chain is like below:
1183 TdxDxeLogHashEvent -> TdxDxeLogEvent -> TcgCommonLogEvent
1184
1185 Before this function is called, the event information (including the digest)
1186 is ready.
1187
1188 @param[in] DigestList A list of digest.
1189 @param[in,out] NewEventHdr Pointer to a TD_EVENT_HDR data structure.
1190 @param[in] NewEventData Pointer to the new event data.
1191
1192 @retval EFI_SUCCESS The new event log entry was added.
1193 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1194 **/
1195 EFI_STATUS
1196 TdxDxeLogHashEvent (
1197 IN TPML_DIGEST_VALUES *DigestList,
1198 IN OUT CC_EVENT_HDR *NewEventHdr,
1199 IN UINT8 *NewEventData
1200 )
1201 {
1202 EFI_STATUS Status;
1203 EFI_TPL OldTpl;
1204 EFI_STATUS RetStatus;
1205 CC_EVENT CcEvent;
1206 UINT8 *DigestBuffer;
1207 UINT32 *EventSizePtr;
1208 EFI_CC_EVENT_LOG_FORMAT LogFormat;
1209
1210 RetStatus = EFI_SUCCESS;
1211 LogFormat = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
1212
1213 ZeroMem (&CcEvent, sizeof (CcEvent));
1214 CcEvent.MrIndex = NewEventHdr->MrIndex;
1215 CcEvent.EventType = NewEventHdr->EventType;
1216 DigestBuffer = (UINT8 *)&CcEvent.Digests;
1217 EventSizePtr = CopyDigestListToBuffer (DigestBuffer, DigestList, HASH_ALG_SHA384);
1218 CopyMem (EventSizePtr, &NewEventHdr->EventSize, sizeof (NewEventHdr->EventSize));
1219
1220 //
1221 // Enter critical region
1222 //
1223 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
1224 Status = TdxDxeLogEvent (
1225 LogFormat,
1226 &CcEvent,
1227 sizeof (CcEvent.MrIndex) + sizeof (CcEvent.EventType) + GetDigestListBinSize (DigestBuffer) + sizeof (CcEvent.EventSize),
1228 NewEventData,
1229 NewEventHdr->EventSize
1230 );
1231 if (Status != EFI_SUCCESS) {
1232 RetStatus = Status;
1233 }
1234
1235 gBS->RestoreTPL (OldTpl);
1236
1237 return RetStatus;
1238 }
1239
1240 /**
1241 Do a hash operation on a data buffer, extend a specific RTMR with the hash result,
1242 and add an entry to the Event Log.
1243
1244 @param[in] Flags Bitmap providing additional information.
1245 @param[in] HashData Physical address of the start of the data buffer
1246 to be hashed, extended, and logged.
1247 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
1248 @param[in, out] NewEventHdr Pointer to a TD_EVENT_HDR data structure.
1249 @param[in] NewEventData Pointer to the new event data.
1250
1251 @retval EFI_SUCCESS Operation completed successfully.
1252 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1253 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1254
1255 **/
1256 EFI_STATUS
1257 TdxDxeHashLogExtendEvent (
1258 IN UINT64 Flags,
1259 IN UINT8 *HashData,
1260 IN UINT64 HashDataLen,
1261 IN OUT CC_EVENT_HDR *NewEventHdr,
1262 IN UINT8 *NewEventData
1263 )
1264 {
1265 EFI_STATUS Status;
1266 TPML_DIGEST_VALUES DigestList;
1267 CC_EVENT_HDR NoActionEvent;
1268
1269 if (NewEventHdr->EventType == EV_NO_ACTION) {
1270 //
1271 // Do not do RTMR extend for EV_NO_ACTION
1272 //
1273 Status = EFI_SUCCESS;
1274 InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);
1275 if ((Flags & EFI_CC_FLAG_EXTEND_ONLY) == 0) {
1276 Status = TdxDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr, NewEventData);
1277 }
1278
1279 return Status;
1280 }
1281
1282 //
1283 // According to UEFI Spec 2.10 Section 38.4.1 the mapping between MrIndex and Intel
1284 // TDX Measurement Register is:
1285 // MrIndex 0 <--> MRTD
1286 // MrIndex 1-3 <--> RTMR[0-2]
1287 // Only the RMTR registers can be extended in TDVF by HashAndExtend. So MrIndex will
1288 // decreased by 1 before it is sent to HashAndExtend.
1289 //
1290 Status = HashAndExtend (
1291 NewEventHdr->MrIndex - 1,
1292 HashData,
1293 (UINTN)HashDataLen,
1294 &DigestList
1295 );
1296 if (!EFI_ERROR (Status)) {
1297 if ((Flags & EFI_CC_FLAG_EXTEND_ONLY) == 0) {
1298 Status = TdxDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);
1299 }
1300 }
1301
1302 return Status;
1303 }
1304
1305 /**
1306 The EFI_CC_MEASUREMENT_PROTOCOL HashLogExtendEvent function call provides callers with
1307 an opportunity to extend and optionally log events without requiring
1308 knowledge of actual TPM commands.
1309 The extend operation will occur even if this function cannot create an event
1310 log entry (e.g. due to the event log being full).
1311
1312 @param[in] This Indicates the calling context
1313 @param[in] Flags Bitmap providing additional information.
1314 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
1315 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
1316 @param[in] Event Pointer to data buffer containing information about the event.
1317
1318 @retval EFI_SUCCESS Operation completed successfully.
1319 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1320 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
1321 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1322 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
1323 **/
1324 EFI_STATUS
1325 EFIAPI
1326 TdHashLogExtendEvent (
1327 IN EFI_CC_MEASUREMENT_PROTOCOL *This,
1328 IN UINT64 Flags,
1329 IN EFI_PHYSICAL_ADDRESS DataToHash,
1330 IN UINT64 DataToHashLen,
1331 IN EFI_CC_EVENT *CcEvent
1332 )
1333 {
1334 EFI_STATUS Status;
1335 CC_EVENT_HDR NewEventHdr;
1336 TPML_DIGEST_VALUES DigestList;
1337
1338 DEBUG ((DEBUG_VERBOSE, "TdHashLogExtendEvent ...\n"));
1339
1340 if ((This == NULL) || (CcEvent == NULL)) {
1341 return EFI_INVALID_PARAMETER;
1342 }
1343
1344 //
1345 // Do not check hash data size for EV_NO_ACTION event.
1346 //
1347 if ((CcEvent->Header.EventType != EV_NO_ACTION) && (DataToHash == 0)) {
1348 return EFI_INVALID_PARAMETER;
1349 }
1350
1351 if (CcEvent->Size < CcEvent->Header.HeaderSize + sizeof (UINT32)) {
1352 return EFI_INVALID_PARAMETER;
1353 }
1354
1355 if (CcEvent->Header.MrIndex == CC_MR_INDEX_0_MRTD) {
1356 DEBUG ((DEBUG_ERROR, "%a: MRTD cannot be extended in TDVF.\n", __FUNCTION__));
1357 return EFI_INVALID_PARAMETER;
1358 }
1359
1360 if (CcEvent->Header.MrIndex >= CC_MR_INDEX_INVALID) {
1361 DEBUG ((DEBUG_ERROR, "%a: MrIndex is invalid. (%d)\n", __FUNCTION__, CcEvent->Header.MrIndex));
1362 return EFI_INVALID_PARAMETER;
1363 }
1364
1365 NewEventHdr.MrIndex = CcEvent->Header.MrIndex;
1366 NewEventHdr.EventType = CcEvent->Header.EventType;
1367 NewEventHdr.EventSize = CcEvent->Size - sizeof (UINT32) - CcEvent->Header.HeaderSize;
1368 if ((Flags & EFI_CC_FLAG_PE_COFF_IMAGE) != 0) {
1369 //
1370 // According to UEFI Spec 2.10 Section 38.4.1 the mapping between MrIndex and Intel
1371 // TDX Measurement Register is:
1372 // MrIndex 0 <--> MRTD
1373 // MrIndex 1-3 <--> RTMR[0-2]
1374 // Only the RMTR registers can be extended in TDVF by HashAndExtend. So MrIndex will
1375 // decreased by 1 before it is sent to MeasurePeImageAndExtend.
1376 //
1377 Status = MeasurePeImageAndExtend (
1378 NewEventHdr.MrIndex - 1,
1379 DataToHash,
1380 (UINTN)DataToHashLen,
1381 &DigestList
1382 );
1383 if (!EFI_ERROR (Status)) {
1384 if ((Flags & EFI_CC_FLAG_EXTEND_ONLY) == 0) {
1385 Status = TdxDxeLogHashEvent (&DigestList, &NewEventHdr, CcEvent->Event);
1386 }
1387 }
1388 } else {
1389 Status = TdxDxeHashLogExtendEvent (
1390 Flags,
1391 (UINT8 *)(UINTN)DataToHash,
1392 DataToHashLen,
1393 &NewEventHdr,
1394 CcEvent->Event
1395 );
1396 }
1397
1398 DEBUG ((DEBUG_VERBOSE, "TdHashLogExtendEvent - %r\n", Status));
1399 return Status;
1400 }
1401
1402 EFI_CC_MEASUREMENT_PROTOCOL mTdProtocol = {
1403 TdGetCapability,
1404 TdGetEventLog,
1405 TdHashLogExtendEvent,
1406 TdMapPcrToMrIndex,
1407 };
1408
1409 #define TD_HASH_COUNT 1
1410 #define TEMP_BUF_LEN (sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) \
1411 + (TD_HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8))
1412
1413 /**
1414 Initialize the TD Event Log and log events passed from the PEI phase.
1415
1416 @retval EFI_SUCCESS Operation completed successfully.
1417 @retval EFI_OUT_OF_RESOURCES Out of memory.
1418
1419 **/
1420 EFI_STATUS
1421 SetupCcEventLog (
1422 VOID
1423 )
1424 {
1425 EFI_STATUS Status;
1426 EFI_PHYSICAL_ADDRESS Lasa;
1427 UINTN Index;
1428 TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;
1429 UINT8 TempBuf[TEMP_BUF_LEN];
1430 TCG_PCR_EVENT_HDR SpecIdEvent;
1431 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
1432 TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;
1433 UINT8 *VendorInfoSize;
1434 UINT32 NumberOfAlgorithms;
1435 EFI_CC_EVENT_LOG_FORMAT LogFormat;
1436 EFI_PEI_HOB_POINTERS GuidHob;
1437 CC_EVENT_HDR NoActionEvent;
1438
1439 Status = EFI_SUCCESS;
1440 DEBUG ((DEBUG_INFO, "SetupCcEventLog\n"));
1441
1442 Index = 0;
1443 LogFormat = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
1444
1445 //
1446 // 1. Create Log Area
1447 //
1448 mTdxDxeData.EventLogAreaStruct[Index].EventLogFormat = LogFormat;
1449
1450 // allocate pages for TD Event log
1451 Status = gBS->AllocatePages (
1452 AllocateAnyPages,
1453 EfiACPIMemoryNVS,
1454 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
1455 &Lasa
1456 );
1457 if (EFI_ERROR (Status)) {
1458 return Status;
1459 }
1460
1461 mTdxDxeData.EventLogAreaStruct[Index].Lasa = Lasa;
1462 mTdxDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);
1463 mTdxDxeData.EventLogAreaStruct[Index].Next800155EventOffset = 0;
1464
1465 //
1466 // Report TD event log address and length, so that they can be reported in
1467 // TD ACPI table. Ignore the return status, because those fields are optional.
1468 //
1469 PcdSet32S (PcdCcEventlogAcpiTableLaml, (UINT32)mTdxDxeData.EventLogAreaStruct[Index].Laml);
1470 PcdSet64S (PcdCcEventlogAcpiTableLasa, mTdxDxeData.EventLogAreaStruct[Index].Lasa);
1471
1472 //
1473 // To initialize them as 0xFF is recommended
1474 // because the OS can know the last entry for that.
1475 //
1476 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);
1477
1478 //
1479 // Create first entry for Log Header Entry Data
1480 //
1481
1482 //
1483 // TcgEfiSpecIdEventStruct
1484 //
1485 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)TempBuf;
1486 CopyMem (TcgEfiSpecIdEventStruct->signature, TCG_EfiSpecIDEventStruct_SIGNATURE_03, sizeof (TcgEfiSpecIdEventStruct->signature));
1487
1488 TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);
1489
1490 TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;
1491 TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;
1492 TcgEfiSpecIdEventStruct->specErrata = TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2;
1493 TcgEfiSpecIdEventStruct->uintnSize = sizeof (UINTN)/sizeof (UINT32);
1494 NumberOfAlgorithms = 0;
1495 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct
1496 + sizeof (*TcgEfiSpecIdEventStruct)
1497 + sizeof (NumberOfAlgorithms));
1498
1499 TempDigestSize = DigestSize;
1500 TempDigestSize += NumberOfAlgorithms;
1501 TempDigestSize->algorithmId = TPM_ALG_SHA384;
1502 TempDigestSize->digestSize = SHA384_DIGEST_SIZE;
1503 NumberOfAlgorithms++;
1504
1505 CopyMem (TcgEfiSpecIdEventStruct + 1, &NumberOfAlgorithms, sizeof (NumberOfAlgorithms));
1506 TempDigestSize = DigestSize;
1507 TempDigestSize += NumberOfAlgorithms;
1508 VendorInfoSize = (UINT8 *)TempDigestSize;
1509 *VendorInfoSize = 0;
1510
1511 SpecIdEvent.PCRIndex = 1; // PCRIndex 0 maps to MrIndex 1
1512 SpecIdEvent.EventType = EV_NO_ACTION;
1513 ZeroMem (&SpecIdEvent.Digest, sizeof (SpecIdEvent.Digest));
1514 SpecIdEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);
1515
1516 //
1517 // TD Event log re-use the spec of TCG2 Event log.
1518 // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.
1519 // TCG EFI Protocol Spec. Section 5.3 Event Log Header
1520 // TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log
1521 //
1522 Status = TdxDxeLogEvent (
1523 LogFormat,
1524 &SpecIdEvent,
1525 sizeof (SpecIdEvent),
1526 (UINT8 *)TcgEfiSpecIdEventStruct,
1527 SpecIdEvent.EventSize
1528 );
1529 //
1530 // record the offset at the end of 800-155 event.
1531 // the future 800-155 event can be inserted here.
1532 //
1533 mTdxDxeData.EventLogAreaStruct[Index].Next800155EventOffset = mTdxDxeData.EventLogAreaStruct[Index].EventLogSize;
1534
1535 //
1536 // Tcg800155PlatformIdEvent. Event format is TCG_PCR_EVENT2
1537 //
1538 GuidHob.Guid = GetFirstGuidHob (&gTcg800155PlatformIdEventHobGuid);
1539 while (GuidHob.Guid != NULL) {
1540 InitNoActionEvent (&NoActionEvent, GET_GUID_HOB_DATA_SIZE (GuidHob.Guid));
1541
1542 Status = TdxDxeLogEvent (
1543 LogFormat,
1544 &NoActionEvent,
1545 sizeof (NoActionEvent.MrIndex) + sizeof (NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof (NoActionEvent.EventSize),
1546 GET_GUID_HOB_DATA (GuidHob.Guid),
1547 GET_GUID_HOB_DATA_SIZE (GuidHob.Guid)
1548 );
1549
1550 GuidHob.Guid = GET_NEXT_HOB (GuidHob);
1551 GuidHob.Guid = GetNextGuidHob (&gTcg800155PlatformIdEventHobGuid, GuidHob.Guid);
1552 }
1553
1554 //
1555 // 2. Create Final Log Area
1556 //
1557 Status = gBS->AllocatePages (
1558 AllocateAnyPages,
1559 EfiACPIMemoryNVS,
1560 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),
1561 &Lasa
1562 );
1563 if (EFI_ERROR (Status)) {
1564 return Status;
1565 }
1566
1567 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcg2FinalLogAreaLen), 0xFF);
1568
1569 //
1570 // Initialize
1571 //
1572 mTdxDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;
1573 (mTdxDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;
1574 (mTdxDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;
1575
1576 mTdxDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = LogFormat;
1577 mTdxDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof (EFI_CC_FINAL_EVENTS_TABLE);
1578 mTdxDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof (EFI_CC_FINAL_EVENTS_TABLE);
1579 mTdxDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
1580 mTdxDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTdxDxeData.FinalEventLogAreaStruct[Index].Lasa;
1581 mTdxDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
1582 mTdxDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
1583 mTdxDxeData.FinalEventLogAreaStruct[Index].Next800155EventOffset = 0;
1584
1585 //
1586 // Install to configuration table for EFI_CC_EVENT_LOG_FORMAT_TCG_2
1587 //
1588 Status = gBS->InstallConfigurationTable (&gEfiCcFinalEventsTableGuid, (VOID *)mTdxDxeData.FinalEventsTable[Index]);
1589 if (EFI_ERROR (Status)) {
1590 return Status;
1591 }
1592
1593 return Status;
1594 }
1595
1596 /**
1597 Measure and log an action string, and extend the measurement result into RTMR.
1598
1599 @param[in] MrIndex MrIndex to extend
1600 @param[in] String A specific string that indicates an Action event.
1601
1602 @retval EFI_SUCCESS Operation completed successfully.
1603 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1604
1605 **/
1606 EFI_STATUS
1607 TdMeasureAction (
1608 IN UINT32 MrIndex,
1609 IN CHAR8 *String
1610 )
1611 {
1612 CC_EVENT_HDR CcEvent;
1613
1614 CcEvent.MrIndex = MrIndex;
1615 CcEvent.EventType = EV_EFI_ACTION;
1616 CcEvent.EventSize = (UINT32)AsciiStrLen (String);
1617 return TdxDxeHashLogExtendEvent (
1618 0,
1619 (UINT8 *)String,
1620 CcEvent.EventSize,
1621 &CcEvent,
1622 (UINT8 *)String
1623 );
1624 }
1625
1626 /**
1627 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1628
1629 @retval EFI_SUCCESS Operation completed successfully.
1630 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1631
1632 **/
1633 EFI_STATUS
1634 MeasureHandoffTables (
1635 VOID
1636 )
1637 {
1638 EFI_STATUS Status;
1639 CC_EVENT_HDR CcEvent;
1640 EFI_HANDOFF_TABLE_POINTERS HandoffTables;
1641 UINTN ProcessorNum;
1642 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
1643
1644 ProcessorLocBuf = NULL;
1645 Status = EFI_SUCCESS;
1646
1647 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
1648 //
1649 // Tcg Server spec.
1650 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1651 //
1652 Status = GetProcessorsCpuLocation (&ProcessorLocBuf, &ProcessorNum);
1653
1654 if (!EFI_ERROR (Status)) {
1655 CcEvent.MrIndex = MapPcrToMrIndex (1);
1656 CcEvent.EventType = EV_TABLE_OF_DEVICES;
1657 CcEvent.EventSize = sizeof (HandoffTables);
1658
1659 HandoffTables.NumberOfTables = 1;
1660 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;
1661 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;
1662
1663 Status = TdxDxeHashLogExtendEvent (
1664 0,
1665 (UINT8 *)(UINTN)ProcessorLocBuf,
1666 sizeof (EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
1667 &CcEvent,
1668 (UINT8 *)&HandoffTables
1669 );
1670
1671 FreePool (ProcessorLocBuf);
1672 }
1673 }
1674
1675 return Status;
1676 }
1677
1678 /**
1679 Measure and log Separator event, and extend the measurement result into a specific PCR.
1680
1681 @param[in] PCRIndex PCR index.
1682
1683 @retval EFI_SUCCESS Operation completed successfully.
1684 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1685
1686 **/
1687 EFI_STATUS
1688 MeasureSeparatorEvent (
1689 IN UINT32 MrIndex
1690 )
1691 {
1692 CC_EVENT_HDR CcEvent;
1693 UINT32 EventData;
1694
1695 DEBUG ((DEBUG_INFO, "MeasureSeparatorEvent to Rtmr - %d\n", MrIndex));
1696
1697 EventData = 0;
1698 CcEvent.MrIndex = MrIndex;
1699 CcEvent.EventType = EV_SEPARATOR;
1700 CcEvent.EventSize = (UINT32)sizeof (EventData);
1701
1702 return TdxDxeHashLogExtendEvent (
1703 0,
1704 (UINT8 *)&EventData,
1705 sizeof (EventData),
1706 &CcEvent,
1707 (UINT8 *)&EventData
1708 );
1709 }
1710
1711 /**
1712 Measure and log an EFI variable, and extend the measurement result into a specific RTMR.
1713
1714 @param[in] MrIndex RTMR Index.
1715 @param[in] EventType Event type.
1716 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1717 @param[in] VendorGuid A unique identifier for the vendor.
1718 @param[in] VarData The content of the variable data.
1719 @param[in] VarSize The size of the variable data.
1720
1721 @retval EFI_SUCCESS Operation completed successfully.
1722 @retval EFI_OUT_OF_RESOURCES Out of memory.
1723 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1724
1725 **/
1726 EFI_STATUS
1727 MeasureVariable (
1728 IN UINT32 MrIndex,
1729 IN TCG_EVENTTYPE EventType,
1730 IN CHAR16 *VarName,
1731 IN EFI_GUID *VendorGuid,
1732 IN VOID *VarData,
1733 IN UINTN VarSize
1734 )
1735 {
1736 EFI_STATUS Status;
1737 CC_EVENT_HDR CcEvent;
1738 UINTN VarNameLength;
1739 UEFI_VARIABLE_DATA *VarLog;
1740
1741 DEBUG ((DEBUG_INFO, "TdTcg2Dxe: MeasureVariable (Rtmr - %x, EventType - %x, ", (UINTN)MrIndex, (UINTN)EventType));
1742 DEBUG ((DEBUG_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
1743
1744 VarNameLength = StrLen (VarName);
1745 CcEvent.MrIndex = MrIndex;
1746 CcEvent.EventType = EventType;
1747
1748 CcEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
1749 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
1750
1751 VarLog = (UEFI_VARIABLE_DATA *)AllocatePool (CcEvent.EventSize);
1752 if (VarLog == NULL) {
1753 return EFI_OUT_OF_RESOURCES;
1754 }
1755
1756 VarLog->VariableName = *VendorGuid;
1757 VarLog->UnicodeNameLength = VarNameLength;
1758 VarLog->VariableDataLength = VarSize;
1759 CopyMem (
1760 VarLog->UnicodeName,
1761 VarName,
1762 VarNameLength * sizeof (*VarName)
1763 );
1764 if ((VarSize != 0) && (VarData != NULL)) {
1765 CopyMem (
1766 (CHAR16 *)VarLog->UnicodeName + VarNameLength,
1767 VarData,
1768 VarSize
1769 );
1770 }
1771
1772 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
1773 //
1774 // Digest is the event data (UEFI_VARIABLE_DATA)
1775 //
1776 Status = TdxDxeHashLogExtendEvent (
1777 0,
1778 (UINT8 *)VarLog,
1779 CcEvent.EventSize,
1780 &CcEvent,
1781 (UINT8 *)VarLog
1782 );
1783 } else {
1784 ASSERT (VarData != NULL);
1785 Status = TdxDxeHashLogExtendEvent (
1786 0,
1787 (UINT8 *)VarData,
1788 VarSize,
1789 &CcEvent,
1790 (UINT8 *)VarLog
1791 );
1792 }
1793
1794 FreePool (VarLog);
1795 return Status;
1796 }
1797
1798 /**
1799 Read then Measure and log an EFI variable, and extend the measurement result into a specific RTMR.
1800
1801 @param[in] MrIndex RTMR Index.
1802 @param[in] EventType Event type.
1803 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1804 @param[in] VendorGuid A unique identifier for the vendor.
1805 @param[out] VarSize The size of the variable data.
1806 @param[out] VarData Pointer to the content of the variable.
1807
1808 @retval EFI_SUCCESS Operation completed successfully.
1809 @retval EFI_OUT_OF_RESOURCES Out of memory.
1810 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1811
1812 **/
1813 EFI_STATUS
1814 ReadAndMeasureVariable (
1815 IN UINT32 MrIndex,
1816 IN TCG_EVENTTYPE EventType,
1817 IN CHAR16 *VarName,
1818 IN EFI_GUID *VendorGuid,
1819 OUT UINTN *VarSize,
1820 OUT VOID **VarData
1821 )
1822 {
1823 EFI_STATUS Status;
1824
1825 Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);
1826 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
1827 if (EFI_ERROR (Status)) {
1828 //
1829 // It is valid case, so we need handle it.
1830 //
1831 *VarData = NULL;
1832 *VarSize = 0;
1833 }
1834 } else {
1835 //
1836 // if status error, VarData is freed and set NULL by GetVariable2
1837 //
1838 if (EFI_ERROR (Status)) {
1839 return EFI_NOT_FOUND;
1840 }
1841 }
1842
1843 Status = MeasureVariable (
1844 MrIndex,
1845 EventType,
1846 VarName,
1847 VendorGuid,
1848 *VarData,
1849 *VarSize
1850 );
1851 return Status;
1852 }
1853
1854 /**
1855 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].
1856 according to TCG PC Client PFP spec 0021 Section 2.4.4.2
1857
1858 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1859 @param[in] VendorGuid A unique identifier for the vendor.
1860 @param[out] VarSize The size of the variable data.
1861 @param[out] VarData Pointer to the content of the variable.
1862
1863 @retval EFI_SUCCESS Operation completed successfully.
1864 @retval EFI_OUT_OF_RESOURCES Out of memory.
1865 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1866
1867 **/
1868 EFI_STATUS
1869 ReadAndMeasureBootVariable (
1870 IN CHAR16 *VarName,
1871 IN EFI_GUID *VendorGuid,
1872 OUT UINTN *VarSize,
1873 OUT VOID **VarData
1874 )
1875 {
1876 return ReadAndMeasureVariable (
1877 MapPcrToMrIndex (1),
1878 EV_EFI_VARIABLE_BOOT,
1879 VarName,
1880 VendorGuid,
1881 VarSize,
1882 VarData
1883 );
1884 }
1885
1886 /**
1887 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
1888
1889 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1890 @param[in] VendorGuid A unique identifier for the vendor.
1891 @param[out] VarSize The size of the variable data.
1892 @param[out] VarData Pointer to the content of the variable.
1893
1894 @retval EFI_SUCCESS Operation completed successfully.
1895 @retval EFI_OUT_OF_RESOURCES Out of memory.
1896 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1897
1898 **/
1899 EFI_STATUS
1900 ReadAndMeasureSecureVariable (
1901 IN CHAR16 *VarName,
1902 IN EFI_GUID *VendorGuid,
1903 OUT UINTN *VarSize,
1904 OUT VOID **VarData
1905 )
1906 {
1907 return ReadAndMeasureVariable (
1908 MapPcrToMrIndex (7),
1909 EV_EFI_VARIABLE_DRIVER_CONFIG,
1910 VarName,
1911 VendorGuid,
1912 VarSize,
1913 VarData
1914 );
1915 }
1916
1917 /**
1918 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
1919
1920 The EFI boot variables are BootOrder and Boot#### variables.
1921
1922 @retval EFI_SUCCESS Operation completed successfully.
1923 @retval EFI_OUT_OF_RESOURCES Out of memory.
1924 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1925
1926 **/
1927 EFI_STATUS
1928 MeasureAllBootVariables (
1929 VOID
1930 )
1931 {
1932 EFI_STATUS Status;
1933 UINT16 *BootOrder;
1934 UINTN BootCount;
1935 UINTN Index;
1936 VOID *BootVarData;
1937 UINTN Size;
1938
1939 Status = ReadAndMeasureBootVariable (
1940 mBootVarName,
1941 &gEfiGlobalVariableGuid,
1942 &BootCount,
1943 (VOID **)&BootOrder
1944 );
1945 if ((Status == EFI_NOT_FOUND) || (BootOrder == NULL)) {
1946 return EFI_SUCCESS;
1947 }
1948
1949 if (EFI_ERROR (Status)) {
1950 //
1951 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
1952 //
1953 FreePool (BootOrder);
1954 return Status;
1955 }
1956
1957 BootCount /= sizeof (*BootOrder);
1958 for (Index = 0; Index < BootCount; Index++) {
1959 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);
1960 Status = ReadAndMeasureBootVariable (
1961 mBootVarName,
1962 &gEfiGlobalVariableGuid,
1963 &Size,
1964 &BootVarData
1965 );
1966 if (!EFI_ERROR (Status)) {
1967 FreePool (BootVarData);
1968 }
1969 }
1970
1971 FreePool (BootOrder);
1972 return EFI_SUCCESS;
1973 }
1974
1975 /**
1976 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
1977
1978 The EFI boot variables are BootOrder and Boot#### variables.
1979
1980 @retval EFI_SUCCESS Operation completed successfully.
1981 @retval EFI_OUT_OF_RESOURCES Out of memory.
1982 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1983
1984 **/
1985 EFI_STATUS
1986 MeasureAllSecureVariables (
1987 VOID
1988 )
1989 {
1990 EFI_STATUS Status;
1991 VOID *Data;
1992 UINTN DataSize;
1993 UINTN Index;
1994
1995 Status = EFI_NOT_FOUND;
1996 for (Index = 0; Index < sizeof (mVariableType)/sizeof (mVariableType[0]); Index++) {
1997 Status = ReadAndMeasureSecureVariable (
1998 mVariableType[Index].VariableName,
1999 mVariableType[Index].VendorGuid,
2000 &DataSize,
2001 &Data
2002 );
2003 if (!EFI_ERROR (Status)) {
2004 if (Data != NULL) {
2005 FreePool (Data);
2006 }
2007 }
2008 }
2009
2010 //
2011 // Measure DBT if present and not empty
2012 //
2013 Status = GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, &Data, &DataSize);
2014 if (!EFI_ERROR (Status)) {
2015 Status = MeasureVariable (
2016 MapPcrToMrIndex (7),
2017 EV_EFI_VARIABLE_DRIVER_CONFIG,
2018 EFI_IMAGE_SECURITY_DATABASE2,
2019 &gEfiImageSecurityDatabaseGuid,
2020 Data,
2021 DataSize
2022 );
2023 FreePool (Data);
2024 } else {
2025 DEBUG ((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2));
2026 }
2027
2028 return EFI_SUCCESS;
2029 }
2030
2031 /**
2032 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
2033
2034 @retval EFI_SUCCESS Operation completed successfully.
2035 @retval EFI_OUT_OF_RESOURCES Out of memory.
2036 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2037
2038 **/
2039 EFI_STATUS
2040 MeasureLaunchOfFirmwareDebugger (
2041 VOID
2042 )
2043 {
2044 CC_EVENT_HDR CcEvent;
2045
2046 CcEvent.MrIndex = MapPcrToMrIndex (7);
2047 CcEvent.EventType = EV_EFI_ACTION;
2048 CcEvent.EventSize = sizeof (FIRMWARE_DEBUGGER_EVENT_STRING) - 1;
2049 return TdxDxeHashLogExtendEvent (
2050 0,
2051 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,
2052 sizeof (FIRMWARE_DEBUGGER_EVENT_STRING) - 1,
2053 &CcEvent,
2054 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING
2055 );
2056 }
2057
2058 /**
2059 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
2060
2061 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
2062 - The contents of the SecureBoot variable
2063 - The contents of the PK variable
2064 - The contents of the KEK variable
2065 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
2066 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
2067 - Separator
2068 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
2069
2070 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
2071 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
2072
2073 @param[in] Event Event whose notification function is being invoked
2074 @param[in] Context Pointer to the notification function's context
2075 **/
2076 VOID
2077 EFIAPI
2078 MeasureSecureBootPolicy (
2079 IN EFI_EVENT Event,
2080 IN VOID *Context
2081 )
2082 {
2083 EFI_STATUS Status;
2084 VOID *Protocol;
2085
2086 Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);
2087 if (EFI_ERROR (Status)) {
2088 return;
2089 }
2090
2091 if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {
2092 Status = MeasureLaunchOfFirmwareDebugger ();
2093 DEBUG ((DEBUG_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));
2094 }
2095
2096 Status = MeasureAllSecureVariables ();
2097 DEBUG ((DEBUG_INFO, "MeasureAllSecureVariables - %r\n", Status));
2098
2099 //
2100 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
2101 // and ImageVerification (Authority)
2102 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
2103 // the Authority measurement happen before ReadToBoot event.
2104 //
2105 Status = MeasureSeparatorEvent (MapPcrToMrIndex (7));
2106 DEBUG ((DEBUG_INFO, "MeasureSeparatorEvent - %r\n", Status));
2107 return;
2108 }
2109
2110 /**
2111 Ready to Boot Event notification handler.
2112
2113 Sequence of OS boot events is measured in this event notification handler.
2114
2115 @param[in] Event Event whose notification function is being invoked
2116 @param[in] Context Pointer to the notification function's context
2117
2118 **/
2119 VOID
2120 EFIAPI
2121 OnReadyToBoot (
2122 IN EFI_EVENT Event,
2123 IN VOID *Context
2124 )
2125 {
2126 EFI_STATUS Status;
2127
2128 PERF_START_EX (mImageHandle, "EventRec", "TdTcg2Dxe", 0, PERF_ID_CC_TCG2_DXE);
2129 if (mBootAttempts == 0) {
2130 //
2131 // Measure handoff tables.
2132 //
2133 Status = MeasureHandoffTables ();
2134 if (EFI_ERROR (Status)) {
2135 DEBUG ((DEBUG_ERROR, "HOBs not Measured. Error!\n"));
2136 }
2137
2138 //
2139 // Measure BootOrder & Boot#### variables.
2140 //
2141 Status = MeasureAllBootVariables ();
2142 if (EFI_ERROR (Status)) {
2143 DEBUG ((DEBUG_ERROR, "Boot Variables not Measured. Error!\n"));
2144 }
2145
2146 //
2147 // 1. This is the first boot attempt.
2148 //
2149 Status = TdMeasureAction (
2150 MapPcrToMrIndex (4),
2151 EFI_CALLING_EFI_APPLICATION
2152 );
2153 if (EFI_ERROR (Status)) {
2154 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
2155 }
2156
2157 //
2158 // 2. Draw a line between pre-boot env and entering post-boot env.
2159 // PCR[7] (is RTMR[0]) is already done.
2160 //
2161 Status = MeasureSeparatorEvent (1);
2162 if (EFI_ERROR (Status)) {
2163 DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n"));
2164 }
2165
2166 //
2167 // 3. Measure GPT. It would be done in SAP driver.
2168 //
2169
2170 //
2171 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
2172 //
2173
2174 //
2175 // 5. Read & Measure variable. BootOrder already measured.
2176 //
2177 } else {
2178 //
2179 // 6. Not first attempt, meaning a return from last attempt
2180 //
2181 Status = TdMeasureAction (
2182 MapPcrToMrIndex (4),
2183 EFI_RETURNING_FROM_EFI_APPLICATION
2184 );
2185 if (EFI_ERROR (Status)) {
2186 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATION));
2187 }
2188
2189 //
2190 // 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again
2191 // TCG PC Client PFP spec Section 2.4.4.5 Step 4
2192 //
2193 Status = TdMeasureAction (
2194 MapPcrToMrIndex (4),
2195 EFI_CALLING_EFI_APPLICATION
2196 );
2197 if (EFI_ERROR (Status)) {
2198 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
2199 }
2200 }
2201
2202 DEBUG ((DEBUG_INFO, "TdTcg2Dxe Measure Data when ReadyToBoot\n"));
2203 //
2204 // Increase boot attempt counter.
2205 //
2206 mBootAttempts++;
2207 PERF_END_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_CC_TCG2_DXE + 1);
2208 }
2209
2210 /**
2211 Exit Boot Services Event notification handler.
2212
2213 Measure invocation and success of ExitBootServices.
2214
2215 @param[in] Event Event whose notification function is being invoked
2216 @param[in] Context Pointer to the notification function's context
2217
2218 **/
2219 VOID
2220 EFIAPI
2221 OnExitBootServices (
2222 IN EFI_EVENT Event,
2223 IN VOID *Context
2224 )
2225 {
2226 EFI_STATUS Status;
2227
2228 //
2229 // Measure invocation of ExitBootServices,
2230 //
2231 Status = TdMeasureAction (
2232 MapPcrToMrIndex (5),
2233 EFI_EXIT_BOOT_SERVICES_INVOCATION
2234 );
2235 if (EFI_ERROR (Status)) {
2236 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));
2237 }
2238
2239 //
2240 // Measure success of ExitBootServices
2241 //
2242 Status = TdMeasureAction (
2243 MapPcrToMrIndex (5),
2244 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
2245 );
2246 if (EFI_ERROR (Status)) {
2247 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));
2248 }
2249 }
2250
2251 /**
2252 Exit Boot Services Failed Event notification handler.
2253
2254 Measure Failure of ExitBootServices.
2255
2256 @param[in] Event Event whose notification function is being invoked
2257 @param[in] Context Pointer to the notification function's context
2258
2259 **/
2260 VOID
2261 EFIAPI
2262 OnExitBootServicesFailed (
2263 IN EFI_EVENT Event,
2264 IN VOID *Context
2265 )
2266 {
2267 EFI_STATUS Status;
2268
2269 //
2270 // Measure Failure of ExitBootServices,
2271 //
2272 Status = TdMeasureAction (
2273 MapPcrToMrIndex (5),
2274 EFI_EXIT_BOOT_SERVICES_FAILED
2275 );
2276 if (EFI_ERROR (Status)) {
2277 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));
2278 }
2279 }
2280
2281 EFI_STATUS
2282 SyncCcEvent (
2283 VOID
2284 )
2285 {
2286 EFI_STATUS Status;
2287 EFI_PEI_HOB_POINTERS GuidHob;
2288 VOID *CcEvent;
2289 VOID *DigestListBin;
2290 UINT32 DigestListBinSize;
2291 UINT8 *Event;
2292 UINT32 EventSize;
2293 EFI_CC_EVENT_LOG_FORMAT LogFormat;
2294
2295 DEBUG ((DEBUG_INFO, "Sync Cc event from SEC\n"));
2296
2297 Status = EFI_SUCCESS;
2298 LogFormat = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
2299 GuidHob.Guid = GetFirstGuidHob (&gCcEventEntryHobGuid);
2300
2301 while (!EFI_ERROR (Status) && GuidHob.Guid != NULL) {
2302 CcEvent = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));
2303 if (CcEvent == NULL) {
2304 return EFI_OUT_OF_RESOURCES;
2305 }
2306
2307 GuidHob.Guid = GET_NEXT_HOB (GuidHob);
2308 GuidHob.Guid = GetNextGuidHob (&gCcEventEntryHobGuid, GuidHob.Guid);
2309
2310 DigestListBin = (UINT8 *)CcEvent + sizeof (UINT32) + sizeof (TCG_EVENTTYPE);
2311 DigestListBinSize = GetDigestListBinSize (DigestListBin);
2312
2313 //
2314 // Event size.
2315 //
2316 EventSize = *(UINT32 *)((UINT8 *)DigestListBin + DigestListBinSize);
2317 Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof (UINT32);
2318
2319 //
2320 // Log the event
2321 //
2322 Status = TdxDxeLogEvent (
2323 LogFormat,
2324 CcEvent,
2325 sizeof (UINT32) + sizeof (TCG_EVENTTYPE) + DigestListBinSize + sizeof (UINT32),
2326 Event,
2327 EventSize
2328 );
2329
2330 DumpCcEvent ((CC_EVENT *)CcEvent);
2331 FreePool (CcEvent);
2332 }
2333
2334 return Status;
2335 }
2336
2337 /**
2338 Install TDVF ACPI Table when ACPI Table Protocol is available.
2339
2340 @param[in] Event Event whose notification function is being invoked
2341 @param[in] Context Pointer to the notification function's context
2342 **/
2343 VOID
2344 EFIAPI
2345 InstallAcpiTable (
2346 IN EFI_EVENT Event,
2347 IN VOID *Context
2348 )
2349 {
2350 UINTN TableKey;
2351 EFI_STATUS Status;
2352 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
2353 UINT64 OemTableId;
2354
2355 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);
2356 if (EFI_ERROR (Status)) {
2357 DEBUG ((DEBUG_ERROR, "TD: AcpiTableProtocol is not installed. %r\n", Status));
2358 return;
2359 }
2360
2361 mTdxEventlogAcpiTemplate.Laml = (UINT64)PcdGet32 (PcdCcEventlogAcpiTableLaml);
2362 mTdxEventlogAcpiTemplate.Lasa = PcdGet64 (PcdCcEventlogAcpiTableLasa);
2363 CopyMem (mTdxEventlogAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTdxEventlogAcpiTemplate.Header.OemId));
2364 OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
2365 CopyMem (&mTdxEventlogAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
2366 mTdxEventlogAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
2367 mTdxEventlogAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
2368 mTdxEventlogAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
2369
2370 //
2371 // Construct ACPI Table
2372 Status = AcpiTable->InstallAcpiTable (
2373 AcpiTable,
2374 &mTdxEventlogAcpiTemplate,
2375 mTdxEventlogAcpiTemplate.Header.Length,
2376 &TableKey
2377 );
2378 ASSERT_EFI_ERROR (Status);
2379
2380 DEBUG ((DEBUG_INFO, "TDVF Eventlog ACPI Table is installed.\n"));
2381 }
2382
2383 /**
2384 The function install TdTcg2 protocol.
2385
2386 @retval EFI_SUCCESS TdTcg2 protocol is installed.
2387 @retval other Some error occurs.
2388 **/
2389 EFI_STATUS
2390 InstallCcMeasurementProtocol (
2391 VOID
2392 )
2393 {
2394 EFI_STATUS Status;
2395 EFI_HANDLE Handle;
2396
2397 Handle = NULL;
2398 Status = gBS->InstallMultipleProtocolInterfaces (
2399 &Handle,
2400 &gEfiCcMeasurementProtocolGuid,
2401 &mTdProtocol,
2402 NULL
2403 );
2404 DEBUG ((DEBUG_INFO, "CcProtocol: Install %r\n", Status));
2405 return Status;
2406 }
2407
2408 /**
2409 The driver's entry point. It publishes EFI Tcg2 Protocol.
2410
2411 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2412 @param[in] SystemTable A pointer to the EFI System Table.
2413
2414 @retval EFI_SUCCESS The entry point is executed successfully.
2415 @retval other Some error occurs when executing this entry point.
2416 **/
2417 EFI_STATUS
2418 EFIAPI
2419 DriverEntry (
2420 IN EFI_HANDLE ImageHandle,
2421 IN EFI_SYSTEM_TABLE *SystemTable
2422 )
2423 {
2424 EFI_STATUS Status;
2425 EFI_EVENT Event;
2426 VOID *Registration;
2427
2428 if (!TdIsEnabled ()) {
2429 return EFI_UNSUPPORTED;
2430 }
2431
2432 mImageHandle = ImageHandle;
2433
2434 //
2435 // Fill information
2436 //
2437 // ASSERT (TD_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTEventInfo)/sizeof(mTcg2EventInfo[0]));
2438
2439 mTdxDxeData.BsCap.Size = sizeof (EFI_CC_BOOT_SERVICE_CAPABILITY);
2440 mTdxDxeData.BsCap.ProtocolVersion.Major = 1;
2441 mTdxDxeData.BsCap.ProtocolVersion.Minor = 0;
2442 mTdxDxeData.BsCap.StructureVersion.Major = 1;
2443 mTdxDxeData.BsCap.StructureVersion.Minor = 0;
2444
2445 //
2446 // Get supported PCR and current Active PCRs
2447 // For TD gueset HA384 is supported.
2448 //
2449 mTdxDxeData.BsCap.HashAlgorithmBitmap = HASH_ALG_SHA384;
2450
2451 // TD guest only supports EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
2452 mTdxDxeData.BsCap.SupportedEventLogs = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
2453
2454 //
2455 // Setup the log area and copy event log from hob list to it
2456 //
2457 Status = SetupCcEventLog ();
2458 ASSERT_EFI_ERROR (Status);
2459
2460 if (!EFI_ERROR (Status)) {
2461 Status = SyncCcEvent ();
2462 ASSERT_EFI_ERROR (Status);
2463 }
2464
2465 //
2466 // Measure handoff tables, Boot#### variables etc.
2467 //
2468 Status = EfiCreateEventReadyToBootEx (
2469 TPL_CALLBACK,
2470 OnReadyToBoot,
2471 NULL,
2472 &Event
2473 );
2474
2475 Status = gBS->CreateEventEx (
2476 EVT_NOTIFY_SIGNAL,
2477 TPL_NOTIFY,
2478 OnExitBootServices,
2479 NULL,
2480 &gEfiEventExitBootServicesGuid,
2481 &Event
2482 );
2483
2484 //
2485 // Measure Exit Boot Service failed
2486 //
2487 Status = gBS->CreateEventEx (
2488 EVT_NOTIFY_SIGNAL,
2489 TPL_NOTIFY,
2490 OnExitBootServicesFailed,
2491 NULL,
2492 &gEventExitBootServicesFailedGuid,
2493 &Event
2494 );
2495
2496 //
2497 // Create event callback, because we need access variable on SecureBootPolicyVariable
2498 // We should use VariableWriteArch instead of VariableArch, because Variable driver
2499 // may update SecureBoot value based on last setting.
2500 //
2501 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);
2502
2503 //
2504 // Install CcMeasurementProtocol
2505 //
2506 Status = InstallCcMeasurementProtocol ();
2507 DEBUG ((DEBUG_INFO, "InstallCcMeasurementProtocol - %r\n", Status));
2508
2509 if (Status == EFI_SUCCESS) {
2510 //
2511 // Create event callback to install CC EventLog ACPI Table
2512 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration);
2513 }
2514
2515 return Status;
2516 }