EFI_STATUS VerifyFfsFile ( IN EFI_FFS_FILE_HEADER *FfsHeader ) /*++ Routine Description: Verify the current pointer points to a FFS file header. Arguments: FfsHeader Pointer to an alleged FFS file. Returns: EFI_SUCCESS The Ffs header is valid. EFI_NOT_FOUND This "file" is the beginning of free space. EFI_VOLUME_CORRUPTED The Ffs header is not valid. EFI_ABORTED The erase polarity is not known. --*/ { BOOLEAN ErasePolarity; EFI_STATUS Status; EFI_FFS_FILE_HEADER2 BlankHeader; UINT8 Checksum; UINT32 FileLength; UINT8 SavedChecksum; UINT8 SavedState; UINT8 FileGuidString[80]; UINT32 FfsHeaderSize; // // Verify library has been initialized. // if (mFvHeader == NULL || mFvLength == 0) { return EFI_ABORTED; } // // Verify FV header // Status = VerifyFv (mFvHeader); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // // Get the erase polarity. // Status = GetErasePolarity (&ErasePolarity); if (EFI_ERROR (Status)) { return EFI_ABORTED; } FfsHeaderSize = GetFfsHeaderLength(FfsHeader); // // Check if we have free space // if (ErasePolarity) { memset (&BlankHeader, -1, FfsHeaderSize); } else { memset (&BlankHeader, 0, FfsHeaderSize); } if (memcmp (&BlankHeader, FfsHeader, FfsHeaderSize) == 0) { return EFI_NOT_FOUND; } // // Convert the GUID to a string so we can at least report which file // if we find an error. // PrintGuidToBuffer (&FfsHeader->Name, FileGuidString, sizeof (FileGuidString), TRUE); // // Verify file header checksum // SavedState = FfsHeader->State; FfsHeader->State = 0; SavedChecksum = FfsHeader->IntegrityCheck.Checksum.File; FfsHeader->IntegrityCheck.Checksum.File = 0; Checksum = CalculateSum8 ((UINT8 *) FfsHeader, FfsHeaderSize); FfsHeader->State = SavedState; FfsHeader->IntegrityCheck.Checksum.File = SavedChecksum; if (Checksum != 0) { Error (NULL, 0, 0006, "invalid FFS file header checksum", "Ffs file with Guid %s", FileGuidString); return EFI_ABORTED; } // // Verify file checksum // if (FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) { // // Verify file data checksum // FileLength = GetFfsFileLength (FfsHeader); Checksum = CalculateSum8 ((UINT8 *) ((UINT8 *)FfsHeader + FfsHeaderSize), FileLength - FfsHeaderSize); Checksum = Checksum + FfsHeader->IntegrityCheck.Checksum.File; if (Checksum != 0) { Error (NULL, 0, 0006, "invalid FFS file checksum", "Ffs file with Guid %s", FileGuidString); return EFI_ABORTED; } } else { // // File does not have a checksum // Verify contents are 0xAA as spec'd // if (FfsHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) { Error (NULL, 0, 0006, "invalid fixed FFS file header checksum", "Ffs file with Guid %s", FileGuidString); return EFI_ABORTED; } } return EFI_SUCCESS; }
EFI_STATUS VerifyFfsFile ( IN EFI_FFS_FILE_HEADER *FfsHeader ) /*++ Routine Description: Verify the current pointer points to a FFS file header. Arguments: FfsHeader Pointer to an alleged FFS file. Returns: EFI_SUCCESS The Ffs header is valid. EFI_NOT_FOUND This "file" is the beginning of free space. EFI_VOLUME_CORRUPTED The Ffs header is not valid. EFI_ABORTED The erase polarity is not known. --*/ { BOOLEAN ErasePolarity; EFI_STATUS Status; EFI_FFS_FILE_HEADER BlankHeader; UINT8 Checksum; UINT32 FileLength; UINT32 OccupiedFileLength; UINT8 SavedChecksum; UINT8 SavedState; UINT8 FileGuidString[80]; UINT32 TailSize; #if (PI_SPECIFICATION_VERSION < 0x00010000) EFI_FFS_FILE_TAIL *Tail; #endif // // Verify library has been initialized. // if (mFvHeader == NULL || mFvLength == 0) { return EFI_ABORTED; } // // Verify FV header // Status = VerifyFv (mFvHeader); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // // Get the erase polarity. // Status = GetErasePolarity (&ErasePolarity); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // // Check if we have free space // if (ErasePolarity) { memset (&BlankHeader, -1, sizeof (EFI_FFS_FILE_HEADER)); } else { memset (&BlankHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); } if (memcmp (&BlankHeader, FfsHeader, sizeof (EFI_FFS_FILE_HEADER)) == 0) { return EFI_NOT_FOUND; } // // Convert the GUID to a string so we can at least report which file // if we find an error. // PrintGuidToBuffer (&FfsHeader->Name, FileGuidString, sizeof (FileGuidString), TRUE); if (FfsHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) { TailSize = sizeof (EFI_FFS_FILE_TAIL); } else { TailSize = 0; } // // Verify file header checksum // SavedState = FfsHeader->State; FfsHeader->State = 0; SavedChecksum = FfsHeader->IntegrityCheck.Checksum.File; FfsHeader->IntegrityCheck.Checksum.File = 0; Checksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER)); FfsHeader->State = SavedState; FfsHeader->IntegrityCheck.Checksum.File = SavedChecksum; if (Checksum != 0) { Error (NULL, 0, 0, FileGuidString, "invalid FFS file header checksum"); return EFI_ABORTED; } // // Verify file checksum // if (FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) { // // Verify file data checksum // FileLength = GetLength (FfsHeader->Size); OccupiedFileLength = (FileLength + 0x07) & (-1 << 3); #if (PI_SPECIFICATION_VERSION < 0x00010000) Checksum = CalculateSum8 ((UINT8 *) FfsHeader, FileLength - TailSize); Checksum = (UINT8) (Checksum - FfsHeader->State); #else Checksum = CalculateSum8 ((UINT8 *) ((UINTN)FfsHeader + sizeof (EFI_FFS_FILE_HEADER)), FileLength - TailSize - sizeof (EFI_FFS_FILE_HEADER)); Checksum = Checksum + (UINT8)FfsHeader->IntegrityCheck.Checksum.File; #endif if (Checksum != 0) { Error (NULL, 0, 0, FileGuidString, "invalid FFS file checksum"); return EFI_ABORTED; } } else { // // File does not have a checksum // Verify contents are 0x5A(Framework) and 0xAA(PI 1.0) as spec'd // if (FfsHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) { Error (NULL, 0, 0, FileGuidString, "invalid fixed file checksum"); return EFI_ABORTED; } } #if (PI_SPECIFICATION_VERSION < 0x00010000) // // Check if the tail is present and verify it if it is. // if (FfsHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) { // // Verify tail is complement of integrity check field in the header. // Tail = (EFI_FFS_FILE_TAIL *) ((UINTN) FfsHeader + GetLength (FfsHeader->Size) - sizeof (EFI_FFS_FILE_TAIL)); if (FfsHeader->IntegrityCheck.TailReference != (EFI_FFS_FILE_TAIL)~(*Tail)) { Error (NULL, 0, 0, FileGuidString, "invalid FFS file tail"); return EFI_ABORTED; } } #endif return EFI_SUCCESS; }