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