/** Check the integrity of firmware volume header. @param[in] FwVolHeader - A pointer to a firmware volume header @retval EFI_SUCCESS - The firmware volume is consistent @retval EFI_NOT_FOUND - The firmware volume has been corrupted. **/ EFI_STATUS ValidateFvHeader ( IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader ) { UINT16 Checksum; // // Verify the header revision, header signature, length // Length of FvBlock cannot be 2**64-1 // HeaderLength cannot be an odd number // if ((FwVolHeader->Revision != EFI_FVH_REVISION) || (FwVolHeader->Signature != EFI_FVH_SIGNATURE) || (FwVolHeader->FvLength != EMU_FVB_SIZE) || (FwVolHeader->HeaderLength != EMU_FV_HEADER_LENGTH) ) { DEBUG ((EFI_D_INFO, "EMU Variable FVB: Basic FV headers were invalid\n")); return EFI_NOT_FOUND; } // // Verify the header checksum // Checksum = CalculateSum16((VOID*) FwVolHeader, FwVolHeader->HeaderLength); if (Checksum != 0) { DEBUG ((EFI_D_INFO, "EMU Variable FVB: FV checksum was invalid\n")); return EFI_NOT_FOUND; } return EFI_SUCCESS; }
/** Check the integrity of firmware volume header. @param[in] FwVolHeader - A pointer to a firmware volume header @retval EFI_SUCCESS - The firmware volume is consistent @retval EFI_NOT_FOUND - The firmware volume has been corrupted. **/ EFI_STATUS ValidateFvHeader ( IN NOR_FLASH_INSTANCE *Instance ) { UINT16 Checksum; EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; VARIABLE_STORE_HEADER *VariableStoreHeader; UINTN VariableStoreLength; UINTN FvLength; FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Instance->RegionBaseAddress; FvLength = PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + PcdGet32(PcdFlashNvStorageFtwSpareSize); // // Verify the header revision, header signature, length // Length of FvBlock cannot be 2**64-1 // HeaderLength cannot be an odd number // if ( (FwVolHeader->Revision != EFI_FVH_REVISION) || (FwVolHeader->Signature != EFI_FVH_SIGNATURE) || (FwVolHeader->FvLength != FvLength) ) { DEBUG ((EFI_D_ERROR, "ValidateFvHeader: No Firmware Volume header present\n")); return EFI_NOT_FOUND; } // Check the Firmware Volume Guid if( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) { DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Firmware Volume Guid non-compatible\n")); return EFI_NOT_FOUND; } // Verify the header checksum Checksum = CalculateSum16((UINT16*)FwVolHeader, FwVolHeader->HeaderLength); if (Checksum != 0) { DEBUG ((EFI_D_ERROR, "ValidateFvHeader: FV checksum is invalid (Checksum:0x%X)\n",Checksum)); return EFI_NOT_FOUND; } VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)FwVolHeader + FwVolHeader->HeaderLength); // Check the Variable Store Guid if( CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) == FALSE ) { DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Variable Store Guid non-compatible\n")); return EFI_NOT_FOUND; } VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength; if (VariableStoreHeader->Size != VariableStoreLength) { DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Variable Store Length does not match\n")); return EFI_NOT_FOUND; } return EFI_SUCCESS; }
/** Verify checksum of the firmware volume header. @param FvHeader Points to the firmware volume header to be checked @retval TRUE Checksum verification passed @retval FALSE Checksum verification failed **/ BOOLEAN VerifyFvHeaderChecksum ( IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader ) { UINT16 Checksum; Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength); if (Checksum == 0) { return TRUE; } else { return FALSE; } }
// // will not parse compressed sections // EFI_STATUS VerifyFv ( IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader ) /*++ Routine Description: Verify the current pointer points to a valid FV header. Arguments: FvHeader Pointer to an alleged FV file. Returns: EFI_SUCCESS The FV header is valid. EFI_VOLUME_CORRUPTED The FV header is not valid. EFI_INVALID_PARAMETER A required parameter was NULL. EFI_ABORTED Operation aborted. --*/ { UINT16 Checksum; // // Verify input parameters // if (FvHeader == NULL) { return EFI_INVALID_PARAMETER; } if (FvHeader->Signature != EFI_FVH_SIGNATURE) { Error (NULL, 0, 0006, "invalid FV header signature", NULL); return EFI_VOLUME_CORRUPTED; } // // Verify header checksum // Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); if (Checksum != 0) { Error (NULL, 0, 0006, "invalid FV header checksum", NULL); return EFI_ABORTED; } return EFI_SUCCESS; }
/** Returns the two's complement checksum of all elements in a buffer of 16-bit values. This function first calculates the sum of the 16-bit values in the buffer specified by Buffer and Length. The carry bits in the result of addition are dropped. Then, the two's complement of the sum is returned. If Length is 0, then 0 is returned. If Buffer is NULL, then ASSERT(). If Buffer is not aligned on a 16-bit boundary, then ASSERT(). If Length is not aligned on a 16-bit boundary, then ASSERT(). If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). @param Buffer Pointer to the buffer to carry out the checksum operation. @param Length The size, in bytes, of Buffer. @return Checksum The 2's complement checksum of Buffer. **/ UINT16 EFIAPI CalculateCheckSum16 ( IN CONST UINT16 *Buffer, IN UINTN Length ) { UINT16 CheckSum; CheckSum = CalculateSum16 (Buffer, Length); // // Return the checksum based on 2's complement. // return (UINT16) (0x10000 - CheckSum); }
UINT16 CalculateChecksum16 ( IN UINT16 *Buffer, IN UINTN Size ) /*++ Routine Description:: This function calculates the value needed for a valid UINT16 checksum Arguments: Buffer Pointer to buffer containing byte data of component. Size Size of the buffer Returns: The 16 bit checksum value needed. --*/ { return (UINT16) (0x10000 - CalculateSum16 (Buffer, Size)); }