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