1 /** @file
2   This library is used by FSP modules to measure data to TPM.
3 
4 Copyright (c) 2020, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #include <PiPei.h>
10 #include <Uefi.h>
11 
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/PeiServicesLib.h>
14 #include <Library/PeiServicesTablePointerLib.h>
15 #include <Library/PcdLib.h>
16 #include <Library/PrintLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/FspWrapperApiLib.h>
19 #include <Library/TpmMeasurementLib.h>
20 #include <Library/FspMeasurementLib.h>
21 #include <Library/TcgEventLogRecordLib.h>
22 #include <Library/HashLib.h>
23 
24 #include <Ppi/Tcg.h>
25 #include <IndustryStandard/UefiTcgPlatform.h>
26 
27 /**
28   Tpm measure and log data, and extend the measurement result into a specific PCR.
29 
30   @param[in]  PcrIndex         PCR Index.
31   @param[in]  EventType        Event type.
32   @param[in]  EventLog         Measurement event log.
33   @param[in]  LogLen           Event log length in bytes.
34   @param[in]  HashData         The start of the data buffer to be hashed, extended.
35   @param[in]  HashDataLen      The length, in bytes, of the buffer referenced by HashData
36   @param[in]  Flags            Bitmap providing additional information.
37 
38   @retval EFI_SUCCESS           Operation completed successfully.
39   @retval EFI_UNSUPPORTED       TPM device not available.
40   @retval EFI_OUT_OF_RESOURCES  Out of memory.
41   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
42 **/
43 EFI_STATUS
44 EFIAPI
TpmMeasureAndLogDataWithFlags(IN UINT32 PcrIndex,IN UINT32 EventType,IN VOID * EventLog,IN UINT32 LogLen,IN VOID * HashData,IN UINT64 HashDataLen,IN UINT64 Flags)45 TpmMeasureAndLogDataWithFlags (
46   IN UINT32             PcrIndex,
47   IN UINT32             EventType,
48   IN VOID               *EventLog,
49   IN UINT32             LogLen,
50   IN VOID               *HashData,
51   IN UINT64             HashDataLen,
52   IN UINT64             Flags
53   )
54 {
55   EFI_STATUS                Status;
56   EDKII_TCG_PPI             *TcgPpi;
57   TCG_PCR_EVENT_HDR         TcgEventHdr;
58 
59   Status = PeiServicesLocatePpi(
60              &gEdkiiTcgPpiGuid,
61              0,
62              NULL,
63              (VOID**)&TcgPpi
64              );
65   if (EFI_ERROR(Status)) {
66     return Status;
67   }
68 
69   TcgEventHdr.PCRIndex  = PcrIndex;
70   TcgEventHdr.EventType = EventType;
71   TcgEventHdr.EventSize = LogLen;
72 
73   Status = TcgPpi->HashLogExtendEvent (
74                      TcgPpi,
75                      Flags,
76                      HashData,
77                      (UINTN)HashDataLen,
78                      &TcgEventHdr,
79                      EventLog
80                      );
81   return Status;
82 }
83 
84 /**
85   Measure a FSP FirmwareBlob.
86 
87   @param[in]  Description             Description for this FirmwareBlob.
88   @param[in]  FirmwareBlobBase        Base address of this FirmwareBlob.
89   @param[in]  FirmwareBlobLength      Size in bytes of this FirmwareBlob.
90   @param[in]  CfgRegionOffset         Configuration region offset in bytes.
91   @param[in]  CfgRegionSize           Configuration region in bytes.
92 
93   @retval EFI_SUCCESS           Operation completed successfully.
94   @retval EFI_UNSUPPORTED       TPM device not available.
95   @retval EFI_OUT_OF_RESOURCES  Out of memory.
96   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
97 **/
98 STATIC
99 EFI_STATUS
100 EFIAPI
MeasureFspFirmwareBlobWithCfg(IN CHAR8 * Description OPTIONAL,IN EFI_PHYSICAL_ADDRESS FirmwareBlobBase,IN UINT64 FirmwareBlobLength,IN UINT32 CfgRegionOffset,IN UINT32 CfgRegionSize)101 MeasureFspFirmwareBlobWithCfg (
102   IN CHAR8                          *Description OPTIONAL,
103   IN EFI_PHYSICAL_ADDRESS           FirmwareBlobBase,
104   IN UINT64                         FirmwareBlobLength,
105   IN UINT32                         CfgRegionOffset,
106   IN UINT32                         CfgRegionSize
107   )
108 {
109   EFI_PLATFORM_FIRMWARE_BLOB        FvBlob, UpdBlob;
110   PLATFORM_FIRMWARE_BLOB2_STRUCT    FvBlob2, UpdBlob2;
111   VOID                              *FvName;
112   UINT32                            FvEventType;
113   VOID                              *FvEventLog, *UpdEventLog;
114   UINT32                            FvEventLogSize, UpdEventLogSize;
115   EFI_STATUS                        Status;
116   HASH_HANDLE                       HashHandle;
117   UINT8                             *HashBase;
118   UINTN                             HashSize;
119   TPML_DIGEST_VALUES                DigestList;
120 
121   FvName = TpmMeasurementGetFvName (FirmwareBlobBase, FirmwareBlobLength);
122 
123   if (((Description != NULL) || (FvName != NULL)) &&
124       (PcdGet32(PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105)) {
125     if (Description != NULL) {
126       AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "%a", Description);
127       AsciiSPrint((CHAR8*)UpdBlob2.BlobDescription, sizeof(UpdBlob2.BlobDescription), "%aUDP", Description);
128      } else {
129       AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "Fv(%g)", FvName);
130       AsciiSPrint((CHAR8*)UpdBlob2.BlobDescription, sizeof(UpdBlob2.BlobDescription), "(%g)UDP", FvName);
131     }
132 
133     FvBlob2.BlobDescriptionSize = sizeof(FvBlob2.BlobDescription);
134     FvBlob2.BlobBase = FirmwareBlobBase;
135     FvBlob2.BlobLength = FirmwareBlobLength;
136     FvEventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2;
137     FvEventLog = &FvBlob2;
138     FvEventLogSize = sizeof(FvBlob2);
139 
140     UpdBlob2.BlobDescriptionSize = sizeof(UpdBlob2.BlobDescription);
141     UpdBlob2.BlobBase = CfgRegionOffset;
142     UpdBlob2.BlobLength = CfgRegionSize;
143     UpdEventLog = &UpdBlob2;
144     UpdEventLogSize = sizeof(UpdBlob2);
145   } else {
146     FvBlob.BlobBase = FirmwareBlobBase;
147     FvBlob.BlobLength = FirmwareBlobLength;
148     FvEventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;
149     FvEventLog = &FvBlob;
150     FvEventLogSize = sizeof(FvBlob);
151 
152     UpdBlob.BlobBase = CfgRegionOffset;
153     UpdBlob.BlobLength = CfgRegionSize;
154     UpdEventLog = &UpdBlob;
155     UpdEventLogSize = sizeof(UpdBlob);
156   }
157 
158   /** Initialize a SHA hash context. **/
159   Status = HashStart (&HashHandle);
160   if (EFI_ERROR (Status)) {
161     DEBUG ((DEBUG_ERROR, "HashStart failed - %r\n", Status));
162     return Status;
163   }
164 
165   /** Hash FSP binary before UDP **/
166   HashBase = (UINT8 *) (UINTN) FirmwareBlobBase;
167   HashSize = (UINTN) CfgRegionOffset;
168   Status = HashUpdate (HashHandle, HashBase, HashSize);
169   if (EFI_ERROR (Status)) {
170     DEBUG ((DEBUG_ERROR, "HashUpdate failed - %r\n", Status));
171     return Status;
172   }
173 
174   /** Hash FSP binary after UDP **/
175   HashBase = (UINT8 *) (UINTN) FirmwareBlobBase + CfgRegionOffset + CfgRegionSize;
176   HashSize = (UINTN)(FirmwareBlobLength - CfgRegionOffset - CfgRegionSize);
177   Status = HashUpdate (HashHandle, HashBase, HashSize);
178   if (EFI_ERROR (Status)) {
179     DEBUG ((DEBUG_ERROR, "HashUpdate failed - %r\n", Status));
180     return Status;
181   }
182 
183   /** Finalize the SHA hash. **/
184   Status = HashCompleteAndExtend (HashHandle, 0, NULL, 0, &DigestList);
185   if (EFI_ERROR (Status)) {
186     DEBUG ((DEBUG_ERROR, "HashCompleteAndExtend failed - %r\n", Status));
187     return Status;
188   }
189 
190   Status = TpmMeasureAndLogDataWithFlags (
191              0,
192              FvEventType,
193              FvEventLog,
194              FvEventLogSize,
195              (UINT8 *) &DigestList,
196              (UINTN) sizeof(DigestList),
197              EDKII_TCG_PRE_HASH_LOG_ONLY
198              );
199 
200   Status = TpmMeasureAndLogData (
201              1,
202              EV_PLATFORM_CONFIG_FLAGS,
203              UpdEventLog,
204              UpdEventLogSize,
205              (UINT8 *) (UINTN) FirmwareBlobBase + CfgRegionOffset,
206              CfgRegionSize
207              );
208 
209   return Status;
210 }
211 
212 /**
213   Measure a FSP FirmwareBlob.
214 
215   @param[in]  PcrIndex                PCR Index.
216   @param[in]  Description             Description for this FirmwareBlob.
217   @param[in]  FirmwareBlobBase        Base address of this FirmwareBlob.
218   @param[in]  FirmwareBlobLength      Size in bytes of this FirmwareBlob.
219 
220   @retval EFI_SUCCESS           Operation completed successfully.
221   @retval EFI_UNSUPPORTED       TPM device not available.
222   @retval EFI_OUT_OF_RESOURCES  Out of memory.
223   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
224 **/
225 EFI_STATUS
226 EFIAPI
MeasureFspFirmwareBlob(IN UINT32 PcrIndex,IN CHAR8 * Description OPTIONAL,IN EFI_PHYSICAL_ADDRESS FirmwareBlobBase,IN UINT64 FirmwareBlobLength)227 MeasureFspFirmwareBlob (
228   IN UINT32                         PcrIndex,
229   IN CHAR8                          *Description OPTIONAL,
230   IN EFI_PHYSICAL_ADDRESS           FirmwareBlobBase,
231   IN UINT64                         FirmwareBlobLength
232   )
233 {
234   UINT32           FspMeasureMask;
235   FSP_INFO_HEADER  *FspHeaderPtr;
236 
237   FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig);
238   if ((FspMeasureMask & FSP_MEASURE_FSPUPD) != 0) {
239     FspHeaderPtr = (FSP_INFO_HEADER *) FspFindFspHeader (FirmwareBlobBase);
240     if (FspHeaderPtr != NULL) {
241       return MeasureFspFirmwareBlobWithCfg(Description, FirmwareBlobBase, FirmwareBlobLength,
242                                            FspHeaderPtr->CfgRegionOffset, FspHeaderPtr->CfgRegionSize);
243     }
244   }
245 
246   return MeasureFirmwareBlob (PcrIndex, Description, FirmwareBlobBase, FirmwareBlobLength);
247 }
248 
249