Пример #1
0
/**
  Check the integrity of firmware volume header

  @param[in]  FwVolHeader   A pointer to a firmware volume header

  @retval     TRUE          The firmware volume is consistent
  @retval     FALSE         The firmware volume has corrupted.

**/
STATIC
BOOLEAN
IsFvHeaderValid (
  IN EFI_FIRMWARE_VOLUME_HEADER    *FwVolHeader
  )
{
  UINT16 Checksum;

  // Skip nv storage fv
  if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) {
    return FALSE;
  }

  if ( (FwVolHeader->Revision != EFI_FVH_REVISION)   ||
     (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
     (FwVolHeader->FvLength == ((UINTN) -1))       ||
     ((FwVolHeader->HeaderLength & 0x01 ) !=0) )  {
    return FALSE;
  }

  Checksum = CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength);
  if (Checksum != 0) {
    DEBUG (( DEBUG_ERROR,
              "ERROR - Invalid Firmware Volume Header Checksum, change 0x%04x to 0x%04x\r\n",
              FwVolHeader->Checksum,
              (UINT16)( Checksum + FwVolHeader->Checksum )));
    return FALSE;
  }

  return TRUE;
}
Пример #2
0
EFI_STATUS
GetFvbInfo (
  IN  UINT64                        FvLength,
  OUT EFI_FIRMWARE_VOLUME_HEADER    **FvbInfo
  )
{
  STATIC BOOLEAN Checksummed = FALSE;
  UINTN Index;

  if (!Checksummed) {
    for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO); Index += 1) {
      UINT16 Checksum;
      mPlatformFvbMediaInfo[Index].FvbInfo.Checksum = 0;
      Checksum = CalculateCheckSum16 (
                   (UINT16*) &mPlatformFvbMediaInfo[Index].FvbInfo,
                   mPlatformFvbMediaInfo[Index].FvbInfo.HeaderLength
                   );
      mPlatformFvbMediaInfo[Index].FvbInfo.Checksum = Checksum;
    }
    Checksummed = TRUE;
  }

  for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO); Index += 1) {
    if (mPlatformFvbMediaInfo[Index].FvLength == FvLength) {
      *FvbInfo = &mPlatformFvbMediaInfo[Index].FvbInfo;
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}
Пример #3
0
EFI_STATUS
ValidateFvHeader (
  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader
  )
/*++

Routine Description:
  Check the integrity of firmware volume header

Arguments:
  FwVolHeader           - A pointer to a firmware volume header

Returns:
  EFI_SUCCESS           - The firmware volume is consistent
  EFI_NOT_FOUND         - The firmware volume has corrupted. So it is not an FV

--*/
{
  //
  // 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 == ((UINTN) -1)) ||
      ((FwVolHeader->HeaderLength & 0x01) != 0)
      ) {
    return EFI_NOT_FOUND;
  }
  
  //
  // Verify the header checksum
  //
  if (CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength) != 0) {
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}
Пример #4
0
/**
  Check the integrity of firmware volume header

  @param[in]  FwVolHeader   A pointer to a firmware volume header

  @retval     TRUE          The firmware volume is consistent
  @retval     FALSE         The firmware volume has corrupted.

**/
STATIC
BOOLEAN
IsFvHeaderValid (
  IN       EFI_PHYSICAL_ADDRESS          FvBase,
  IN CONST EFI_FIRMWARE_VOLUME_HEADER    *FwVolHeader
  )
{
  UINT16 Checksum;

  if (FvBase == PcdGet32(PcdFlashNvStorageVariableBase)) {
    if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid, sizeof(EFI_GUID)) != 0 ) {
      return FALSE;
    }
  } else {
    if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) {
      return FALSE;
    }
  }
  if ((FwVolHeader->Revision != EFI_FVH_REVISION)   ||
       (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
       (FwVolHeader->FvLength == ((UINTN) -1))       ||
       ((FwVolHeader->HeaderLength & 0x01 ) !=0)) {
    return FALSE;
  }

  Checksum = CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength);
  if (Checksum != 0) {
    DEBUG (( DEBUG_ERROR,
              "ERROR - Invalid Firmware Volume Header Checksum, change 0x%04x to 0x%04x\r\n",
              FwVolHeader->Checksum,
              (UINT16)( Checksum + FwVolHeader->Checksum )));
    return FALSE;
  }

  return TRUE;
}
Пример #5
0
/**
  Initializes the FV Header and Variable Store Header
  to support variable operations.

  @param[in]  Ptr - Location to initialize the headers

**/
VOID
InitializeFvAndVariableStoreHeaders (
  IN  VOID   *Ptr
  )
{
  //
  // Templates for standard (non-authenticated) variable FV header
  //
  STATIC FVB_FV_HDR_AND_VARS_TEMPLATE FvAndVarTemplate = {
    { // EFI_FIRMWARE_VOLUME_HEADER FvHdr;
      // UINT8                     ZeroVector[16];
      { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },

      // EFI_GUID                  FileSystemGuid;
      EFI_SYSTEM_NV_DATA_FV_GUID,

      // UINT64                    FvLength;
      EMU_FVB_SIZE,

      // UINT32                    Signature;
      EFI_FVH_SIGNATURE,

      // EFI_FVB_ATTRIBUTES_2      Attributes;
      0x4feff,

      // UINT16                    HeaderLength;
      EMU_FV_HEADER_LENGTH,

      // UINT16                    Checksum;
      0,

      // UINT16                    ExtHeaderOffset;
      0,

      // UINT8                     Reserved[1];
      {0},

      // UINT8                     Revision;
      EFI_FVH_REVISION,

      // EFI_FV_BLOCK_MAP_ENTRY    BlockMap[1];
      { 
        {
          2, // UINT32 NumBlocks;
          EMU_FVB_BLOCK_SIZE  // UINT32 Length;
        }
      }
    },
    // EFI_FV_BLOCK_MAP_ENTRY     EndBlockMap;
    { 0, 0 }, // End of block map
    { // VARIABLE_STORE_HEADER      VarHdr;
      // EFI_GUID  Signature;
      EFI_VARIABLE_GUID,

      // UINT32  Size;
      (
        FixedPcdGet32 (PcdVariableStoreSize) -
        OFFSET_OF (FVB_FV_HDR_AND_VARS_TEMPLATE, VarHdr)
      ),

      // UINT8   Format;
      VARIABLE_STORE_FORMATTED,

      // UINT8   State;
      VARIABLE_STORE_HEALTHY,

      // UINT16  Reserved;
      0,

      // UINT32  Reserved1;
      0
    }
  };

  //
  // Templates for authenticated variable FV header
  //
  STATIC FVB_FV_HDR_AND_VARS_TEMPLATE FvAndAuthenticatedVarTemplate = {
    { // EFI_FIRMWARE_VOLUME_HEADER FvHdr;
      // UINT8                     ZeroVector[16];
      { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },

      // EFI_GUID                  FileSystemGuid;
      EFI_SYSTEM_NV_DATA_FV_GUID,

      // UINT64                    FvLength;
      EMU_FVB_SIZE,

      // UINT32                    Signature;
      EFI_FVH_SIGNATURE,

      // EFI_FVB_ATTRIBUTES_2      Attributes;
      0x4feff,

      // UINT16                    HeaderLength;
      EMU_FV_HEADER_LENGTH,

      // UINT16                    Checksum;
      0,

      // UINT16                    ExtHeaderOffset;
      0,

      // UINT8                     Reserved[1];
      {0},

      // UINT8                     Revision;
      EFI_FVH_REVISION,

      // EFI_FV_BLOCK_MAP_ENTRY    BlockMap[1];
      {
        {
          2, // UINT32 NumBlocks;
          EMU_FVB_BLOCK_SIZE  // UINT32 Length;
        }
      }
    },
    // EFI_FV_BLOCK_MAP_ENTRY     EndBlockMap;
    { 0, 0 }, // End of block map
    { // VARIABLE_STORE_HEADER      VarHdr;
        // EFI_GUID  Signature;     // need authenticated variables for secure boot
        EFI_AUTHENTICATED_VARIABLE_GUID,

      // UINT32  Size;
      (
        FixedPcdGet32 (PcdVariableStoreSize) -
        OFFSET_OF (FVB_FV_HDR_AND_VARS_TEMPLATE, VarHdr)
      ),

      // UINT8   Format;
      VARIABLE_STORE_FORMATTED,

      // UINT8   State;
      VARIABLE_STORE_HEALTHY,

      // UINT16  Reserved;
      0,

      // UINT32  Reserved1;
      0
    }
  };

  EFI_FIRMWARE_VOLUME_HEADER  *Fv;

  //
  // Copy the template structure into the location
  //
  if (FeaturePcdGet (PcdSecureBootEnable) == FALSE) {
    CopyMem (Ptr, (VOID*)&FvAndVarTemplate, sizeof (FvAndVarTemplate));
  } else {
    CopyMem (Ptr, (VOID*)&FvAndAuthenticatedVarTemplate, sizeof (FvAndAuthenticatedVarTemplate));
  }

  //
  // Update the checksum for the FV header
  //
  Fv = (EFI_FIRMWARE_VOLUME_HEADER*) Ptr;
  Fv->Checksum = CalculateCheckSum16 (Ptr, Fv->HeaderLength);
}
Пример #6
0
/**
  Initialises the FV Header and Variable Store Header
  to support variable operations.

  @param[in]  Ptr - Location to initialise the headers

**/
EFI_STATUS
InitializeFvAndVariableStoreHeaders (
  IN NOR_FLASH_INSTANCE *Instance
  )
{
  EFI_STATUS                          Status;
  VOID*                               Headers;
  UINTN                               HeadersLength;
  EFI_FIRMWARE_VOLUME_HEADER          *FirmwareVolumeHeader;
  VARIABLE_STORE_HEADER               *VariableStoreHeader;

  if (!Instance->Initialized && Instance->Initialize) {
    Instance->Initialize (Instance);
  }

  HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER);
  Headers = AllocateZeroPool(HeadersLength);

  // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous.
  ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase));
  ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase));

  // Check if the size of the area is at least one block size
  ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0));
  ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0));
  ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0));

  // Ensure the Variable area Base Addresses are aligned on a block size boundaries
  ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->Media.BlockSize == 0);
  ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->Media.BlockSize == 0);
  ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0);

  //
  // EFI_FIRMWARE_VOLUME_HEADER
  //
  FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers;
  CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid);
  FirmwareVolumeHeader->FvLength =
      PcdGet32(PcdFlashNvStorageVariableSize) +
      PcdGet32(PcdFlashNvStorageFtwWorkingSize) +
      PcdGet32(PcdFlashNvStorageFtwSpareSize);
  FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE;
  FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) (
                                          EFI_FVB2_READ_ENABLED_CAP   | // Reads may be enabled
                                          EFI_FVB2_READ_STATUS        | // Reads are currently enabled
                                          EFI_FVB2_STICKY_WRITE       | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
                                          EFI_FVB2_MEMORY_MAPPED      | // It is memory mapped
                                          EFI_FVB2_ERASE_POLARITY     | // After erasure all bits take this value (i.e. '1')
                                          EFI_FVB2_WRITE_STATUS       | // Writes are currently enabled
                                          EFI_FVB2_WRITE_ENABLED_CAP    // Writes may be enabled
                                      );
  FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY);
  FirmwareVolumeHeader->Revision = EFI_FVH_REVISION;
  FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->Media.LastBlock + 1;
  FirmwareVolumeHeader->BlockMap[0].Length      = Instance->Media.BlockSize;
  FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0;
  FirmwareVolumeHeader->BlockMap[1].Length      = 0;
  FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16*)FirmwareVolumeHeader,FirmwareVolumeHeader->HeaderLength);

  //
  // VARIABLE_STORE_HEADER
  //
  VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength);
  CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid);
  VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength;
  VariableStoreHeader->Format            = VARIABLE_STORE_FORMATTED;
  VariableStoreHeader->State             = VARIABLE_STORE_HEALTHY;

  // Install the combined super-header in the NorFlash
  Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers);

  FreePool (Headers);
  return Status;
}