1 /** @file 2 FFS file access utilities. 3 4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 16 #include "DxeMain.h" 17 #include "FwVolDriver.h" 18 19 20 /** 21 Get the FFS file state by checking the highest bit set in the header's state field. 22 23 @param ErasePolarity Erase polarity attribute of the firmware volume 24 @param FfsHeader Points to the FFS file header 25 26 @return FFS File state 27 28 **/ 29 EFI_FFS_FILE_STATE 30 GetFileState ( 31 IN UINT8 ErasePolarity, 32 IN EFI_FFS_FILE_HEADER *FfsHeader 33 ) 34 { 35 EFI_FFS_FILE_STATE FileState; 36 UINT8 HighestBit; 37 38 FileState = FfsHeader->State; 39 40 if (ErasePolarity != 0) { 41 FileState = (EFI_FFS_FILE_STATE)~FileState; 42 } 43 44 HighestBit = 0x80; 45 while (HighestBit != 0 && ((HighestBit & FileState) == 0)) { 46 HighestBit >>= 1; 47 } 48 49 return (EFI_FFS_FILE_STATE) HighestBit; 50 } 51 52 53 54 /** 55 Check if a block of buffer is erased. 56 57 @param ErasePolarity Erase polarity attribute of the firmware volume 58 @param InBuffer The buffer to be checked 59 @param BufferSize Size of the buffer in bytes 60 61 @retval TRUE The block of buffer is erased 62 @retval FALSE The block of buffer is not erased 63 64 **/ 65 BOOLEAN 66 IsBufferErased ( 67 IN UINT8 ErasePolarity, 68 IN VOID *InBuffer, 69 IN UINTN BufferSize 70 ) 71 { 72 UINTN Count; 73 UINT8 EraseByte; 74 UINT8 *Buffer; 75 76 if(ErasePolarity == 1) { 77 EraseByte = 0xFF; 78 } else { 79 EraseByte = 0; 80 } 81 82 Buffer = InBuffer; 83 for (Count = 0; Count < BufferSize; Count++) { 84 if (Buffer[Count] != EraseByte) { 85 return FALSE; 86 } 87 } 88 89 return TRUE; 90 } 91 92 93 94 /** 95 Verify checksum of the firmware volume header. 96 97 @param FvHeader Points to the firmware volume header to be checked 98 99 @retval TRUE Checksum verification passed 100 @retval FALSE Checksum verification failed 101 102 **/ 103 BOOLEAN 104 VerifyFvHeaderChecksum ( 105 IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader 106 ) 107 { 108 UINT16 Checksum; 109 110 Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength); 111 112 if (Checksum == 0) { 113 return TRUE; 114 } else { 115 return FALSE; 116 } 117 } 118 119 120 /** 121 Verify checksum of the FFS file header. 122 123 @param FfsHeader Points to the FFS file header to be checked 124 125 @retval TRUE Checksum verification passed 126 @retval FALSE Checksum verification failed 127 128 **/ 129 BOOLEAN 130 VerifyHeaderChecksum ( 131 IN EFI_FFS_FILE_HEADER *FfsHeader 132 ) 133 { 134 UINT8 HeaderChecksum; 135 136 if (IS_FFS_FILE2 (FfsHeader)) { 137 HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER2)); 138 } else { 139 HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER)); 140 } 141 HeaderChecksum = (UINT8) (HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File); 142 143 if (HeaderChecksum == 0) { 144 return TRUE; 145 } else { 146 return FALSE; 147 } 148 } 149 150 151 152 /** 153 Check if it's a valid FFS file header. 154 155 @param ErasePolarity Erase polarity attribute of the firmware volume 156 @param FfsHeader Points to the FFS file header to be checked 157 @param FileState FFS file state to be returned 158 159 @retval TRUE Valid FFS file header 160 @retval FALSE Invalid FFS file header 161 162 **/ 163 BOOLEAN 164 IsValidFfsHeader ( 165 IN UINT8 ErasePolarity, 166 IN EFI_FFS_FILE_HEADER *FfsHeader, 167 OUT EFI_FFS_FILE_STATE *FileState 168 ) 169 { 170 *FileState = GetFileState (ErasePolarity, FfsHeader); 171 172 switch (*FileState) { 173 case EFI_FILE_HEADER_VALID: 174 case EFI_FILE_DATA_VALID: 175 case EFI_FILE_MARKED_FOR_UPDATE: 176 case EFI_FILE_DELETED: 177 // 178 // Here we need to verify header checksum 179 // 180 return VerifyHeaderChecksum (FfsHeader); 181 182 case EFI_FILE_HEADER_CONSTRUCTION: 183 case EFI_FILE_HEADER_INVALID: 184 default: 185 return FALSE; 186 } 187 } 188 189 190 /** 191 Check if it's a valid FFS file. 192 Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first. 193 194 @param ErasePolarity Erase polarity attribute of the firmware volume 195 @param FfsHeader Points to the FFS file to be checked 196 197 @retval TRUE Valid FFS file 198 @retval FALSE Invalid FFS file 199 200 **/ 201 BOOLEAN 202 IsValidFfsFile ( 203 IN UINT8 ErasePolarity, 204 IN EFI_FFS_FILE_HEADER *FfsHeader 205 ) 206 { 207 EFI_FFS_FILE_STATE FileState; 208 UINT8 DataCheckSum; 209 210 FileState = GetFileState (ErasePolarity, FfsHeader); 211 switch (FileState) { 212 213 case EFI_FILE_DELETED: 214 case EFI_FILE_DATA_VALID: 215 case EFI_FILE_MARKED_FOR_UPDATE: 216 DataCheckSum = FFS_FIXED_CHECKSUM; 217 if ((FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) { 218 if (IS_FFS_FILE2 (FfsHeader)) { 219 DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2), FFS_FILE2_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER2)); 220 } else { 221 DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER), FFS_FILE_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER)); 222 } 223 } 224 if (FfsHeader->IntegrityCheck.Checksum.File == DataCheckSum) { 225 return TRUE; 226 } 227 228 default: 229 return FALSE; 230 } 231 } 232 233 234