Home | History | Annotate | Download | only in FwVol
      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