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