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