TianoCore EDK2 master
Loading...
Searching...
No Matches
FvReportPei.c
Go to the documentation of this file.
1
9#include "FvReportPei.h"
10
11STATIC CONST HASH_ALG_INFO mHashAlgInfo[] = {
15};
16
29 IN UINT16 HashAlgId
30 )
31{
32 UINTN Index;
33
34 for (Index = 0; Index < ARRAY_SIZE (mHashAlgInfo); ++Index) {
35 if (mHashAlgInfo[Index].HashAlgId == HashAlgId) {
36 return &mHashAlgInfo[Index];
37 }
38 }
39
40 return NULL;
41}
42
54VOID
56 IN VOID *FvBuffer,
57 IN UINTN FvLength,
58 IN UINT16 HashAlgoId,
59 IN UINT16 HashSize,
60 IN UINT8 *HashValue
61 )
62{
63 EFI_STATUS Status;
64 EFI_PEI_PPI_DESCRIPTOR *FvInfoPpiDescriptor;
66 UINTN PpiSize;
67 HASH_INFO *HashInfo;
68
70 + sizeof (HASH_INFO)
71 + HashSize;
72
73 PreHashedFvPpi = AllocatePool (PpiSize);
74 ASSERT (PreHashedFvPpi != NULL);
75
76 PreHashedFvPpi->FvBase = (UINT32)(UINTN)FvBuffer;
77 PreHashedFvPpi->FvLength = (UINT32)FvLength;
78 PreHashedFvPpi->Count = 1;
79
80 HashInfo = HASH_INFO_PTR (PreHashedFvPpi);
81 HashInfo->HashAlgoId = HashAlgoId;
82 HashInfo->HashSize = HashSize;
83 CopyMem (HASH_VALUE_PTR (HashInfo), HashValue, HashSize);
84
85 FvInfoPpiDescriptor = AllocatePool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
86 ASSERT (FvInfoPpiDescriptor != NULL);
87
88 FvInfoPpiDescriptor->Guid = &gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid;
89 FvInfoPpiDescriptor->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
90 FvInfoPpiDescriptor->Ppi = (VOID *)PreHashedFvPpi;
91
92 Status = PeiServicesInstallPpi (FvInfoPpiDescriptor);
93 ASSERT_EFI_ERROR (Status);
94}
95
108STATIC
111 IN FV_HASH_INFO *HashInfo,
112 IN HASHED_FV_INFO *FvInfo,
113 IN UINTN FvNumber,
114 IN EFI_BOOT_MODE BootMode
115 )
116{
117 UINTN FvIndex;
118 CONST HASH_ALG_INFO *AlgInfo;
119 UINT8 *HashValue;
120 UINT8 *FvHashValue;
121 VOID *FvBuffer;
123 EFI_STATUS Status;
124
125 if ((HashInfo == NULL) ||
126 (HashInfo->HashSize == 0) ||
127 (HashInfo->HashAlgoId == TPM_ALG_NULL))
128 {
129 DEBUG ((DEBUG_INFO, "Bypass FV hash verification\r\n"));
130 return EFI_SUCCESS;
131 }
132
133 AlgInfo = FindHashAlgInfo (HashInfo->HashAlgoId);
134 if ((AlgInfo == NULL) || (AlgInfo->HashSize != HashInfo->HashSize)) {
135 DEBUG ((
136 DEBUG_ERROR,
137 "Unsupported or wrong hash algorithm: %04X (size=%d)\r\n",
138 HashInfo->HashAlgoId,
139 HashInfo->HashSize
140 ));
141 return EFI_UNSUPPORTED;
142 }
143
144 ASSERT (FvInfo != NULL);
145 ASSERT (FvNumber > 0);
146
147 //
148 // We need a hash value for each FV as well as one for all FVs.
149 //
150 HashValue = AllocateZeroPool (AlgInfo->HashSize * (FvNumber + 1));
151 ASSERT (HashValue != NULL);
152
153 Status = PeiServicesLocatePpi (
154 &gEdkiiPeiFirmwareVolumeShadowPpiGuid,
155 0,
156 NULL,
157 (VOID **)&FvShadowPpi
158 );
159 if (EFI_ERROR (Status)) {
160 FvShadowPpi = NULL;
161 }
162
163 //
164 // Calculate hash value for each FV first.
165 //
166 FvHashValue = HashValue;
167 for (FvIndex = 0; FvIndex < FvNumber; ++FvIndex) {
168 //
169 // Not meant for verified boot and/or measured boot?
170 //
171 if (((FvInfo[FvIndex].Flag & HASHED_FV_FLAG_VERIFIED_BOOT) == 0) &&
172 ((FvInfo[FvIndex].Flag & HASHED_FV_FLAG_MEASURED_BOOT) == 0))
173 {
174 continue;
175 }
176
177 //
178 // Skip any FV not meant for current boot mode.
179 //
180 if ((FvInfo[FvIndex].Flag & HASHED_FV_FLAG_SKIP_BOOT_MODE (BootMode)) != 0) {
181 DEBUG ((
182 DEBUG_INFO,
183 "Skip FV[%016lX] for boot mode[%d]\r\n",
184 FvInfo[FvIndex].Base,
185 BootMode
186 ));
187 continue;
188 }
189
190 DEBUG ((
191 DEBUG_INFO,
192 "Pre-hashed[alg=%04X,size=%d,flag=%016lX] FV: 0x%016lX (%08lX) (Flag=%016lX)\r\n",
193 HashInfo->HashAlgoId,
194 HashInfo->HashSize,
195 HashInfo->HashFlag,
196 FvInfo[FvIndex].Base,
197 FvInfo[FvIndex].Length,
198 FvInfo[FvIndex].Flag
199 ));
200
201 //
202 // Copy FV to permanent memory to avoid potential TOC/TOU.
203 //
204 FvBuffer = AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)FvInfo[FvIndex].Length));
205
206 ASSERT (FvBuffer != NULL);
207
208 if (FvShadowPpi != NULL) {
209 Status = FvShadowPpi->FirmwareVolumeShadow (
210 (EFI_PHYSICAL_ADDRESS)FvInfo[FvIndex].Base,
211 FvBuffer,
212 (UINTN)FvInfo[FvIndex].Length
213 );
214 }
215
216 if ((FvShadowPpi == NULL) || (EFI_ERROR (Status))) {
217 CopyMem (
218 FvBuffer,
219 (CONST VOID *)(UINTN)FvInfo[FvIndex].Base,
220 (UINTN)FvInfo[FvIndex].Length
221 );
222 }
223
224 if (!AlgInfo->HashAll (FvBuffer, (UINTN)FvInfo[FvIndex].Length, FvHashValue)) {
225 Status = EFI_ABORTED;
226 goto Done;
227 }
228
229 //
230 // Report the FV measurement.
231 //
232 if ((FvInfo[FvIndex].Flag & HASHED_FV_FLAG_MEASURED_BOOT) != 0) {
234 FvBuffer,
235 (UINTN)FvInfo[FvIndex].Length,
236 HashInfo->HashAlgoId,
237 HashInfo->HashSize,
238 FvHashValue
239 );
240 }
241
242 //
243 // Don't keep the hash value of current FV if we don't need to verify it.
244 //
245 if ((FvInfo[FvIndex].Flag & HASHED_FV_FLAG_VERIFIED_BOOT) != 0) {
246 FvHashValue += AlgInfo->HashSize;
247 }
248
249 //
250 // Use memory copy of the FV from now on.
251 //
252 FvInfo[FvIndex].Base = (UINT64)(UINTN)FvBuffer;
253 }
254
255 //
256 // Check final hash for all FVs.
257 //
258 if ((FvHashValue == HashValue) ||
259 (AlgInfo->HashAll (HashValue, FvHashValue - HashValue, FvHashValue) &&
260 (CompareMem (HashInfo->Hash, FvHashValue, AlgInfo->HashSize) == 0)))
261 {
262 Status = EFI_SUCCESS;
263 } else {
264 Status = EFI_VOLUME_CORRUPTED;
265 }
266
267Done:
268 FreePool (HashValue);
269 return Status;
270}
271
278STATIC
279VOID
281 IN HASHED_FV_INFO *FvInfo
282 )
283{
284 CONST EFI_GUID *FvFormat;
285
286 if ((FvInfo->Flag & HASHED_FV_FLAG_REPORT_FV_HOB) != 0) {
287 //
288 // Require DXE core to process this FV.
289 //
290 BuildFvHob (
291 (EFI_PHYSICAL_ADDRESS)FvInfo->Base,
292 FvInfo->Length
293 );
294 DEBUG ((DEBUG_INFO, "Reported FV HOB: %016lX (%08lX)\r\n", FvInfo->Base, FvInfo->Length));
295 }
296
297 if ((FvInfo->Flag & HASHED_FV_FLAG_REPORT_FV_INFO_PPI) != 0) {
298 //
299 // Require PEI core to process this FV.
300 //
301 FvFormat = &((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvInfo->Base)->FileSystemGuid;
303 FvFormat,
304 (VOID *)(UINTN)FvInfo->Base,
305 (UINT32)FvInfo->Length,
306 NULL,
307 NULL
308 );
309 DEBUG ((DEBUG_INFO, "Reported FV PPI: %016lX (%08lX)\r\n", FvInfo->Base, FvInfo->Length));
310 }
311}
312
327STATIC
331 IN EFI_BOOT_MODE BootMode
332 )
333{
334 FV_HASH_INFO *HashInfo;
335
336 if ((StoredHashFvPpi->HashInfo.HashFlag & FV_HASH_FLAG_BOOT_MODE (BootMode)) != 0) {
337 HashInfo = &StoredHashFvPpi->HashInfo;
338 } else {
339 HashInfo = NULL;
340 }
341
342 return HashInfo;
343}
344
358STATIC
361 IN CONST EFI_PEI_SERVICES **PeiServices,
362 IN EFI_BOOT_MODE BootMode
363 )
364{
365 EFI_STATUS Status;
367 FV_HASH_INFO *HashInfo;
368 UINTN FvIndex;
369
370 //
371 // Check pre-hashed FV list
372 //
373 StoredHashFvPpi = NULL;
374 Status = PeiServicesLocatePpi (
375 &gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid,
376 0,
377 NULL,
378 (VOID **)&StoredHashFvPpi
379 );
380 if (!EFI_ERROR (Status) && (StoredHashFvPpi != NULL) && (StoredHashFvPpi->FvNumber > 0)) {
381 HashInfo = GetHashInfo (StoredHashFvPpi, BootMode);
382 Status = VerifyHashedFv (
383 HashInfo,
384 StoredHashFvPpi->FvInfo,
385 StoredHashFvPpi->FvNumber,
386 BootMode
387 );
388 if (!EFI_ERROR (Status)) {
389 DEBUG ((DEBUG_INFO, "OBB verification passed (%r)\r\n", Status));
390
391 //
392 // Report the FVs to PEI core and/or DXE core.
393 //
394 for (FvIndex = 0; FvIndex < StoredHashFvPpi->FvNumber; ++FvIndex) {
395 if ((StoredHashFvPpi->FvInfo[FvIndex].Flag
396 & HASHED_FV_FLAG_SKIP_BOOT_MODE (BootMode)) == 0)
397 {
398 ReportHashedFv (&StoredHashFvPpi->FvInfo[FvIndex]);
399 }
400 }
401
404 PcdGet32 (PcdStatusCodeFvVerificationPass)
405 );
406 } else {
407 DEBUG ((DEBUG_ERROR, "ERROR: Failed to verify OBB FVs (%r)\r\n", Status));
408
411 PcdGet32 (PcdStatusCodeFvVerificationFail),
412 0,
413 NULL,
414 &gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid,
415 StoredHashFvPpi,
416 sizeof (*StoredHashFvPpi)
417 );
418
419 ASSERT_EFI_ERROR (Status);
420 }
421 } else {
422 DEBUG ((DEBUG_ERROR, "ERROR: No/invalid StoredHashFvPpi located\r\n"));
423
424 ASSERT_EFI_ERROR (Status);
425 ASSERT (StoredHashFvPpi != NULL && StoredHashFvPpi->FvNumber > 0);
426
427 Status = EFI_NOT_FOUND;
428 }
429
430 return Status;
431}
432
443EFIAPI
445 IN EFI_PEI_FILE_HANDLE FileHandle,
446 IN CONST EFI_PEI_SERVICES **PeiServices
447 )
448{
449 EFI_STATUS Status;
450 EFI_BOOT_MODE BootMode;
451
452 Status = PeiServicesGetBootMode (&BootMode);
453 ASSERT_EFI_ERROR (Status);
454
455 Status = CheckStoredHashFv (PeiServices, BootMode);
456 if (EFI_ERROR (Status)) {
457 //
458 // Never pass control to left part of BIOS if any error.
459 //
460 CpuDeadLoop ();
461 }
462
463 return Status;
464}
UINT64 UINTN
VOID EFIAPI BuildFvHob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
Definition: HobLib.c:404
BOOLEAN EFIAPI Sha512HashAll(IN CONST VOID *Data, IN UINTN DataSize, OUT UINT8 *HashValue)
Definition: CryptSha512.c:427
BOOLEAN EFIAPI Sha512Final(IN OUT VOID *Sha512Context, OUT UINT8 *HashValue)
Definition: CryptSha512.c:389
BOOLEAN EFIAPI Sha512Init(OUT VOID *Sha512Context)
Definition: CryptSha512.c:270
#define SHA512_DIGEST_SIZE
Definition: BaseCryptLib.h:54
BOOLEAN EFIAPI Sha256Init(OUT VOID *Sha256Context)
Definition: CryptSha256.c:44
BOOLEAN EFIAPI Sha384HashAll(IN CONST VOID *Data, IN UINTN DataSize, OUT UINT8 *HashValue)
Definition: CryptSha512.c:201
BOOLEAN EFIAPI Sha256Final(IN OUT VOID *Sha256Context, OUT UINT8 *HashValue)
Definition: CryptSha256.c:161
#define SHA256_DIGEST_SIZE
Definition: BaseCryptLib.h:44
BOOLEAN EFIAPI Sha384Update(IN OUT VOID *Sha384Context, IN CONST VOID *Data, IN UINTN DataSize)
Definition: CryptSha512.c:115
BOOLEAN EFIAPI Sha256HashAll(IN CONST VOID *Data, IN UINTN DataSize, OUT UINT8 *HashValue)
Definition: CryptSha256.c:199
BOOLEAN EFIAPI Sha256Update(IN OUT VOID *Sha256Context, IN CONST VOID *Data, IN UINTN DataSize)
Definition: CryptSha256.c:113
BOOLEAN EFIAPI Sha384Final(IN OUT VOID *Sha384Context, OUT UINT8 *HashValue)
Definition: CryptSha512.c:163
BOOLEAN EFIAPI Sha384Init(OUT VOID *Sha384Context)
Definition: CryptSha512.c:44
BOOLEAN EFIAPI Sha512Update(IN OUT VOID *Sha512Context, IN CONST VOID *Data, IN UINTN DataSize)
Definition: CryptSha512.c:341
#define SHA384_DIGEST_SIZE
Definition: BaseCryptLib.h:49
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS EFIAPI PeiServicesGetBootMode(OUT EFI_BOOT_MODE *BootMode)
VOID EFIAPI PeiServicesInstallFvInfoPpi(IN CONST EFI_GUID *FvFormat OPTIONAL, IN CONST VOID *FvInfo, IN UINT32 FvInfoSize, IN CONST EFI_GUID *ParentFvName OPTIONAL, IN CONST EFI_GUID *ParentFileName OPTIONAL)
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
STATIC EFI_STATUS CheckStoredHashFv(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_BOOT_MODE BootMode)
Definition: FvReportPei.c:360
EFI_STATUS EFIAPI FvReportEntryPoint(IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
Definition: FvReportPei.c:444
STATIC VOID ReportHashedFv(IN HASHED_FV_INFO *FvInfo)
Definition: FvReportPei.c:280
STATIC EFI_STATUS VerifyHashedFv(IN FV_HASH_INFO *HashInfo, IN HASHED_FV_INFO *FvInfo, IN UINTN FvNumber, IN EFI_BOOT_MODE BootMode)
Definition: FvReportPei.c:110
STATIC CONST HASH_ALG_INFO * FindHashAlgInfo(IN UINT16 HashAlgId)
Definition: FvReportPei.c:28
STATIC FV_HASH_INFO * GetHashInfo(IN EDKII_PEI_FIRMWARE_VOLUME_INFO_STORED_HASH_FV_PPI *StoredHashFvPpi, IN EFI_BOOT_MODE BootMode)
Definition: FvReportPei.c:329
STATIC VOID InstallPreHashFvPpi(IN VOID *FvBuffer, IN UINTN FvLength, IN UINT16 HashAlgoId, IN UINT16 HashSize, IN UINT8 *HashValue)
Definition: FvReportPei.c:55
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define REPORT_STATUS_CODE_EX(Type, Value, Instance, CallerId, ExtendedDataGuid, ExtendedData, ExtendedDataSize)
#define REPORT_STATUS_CODE(Type, Value)
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
UINT32 EFI_BOOT_MODE
Definition: PiBootMode.h:18
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:43
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
Definition: Base.h:213