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
InternalDumpData(IN UINT8 * Data,IN UINTN Size)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
InternalDumpHex(IN UINT8 * Data,IN UINTN Size)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
IsZeroBuffer(IN VOID * Buffer,IN UINTN BufferSize)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
GetProcessorsCpuLocation(OUT EFI_CPU_PHYSICAL_LOCATION ** LocationBuf,OUT UINTN * Num)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
Tcg2GetCapability(IN EFI_TCG2_PROTOCOL * This,IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY * ProtocolCapability)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
DumpEvent(IN TCG_PCR_EVENT_HDR * EventHdr)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
DumpTcgEfiSpecIdEventStruct(IN TCG_EfiSpecIDEventStruct * TcgEfiSpecIdEventStruct)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
GetTcgEfiSpecIdEventStructSize(IN TCG_EfiSpecIDEventStruct * TcgEfiSpecIdEventStruct)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
DumpEvent2(IN TCG_PCR_EVENT2 * TcgPcrEvent2)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
GetPcrEvent2Size(IN TCG_PCR_EVENT2 * TcgPcrEvent2)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
DumpEventLog(IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,IN EFI_PHYSICAL_ADDRESS EventLogLocation,IN EFI_PHYSICAL_ADDRESS EventLogLastEntry,IN EFI_TCG2_FINAL_EVENTS_TABLE * FinalEventsTable)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
Tcg2GetEventLog(IN EFI_TCG2_PROTOCOL * This,IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry,OUT BOOLEAN * EventLogTruncated)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
TcgCommLogEvent(IN OUT UINT8 ** EventLogPtr,IN OUT UINTN * LogSize,IN UINTN MaxSize,IN VOID * NewEventHdr,IN UINT32 NewEventHdrSize,IN UINT8 * NewEventData,IN UINT32 NewEventSize)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
TcgDxeLogEvent(IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,IN VOID * NewEventHdr,IN UINT32 NewEventHdrSize,IN UINT8 * NewEventData,IN UINT32 NewEventSize)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
Tpm2GetDigestFromDigestList(IN TPMI_ALG_HASH HashAlg,IN TPML_DIGEST_VALUES * DigestList,IN VOID * Digest)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
GetDigestListSize(IN TPML_DIGEST_VALUES * DigestList)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
GetDigestListBinSize(IN VOID * DigestListBin)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
IsHashAlgSupportedInPcrBank(IN TPMI_ALG_HASH HashAlg)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 *
CopyDigestListToBuffer(IN OUT VOID * Buffer,IN TPML_DIGEST_VALUES * DigestList)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
TcgDxeLogHashEvent(IN TPML_DIGEST_VALUES * DigestList,IN OUT TCG_PCR_EVENT_HDR * NewEventHdr,IN UINT8 * NewEventData)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
TcgDxeHashLogExtendEvent(IN UINT64 Flags,IN UINT8 * HashData,IN UINT64 HashDataLen,IN OUT TCG_PCR_EVENT_HDR * NewEventHdr,IN UINT8 * NewEventData)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
Tcg2HashLogExtendEvent(IN EFI_TCG2_PROTOCOL * This,IN UINT64 Flags,IN EFI_PHYSICAL_ADDRESS DataToHash,IN UINT64 DataToHashLen,IN EFI_TCG2_EVENT * Event)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
Tcg2SubmitCommand(IN EFI_TCG2_PROTOCOL * This,IN UINT32 InputParameterBlockSize,IN UINT8 * InputParameterBlock,IN UINT32 OutputParameterBlockSize,IN UINT8 * OutputParameterBlock)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
Tcg2GetActivePCRBanks(IN EFI_TCG2_PROTOCOL * This,OUT UINT32 * ActivePcrBanks)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
Tcg2SetActivePCRBanks(IN EFI_TCG2_PROTOCOL * This,IN UINT32 ActivePcrBanks)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
Tcg2GetResultOfSetActivePcrBanks(IN EFI_TCG2_PROTOCOL * This,OUT UINT32 * OperationPresent,OUT UINT32 * Response)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
SetupEventLog(VOID)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
TcgMeasureAction(IN CHAR8 * String)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
MeasureHandoffTables(VOID)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
MeasureSeparatorEvent(IN TPM_PCRINDEX PCRIndex)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
MeasureVariable(IN TPM_PCRINDEX PCRIndex,IN TCG_EVENTTYPE EventType,IN CHAR16 * VarName,IN EFI_GUID * VendorGuid,IN VOID * VarData,IN UINTN VarSize)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
ReadAndMeasureVariable(IN TPM_PCRINDEX PCRIndex,IN TCG_EVENTTYPE EventType,IN CHAR16 * VarName,IN EFI_GUID * VendorGuid,OUT UINTN * VarSize,OUT VOID ** VarData)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
ReadAndMeasureBootVariable(IN CHAR16 * VarName,IN EFI_GUID * VendorGuid,OUT UINTN * VarSize,OUT VOID ** VarData)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
ReadAndMeasureSecureVariable(IN CHAR16 * VarName,IN EFI_GUID * VendorGuid,OUT UINTN * VarSize,OUT VOID ** VarData)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
MeasureAllBootVariables(VOID)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
MeasureAllSecureVariables(VOID)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
MeasureLaunchOfFirmwareDebugger(VOID)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
MeasureSecureBootPolicy(IN EFI_EVENT Event,IN VOID * Context)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
OnReadyToBoot(IN EFI_EVENT Event,IN VOID * Context)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
OnExitBootServices(IN EFI_EVENT Event,IN VOID * Context)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
OnExitBootServicesFailed(IN EFI_EVENT Event,IN VOID * Context)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
InstallTcg2(VOID)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
DriverEntry(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)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