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