SignedCapsulePkg: Remove package

SignedCapsulePkg is no longer used. The features provided by this
package have been superseded by FmpDevicePkg.

Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
This commit is contained in:
Michael D Kinney 2026-05-01 11:11:48 -07:00 committed by mergify[bot]
parent 6d4e973807
commit c00e8d0bcd
34 changed files with 0 additions and 6784 deletions

View file

@ -1,143 +0,0 @@
/** @file
Guid & data structure used for Delivering Capsules Containing Updates to
EDKII System Firmware Management Protocol
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#pragma once
/**
@verbatim
1. Capsule Layout is below:
+------------------------------------------+
| Capsule Header (OPTIONAL, WFU) | <== ESRT.FwClass (Optional)
+------------------------------------------+
| FMP Capsule Header | <== EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID
+------------------------------------------+
| FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER | <== PcdSystemFmpCapsuleImageTypeIdGuid
+------------------------------------------+
| EFI_FIRMWARE_IMAGE_AUTHENTICATION |
+------------------------------------------+
| FMP Payload |
+------------------------------------------+
2. System FMP Payload is below:
+------------------------------------------+
| EFI_FIRMWARE_VOLUME |
| +------------------------------------+ |
| | FFS (Configure File) | | <== gEdkiiSystemFmpCapsuleConfigFileGuid
| +------------------------------------+ |
| | FFS (Driver FV) | | <== gEdkiiSystemFmpCapsuleDriverFvFileGuid
| +------------------------------------+ |
| | FFS (System Firmware Image) | | <== PcdEdkiiSystemFirmwareFileGuid
| | +------------------------------+ | |
| | | FV Recovery | | |
| | |------------------------------| | |
| | | FV Main | | |
| | +------------------------------+ | |
| +------------------------------------+ |
+------------------------------------------+
NOTE: There might be multiple FFS (System Firmware Image) exist in the System FMP Capsule.
Only the one, whose FFS GUID matches PcdEdkiiSystemFirmwareFileGuid, takes effect.
The other FFS is ignored.
3. The format of the recovery configuration is below:
[Head]
NumOfRecovery = <Num> # Decimal
Recovery0 = <Name1> # String
Recovery1 = <Name2> # String
Recovery<Num-1> = <NameX> # String
[Name?]
Length = <Length> # Fv Length (HEX)
ImageOffset = <ImageOffset> # Fv offset of this SystemFirmware image (HEX)
FileGuid = XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX # PcdEdkiiSystemFirmwareFileGuid
NOTE: The [Name?] entry may have different FileGuid.
Only the one, whose FileGuid matches PcdEdkiiSystemFirmwareFileGuid, takes effect.
The other entry is ignored.
4. The format of the capsule update configuration is below:
[Head]
NumOfUpdate = <Num> # Decimal
Update0 = <Name1> # String
Update1 = <Name2> # String
Update<Num-1> = <NameX> # String
[Name?]
FirmwareType = 0 # 0 - SystemFirmware, 1 - NvRam
AddressType = 0 # 0 - relative address, 1 - absolute address.
BaseAddress = <BaseAddress> # Base address offset on flash (HEX)
Length = <Length> # Image Length (HEX)
ImageOffset = <ImageOffset> # Image offset of this SystemFirmware image (HEX)
FileGuid = XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX # PcdEdkiiSystemFirmwareFileGuid
NOTE: The [Name?] entry may have different FileGuid.
Only the one, whose FileGuid matches PcdEdkiiSystemFirmwareFileGuid, takes effect.
The other entry is ignored.
@endverbatim
**/
#define EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR_SIGNATURE SIGNATURE_32('S', 'F', 'I', 'D')
#pragma pack(1)
typedef struct {
UINT32 Signature;
UINT32 HeaderLength; // Length of EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR, excluding NameString
UINT32 Length; // Length of the data structure, including NameString
// Below structure is similar as UEFI EFI_FIRMWARE_MANAGEMENT_PROTOCOL.GetPackageInfo()
UINT32 PackageVersion;
UINT32 PackageVersionNameStringOffset; // Offset from head, CHAR16 string including NULL terminate char
// Below structure is similar as UEFI EFI_FIRMWARE_IMAGE_DESCRIPTOR
UINT8 ImageIndex;
UINT8 Reserved[3];
EFI_GUID ImageTypeId;
UINT64 ImageId;
UINT32 ImageIdNameStringOffset; // Offset from head, CHAR16 string including NULL terminate char
UINT32 Version;
UINT32 VersionNameStringOffset; // Offset from head, CHAR16 string including NULL terminate char
UINT8 Reserved2[4];
UINT64 Size;
UINT64 AttributesSupported;
UINT64 AttributesSetting;
UINT64 Compatibilities;
UINT32 LowestSupportedImageVersion;
UINT32 LastAttemptVersion;
UINT32 LastAttemptStatus;
UINT8 Reserved3[4];
UINT64 HardwareInstance;
// real string data
// CHAR16 ImageIdNameStr[]; // CHAR16 string including NULL terminate char
// CHAR16 VersionNameStr[]; // CHAR16 string including NULL terminate char
// CHAR16 PackageVersionNameStr[]; // CHAR16 string including NULL terminate char
} EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR;
#pragma pack()
/**
@verbatim
System Firmware Image Descriptor is below:
+----------------------+
| System Firmware (FV) |
|+--------------------+|
|| FFS (Freeform) || <== gEdkiiSystemFirmwareImageDescriptorFileGuid
||+------------------+||
||| SECTION (RAW) |||
||| System Firmware |||
||| Image Descriptor |||
||+------------------+||
|+--------------------+|
| |
| |
+----------------------+
@endverbatim
**/
extern EFI_GUID gEdkiiSystemFirmwareImageDescriptorFileGuid;
extern EFI_GUID gEdkiiSystemFmpCapsuleConfigFileGuid;
extern EFI_GUID gEdkiiSystemFmpCapsuleDriverFvFileGuid;

View file

@ -1,143 +0,0 @@
/** @file
EDKII System Capsule library.
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#pragma once
#include <Guid/EdkiiSystemFmpCapsule.h>
/**
Extract ImageFmpInfo from system firmware.
@param[in] SystemFirmwareImage The System Firmware image.
@param[in] SystemFirmwareImageSize The size of the System Firmware image in bytes.
@param[out] ImageFmpInfo The ImageFmpInfo.
@param[out] ImageFmpInfoSize The size of the ImageFmpInfo in bytes.
@retval TRUE The ImageFmpInfo is extracted.
@retval FALSE The ImageFmpInfo is not extracted.
**/
BOOLEAN
EFIAPI
ExtractSystemFirmwareImageFmpInfo (
IN VOID *SystemFirmwareImage,
IN UINTN SystemFirmwareImageSize,
OUT EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR **ImageFmpInfo,
OUT UINTN *ImageFmpInfoSize
);
/**
Extract the driver FV from an authenticated image.
@param[in] AuthenticatedImage The authenticated capsule image.
@param[in] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
@param[out] DriverFvImage The driver FV image.
@param[out] DriverFvImageSize The size of the driver FV image in bytes.
@retval TRUE The driver Fv is extracted.
@retval FALSE The driver Fv is not extracted.
**/
BOOLEAN
EFIAPI
ExtractDriverFvImage (
IN VOID *AuthenticatedImage,
IN UINTN AuthenticatedImageSize,
OUT VOID **DriverFvImage,
OUT UINTN *DriverFvImageSize
);
/**
Extract the config image from an authenticated image.
@param[in] AuthenticatedImage The authenticated capsule image.
@param[in] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
@param[out] ConfigImage The config image.
@param[out] ConfigImageSize The size of the config image in bytes.
@retval TRUE The config image is extracted.
@retval FALSE The config image is not extracted.
**/
BOOLEAN
EFIAPI
ExtractConfigImage (
IN VOID *AuthenticatedImage,
IN UINTN AuthenticatedImageSize,
OUT VOID **ConfigImage,
OUT UINTN *ConfigImageSize
);
/**
Extract the System Firmware image from an authenticated image.
@param[in] AuthenticatedImage The authenticated capsule image.
@param[in] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
@param[out] SystemFirmwareImage The System Firmware image.
@param[out] SystemFirmwareImageSize The size of the System Firmware image in bytes.
@retval TRUE The System Firmware image is extracted.
@retval FALSE The System Firmware image is not extracted.
**/
BOOLEAN
EFIAPI
ExtractSystemFirmwareImage (
IN VOID *AuthenticatedImage,
IN UINTN AuthenticatedImageSize,
OUT VOID **SystemFirmwareImage,
OUT UINTN *SystemFirmwareImageSize
);
/**
Extract the authenticated image from an FMP capsule image.
@param[in] Image The FMP capsule image, including EFI_FIRMWARE_IMAGE_AUTHENTICATION.
@param[in] ImageSize The size of FMP capsule image in bytes.
@param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] AuthenticatedImage The authenticated capsule image, excluding EFI_FIRMWARE_IMAGE_AUTHENTICATION.
@param[out] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
@retval TRUE The authenticated image is extracted.
@retval FALSE The authenticated image is not extracted.
**/
BOOLEAN
EFIAPI
ExtractAuthenticatedImage (
IN VOID *Image,
IN UINTN ImageSize,
OUT UINT32 *LastAttemptStatus,
OUT VOID **AuthenticatedImage,
OUT UINTN *AuthenticatedImageSize
);
/**
Authenticated system firmware FMP capsule image.
Caution: This function may receive untrusted input.
@param[in] Image The FMP capsule image, including EFI_FIRMWARE_IMAGE_AUTHENTICATION.
@param[in] ImageSize The size of FMP capsule image in bytes.
@param[in] ForceVersionMatch TRUE: The version of capsule must be as same as the version of current image.
FALSE: The version of capsule must be as same as greater than the lowest
supported version of current image.
@param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] AuthenticatedImage The authenticated capsule image, excluding EFI_FIRMWARE_IMAGE_AUTHENTICATION.
@param[out] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
@retval TRUE Authentication passes and the authenticated image is extracted.
@retval FALSE Authentication fails and the authenticated image is not extracted.
**/
EFI_STATUS
EFIAPI
CapsuleAuthenticateSystemFirmware (
IN VOID *Image,
IN UINTN ImageSize,
IN BOOLEAN ForceVersionMatch,
OUT UINT32 *LastAttemptVersion,
OUT UINT32 *LastAttemptStatus,
OUT VOID **AuthenticatedImage,
OUT UINTN *AuthenticatedImageSize
);

View file

@ -1,155 +0,0 @@
/** @file
INI configuration parsing library.
The INI file format is:
================
[SectionName]
EntryName=EntryValue
================
Where:
1) SectionName is an ASCII string. The valid format is [A-Za-z0-9_]+
2) EntryName is an ASCII string. The valid format is [A-Za-z0-9_]+
3) EntryValue can be:
3.1) an ASCII String. The valid format is [A-Za-z0-9_]+
3.2) a GUID. The valid format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, where x is [A-Fa-f0-9]
3.3) a decimal value. The valid format is [0-9]+
3.4) a hexadecimal value. The valid format is 0x[A-Fa-f0-9]+
4) '#' or ';' can be used as comment at anywhere.
5) TAB(0x20) or SPACE(0x9) can be used as separator.
6) LF(\n, 0xA) or CR(\r, 0xD) can be used as line break.
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#pragma once
/**
Open an INI config file and return a context.
@param[in] DataBuffer Config raw file buffer.
@param[in] BufferSize Size of raw buffer.
@return Config data buffer is opened and context is returned.
@retval NULL No enough memory is allocated.
@retval NULL Config data buffer is invalid.
**/
VOID *
EFIAPI
OpenIniFile (
IN UINT8 *DataBuffer,
IN UINTN BufferSize
);
/**
Get section entry string value.
@param[in] Context INI Config file context.
@param[in] SectionName Section name.
@param[in] EntryName Section entry name.
@param[out] EntryValue Point to the got entry string value.
@retval EFI_SUCCESS Section entry string value is got.
@retval EFI_NOT_FOUND Section is not found.
**/
EFI_STATUS
EFIAPI
GetStringFromDataFile (
IN VOID *Context,
IN CHAR8 *SectionName,
IN CHAR8 *EntryName,
OUT CHAR8 **EntryValue
);
/**
Get section entry GUID value.
@param[in] Context INI Config file context.
@param[in] SectionName Section name.
@param[in] EntryName Section entry name.
@param[out] Guid Point to the got GUID value.
@retval EFI_SUCCESS Section entry GUID value is got.
@retval EFI_NOT_FOUND Section is not found.
**/
EFI_STATUS
EFIAPI
GetGuidFromDataFile (
IN VOID *Context,
IN CHAR8 *SectionName,
IN CHAR8 *EntryName,
OUT EFI_GUID *Guid
);
/**
Get section entry decimal UINTN value.
@param[in] Context INI Config file context.
@param[in] SectionName Section name.
@param[in] EntryName Section entry name.
@param[out] Data Point to the got decimal UINTN value.
@retval EFI_SUCCESS Section entry decimal UINTN value is got.
@retval EFI_NOT_FOUND Section is not found.
**/
EFI_STATUS
EFIAPI
GetDecimalUintnFromDataFile (
IN VOID *Context,
IN CHAR8 *SectionName,
IN CHAR8 *EntryName,
OUT UINTN *Data
);
/**
Get section entry hexadecimal UINTN value.
@param[in] Context INI Config file context.
@param[in] SectionName Section name.
@param[in] EntryName Section entry name.
@param[out] Data Point to the got hexadecimal UINTN value.
@retval EFI_SUCCESS Section entry hexadecimal UINTN value is got.
@retval EFI_NOT_FOUND Section is not found.
**/
EFI_STATUS
EFIAPI
GetHexUintnFromDataFile (
IN VOID *Context,
IN CHAR8 *SectionName,
IN CHAR8 *EntryName,
OUT UINTN *Data
);
/**
Get section entry hexadecimal UINT64 value.
@param[in] Context INI Config file context.
@param[in] SectionName Section name.
@param[in] EntryName Section entry name.
@param[out] Data Point to the got hexadecimal UINT64 value.
@retval EFI_SUCCESS Section entry hexadecimal UINT64 value is got.
@retval EFI_NOT_FOUND Section is not found.
**/
EFI_STATUS
EFIAPI
GetHexUint64FromDataFile (
IN VOID *Context,
IN CHAR8 *SectionName,
IN CHAR8 *EntryName,
OUT UINT64 *Data
);
/**
Close an INI config file and free the context.
@param[in] Context INI Config file context.
**/
VOID
EFIAPI
CloseIniFile (
IN VOID *Context
);

View file

@ -1,92 +0,0 @@
/** @file
Platform flash device access library.
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#pragma once
#include <Protocol/FirmwareManagement.h>
typedef enum {
FlashAddressTypeRelativeAddress,
FlashAddressTypeAbsoluteAddress,
} FLASH_ADDRESS_TYPE;
//
// Type 0 ~ 0x7FFFFFFF is defined in this library.
// Type 0x80000000 ~ 0xFFFFFFFF is reserved for OEM.
//
typedef enum {
PlatformFirmwareTypeSystemFirmware,
PlatformFirmwareTypeNvRam,
} PLATFORM_FIRMWARE_TYPE;
/**
Perform flash write operation.
@param[in] FirmwareType The type of firmware.
@param[in] FlashAddress The address of flash device to be accessed.
@param[in] FlashAddressType The type of flash device address.
@param[in] Buffer The pointer to the data buffer.
@param[in] Length The length of data buffer in bytes.
@retval EFI_SUCCESS The operation returns successfully.
@retval EFI_WRITE_PROTECTED The flash device is read only.
@retval EFI_UNSUPPORTED The flash device access is unsupported.
@retval EFI_INVALID_PARAMETER The input parameter is not valid.
**/
EFI_STATUS
EFIAPI
PerformFlashWrite (
IN PLATFORM_FIRMWARE_TYPE FirmwareType,
IN EFI_PHYSICAL_ADDRESS FlashAddress,
IN FLASH_ADDRESS_TYPE FlashAddressType,
IN VOID *Buffer,
IN UINTN Length
);
/**
Perform flash write operation with progress indicator. The start and end
completion percentage values are passed into this function. If the requested
flash write operation is broken up, then completion percentage between the
start and end values may be passed to the provided Progress function. The
caller of this function is required to call the Progress function for the
start and end completion percentage values. This allows the Progress,
StartPercentage, and EndPercentage parameters to be ignored if the requested
flash write operation can not be broken up
@param[in] FirmwareType The type of firmware.
@param[in] FlashAddress The address of flash device to be accessed.
@param[in] FlashAddressType The type of flash device address.
@param[in] Buffer The pointer to the data buffer.
@param[in] Length The length of data buffer in bytes.
@param[in] Progress A function used report the progress of the
firmware update. This is an optional parameter
that may be NULL.
@param[in] StartPercentage The start completion percentage value that may
be used to report progress during the flash
write operation.
@param[in] EndPercentage The end completion percentage value that may
be used to report progress during the flash
write operation.
@retval EFI_SUCCESS The operation returns successfully.
@retval EFI_WRITE_PROTECTED The flash device is read only.
@retval EFI_UNSUPPORTED The flash device access is unsupported.
@retval EFI_INVALID_PARAMETER The input parameter is not valid.
**/
EFI_STATUS
EFIAPI
PerformFlashWriteWithProgress (
IN PLATFORM_FIRMWARE_TYPE FirmwareType,
IN EFI_PHYSICAL_ADDRESS FlashAddress,
IN FLASH_ADDRESS_TYPE FlashAddressType,
IN VOID *Buffer,
IN UINTN Length,
IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress OPTIONAL,
IN UINTN StartPercentage,
IN UINTN EndPercentage
);

View file

@ -1,773 +0,0 @@
/** @file
EDKII System Capsule library.
EDKII System Capsule library instance.
CapsuleAuthenticateSystemFirmware(), ExtractAuthenticatedImage() will receive
untrusted input and do basic validation.
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiDxe.h>
#include <Guid/SystemResourceTable.h>
#include <Guid/FirmwareContentsSigned.h>
#include <Guid/WinCertificate.h>
#include <Guid/EdkiiSystemFmpCapsule.h>
#include <Guid/WinCertificate.h>
#include <Guid/ImageAuthentication.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/EdkiiSystemCapsuleLib.h>
#include <Library/FmpAuthenticationLib.h>
#include <Protocol/FirmwareManagement.h>
EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR *mImageFmpInfo;
UINTN mImageFmpInfoSize;
EFI_GUID mEdkiiSystemFirmwareFileGuid;
/**
Check if a block of buffer is erased.
@param[in] ErasePolarity Erase polarity attribute of the firmware volume
@param[in] InBuffer The buffer to be checked
@param[in] BufferSize Size of the buffer in bytes
@retval TRUE The block of buffer is erased
@retval FALSE The block of buffer is not erased
**/
BOOLEAN
IsBufferErased (
IN UINT8 ErasePolarity,
IN VOID *InBuffer,
IN UINTN BufferSize
)
{
UINTN Count;
UINT8 EraseByte;
UINT8 *Buffer;
if (ErasePolarity == 1) {
EraseByte = 0xFF;
} else {
EraseByte = 0;
}
Buffer = InBuffer;
for (Count = 0; Count < BufferSize; Count++) {
if (Buffer[Count] != EraseByte) {
return FALSE;
}
}
return TRUE;
}
/**
Get Section buffer pointer by SectionType and SectionInstance.
@param[in] SectionBuffer The buffer of section
@param[in] SectionBufferSize The size of SectionBuffer in bytes
@param[in] SectionType The SectionType of Section to be found
@param[in] SectionInstance The Instance of Section to be found
@param[out] OutSectionBuffer The section found, including SECTION_HEADER
@param[out] OutSectionSize The size of section found, including SECTION_HEADER
@retval TRUE The FFS buffer is found.
@retval FALSE The FFS buffer is not found.
**/
BOOLEAN
GetSectionByType (
IN VOID *SectionBuffer,
IN UINT32 SectionBufferSize,
IN EFI_SECTION_TYPE SectionType,
IN UINTN SectionInstance,
OUT VOID **OutSectionBuffer,
OUT UINTN *OutSectionSize
)
{
EFI_COMMON_SECTION_HEADER *SectionHeader;
UINTN SectionSize;
UINTN Instance;
DEBUG ((DEBUG_INFO, "GetSectionByType - Buffer: 0x%08x - 0x%08x\n", SectionBuffer, SectionBufferSize));
//
// Find Section
//
SectionHeader = SectionBuffer;
Instance = 0;
while ((UINTN)SectionHeader < (UINTN)SectionBuffer + SectionBufferSize) {
DEBUG ((DEBUG_INFO, "GetSectionByType - Section: 0x%08x\n", SectionHeader));
if (IS_SECTION2 (SectionHeader)) {
SectionSize = SECTION2_SIZE (SectionHeader);
} else {
SectionSize = SECTION_SIZE (SectionHeader);
}
if (SectionHeader->Type == SectionType) {
if (Instance == SectionInstance) {
*OutSectionBuffer = (UINT8 *)SectionHeader;
*OutSectionSize = SectionSize;
DEBUG ((DEBUG_INFO, "GetSectionByType - 0x%x - 0x%x\n", *OutSectionBuffer, *OutSectionSize));
return TRUE;
} else {
DEBUG ((DEBUG_INFO, "GetSectionByType - find section instance %x\n", Instance));
Instance++;
}
} else {
//
// Skip other section type
//
DEBUG ((DEBUG_INFO, "GetSectionByType - other section type 0x%x\n", SectionHeader->Type));
}
//
// Next Section
//
SectionHeader = (EFI_COMMON_SECTION_HEADER *)((UINTN)SectionHeader + ALIGN_VALUE (SectionSize, 4));
}
return FALSE;
}
/**
Get FFS buffer pointer by FileName GUID and FileType.
@param[in] FdStart The System Firmware FD image
@param[in] FdSize The size of System Firmware FD image
@param[in] FileName The FileName GUID of FFS to be found
@param[in] Type The FileType of FFS to be found
@param[out] OutFfsBuffer The FFS buffer found, including FFS_FILE_HEADER
@param[out] OutFfsBufferSize The size of FFS buffer found, including FFS_FILE_HEADER
@retval TRUE The FFS buffer is found.
@retval FALSE The FFS buffer is not found.
**/
BOOLEAN
GetFfsByName (
IN VOID *FdStart,
IN UINTN FdSize,
IN EFI_GUID *FileName,
IN EFI_FV_FILETYPE Type,
OUT VOID **OutFfsBuffer,
OUT UINTN *OutFfsBufferSize
)
{
UINTN FvSize;
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;
EFI_FFS_FILE_HEADER *FfsHeader;
UINT32 FfsSize;
UINTN TestLength;
BOOLEAN FvFound;
DEBUG ((DEBUG_INFO, "GetFfsByName - FV: 0x%08x - 0x%08x\n", (UINTN)FdStart, (UINTN)FdSize));
FvFound = FALSE;
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FdStart;
while ((UINTN)FvHeader < (UINTN)FdStart + FdSize - 1) {
FvSize = (UINTN)FdStart + FdSize - (UINTN)FvHeader;
if (FvHeader->Signature != EFI_FVH_SIGNATURE) {
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvHeader + SIZE_4KB);
continue;
}
DEBUG ((DEBUG_INFO, "checking FV....0x%08x - 0x%x\n", FvHeader, FvHeader->FvLength));
FvFound = TRUE;
if (FvHeader->FvLength > FvSize) {
DEBUG ((DEBUG_ERROR, "GetFfsByName - FvSize: 0x%08x, MaxSize - 0x%08x\n", (UINTN)FvHeader->FvLength, (UINTN)FvSize));
return FALSE;
}
FvSize = (UINTN)FvHeader->FvLength;
//
// Find FFS
//
if (FvHeader->ExtHeaderOffset != 0) {
FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FvHeader + FvHeader->ExtHeaderOffset);
FfsHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FvExtHeader + FvExtHeader->ExtHeaderSize);
} else {
FfsHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FvHeader + FvHeader->HeaderLength);
}
FfsHeader = (EFI_FFS_FILE_HEADER *)((UINTN)FvHeader + ALIGN_VALUE ((UINTN)FfsHeader - (UINTN)FvHeader, 8));
while ((UINTN)FfsHeader < (UINTN)FvHeader + FvSize - 1) {
DEBUG ((DEBUG_INFO, "GetFfsByName - FFS: 0x%08x\n", FfsHeader));
TestLength = (UINTN)((UINTN)FvHeader + FvSize - (UINTN)FfsHeader);
if (TestLength > sizeof (EFI_FFS_FILE_HEADER)) {
TestLength = sizeof (EFI_FFS_FILE_HEADER);
}
if (IsBufferErased (1, FfsHeader, TestLength)) {
break;
}
if (IS_FFS_FILE2 (FfsHeader)) {
FfsSize = FFS_FILE2_SIZE (FfsHeader);
} else {
FfsSize = FFS_FILE_SIZE (FfsHeader);
}
if (CompareGuid (FileName, &FfsHeader->Name) &&
((Type == EFI_FV_FILETYPE_ALL) || (FfsHeader->Type == Type)))
{
*OutFfsBuffer = FfsHeader;
*OutFfsBufferSize = FfsSize;
return TRUE;
} else {
//
// Any other type is not allowed
//
DEBUG ((DEBUG_INFO, "GetFfsByName - other FFS type 0x%x, name %g\n", FfsHeader->Type, &FfsHeader->Name));
}
//
// Next File
//
FfsHeader = (EFI_FFS_FILE_HEADER *)((UINTN)FfsHeader + ALIGN_VALUE (FfsSize, 8));
}
//
// Next FV
//
FvHeader = (VOID *)(UINTN)((UINTN)FvHeader + FvHeader->FvLength);
}
if (!FvFound) {
DEBUG ((DEBUG_ERROR, "GetFfsByName - NO FV Found\n"));
}
return FALSE;
}
/**
Extract the driver FV from an authenticated image.
@param[in] AuthenticatedImage The authenticated capsule image.
@param[in] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
@param[out] DriverFvImage The driver FV image.
@param[out] DriverFvImageSize The size of the driver FV image in bytes.
@retval TRUE The driver Fv is extracted.
@retval FALSE The driver Fv is not extracted.
**/
BOOLEAN
EFIAPI
ExtractDriverFvImage (
IN VOID *AuthenticatedImage,
IN UINTN AuthenticatedImageSize,
OUT VOID **DriverFvImage,
OUT UINTN *DriverFvImageSize
)
{
BOOLEAN Result;
UINT32 FileHeaderSize;
*DriverFvImage = NULL;
*DriverFvImageSize = 0;
Result = GetFfsByName (AuthenticatedImage, AuthenticatedImageSize, &gEdkiiSystemFmpCapsuleDriverFvFileGuid, EFI_FV_FILETYPE_RAW, DriverFvImage, DriverFvImageSize);
if (!Result) {
return FALSE;
}
if (IS_FFS_FILE2 (*DriverFvImage)) {
FileHeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
} else {
FileHeaderSize = sizeof (EFI_FFS_FILE_HEADER);
}
*DriverFvImage = (UINT8 *)*DriverFvImage + FileHeaderSize;
*DriverFvImageSize = *DriverFvImageSize - FileHeaderSize;
return Result;
}
/**
Extract the config image from an authenticated image.
@param[in] AuthenticatedImage The authenticated capsule image.
@param[in] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
@param[out] ConfigImage The config image.
@param[out] ConfigImageSize The size of the config image in bytes.
@retval TRUE The config image is extracted.
@retval FALSE The config image is not extracted.
**/
BOOLEAN
EFIAPI
ExtractConfigImage (
IN VOID *AuthenticatedImage,
IN UINTN AuthenticatedImageSize,
OUT VOID **ConfigImage,
OUT UINTN *ConfigImageSize
)
{
BOOLEAN Result;
UINT32 FileHeaderSize;
*ConfigImage = NULL;
*ConfigImageSize = 0;
Result = GetFfsByName (AuthenticatedImage, AuthenticatedImageSize, &gEdkiiSystemFmpCapsuleConfigFileGuid, EFI_FV_FILETYPE_RAW, ConfigImage, ConfigImageSize);
if (!Result) {
return FALSE;
}
if (IS_FFS_FILE2 (*ConfigImage)) {
FileHeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
} else {
FileHeaderSize = sizeof (EFI_FFS_FILE_HEADER);
}
*ConfigImage = (UINT8 *)*ConfigImage + FileHeaderSize;
*ConfigImageSize = *ConfigImageSize - FileHeaderSize;
return Result;
}
/**
Extract the authenticated image from an FMP capsule image.
Caution: This function may receive untrusted input.
@param[in] Image The FMP capsule image, including EFI_FIRMWARE_IMAGE_AUTHENTICATION.
@param[in] ImageSize The size of FMP capsule image in bytes.
@param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] AuthenticatedImage The authenticated capsule image, excluding EFI_FIRMWARE_IMAGE_AUTHENTICATION.
@param[out] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
@retval TRUE The authenticated image is extracted.
@retval FALSE The authenticated image is not extracted.
**/
BOOLEAN
EFIAPI
ExtractAuthenticatedImage (
IN VOID *Image,
IN UINTN ImageSize,
OUT UINT32 *LastAttemptStatus,
OUT VOID **AuthenticatedImage,
OUT UINTN *AuthenticatedImageSize
)
{
EFI_FIRMWARE_IMAGE_AUTHENTICATION *ImageAuth;
EFI_STATUS Status;
GUID *CertType;
VOID *PublicKeyData;
UINTN PublicKeyDataLength;
DEBUG ((DEBUG_INFO, "ExtractAuthenticatedImage - Image: 0x%08x - 0x%08x\n", (UINTN)Image, (UINTN)ImageSize));
*LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT;
if ((Image == NULL) || (ImageSize == 0)) {
return FALSE;
}
ImageAuth = (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image;
if (ImageSize < sizeof (EFI_FIRMWARE_IMAGE_AUTHENTICATION)) {
DEBUG ((DEBUG_ERROR, "ExtractAuthenticatedImage - ImageSize too small\n"));
return FALSE;
}
if (ImageAuth->AuthInfo.Hdr.dwLength <= OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)) {
DEBUG ((DEBUG_ERROR, "ExtractAuthenticatedImage - dwLength too small\n"));
return FALSE;
}
if ((UINTN)ImageAuth->AuthInfo.Hdr.dwLength > MAX_UINTN - sizeof (UINT64)) {
DEBUG ((DEBUG_ERROR, "ExtractAuthenticatedImage - dwLength too big\n"));
return FALSE;
}
if (ImageSize <= sizeof (ImageAuth->MonotonicCount) + ImageAuth->AuthInfo.Hdr.dwLength) {
DEBUG ((DEBUG_ERROR, "ExtractAuthenticatedImage - ImageSize too small\n"));
return FALSE;
}
if (ImageAuth->AuthInfo.Hdr.wRevision != 0x0200) {
DEBUG ((DEBUG_ERROR, "ExtractAuthenticatedImage - wRevision: 0x%02x, expect - 0x%02x\n", (UINTN)ImageAuth->AuthInfo.Hdr.wRevision, (UINTN)0x0200));
return FALSE;
}
if (ImageAuth->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) {
DEBUG ((DEBUG_ERROR, "ExtractAuthenticatedImage - wCertificateType: 0x%02x, expect - 0x%02x\n", (UINTN)ImageAuth->AuthInfo.Hdr.wCertificateType, (UINTN)WIN_CERT_TYPE_EFI_GUID));
return FALSE;
}
CertType = &ImageAuth->AuthInfo.CertType;
DEBUG ((DEBUG_INFO, "ExtractAuthenticatedImage - CertType: %g\n", CertType));
if (CompareGuid (&gEfiCertPkcs7Guid, CertType)) {
PublicKeyData = PcdGetPtr (PcdPkcs7CertBuffer);
PublicKeyDataLength = PcdGetSize (PcdPkcs7CertBuffer);
} else if (CompareGuid (&gEfiCertTypeRsa2048Sha256Guid, CertType)) {
PublicKeyData = PcdGetPtr (PcdRsa2048Sha256PublicKeyBuffer);
PublicKeyDataLength = PcdGetSize (PcdRsa2048Sha256PublicKeyBuffer);
} else {
return FALSE;
}
ASSERT (PublicKeyData != NULL);
ASSERT (PublicKeyDataLength != 0);
Status = AuthenticateFmpImage (
ImageAuth,
ImageSize,
PublicKeyData,
PublicKeyDataLength
);
switch (Status) {
case RETURN_SUCCESS:
*LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
break;
case RETURN_SECURITY_VIOLATION:
*LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR;
break;
case RETURN_INVALID_PARAMETER:
*LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT;
break;
case RETURN_UNSUPPORTED:
*LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT;
break;
case RETURN_OUT_OF_RESOURCES:
*LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES;
break;
default:
*LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
break;
}
if (EFI_ERROR (Status)) {
return FALSE;
}
if (AuthenticatedImage != NULL) {
*AuthenticatedImage = (UINT8 *)ImageAuth + ImageAuth->AuthInfo.Hdr.dwLength + sizeof (ImageAuth->MonotonicCount);
}
if (AuthenticatedImageSize != NULL) {
*AuthenticatedImageSize = ImageSize - ImageAuth->AuthInfo.Hdr.dwLength - sizeof (ImageAuth->MonotonicCount);
}
return TRUE;
}
/**
Extract ImageFmpInfo from system firmware.
@param[in] SystemFirmwareImage The System Firmware image.
@param[in] SystemFirmwareImageSize The size of the System Firmware image in bytes.
@param[out] ImageFmpInfo The ImageFmpInfo.
@param[out] ImageFmpInfoSize The size of the ImageFmpInfo in bytes.
@retval TRUE The ImageFmpInfo is extracted.
@retval FALSE The ImageFmpInfo is not extracted.
**/
BOOLEAN
EFIAPI
ExtractSystemFirmwareImageFmpInfo (
IN VOID *SystemFirmwareImage,
IN UINTN SystemFirmwareImageSize,
OUT EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR **ImageFmpInfo,
OUT UINTN *ImageFmpInfoSize
)
{
BOOLEAN Result;
UINT32 SectionHeaderSize;
UINT32 FileHeaderSize;
*ImageFmpInfo = NULL;
*ImageFmpInfoSize = 0;
Result = GetFfsByName (SystemFirmwareImage, SystemFirmwareImageSize, &gEdkiiSystemFirmwareImageDescriptorFileGuid, EFI_FV_FILETYPE_ALL, (VOID **)ImageFmpInfo, ImageFmpInfoSize);
if (!Result) {
return FALSE;
}
if (IS_FFS_FILE2 (*ImageFmpInfo)) {
FileHeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
} else {
FileHeaderSize = sizeof (EFI_FFS_FILE_HEADER);
}
*ImageFmpInfo = (VOID *)((UINT8 *)*ImageFmpInfo + FileHeaderSize);
*ImageFmpInfoSize = *ImageFmpInfoSize - FileHeaderSize;
Result = GetSectionByType (*ImageFmpInfo, (UINT32)*ImageFmpInfoSize, EFI_SECTION_RAW, 0, (VOID **)ImageFmpInfo, ImageFmpInfoSize);
if (!Result) {
return FALSE;
}
if (IS_SECTION2 (*ImageFmpInfo)) {
SectionHeaderSize = sizeof (EFI_RAW_SECTION2);
} else {
SectionHeaderSize = sizeof (EFI_RAW_SECTION);
}
*ImageFmpInfo = (VOID *)((UINT8 *)*ImageFmpInfo + SectionHeaderSize);
*ImageFmpInfoSize = *ImageFmpInfoSize - SectionHeaderSize;
return TRUE;
}
/**
Extract the System Firmware image from an authenticated image.
@param[in] AuthenticatedImage The authenticated capsule image.
@param[in] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
@param[out] SystemFirmwareImage The System Firmware image.
@param[out] SystemFirmwareImageSize The size of the System Firmware image in bytes.
@retval TRUE The System Firmware image is extracted.
@retval FALSE The System Firmware image is not extracted.
**/
BOOLEAN
EFIAPI
ExtractSystemFirmwareImage (
IN VOID *AuthenticatedImage,
IN UINTN AuthenticatedImageSize,
OUT VOID **SystemFirmwareImage,
OUT UINTN *SystemFirmwareImageSize
)
{
BOOLEAN Result;
UINT32 FileHeaderSize;
*SystemFirmwareImage = NULL;
*SystemFirmwareImageSize = 0;
Result = GetFfsByName (AuthenticatedImage, AuthenticatedImageSize, &mEdkiiSystemFirmwareFileGuid, EFI_FV_FILETYPE_RAW, SystemFirmwareImage, SystemFirmwareImageSize);
if (!Result) {
// no nested FV, just return all data.
*SystemFirmwareImage = AuthenticatedImage;
*SystemFirmwareImageSize = AuthenticatedImageSize;
return TRUE;
}
if (IS_FFS_FILE2 (*SystemFirmwareImage)) {
FileHeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
} else {
FileHeaderSize = sizeof (EFI_FFS_FILE_HEADER);
}
*SystemFirmwareImage = (UINT8 *)*SystemFirmwareImage + FileHeaderSize;
*SystemFirmwareImageSize = *SystemFirmwareImageSize - FileHeaderSize;
return Result;
}
/**
Authenticated system firmware FMP capsule image.
Caution: This function may receive untrusted input.
@param[in] Image The FMP capsule image, including EFI_FIRMWARE_IMAGE_AUTHENTICATION.
@param[in] ImageSize The size of FMP capsule image in bytes.
@param[in] ForceVersionMatch TRUE: The version of capsule must be as same as the version of current image.
FALSE: The version of capsule must be as same as greater than the lowest
supported version of current image.
@param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] AuthenticatedImage The authenticated capsule image, excluding EFI_FIRMWARE_IMAGE_AUTHENTICATION.
@param[out] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
@retval TRUE Authentication passes and the authenticated image is extracted.
@retval FALSE Authentication fails and the authenticated image is not extracted.
**/
EFI_STATUS
EFIAPI
CapsuleAuthenticateSystemFirmware (
IN VOID *Image,
IN UINTN ImageSize,
IN BOOLEAN ForceVersionMatch,
OUT UINT32 *LastAttemptVersion,
OUT UINT32 *LastAttemptStatus,
OUT VOID **AuthenticatedImage,
OUT UINTN *AuthenticatedImageSize
)
{
BOOLEAN Result;
EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR *ImageFmpInfo;
UINTN ImageFmpInfoSize;
EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageFmpInfo;
UINTN CurrentImageFmpInfoSize;
VOID *SystemFirmwareImage;
UINTN SystemFirmwareImageSize;
*LastAttemptVersion = 0;
//
// NOTE: This function need run in an isolated environment.
// Do not touch FMP protocol and its private structure.
//
if (mImageFmpInfo == NULL) {
DEBUG ((DEBUG_INFO, "ImageFmpInfo is not set\n"));
return EFI_SECURITY_VIOLATION;
}
Result = ExtractAuthenticatedImage ((VOID *)Image, ImageSize, LastAttemptStatus, AuthenticatedImage, AuthenticatedImageSize);
if (!Result) {
DEBUG ((DEBUG_INFO, "ExtractAuthenticatedImage - fail\n"));
return EFI_SECURITY_VIOLATION;
}
DEBUG ((DEBUG_INFO, "AuthenticatedImage - 0x%x - 0x%x\n", *AuthenticatedImage, *AuthenticatedImageSize));
Result = ExtractSystemFirmwareImage (*AuthenticatedImage, *AuthenticatedImageSize, &SystemFirmwareImage, &SystemFirmwareImageSize);
if (!Result) {
*LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT;
DEBUG ((DEBUG_INFO, "ExtractSystemFirmwareImage - fail\n"));
return EFI_SECURITY_VIOLATION;
}
DEBUG ((DEBUG_INFO, "SystemFirmwareImage - 0x%x - 0x%x\n", SystemFirmwareImage, SystemFirmwareImageSize));
Result = ExtractSystemFirmwareImageFmpInfo (SystemFirmwareImage, SystemFirmwareImageSize, &ImageFmpInfo, &ImageFmpInfoSize);
if (!Result) {
*LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT;
DEBUG ((DEBUG_INFO, "ExtractSystemFirmwareImageFmpInfo - fail\n"));
return EFI_SECURITY_VIOLATION;
}
*LastAttemptVersion = ImageFmpInfo->Version;
DEBUG ((DEBUG_INFO, "ImageFmpInfo - 0x%x - 0x%x\n", ImageFmpInfo, ImageFmpInfoSize));
DEBUG ((DEBUG_INFO, "NewImage Version - 0x%x\n", ImageFmpInfo->Version));
DEBUG ((DEBUG_INFO, "NewImage LowestSupportedImageVersion - 0x%x\n", ImageFmpInfo->LowestSupportedImageVersion));
CurrentImageFmpInfo = mImageFmpInfo;
CurrentImageFmpInfoSize = mImageFmpInfoSize;
DEBUG ((DEBUG_INFO, "ImageFmpInfo - 0x%x - 0x%x\n", CurrentImageFmpInfo, CurrentImageFmpInfoSize));
DEBUG ((DEBUG_INFO, "Current Version - 0x%x\n", CurrentImageFmpInfo->Version));
DEBUG ((DEBUG_INFO, "Current LowestSupportedImageVersion - 0x%x\n", CurrentImageFmpInfo->LowestSupportedImageVersion));
if (ForceVersionMatch) {
if (CurrentImageFmpInfo->Version != ImageFmpInfo->Version) {
*LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION;
DEBUG ((DEBUG_INFO, "ForceVersionMatch check - fail\n"));
return EFI_SECURITY_VIOLATION;
}
} else {
if (ImageFmpInfo->Version < CurrentImageFmpInfo->LowestSupportedImageVersion) {
*LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION;
DEBUG ((DEBUG_INFO, "LowestSupportedImageVersion check - fail\n"));
return EFI_SECURITY_VIOLATION;
}
}
*LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
return EFI_SUCCESS;
}
/**
PcdCallBack gets the real set PCD value
@param[in] CallBackGuid The PCD token GUID being set.
@param[in] CallBackToken The PCD token number being set.
@param[in, out] TokenData A pointer to the token data being set.
@param[in] TokenDataSize The size, in bytes, of the data being set.
**/
VOID
EFIAPI
EdkiiSystemCapsuleLibPcdCallBack (
IN CONST GUID *CallBackGuid OPTIONAL,
IN UINTN CallBackToken,
IN OUT VOID *TokenData,
IN UINTN TokenDataSize
)
{
if (CompareGuid (CallBackGuid, &gEfiSignedCapsulePkgTokenSpaceGuid) &&
(CallBackToken == PcdToken (PcdEdkiiSystemFirmwareImageDescriptor)))
{
mImageFmpInfoSize = TokenDataSize;
mImageFmpInfo = AllocateCopyPool (mImageFmpInfoSize, TokenData);
ASSERT (mImageFmpInfo != NULL);
//
// Cancel Callback after get the real set value
//
LibPcdCancelCallback (
&gEfiSignedCapsulePkgTokenSpaceGuid,
PcdToken (PcdEdkiiSystemFirmwareImageDescriptor),
EdkiiSystemCapsuleLibPcdCallBack
);
}
if (CompareGuid (CallBackGuid, &gEfiSignedCapsulePkgTokenSpaceGuid) &&
(CallBackToken == PcdToken (PcdEdkiiSystemFirmwareFileGuid)))
{
CopyGuid (&mEdkiiSystemFirmwareFileGuid, TokenData);
//
// Cancel Callback after get the real set value
//
LibPcdCancelCallback (
&gEfiSignedCapsulePkgTokenSpaceGuid,
PcdToken (PcdEdkiiSystemFirmwareFileGuid),
EdkiiSystemCapsuleLibPcdCallBack
);
}
}
/**
The constructor function.
@retval EFI_SUCCESS The constructor successfully .
**/
EFI_STATUS
EFIAPI
EdkiiSystemCapsuleLibConstructor (
VOID
)
{
mImageFmpInfoSize = PcdGetSize (PcdEdkiiSystemFirmwareImageDescriptor);
mImageFmpInfo = PcdGetPtr (PcdEdkiiSystemFirmwareImageDescriptor);
//
// Verify Firmware Image Descriptor first
//
if ((mImageFmpInfoSize < sizeof (EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR)) ||
(mImageFmpInfo->Signature != EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR_SIGNATURE))
{
//
// SystemFirmwareImageDescriptor is not set.
// Register PCD set callback to hook PCD value set.
//
mImageFmpInfo = NULL;
mImageFmpInfoSize = 0;
LibPcdCallbackOnSet (
&gEfiSignedCapsulePkgTokenSpaceGuid,
PcdToken (PcdEdkiiSystemFirmwareImageDescriptor),
EdkiiSystemCapsuleLibPcdCallBack
);
} else {
mImageFmpInfo = AllocateCopyPool (mImageFmpInfoSize, mImageFmpInfo);
ASSERT (mImageFmpInfo != NULL);
}
CopyGuid (&mEdkiiSystemFirmwareFileGuid, PcdGetPtr (PcdEdkiiSystemFirmwareFileGuid));
//
// Verify GUID value first
//
if (CompareGuid (&mEdkiiSystemFirmwareFileGuid, &gZeroGuid)) {
LibPcdCallbackOnSet (
&gEfiSignedCapsulePkgTokenSpaceGuid,
PcdToken (PcdEdkiiSystemFirmwareFileGuid),
EdkiiSystemCapsuleLibPcdCallBack
);
}
return EFI_SUCCESS;
}

View file

@ -1,58 +0,0 @@
## @file
# EDKII System Capsule library.
#
# EDKII System Capsule library instance for DXE/PEI post memory phase.
#
# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = EdkiiSystemCapsuleLib
MODULE_UNI_FILE = EdkiiSystemCapsuleLib.uni
FILE_GUID = 109D5FC6-56E6-481A-88EF-0CB828FBE0F6
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = EdkiiSystemCapsuleLib
CONSTRUCTOR = EdkiiSystemCapsuleLibConstructor
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 EBC
#
[Sources]
EdkiiSystemCapsuleLib.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SecurityPkg/SecurityPkg.dec
SignedCapsulePkg/SignedCapsulePkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
PcdLib
MemoryAllocationLib
FmpAuthenticationLib
[Pcd]
gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareImageDescriptor ## CONSUMES
gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid ## CONSUMES
gEfiSecurityPkgTokenSpaceGuid.PcdRsa2048Sha256PublicKeyBuffer ## CONSUMES
gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer ## CONSUMES
[Guids]
gEdkiiSystemFirmwareImageDescriptorFileGuid ## SOMETIMES_CONSUMES ## GUID
gEdkiiSystemFmpCapsuleConfigFileGuid ## SOMETIMES_CONSUMES ## GUID
gEdkiiSystemFmpCapsuleDriverFvFileGuid ## SOMETIMES_CONSUMES ## GUID
gEfiCertPkcs7Guid ## SOMETIMES_CONSUMES ## GUID
gEfiCertTypeRsa2048Sha256Guid ## SOMETIMES_CONSUMES ## GUID
gEfiSignedCapsulePkgTokenSpaceGuid ## SOMETIMES_CONSUMES ## GUID
gZeroGuid ## SOMETIMES_CONSUMES ## GUID

View file

@ -1,16 +0,0 @@
// /** @file
// EDKII System Capsule library.
//
// EDKII System Capsule library instance for DXE/PEI post memory phase.
//
// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "EDKII System Capsule library."
#string STR_MODULE_DESCRIPTION #language en-US "EDKII System Capsule library instance for DXE/PEI post memory phase."

File diff suppressed because it is too large Load diff

View file

@ -1,37 +0,0 @@
## @file
# INI configuration parsing library.
#
# This library parses the INI configuration file.
#
# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = IniParsingLib
MODULE_UNI_FILE = IniParsingLib.uni
FILE_GUID = 6E4CD200-43E5-43CE-89E9-D715CF9526C4
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = IniParsingLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 EBC
#
[Sources]
IniParsingLib.c
[Packages]
MdePkg/MdePkg.dec
SignedCapsulePkg/SignedCapsulePkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
MemoryAllocationLib

View file

@ -1,16 +0,0 @@
// /** @file
// INI configuration parsing library.
//
// This library parses the INI configuration file.
//
// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "INI configuration parsing library."
#string STR_MODULE_DESCRIPTION #language en-US "This library parses the INI configuration file."

View file

@ -1,101 +0,0 @@
/** @file
Platform flash device access library NULL instance.
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiDxe.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PlatformFlashAccessLib.h>
UINT64 mInternalFdAddress;
/**
Perform flash write operation with progress indicator. The start and end
completion percentage values are passed into this function. If the requested
flash write operation is broken up, then completion percentage between the
start and end values may be passed to the provided Progress function. The
caller of this function is required to call the Progress function for the
start and end completion percentage values. This allows the Progress,
StartPercentage, and EndPercentage parameters to be ignored if the requested
flash write operation can not be broken up
@param[in] FirmwareType The type of firmware.
@param[in] FlashAddress The address of flash device to be accessed.
@param[in] FlashAddressType The type of flash device address.
@param[in] Buffer The pointer to the data buffer.
@param[in] Length The length of data buffer in bytes.
@param[in] Progress A function used report the progress of the
firmware update. This is an optional parameter
that may be NULL.
@param[in] StartPercentage The start completion percentage value that may
be used to report progress during the flash
write operation.
@param[in] EndPercentage The end completion percentage value that may
be used to report progress during the flash
write operation.
@retval EFI_SUCCESS The operation returns successfully.
@retval EFI_WRITE_PROTECTED The flash device is read only.
@retval EFI_UNSUPPORTED The flash device access is unsupported.
@retval EFI_INVALID_PARAMETER The input parameter is not valid.
**/
EFI_STATUS
EFIAPI
PerformFlashWriteWithProgress (
IN PLATFORM_FIRMWARE_TYPE FirmwareType,
IN EFI_PHYSICAL_ADDRESS FlashAddress,
IN FLASH_ADDRESS_TYPE FlashAddressType,
IN VOID *Buffer,
IN UINTN Length,
IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress OPTIONAL,
IN UINTN StartPercentage,
IN UINTN EndPercentage
)
{
if (FlashAddressType == FlashAddressTypeRelativeAddress) {
FlashAddress = FlashAddress + mInternalFdAddress;
}
CopyMem ((VOID *)(UINTN)(FlashAddress), Buffer, Length);
return EFI_SUCCESS;
}
/**
Perform flash write operation.
@param[in] FirmwareType The type of firmware.
@param[in] FlashAddress The address of flash device to be accessed.
@param[in] FlashAddressType The type of flash device address.
@param[in] Buffer The pointer to the data buffer.
@param[in] Length The length of data buffer in bytes.
@retval EFI_SUCCESS The operation returns successfully.
@retval EFI_WRITE_PROTECTED The flash device is read only.
@retval EFI_UNSUPPORTED The flash device access is unsupported.
@retval EFI_INVALID_PARAMETER The input parameter is not valid.
**/
EFI_STATUS
EFIAPI
PerformFlashWrite (
IN PLATFORM_FIRMWARE_TYPE FirmwareType,
IN EFI_PHYSICAL_ADDRESS FlashAddress,
IN FLASH_ADDRESS_TYPE FlashAddressType,
IN VOID *Buffer,
IN UINTN Length
)
{
return PerformFlashWriteWithProgress (
FirmwareType,
FlashAddress,
FlashAddressType,
Buffer,
Length,
NULL,
0,
0
);
}

View file

@ -1,34 +0,0 @@
## @file
# Platform flash device access library.
#
# Platform flash device access library NULL instance.
#
# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = PlatformFlashAccessLibNull
MODULE_UNI_FILE = PlatformFlashAccessLibNull.uni
FILE_GUID = A0534D92-9776-4E4E-9234-C9DC1849DBB5
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = PlatformFlashAccessLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 EBC
#
[Sources]
PlatformFlashAccessLibNull.c
[Packages]
MdePkg/MdePkg.dec
SignedCapsulePkg/SignedCapsulePkg.dec
[LibraryClasses]
BaseMemoryLib

View file

@ -1,16 +0,0 @@
// /** @file
// Platform flash device access library.
//
// Platform flash device access library NULL instance.
//
// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "Platform flash device access library."
#string STR_MODULE_DESCRIPTION #language en-US "Platform flash device access library NULL instance."

View file

@ -1,11 +0,0 @@
# SignedCapsulePkg
This package provides a signed capsule solution in EDKII to support a secure capsule update and recovery solution.
Source Repository: https://github.com/tianocore/edk2/tree/master/SignedCapsulePkg
A whitepaper to describe the capsule design: https://github.com/tianocore-docs/Docs/raw/master/White_Papers/A_Tour_Beyond_BIOS_Capsule_Update_and_Recovery_in_EDK_II.pdf
Wiki page with additional information:
[Capsule-Based Firmware Update and Firmware Recovery](https://www.tianocore.org/tianocore-wiki.github.io/reference/specs-standards/capsule_based_firmware_update_and_firmware_recovery.html)

View file

@ -1,93 +0,0 @@
## @file
# Core CI configuration for SignedCapsulePkg
#
# Copyright (c) Microsoft Corporation
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
"PrEval": {
"DscPath": "SignedCapsulePkg.dsc",
},
## options defined .pytool/Plugin/LicenseCheck
"LicenseCheck": {
"IgnoreFiles": []
},
"EccCheck": {
## Exception sample looks like below:
## "ExceptionList": [
## "<ErrorID>", "<KeyWord>"
## ]
"ExceptionList": [
],
## Both file path and directory path are accepted.
"IgnoreFiles": []
},
## options defined .pytool/Plugin/CompilerPlugin
"CompilerPlugin": {
"DscPath": "SignedCapsulePkg.dsc"
},
## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
"HostUnitTestCompilerPlugin": {
"DscPath": "" # Don't support this test
},
## options defined .pytool/Plugin/CharEncodingCheck
"CharEncodingCheck": {
"IgnoreFiles": []
},
## options defined .pytool/Plugin/DependencyCheck
"DependencyCheck": {
"AcceptableDependencies": [
"MdeModulePkg/MdeModulePkg.dec",
"MdePkg/MdePkg.dec",
"SecurityPkg/SecurityPkg.dec",
"SignedCapsulePkg/SignedCapsulePkg.dec"
],
# For host based unit tests
"AcceptableDependencies-HOST_APPLICATION":[
"UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
],
# For UEFI shell based apps
"AcceptableDependencies-UEFI_APPLICATION":[],
"IgnoreInf": []
},
## options defined .pytool/Plugin/DscCompleteCheck
"DscCompleteCheck": {
"IgnoreInf": [""],
"DscPath": "SignedCapsulePkg.dsc"
},
## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
"HostUnitTestDscCompleteCheck": {
"IgnoreInf": [""],
"DscPath": "" # Don't support this test
},
## options defined .pytool/Plugin/GuidCheck
"GuidCheck": {
"IgnoreGuidName": [],
"IgnoreGuidValue": [],
"IgnoreFoldersAndFiles": [],
"IgnoreDuplicates": [],
},
## options defined .pytool/Plugin/LibraryClassCheck
"LibraryClassCheck": {
"IgnoreHeaderFile": []
},
## options defined .pytool/Plugin/SpellCheck
"SpellCheck": {
"AuditOnly": True, # Failures need to be reviewed and resolved in the future
"IgnoreFiles": [], # use gitignore syntax to ignore errors in matching files
"ExtendWords": [], # words to extend to the dictionary for this package
"IgnoreStandardPaths": [], # Standard Plugin defined paths that should be ignore
"AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
}
}

View file

@ -1,74 +0,0 @@
## @file
# This package provides EDKII capsule related support.
#
# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
DEC_SPECIFICATION = 0x00010005
PACKAGE_NAME = SignedCapsulePkg
PACKAGE_GUID = 75AA5D82-7BC4-44A9-82FB-0820EBC79BED
PACKAGE_VERSION = 0.1
[Includes]
Include
[LibraryClasses]
## @libraryclass Provides services for EDKII system FMP capsule.
#
EdkiiSystemCapsuleLib|Include/Library/EdkiiSystemCapsuleLib.h
## @libraryclass Provides services to parse the INI configuration file.
#
IniParsingLib|Include/Library/IniParsingLib.h
## @libraryclass Provides services to access flash device.
#
PlatformFlashAccessLib|Include/Library/PlatformFlashAccessLib.h
[Guids]
gEfiSignedCapsulePkgTokenSpaceGuid = { 0xe1eb612f, 0x1c6c, 0x485d, { 0x9d, 0x6, 0x65, 0x8, 0x44, 0x88, 0x15, 0x69 }}
## Include/Guid/EdkiiSystemFmpCapsule.h
gEdkiiSystemFirmwareImageDescriptorFileGuid = {0x90b2b846, 0xca6d, 0x4d6e, {0xa8, 0xd3, 0xc1, 0x40, 0xa8, 0xe1, 0x10, 0xac}}
gEdkiiSystemFmpCapsuleConfigFileGuid = {0x812136d3, 0x4d3a, 0x433a, {0x94, 0x18, 0x29, 0xbb, 0x9b, 0xf7, 0x8f, 0x6e}}
gEdkiiSystemFmpCapsuleDriverFvFileGuid = {0xce57b167, 0xb0e4, 0x41e8, {0xa8, 0x97, 0x5f, 0x4f, 0xeb, 0x78, 0x1d, 0x40}}
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
## This is the GUID of the FFS which contains the Rsa2048Sha256TestPublicKeyFile as a RAW section.
# @Prompt GUID of the FFS which contains the Rsa2048Sha256TestPublicKeyFile.
gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid|{0x04, 0xe1, 0xfe, 0xc4, 0x57, 0x66, 0x36, 0x49, 0xa6, 0x11, 0x13, 0x8d, 0xbc, 0x2a, 0x76, 0xad}|VOID*|0xA0010001
## This is the GUID of the FFS which contains the Pkcs7TestPublicKeyFile as a RAW section.
# @Prompt GUID of the FFS which contains the Pkcs7TestPublicKeyFile.
gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiPkcs7TestPublicKeyFileGuid|{0xba, 0xf5, 0x93, 0xf0, 0x37, 0x6f, 0x16, 0x48, 0x9e, 0x52, 0x91, 0xbe, 0xa0, 0xf7, 0xe0, 0xb8}|VOID*|0xA0010002
## This is the lowest supported version number that can be upgraded to, as exposed via the System Firmware descriptor.
# @Prompt Lowest support version number that can be upgraded to via capsule update
gEfiSignedCapsulePkgTokenSpaceGuid.PcdLowestSupportedFirmwareVersion|0x1|UINT32|0xA0010003
[PcdsDynamicEx]
## This dynamic PCD holds the EDKII system firmware image descriptor.
# This information can be used for version check in EDKII system FMP capsule.
# Only if the new EdkiiSystemFirmwareImageDescriptor.Version is not less than
# the current PcdEdkiiSystemFirmwareImageDescriptor.LowestSupportedVersion,
# the EDKII system FmpCapsule will be processed.
# The data structure of this PCD is EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR,
# SignedCapsulePkg/Include/Guid/EdkiiSystemFmpCapsule.h.
# It must be in [PcdsDynamicEx], because the EDKII system firmware update module may
# consume the PCD produced in current system firmware.
# @Prompt EDKII system firmware image descriptor.
gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareImageDescriptor|{0x0}|VOID*|0x00000037
## This dynamic PCD hold the GUID of a firmware FFS which includes EDKII
# system firmware image.
# An EDKII system firmware update module need consume this PCD to extract
# the EDKII system firmware from the capsule image.
# It must be in [PcdsDynamicEx], because the EDKII system firmware update module may
# consume the PCD produced in current system firmware image.
# @Prompt EDKII system firmware image FFS GUID.
gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid|{0x0}|VOID*|0x00001010

View file

@ -1,238 +0,0 @@
## @file
# This package provides EDKII capsule related support.
#
# Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
PLATFORM_NAME = SignedCapsulePkg
PLATFORM_GUID = 164E16D7-B56A-416D-92FF-0A63983733F6
PLATFORM_VERSION = 0.96
DSC_SPECIFICATION = 0x00010005
OUTPUT_DIRECTORY = Build/SignedCapsulePkg
SUPPORTED_ARCHITECTURES = AARCH64|IA32|X64
BUILD_TARGETS = DEBUG|RELEASE|NOOPT
SKUID_IDENTIFIER = DEFAULT
!include MdePkg/MdeLibs.dsc.inc
[LibraryClasses]
#
# Entry point
#
PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
#
# Basic
#
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf
#
# UEFI & PI
#
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
#
# Generic Modules
#
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
#
# Misc
#
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf
SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf
S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
PlatformBootManagerLib|MdeModulePkg/Library/PlatformBootManagerLibNull/PlatformBootManagerLibNull.inf
PciHostBridgeLib|MdeModulePkg/Library/PciHostBridgeLibNull/PciHostBridgeLibNull.inf
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
EdkiiSystemCapsuleLib|SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.inf
IniParsingLib|SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.inf
PlatformFlashAccessLib|SignedCapsulePkg/Library/PlatformFlashAccessLibNull/PlatformFlashAccessLibNull.inf
RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
[LibraryClasses.RISCV64]
RngLib|MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
[LibraryClasses.common.PEI_CORE]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
[LibraryClasses.common.PEIM]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
!ifdef CONTINUOUS_INTEGRATION
BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
!else
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
!endif
[LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
[LibraryClasses.common.DXE_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
!ifdef CONTINUOUS_INTEGRATION
BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
!else
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
!endif
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
!ifdef CONTINUOUS_INTEGRATION
BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
!else
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
!endif
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
[LibraryClasses.common.SMM_CORE]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf
SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf
SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf
SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
[LibraryClasses.common.DXE_SMM_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
!ifdef CONTINUOUS_INTEGRATION
BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
!else
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
!endif
[LibraryClasses.common.UEFI_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
!ifdef CONTINUOUS_INTEGRATION
BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
!else
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
!endif
[LibraryClasses.common.UEFI_APPLICATION]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
!ifdef CONTINUOUS_INTEGRATION
BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
!else
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
!endif
[PcdsFixedAtBuild]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0f
gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x06
[PcdsDynamicExDefault]
gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareImageDescriptor|{0x0}|VOID*|0x100
###################################################################################################
#
# Components Section - list of the modules and components that will be processed by compilation
# tools and the EDK II tools to generate PE32/PE32+/Coff image files.
#
# Note: The EDK II DSC file is not used to specify how compiled binary images get placed
# into firmware volume images. This section is just a list of modules to compile from
# source into UEFI-compliant binaries.
# It is the FDF file that contains information on combining binary files into firmware
# volume images, whose concept is beyond UEFI and is described in PI specification.
# Binary modules do not need to be listed in this section, as they should be
# specified in the FDF file. For example: Shell binary (Shell_Full.efi), FAT binary (Fat.efi),
# Logo (Logo.bmp), and etc.
# There may also be modules listed in this section that are not required in the FDF file,
# When a module listed here is excluded from FDF file, then UEFI-compliant binary will be
# generated for it, but the binary will not be put into any firmware volume.
#
###################################################################################################
[Components]
SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.inf
SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.inf
SignedCapsulePkg/Library/PlatformFlashAccessLibNull/PlatformFlashAccessLibNull.inf
SignedCapsulePkg/Universal/SystemFirmwareUpdate/SystemFirmwareReportDxe.inf {
<LibraryClasses>
FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
}
SignedCapsulePkg/Universal/SystemFirmwareUpdate/SystemFirmwareUpdateDxe.inf {
<LibraryClasses>
FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
}
SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoadPei.inf {
<LibraryClasses>
FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibRsa2048Sha256/FmpAuthenticationLibRsa2048Sha256.inf
}
[BuildOptions]
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES

View file

@ -1,163 +0,0 @@
/** @file
Parse the INI configuration file and pass the information to the recovery driver
so that the driver can perform recovery accordingly.
Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "RecoveryModuleLoadPei.h"
#include <Library/IniParsingLib.h>
#include <Library/PrintLib.h>
#define MAX_LINE_LENGTH 512
/**
Parse Config data file to get the updated data array.
@param[in] DataBuffer Config raw file buffer.
@param[in] BufferSize Size of raw buffer.
@param[in, out] ConfigHeader Pointer to the config header.
@param[in, out] RecoveryArray Pointer to the config of recovery data.
@retval EFI_NOT_FOUND No config data is found.
@retval EFI_OUT_OF_RESOURCES No enough memory is allocated.
@retval EFI_SUCCESS Parse the config file successfully.
**/
EFI_STATUS
ParseRecoveryDataFile (
IN UINT8 *DataBuffer,
IN UINTN BufferSize,
IN OUT CONFIG_HEADER *ConfigHeader,
IN OUT RECOVERY_CONFIG_DATA **RecoveryArray
)
{
EFI_STATUS Status;
CHAR8 *SectionName;
CHAR8 Entry[MAX_LINE_LENGTH];
UINTN Num;
UINTN Index;
EFI_GUID FileGuid;
VOID *Context;
//
// First process the data buffer and get all sections and entries
//
Context = OpenIniFile (DataBuffer, BufferSize);
if (Context == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Now get NumOfUpdate
//
Status = GetDecimalUintnFromDataFile (
Context,
"Head",
"NumOfRecovery",
&Num
);
if (EFI_ERROR (Status) || (Num == 0)) {
DEBUG ((DEBUG_ERROR, "NumOfRecovery not found\n"));
CloseIniFile (Context);
return EFI_NOT_FOUND;
}
ConfigHeader->NumOfRecovery = Num;
*RecoveryArray = AllocateZeroPool ((sizeof (RECOVERY_CONFIG_DATA) * Num));
if (*RecoveryArray == NULL) {
CloseIniFile (Context);
return EFI_OUT_OF_RESOURCES;
}
for (Index = 0; Index < ConfigHeader->NumOfRecovery; Index++) {
//
// Get the section name of each update
//
AsciiStrCpyS (Entry, MAX_LINE_LENGTH, "Recovery");
AsciiValueToStringS (
Entry + AsciiStrnLenS (Entry, MAX_LINE_LENGTH),
MAX_LINE_LENGTH - AsciiStrnLenS (Entry, MAX_LINE_LENGTH),
0,
Index,
0
);
Status = GetStringFromDataFile (
Context,
"Head",
Entry,
&SectionName
);
if (EFI_ERROR (Status) || (SectionName == NULL)) {
DEBUG ((DEBUG_ERROR, "[%d] %a not found\n", Index, Entry));
CloseIniFile (Context);
return EFI_NOT_FOUND;
}
//
// The section name of this update has been found.
// Now looks for all the config data of this update
//
//
// FileGuid
//
Status = GetGuidFromDataFile (
Context,
SectionName,
"FileGuid",
&FileGuid
);
if (EFI_ERROR (Status)) {
CloseIniFile (Context);
DEBUG ((DEBUG_ERROR, "[%d] FileGuid not found\n", Index));
return EFI_NOT_FOUND;
}
CopyGuid (&((*RecoveryArray)[Index].FileGuid), &FileGuid);
//
// Length
//
Status = GetHexUintnFromDataFile (
Context,
SectionName,
"Length",
&Num
);
if (EFI_ERROR (Status)) {
CloseIniFile (Context);
DEBUG ((DEBUG_ERROR, "[%d] Length not found\n", Index));
return EFI_NOT_FOUND;
}
(*RecoveryArray)[Index].Length = Num;
//
// ImageOffset
//
Status = GetHexUintnFromDataFile (
Context,
SectionName,
"ImageOffset",
&Num
);
if (EFI_ERROR (Status)) {
CloseIniFile (Context);
DEBUG ((DEBUG_ERROR, "[%d] ImageOffset not found\n", Index));
return EFI_NOT_FOUND;
}
(*RecoveryArray)[Index].ImageOffset = Num;
}
//
// Now all configuration data got. Free those temporary buffers
//
CloseIniFile (Context);
return EFI_SUCCESS;
}

View file

@ -1,833 +0,0 @@
/** @file
Recovery module.
Caution: This module requires additional review when modified.
This module will have external input - capsule image.
This external input must be validated carefully to avoid security issue like
buffer overflow, integer overflow.
ProcessRecoveryCapsule(), ProcessFmpCapsuleImage(), ProcessRecoveryImage(),
ValidateFmpCapsule() will receive untrusted input and do basic validation.
Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
//
// The package level header files this module uses
//
#include <Uefi.h>
#include <PiPei.h>
//
// The protocols, PPI and GUID definitions for this module
//
#include <Ppi/MasterBootMode.h>
#include <Ppi/BootInRecoveryMode.h>
#include <Ppi/RecoveryModule.h>
#include <Ppi/DeviceRecoveryModule.h>
#include <Ppi/FirmwareVolumeInfo.h>
#include <Guid/FirmwareFileSystem2.h>
#include <Guid/FmpCapsule.h>
#include <Guid/EdkiiSystemFmpCapsule.h>
//
// The Library classes this module consumes
//
#include <Library/DebugLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
#include <Library/HobLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include "RecoveryModuleLoadPei.h"
/**
Loads a DXE capsule from some media into memory and updates the HOB table
with the DXE firmware volume information.
@param[in] PeiServices General-purpose services that are available to every PEIM.
@param[in] This Indicates the EFI_PEI_RECOVERY_MODULE_PPI instance.
@retval EFI_SUCCESS The capsule was loaded correctly.
@retval EFI_DEVICE_ERROR A device error occurred.
@retval EFI_NOT_FOUND A recovery DXE capsule cannot be found.
**/
EFI_STATUS
EFIAPI
LoadRecoveryCapsule (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_RECOVERY_MODULE_PPI *This
);
EFI_PEI_RECOVERY_MODULE_PPI mRecoveryPpi = {
LoadRecoveryCapsule
};
EFI_PEI_PPI_DESCRIPTOR mRecoveryPpiList = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiPeiRecoveryModulePpiGuid,
&mRecoveryPpi
};
/**
Parse Config data file to get the updated data array.
@param[in] DataBuffer Config raw file buffer.
@param[in] BufferSize Size of raw buffer.
@param[in, out] ConfigHeader Pointer to the config header.
@param[in, out] RecoveryArray Pointer to the config of recovery data.
@retval EFI_NOT_FOUND No config data is found.
@retval EFI_OUT_OF_RESOURCES No enough memory is allocated.
@retval EFI_SUCCESS Parse the config file successfully.
**/
EFI_STATUS
ParseRecoveryDataFile (
IN UINT8 *DataBuffer,
IN UINTN BufferSize,
IN OUT CONFIG_HEADER *ConfigHeader,
IN OUT RECOVERY_CONFIG_DATA **RecoveryArray
);
/**
Return if this FMP is a system FMP or a device FMP, based upon FmpImageInfo.
@param[in] FmpImageHeader A pointer to EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER
@return TRUE It is a system FMP.
@return FALSE It is a device FMP.
**/
BOOLEAN
IsSystemFmpImage (
IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *FmpImageHeader
)
{
GUID *Guid;
UINTN Count;
UINTN Index;
Guid = PcdGetPtr (PcdSystemFmpCapsuleImageTypeIdGuid);
Count = PcdGetSize (PcdSystemFmpCapsuleImageTypeIdGuid) / sizeof (GUID);
for (Index = 0; Index < Count; Index++, Guid++) {
if (CompareGuid (&FmpImageHeader->UpdateImageTypeId, Guid)) {
return TRUE;
}
}
return FALSE;
}
/**
Return if this CapsuleGuid is a FMP capsule GUID or not.
@param[in] CapsuleGuid A pointer to EFI_GUID
@return TRUE It is a FMP capsule GUID.
@return FALSE It is not a FMP capsule GUID.
**/
BOOLEAN
IsFmpCapsuleGuid (
IN EFI_GUID *CapsuleGuid
)
{
if (CompareGuid (&gEfiFmpCapsuleGuid, CapsuleGuid)) {
return TRUE;
}
return FALSE;
}
/**
This function assumes the input Capsule image already passes basic check in
ValidateFmpCapsule().
Criteria of system FMP capsule is:
1) FmpCapsuleHeader->EmbeddedDriverCount is 0.
2) FmpCapsuleHeader->PayloadItemCount is not 0.
3) All ImageHeader->UpdateImageTypeId matches PcdSystemFmpCapsuleImageTypeIdGuid.
@param[in] CapsuleHeader Points to a capsule header.
@retval TRUE Input capsule is a correct system FMP capsule.
@retval FALSE Input capsule is not a correct system FMP capsule.
**/
BOOLEAN
IsSystemFmpCapsuleImage (
IN EFI_CAPSULE_HEADER *CapsuleHeader
)
{
EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *FmpCapsuleHeader;
EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *ImageHeader;
UINT64 *ItemOffsetList;
UINT32 ItemNum;
UINTN Index;
FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
if (FmpCapsuleHeader->EmbeddedDriverCount != 0) {
return FALSE;
}
if (FmpCapsuleHeader->PayloadItemCount == 0) {
return FALSE;
}
ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;
ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);
for (Index = 0; Index < ItemNum; Index++) {
ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);
if (!IsSystemFmpImage (ImageHeader)) {
return FALSE;
}
}
return TRUE;
}
/**
Validate if it is valid capsule header
This function assumes the caller provided correct CapsuleHeader pointer
and CapsuleSize.
This function validates the fields in EFI_CAPSULE_HEADER.
@param[in] CapsuleHeader Points to a capsule header.
@param[in] CapsuleSize Size of the whole capsule image.
**/
BOOLEAN
IsValidCapsuleHeader (
IN EFI_CAPSULE_HEADER *CapsuleHeader,
IN UINT64 CapsuleSize
)
{
if (CapsuleHeader->CapsuleImageSize != CapsuleSize) {
return FALSE;
}
if (CapsuleHeader->HeaderSize >= CapsuleHeader->CapsuleImageSize) {
return FALSE;
}
return TRUE;
}
/**
Validate Fmp capsules layout.
Caution: This function may receive untrusted input.
This function assumes the caller validated the capsule by using
IsValidCapsuleHeader(), so that all fields in EFI_CAPSULE_HEADER are correct.
The capsule buffer size is CapsuleHeader->CapsuleImageSize.
This function validates the fields in EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER
and EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.
@param[in] CapsuleHeader Points to a capsule header.
@param[out] IsSystemFmp If it is a system FMP.
@param[out] EmbeddedDriverCount The EmbeddedDriverCount in the FMP capsule.
@retval EFI_SUCCESS Input capsule is a correct FMP capsule.
@retval EFI_INVALID_PARAMETER Input capsule is not a correct FMP capsule.
**/
EFI_STATUS
ValidateFmpCapsule (
IN EFI_CAPSULE_HEADER *CapsuleHeader,
OUT BOOLEAN *IsSystemFmp OPTIONAL,
OUT UINT16 *EmbeddedDriverCount OPTIONAL
)
{
EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *FmpCapsuleHeader;
UINT8 *EndOfCapsule;
EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *ImageHeader;
UINT8 *EndOfPayload;
UINT64 *ItemOffsetList;
UINT32 ItemNum;
UINTN Index;
UINTN FmpCapsuleSize;
UINTN FmpCapsuleHeaderSize;
UINT64 FmpImageSize;
UINTN FmpImageHeaderSize;
if (CapsuleHeader->HeaderSize >= CapsuleHeader->CapsuleImageSize) {
DEBUG ((DEBUG_ERROR, "HeaderSize(0x%x) >= CapsuleImageSize(0x%x)\n", CapsuleHeader->HeaderSize, CapsuleHeader->CapsuleImageSize));
return EFI_INVALID_PARAMETER;
}
FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
EndOfCapsule = (UINT8 *)CapsuleHeader + CapsuleHeader->CapsuleImageSize;
FmpCapsuleSize = (UINTN)EndOfCapsule - (UINTN)FmpCapsuleHeader;
if (FmpCapsuleSize < sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER)) {
DEBUG ((DEBUG_ERROR, "FmpCapsuleSize(0x%x) < EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER\n", FmpCapsuleSize));
return EFI_INVALID_PARAMETER;
}
// Check EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER
if (FmpCapsuleHeader->Version != EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION) {
DEBUG ((DEBUG_ERROR, "FmpCapsuleHeader->Version(0x%x) != EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION\n", FmpCapsuleHeader->Version));
return EFI_INVALID_PARAMETER;
}
ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);
// No overflow
ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;
if ((FmpCapsuleSize - sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER))/sizeof (UINT64) < ItemNum) {
DEBUG ((DEBUG_ERROR, "ItemNum(0x%x) too big\n", ItemNum));
return EFI_INVALID_PARAMETER;
}
FmpCapsuleHeaderSize = sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER) + sizeof (UINT64)*ItemNum;
// Check ItemOffsetList
for (Index = 0; Index < ItemNum; Index++) {
if (ItemOffsetList[Index] >= FmpCapsuleSize) {
DEBUG ((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) >= FmpCapsuleSize(0x%x)\n", Index, ItemOffsetList[Index], FmpCapsuleSize));
return EFI_INVALID_PARAMETER;
}
if (ItemOffsetList[Index] < FmpCapsuleHeaderSize) {
DEBUG ((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < FmpCapsuleHeaderSize(0x%x)\n", Index, ItemOffsetList[Index], FmpCapsuleHeaderSize));
return EFI_INVALID_PARAMETER;
}
//
// All the address in ItemOffsetList must be stored in ascending order
//
if (Index > 0) {
if (ItemOffsetList[Index] <= ItemOffsetList[Index - 1]) {
DEBUG ((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < ItemOffsetList[%d](0x%x)\n", Index, ItemOffsetList[Index], Index, ItemOffsetList[Index - 1]));
return EFI_INVALID_PARAMETER;
}
}
}
// Check EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER
for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < ItemNum; Index++) {
ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);
if (Index == ItemNum - 1) {
EndOfPayload = (UINT8 *)((UINTN)EndOfCapsule - (UINTN)FmpCapsuleHeader);
} else {
EndOfPayload = (UINT8 *)(UINTN)ItemOffsetList[Index+1];
}
FmpImageSize = (UINTN)EndOfPayload - ItemOffsetList[Index];
if (FmpImageSize < OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance)) {
DEBUG ((DEBUG_ERROR, "FmpImageSize(0x%lx) < EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER\n", FmpImageSize));
return EFI_INVALID_PARAMETER;
}
FmpImageHeaderSize = sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER);
if ((ImageHeader->Version > EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) ||
(ImageHeader->Version < 1))
{
DEBUG ((DEBUG_ERROR, "ImageHeader->Version(0x%x) Unknown\n", ImageHeader->Version));
return EFI_INVALID_PARAMETER;
}
///
/// Current Init ImageHeader version is 3. UpdateHardwareInstance field was added in version 2
/// and ImageCapsuleSupport field was added in version 3
///
if (ImageHeader->Version == 1) {
FmpImageHeaderSize = OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance);
} else if (ImageHeader->Version == 2) {
FmpImageHeaderSize = OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, ImageCapsuleSupport);
}
// No overflow
if (FmpImageSize != (UINT64)FmpImageHeaderSize + (UINT64)ImageHeader->UpdateImageSize + (UINT64)ImageHeader->UpdateVendorCodeSize) {
DEBUG ((DEBUG_ERROR, "FmpImageSize(0x%lx) mismatch, UpdateImageSize(0x%x) UpdateVendorCodeSize(0x%x)\n", FmpImageSize, ImageHeader->UpdateImageSize, ImageHeader->UpdateVendorCodeSize));
return EFI_INVALID_PARAMETER;
}
}
if (ItemNum == 0) {
//
// No driver & payload element in FMP
//
EndOfPayload = (UINT8 *)(FmpCapsuleHeader + 1);
if (EndOfPayload != EndOfCapsule) {
DEBUG ((DEBUG_ERROR, "EndOfPayload(0x%x) mismatch, EndOfCapsule(0x%x)\n", EndOfPayload, EndOfCapsule));
return EFI_INVALID_PARAMETER;
}
return EFI_UNSUPPORTED;
}
//
// Check in system FMP capsule
//
if (IsSystemFmp != NULL) {
*IsSystemFmp = IsSystemFmpCapsuleImage (CapsuleHeader);
}
if (EmbeddedDriverCount != NULL) {
*EmbeddedDriverCount = FmpCapsuleHeader->EmbeddedDriverCount;
}
return EFI_SUCCESS;
}
/**
Recovery module entrypoint
@param[in] FileHandle Handle of the file being invoked.
@param[in] PeiServices Describes the list of possible PEI Services.
@return EFI_SUCCESS Recovery module is initialized.
**/
EFI_STATUS
EFIAPI
InitializeRecoveryModule (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
UINTN BootMode;
BootMode = GetBootModeHob ();
ASSERT (BootMode == BOOT_IN_RECOVERY_MODE);
Status = (**PeiServices).InstallPpi (PeiServices, &mRecoveryPpiList);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
Create hob and install FvInfo PPI for recovery capsule.
@param[in] FvImage Points to the DXE FV image.
@param[in] FvImageSize The length of the DXE FV image in bytes.
@retval EFI_SUCCESS Create hob and install FvInfo PPI successfully.
@retval EFI_VOLUME_CORRUPTED The input data is not an FV.
@retval EFI_OUT_OF_RESOURCES No enough resource to process the input data.
**/
EFI_STATUS
EFIAPI
CreateHobForRecoveryCapsule (
IN VOID *FvImage,
IN UINTN FvImageSize
)
{
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
UINT32 FvAlignment;
UINT64 FvLength;
VOID *NewFvBuffer;
//
// FvImage should be at its required alignment.
//
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvImage;
//
// Validate FV Header, if not as expected, return
//
if (ReadUnaligned32 (&FvHeader->Signature) != EFI_FVH_SIGNATURE) {
DEBUG ((DEBUG_ERROR, "CreateHobForRecoveryCapsule (Fv Signature Error)\n"));
return EFI_VOLUME_CORRUPTED;
}
//
// If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume
// can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from
// its initial linked location and maintain its alignment.
//
if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {
//
// Get FvHeader alignment
//
FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);
//
// FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
//
if (FvAlignment < 8) {
FvAlignment = 8;
}
//
// Allocate the aligned buffer for the FvImage.
//
if ((UINTN)FvHeader % FvAlignment != 0) {
DEBUG ((DEBUG_INFO, "CreateHobForRecoveryCapsule (FvHeader 0x%lx is not aligned)\n", (UINT64)(UINTN)FvHeader));
FvLength = ReadUnaligned64 (&FvHeader->FvLength);
NewFvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN)FvLength), FvAlignment);
if (NewFvBuffer == NULL) {
DEBUG ((DEBUG_ERROR, "CreateHobForRecoveryCapsule (Not enough resource to allocate 0x%lx bytes)\n", FvLength));
return EFI_OUT_OF_RESOURCES;
}
CopyMem (NewFvBuffer, FvHeader, (UINTN)FvLength);
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)NewFvBuffer;
}
}
BuildFvHob ((UINT64)(UINTN)FvHeader, FvHeader->FvLength);
DEBUG ((DEBUG_INFO, "BuildFvHob (FV in recovery) - 0x%lx - 0x%lx\n", (UINT64)(UINTN)FvHeader, FvHeader->FvLength));
PeiServicesInstallFvInfoPpi (
&FvHeader->FileSystemGuid,
(VOID *)FvHeader,
(UINT32)FvHeader->FvLength,
NULL,
NULL
);
return EFI_SUCCESS;
}
/**
Create recovery context based upon System Firmware image and config file.
@param[in] SystemFirmwareImage Points to the System Firmware image.
@param[in] SystemFirmwareImageSize The length of the System Firmware image in bytes.
@param[in] ConfigImage Points to the config file image.
@param[in] ConfigImageSize The length of the config file image in bytes.
@retval EFI_SUCCESS Process Recovery Image successfully.
**/
EFI_STATUS
RecoverImage (
IN VOID *SystemFirmwareImage,
IN UINTN SystemFirmwareImageSize,
IN VOID *ConfigImage,
IN UINTN ConfigImageSize
)
{
EFI_STATUS Status;
RECOVERY_CONFIG_DATA *ConfigData;
RECOVERY_CONFIG_DATA *RecoveryConfigData;
CONFIG_HEADER ConfigHeader;
UINTN Index;
if (ConfigImage == NULL) {
DEBUG ((DEBUG_INFO, "RecoverImage (NoConfig)\n"));
Status = CreateHobForRecoveryCapsule (
SystemFirmwareImage,
SystemFirmwareImageSize
);
return Status;
}
ConfigData = NULL;
ZeroMem (&ConfigHeader, sizeof (ConfigHeader));
Status = ParseRecoveryDataFile (
ConfigImage,
ConfigImageSize,
&ConfigHeader,
&ConfigData
);
DEBUG ((DEBUG_INFO, "ParseRecoveryDataFile - %r\n", Status));
if (EFI_ERROR (Status)) {
return Status;
}
DEBUG ((DEBUG_INFO, "ConfigHeader.NumOfRecovery - 0x%x\n", ConfigHeader.NumOfRecovery));
DEBUG ((DEBUG_INFO, "PcdEdkiiSystemFirmwareFileGuid - %g\n", PcdGetPtr (PcdEdkiiSystemFirmwareFileGuid)));
Index = 0;
RecoveryConfigData = ConfigData;
while (Index < ConfigHeader.NumOfRecovery) {
if (CompareGuid (&RecoveryConfigData->FileGuid, PcdGetPtr (PcdEdkiiSystemFirmwareFileGuid))) {
DEBUG ((DEBUG_INFO, "FileGuid - %g (processing)\n", &RecoveryConfigData->FileGuid));
Status = CreateHobForRecoveryCapsule (
(UINT8 *)SystemFirmwareImage + RecoveryConfigData->ImageOffset,
RecoveryConfigData->Length
);
//
// Shall updates be serialized so that if a recovery FV is not successfully completed,
// the remaining updates won't be performed.
//
if (EFI_ERROR (Status)) {
break;
}
} else {
DEBUG ((DEBUG_INFO, "FileGuid - %g (ignored)\n", &RecoveryConfigData->FileGuid));
}
Index++;
RecoveryConfigData++;
}
return Status;
}
/**
Process recovery image.
Caution: This function may receive untrusted input.
@param[in] Image Points to the recovery image.
@param[in] Length The length of the recovery image in bytes.
@retval EFI_SUCCESS Process Recovery Image successfully.
@retval EFI_SECURITY_VIOLATION Recovery image is not processed due to security violation.
**/
EFI_STATUS
ProcessRecoveryImage (
IN VOID *Image,
IN UINTN Length
)
{
UINT32 LastAttemptVersion;
UINT32 LastAttemptStatus;
EFI_STATUS Status;
VOID *SystemFirmwareImage;
UINTN SystemFirmwareImageSize;
VOID *ConfigImage;
UINTN ConfigImageSize;
VOID *AuthenticatedImage;
UINTN AuthenticatedImageSize;
AuthenticatedImage = NULL;
AuthenticatedImageSize = 0;
Status = CapsuleAuthenticateSystemFirmware (Image, Length, TRUE, &LastAttemptVersion, &LastAttemptStatus, &AuthenticatedImage, &AuthenticatedImageSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "CapsuleAuthenticateSystemFirmware - %r\n", Status));
return Status;
}
ExtractSystemFirmwareImage (AuthenticatedImage, AuthenticatedImageSize, &SystemFirmwareImage, &SystemFirmwareImageSize);
ExtractConfigImage (AuthenticatedImage, AuthenticatedImageSize, &ConfigImage, &ConfigImageSize);
Status = RecoverImage (SystemFirmwareImage, SystemFirmwareImageSize, ConfigImage, ConfigImageSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "RecoverImage - %r\n", Status));
return Status;
}
return EFI_SUCCESS;
}
/**
Process Firmware management protocol data capsule.
Caution: This function may receive untrusted input.
This function assumes the caller validated the capsule by using
ValidateFmpCapsule(), so that all fields in EFI_CAPSULE_HEADER,
EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER and
EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER are correct.
@param[in] CapsuleHeader Points to a capsule header.
@param[in] IsSystemFmp If this capsule is a system FMP capsule.
@retval EFI_SUCCESS Process Capsule Image successfully.
@retval EFI_UNSUPPORTED Capsule image is not supported by the firmware.
@retval EFI_VOLUME_CORRUPTED FV volume in the capsule is corrupted.
@retval EFI_OUT_OF_RESOURCES Not enough memory.
**/
EFI_STATUS
ProcessFmpCapsuleImage (
IN EFI_CAPSULE_HEADER *CapsuleHeader,
IN BOOLEAN IsSystemFmp
)
{
EFI_STATUS Status;
EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *FmpCapsuleHeader;
EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *ImageHeader;
UINT8 *Image;
UINT64 *ItemOffsetList;
UINTN ItemIndex;
if (!IsSystemFmp) {
return EFI_UNSUPPORTED;
}
FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);
for (ItemIndex = 0; ItemIndex < FmpCapsuleHeader->PayloadItemCount; ItemIndex++) {
ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[ItemIndex]);
if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {
Image = (UINT8 *)(ImageHeader + 1);
} else {
//
// If the EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER is version 1, only match ImageTypeId.
// Header should exclude UpdateHardwareInstance field.
// If version is 2 Header should exclude ImageCapsuleSupport field.
//
if (ImageHeader->Version == 1) {
Image = (UINT8 *)ImageHeader + OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance);
} else {
Image = (UINT8 *)ImageHeader + OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, ImageCapsuleSupport);
}
}
Status = ProcessRecoveryImage (Image, ImageHeader->UpdateImageSize);
if (EFI_ERROR (Status)) {
return Status;
}
}
return EFI_SUCCESS;
}
/**
Process recovery capsule image.
Caution: This function may receive untrusted input.
@param[in] CapsuleBuffer The capsule image buffer.
@param[in] CapsuleSize The size of the capsule image in bytes.
@retval EFI_SUCCESS The recovery capsule is processed.
@retval EFI_SECURITY_VIOLATION The recovery capsule is not process because of security violation.
@retval EFI_NOT_FOUND The recovery capsule is not process because of unrecognization.
**/
EFI_STATUS
EFIAPI
ProcessRecoveryCapsule (
IN VOID *CapsuleBuffer,
IN UINTN CapsuleSize
)
{
EFI_STATUS Status;
BOOLEAN IsSystemFmp;
EFI_CAPSULE_HEADER *CapsuleHeader;
CapsuleHeader = CapsuleBuffer;
if (!IsValidCapsuleHeader (CapsuleHeader, CapsuleSize)) {
DEBUG ((DEBUG_ERROR, "CapsuleImageSize incorrect\n"));
return EFI_SECURITY_VIOLATION;
}
//
// Check FMP capsule layout
//
if (IsFmpCapsuleGuid (&CapsuleHeader->CapsuleGuid)) {
DEBUG ((DEBUG_INFO, "CreateHobForRecoveryCapsule\n"));
DEBUG ((DEBUG_INFO, "ProcessCapsuleImage for FmpCapsule ...\n"));
DEBUG ((DEBUG_INFO, "ValidateFmpCapsule ...\n"));
Status = ValidateFmpCapsule (CapsuleHeader, &IsSystemFmp, NULL);
DEBUG ((DEBUG_INFO, "ValidateFmpCapsule - %r\n", Status));
if (EFI_ERROR (Status)) {
return Status;
}
//
// Process EFI FMP Capsule
//
DEBUG ((DEBUG_INFO, "ProcessFmpCapsuleImage ...\n"));
Status = ProcessFmpCapsuleImage (CapsuleHeader, IsSystemFmp);
DEBUG ((DEBUG_INFO, "ProcessFmpCapsuleImage - %r\n", Status));
DEBUG ((DEBUG_INFO, "CreateHobForRecoveryCapsule Done\n"));
return Status;
}
return EFI_UNSUPPORTED;
}
/**
Loads a DXE capsule from some media into memory and updates the HOB table
with the DXE firmware volume information.
@param[in] PeiServices General-purpose services that are available to every PEIM.
@param[in] This Indicates the EFI_PEI_RECOVERY_MODULE_PPI instance.
@retval EFI_SUCCESS The capsule was loaded correctly.
@retval EFI_DEVICE_ERROR A device error occurred.
@retval EFI_NOT_FOUND A recovery DXE capsule cannot be found.
**/
EFI_STATUS
EFIAPI
LoadRecoveryCapsule (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_RECOVERY_MODULE_PPI *This
)
{
EFI_STATUS Status;
EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *DeviceRecoveryPpi;
UINTN NumberRecoveryCapsules;
UINTN Instance;
UINTN CapsuleInstance;
UINTN CapsuleSize;
EFI_GUID CapsuleType;
VOID *CapsuleBuffer;
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Recovery Entry\n"));
for (Instance = 0; ; Instance++) {
Status = PeiServicesLocatePpi (
&gEfiPeiDeviceRecoveryModulePpiGuid,
Instance,
NULL,
(VOID **)&DeviceRecoveryPpi
);
DEBUG ((DEBUG_ERROR, "LoadRecoveryCapsule - LocateRecoveryPpi (%d) - %r\n", Instance, Status));
if (EFI_ERROR (Status)) {
break;
}
NumberRecoveryCapsules = 0;
Status = DeviceRecoveryPpi->GetNumberRecoveryCapsules (
(EFI_PEI_SERVICES **)PeiServices,
DeviceRecoveryPpi,
&NumberRecoveryCapsules
);
DEBUG ((DEBUG_ERROR, "LoadRecoveryCapsule - GetNumberRecoveryCapsules (%d) - %r\n", NumberRecoveryCapsules, Status));
if (EFI_ERROR (Status)) {
continue;
}
for (CapsuleInstance = 1; CapsuleInstance <= NumberRecoveryCapsules; CapsuleInstance++) {
CapsuleSize = 0;
Status = DeviceRecoveryPpi->GetRecoveryCapsuleInfo (
(EFI_PEI_SERVICES **)PeiServices,
DeviceRecoveryPpi,
CapsuleInstance,
&CapsuleSize,
&CapsuleType
);
DEBUG ((DEBUG_ERROR, "LoadRecoveryCapsule - GetRecoveryCapsuleInfo (%d - %x) - %r\n", CapsuleInstance, CapsuleSize, Status));
if (EFI_ERROR (Status)) {
break;
}
CapsuleBuffer = AllocatePages (EFI_SIZE_TO_PAGES (CapsuleSize));
if (CapsuleBuffer == NULL) {
DEBUG ((DEBUG_ERROR, "LoadRecoveryCapsule - AllocatePool fail\n"));
continue;
}
Status = DeviceRecoveryPpi->LoadRecoveryCapsule (
(EFI_PEI_SERVICES **)PeiServices,
DeviceRecoveryPpi,
CapsuleInstance,
CapsuleBuffer
);
DEBUG ((DEBUG_ERROR, "LoadRecoveryCapsule - LoadRecoveryCapsule (%d) - %r\n", CapsuleInstance, Status));
if (EFI_ERROR (Status)) {
FreePages (CapsuleBuffer, EFI_SIZE_TO_PAGES (CapsuleSize));
break;
}
//
// good, load capsule buffer
//
Status = ProcessRecoveryCapsule (CapsuleBuffer, CapsuleSize);
return Status;
}
}
return EFI_NOT_FOUND;
}

View file

@ -1,34 +0,0 @@
/** @file
Recovery module header file.
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#pragma once
#include <PiPei.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/HobLib.h>
#include <Library/EdkiiSystemCapsuleLib.h>
//
// Update data
//
typedef struct {
UINTN NumOfRecovery;
} CONFIG_HEADER;
typedef struct {
UINTN Index;
EFI_GUID FileGuid;
UINTN Length;
UINTN ImageOffset;
} RECOVERY_CONFIG_DATA;

View file

@ -1,73 +0,0 @@
## @file
# Recovery module.
#
# Load Recovery capsule and install FV.
#
# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = RecoveryModuleLoadPei
MODULE_UNI_FILE = RecoveryModuleLoadPei.uni
FILE_GUID = 4278A574-4769-4D60-B090-DD4916691590
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
ENTRY_POINT = InitializeRecoveryModule
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 EBC
#
[Sources]
RecoveryModuleLoadPei.h
RecoveryModuleLoadPei.c
ParseConfigProfile.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SignedCapsulePkg/SignedCapsulePkg.dec
[LibraryClasses]
PeimEntryPoint
DebugLib
HobLib
BaseMemoryLib
MemoryAllocationLib
EdkiiSystemCapsuleLib
IniParsingLib
PrintLib
[Ppis]
gEfiPeiRecoveryModulePpiGuid ## PRODUCES
gEfiPeiDeviceRecoveryModulePpiGuid ## CONSUMES
[Guids]
gEfiFmpCapsuleGuid ## SOMETIMES_CONSUMES ## GUID
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid ## CONSUMES
gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid ## CONSUMES
[depex]
gEfiPeiBootInRecoveryModePpiGuid
[BuildOptions]
# 4KB alignment required because this module exceeds maximum size
# for some NOOPT build configurations. This is a post-memory PEIM
# that can be compressed, so size impacts for 4KB alignment can be
# minimized. Must be in DLINK2_FLAGS to override DLINK_XIPFLAGS
# for GCC PEIM build rules flags ordering.
GCC:*_*_*_DLINK2_FLAGS = -z common-page-size=0x1000
CLANGPDB:*_*_*_DLINK2_FLAGS =
[UserExtensions.TianoCore."ExtraFiles"]
RecoveryModuleLoadPeiExtra.uni

View file

@ -1,15 +0,0 @@
// /** @file
// Recovery module.
//
// Load Recovery capsule and install FV.
//
// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "Recovery module."
#string STR_MODULE_DESCRIPTION #language en-US "Load Recovery capsule and install FV."

View file

@ -1,14 +0,0 @@
// /** @file
// RecoveryModuleLoadPei Localized Strings and Content
//
// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_PROPERTIES_MODULE_NAME
#language en-US
"RecoveryModuleLoad PEI Driver"

View file

@ -1,216 +0,0 @@
/** @file
Parse the INI configuration file and pass the information to the update driver
so that the driver can perform update accordingly.
Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "SystemFirmwareDxe.h"
#include <Library/IniParsingLib.h>
#include <Library/PrintLib.h>
#define MAX_LINE_LENGTH 512
/**
Parse Config data file to get the updated data array.
@param[in] DataBuffer Config raw file buffer.
@param[in] BufferSize Size of raw buffer.
@param[in, out] ConfigHeader Pointer to the config header.
@param[in, out] UpdateArray Pointer to the config of update data.
@retval EFI_NOT_FOUND No config data is found.
@retval EFI_OUT_OF_RESOURCES No enough memory is allocated.
@retval EFI_SUCCESS Parse the config file successfully.
**/
EFI_STATUS
ParseUpdateDataFile (
IN UINT8 *DataBuffer,
IN UINTN BufferSize,
IN OUT CONFIG_HEADER *ConfigHeader,
IN OUT UPDATE_CONFIG_DATA **UpdateArray
)
{
EFI_STATUS Status;
CHAR8 *SectionName;
CHAR8 Entry[MAX_LINE_LENGTH];
UINTN Num;
UINT64 Num64;
UINTN Index;
EFI_GUID FileGuid;
VOID *Context;
//
// First process the data buffer and get all sections and entries
//
Context = OpenIniFile (DataBuffer, BufferSize);
if (Context == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Now get NumOfUpdate
//
Status = GetDecimalUintnFromDataFile (
Context,
"Head",
"NumOfUpdate",
&Num
);
if (EFI_ERROR (Status) || (Num == 0)) {
DEBUG ((DEBUG_ERROR, "NumOfUpdate not found\n"));
CloseIniFile (Context);
return EFI_NOT_FOUND;
}
ConfigHeader->NumOfUpdates = Num;
*UpdateArray = AllocateZeroPool ((sizeof (UPDATE_CONFIG_DATA) * Num));
if (*UpdateArray == NULL) {
CloseIniFile (Context);
return EFI_OUT_OF_RESOURCES;
}
for (Index = 0; Index < ConfigHeader->NumOfUpdates; Index++) {
//
// Get the section name of each update
//
AsciiStrCpyS (Entry, MAX_LINE_LENGTH, "Update");
AsciiValueToStringS (
Entry + AsciiStrnLenS (Entry, MAX_LINE_LENGTH),
MAX_LINE_LENGTH - AsciiStrnLenS (Entry, MAX_LINE_LENGTH),
0,
Index,
0
);
Status = GetStringFromDataFile (
Context,
"Head",
Entry,
&SectionName
);
if (EFI_ERROR (Status) || (SectionName == NULL)) {
DEBUG ((DEBUG_ERROR, "[%d] %a not found\n", Index, Entry));
CloseIniFile (Context);
return EFI_NOT_FOUND;
}
//
// The section name of this update has been found.
// Now looks for all the config data of this update
//
(*UpdateArray)[Index].Index = Index;
//
// FirmwareType
//
Status = GetDecimalUintnFromDataFile (
Context,
SectionName,
"FirmwareType",
&Num
);
if (EFI_ERROR (Status)) {
CloseIniFile (Context);
DEBUG ((DEBUG_ERROR, "[%d] FirmwareType not found\n", Index));
return EFI_NOT_FOUND;
}
(*UpdateArray)[Index].FirmwareType = (PLATFORM_FIRMWARE_TYPE)Num;
//
// AddressType
//
Status = GetDecimalUintnFromDataFile (
Context,
SectionName,
"AddressType",
&Num
);
if (EFI_ERROR (Status)) {
CloseIniFile (Context);
DEBUG ((DEBUG_ERROR, "[%d] AddressType not found\n", Index));
return EFI_NOT_FOUND;
}
(*UpdateArray)[Index].AddressType = (FLASH_ADDRESS_TYPE)Num;
//
// BaseAddress
//
Status = GetHexUint64FromDataFile (
Context,
SectionName,
"BaseAddress",
&Num64
);
if (EFI_ERROR (Status)) {
CloseIniFile (Context);
DEBUG ((DEBUG_ERROR, "[%d] BaseAddress not found\n", Index));
return EFI_NOT_FOUND;
}
(*UpdateArray)[Index].BaseAddress = (EFI_PHYSICAL_ADDRESS)Num64;
//
// FileGuid
//
Status = GetGuidFromDataFile (
Context,
SectionName,
"FileGuid",
&FileGuid
);
if (EFI_ERROR (Status)) {
CloseIniFile (Context);
DEBUG ((DEBUG_ERROR, "[%d] FileGuid not found\n", Index));
return EFI_NOT_FOUND;
}
CopyGuid (&((*UpdateArray)[Index].FileGuid), &FileGuid);
//
// Length
//
Status = GetHexUintnFromDataFile (
Context,
SectionName,
"Length",
&Num
);
if (EFI_ERROR (Status)) {
CloseIniFile (Context);
DEBUG ((DEBUG_ERROR, "[%d] Length not found\n", Index));
return EFI_NOT_FOUND;
}
(*UpdateArray)[Index].Length = (UINTN)Num;
//
// ImageOffset
//
Status = GetHexUintnFromDataFile (
Context,
SectionName,
"ImageOffset",
&Num
);
if (EFI_ERROR (Status)) {
CloseIniFile (Context);
DEBUG ((DEBUG_ERROR, "[%d] ImageOffset not found\n", Index));
return EFI_NOT_FOUND;
}
(*UpdateArray)[Index].ImageOffset = (UINTN)Num;
}
//
// Now all configuration data got. Free those temporary buffers
//
CloseIniFile (Context);
return EFI_SUCCESS;
}

View file

@ -1,344 +0,0 @@
/** @file
Produce FMP instance for system firmware.
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "SystemFirmwareDxe.h"
EFI_GUID gSystemFmpLastAttemptVariableGuid = SYSTEM_FMP_LAST_ATTEMPT_VARIABLE_GUID;
EFI_GUID gSystemFmpProtocolGuid = SYSTEM_FMP_PROTOCOL_GUID;
EFI_FIRMWARE_MANAGEMENT_PROTOCOL mFirmwareManagementProtocol = {
FmpGetImageInfo,
FmpGetImage,
FmpSetImage,
FmpCheckImage,
FmpGetPackageInfo,
FmpSetPackageInfo
};
/**
Returns information about the current firmware image(s) of the device.
This function allows a copy of the current firmware image to be created and saved.
The saved copy could later been used, for example, in firmware image recovery or rollback.
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
@param[in, out] ImageInfoSize A pointer to the size, in bytes, of the ImageInfo buffer.
On input, this is the size of the buffer allocated by the caller.
On output, it is the size of the buffer returned by the firmware
if the buffer was large enough, or the size of the buffer needed
to contain the image(s) information if the buffer was too small.
@param[in, out] ImageInfo A pointer to the buffer in which firmware places the current image(s)
information. The information is an array of EFI_FIRMWARE_IMAGE_DESCRIPTORs.
@param[out] DescriptorVersion A pointer to the location in which firmware returns the version number
associated with the EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] DescriptorCount A pointer to the location in which firmware returns the number of
descriptors or firmware images within this device.
@param[out] DescriptorSize A pointer to the location in which firmware returns the size, in bytes,
of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] PackageVersion A version number that represents all the firmware images in the device.
The format is vendor specific and new version must have a greater value
than the old version. If PackageVersion is not supported, the value is
0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version comparison
is to be performed using PackageVersionName. A value of 0xFFFFFFFD indicates
that package version update is in progress.
@param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing the
package version name. The buffer is allocated by this function with
AllocatePool(), and it is the caller's responsibility to free it with a call
to FreePool().
@retval EFI_SUCCESS The device was successfully updated with the new image.
@retval EFI_BUFFER_TOO_SMALL The ImageInfo buffer was too small. The current buffer size
needed to hold the image(s) information is returned in ImageInfoSize.
@retval EFI_INVALID_PARAMETER ImageInfoSize is NULL.
@retval EFI_DEVICE_ERROR Valid information could not be returned. Possible corrupted image.
**/
EFI_STATUS
EFIAPI
FmpGetImageInfo (
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
IN OUT UINTN *ImageInfoSize,
IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,
OUT UINT32 *DescriptorVersion,
OUT UINT8 *DescriptorCount,
OUT UINTN *DescriptorSize,
OUT UINT32 *PackageVersion,
OUT CHAR16 **PackageVersionName
)
{
SYSTEM_FMP_PRIVATE_DATA *SystemFmpPrivate;
EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor;
SystemFmpPrivate = SYSTEM_FMP_PRIVATE_DATA_FROM_FMP (This);
if (ImageInfoSize == NULL) {
return EFI_INVALID_PARAMETER;
}
if (*ImageInfoSize < sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR) * SystemFmpPrivate->DescriptorCount) {
*ImageInfoSize = sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR) * SystemFmpPrivate->DescriptorCount;
return EFI_BUFFER_TOO_SMALL;
}
if ((ImageInfo == NULL) ||
(DescriptorVersion == NULL) ||
(DescriptorCount == NULL) ||
(DescriptorSize == NULL) ||
(PackageVersion == NULL) ||
(PackageVersionName == NULL))
{
return EFI_INVALID_PARAMETER;
}
*ImageInfoSize = sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR) * SystemFmpPrivate->DescriptorCount;
*DescriptorSize = sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR);
*DescriptorCount = SystemFmpPrivate->DescriptorCount;
*DescriptorVersion = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
//
// supports 1 ImageInfo descriptor
//
ImageDescriptor = SystemFmpPrivate->ImageDescriptor;
ImageInfo->ImageIndex = ImageDescriptor->ImageIndex;
CopyGuid (&ImageInfo->ImageTypeId, &ImageDescriptor->ImageTypeId);
ImageInfo->ImageId = ImageDescriptor->ImageId;
if (ImageDescriptor->ImageIdNameStringOffset != 0) {
ImageInfo->ImageIdName = (CHAR16 *)((UINTN)ImageDescriptor + ImageDescriptor->ImageIdNameStringOffset);
} else {
ImageInfo->ImageIdName = NULL;
}
ImageInfo->Version = ImageDescriptor->Version;
if (ImageDescriptor->VersionNameStringOffset != 0) {
ImageInfo->VersionName = (CHAR16 *)((UINTN)ImageDescriptor + ImageDescriptor->VersionNameStringOffset);
} else {
ImageInfo->VersionName = NULL;
}
ImageInfo->Size = (UINTN)ImageDescriptor->Size;
ImageInfo->AttributesSupported = ImageDescriptor->AttributesSupported;
ImageInfo->AttributesSetting = ImageDescriptor->AttributesSetting;
ImageInfo->Compatibilities = ImageDescriptor->Compatibilities;
ImageInfo->LowestSupportedImageVersion = ImageDescriptor->LowestSupportedImageVersion;
ImageInfo->LastAttemptVersion = SystemFmpPrivate->LastAttempt.LastAttemptVersion;
ImageInfo->LastAttemptStatus = SystemFmpPrivate->LastAttempt.LastAttemptStatus;
ImageInfo->HardwareInstance = ImageDescriptor->HardwareInstance;
//
// package version
//
*PackageVersion = ImageDescriptor->PackageVersion;
if (ImageDescriptor->PackageVersionNameStringOffset != 0) {
*PackageVersionName = (VOID *)((UINTN)ImageDescriptor + ImageDescriptor->PackageVersionNameStringOffset);
*PackageVersionName = AllocateCopyPool (StrSize (*PackageVersionName), *PackageVersionName);
} else {
*PackageVersionName = NULL;
}
return EFI_SUCCESS;
}
/**
Retrieves a copy of the current firmware image of the device.
This function allows a copy of the current firmware image to be created and saved.
The saved copy could later been used, for example, in firmware image recovery or rollback.
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
@param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
The number is between 1 and DescriptorCount.
@param[in,out] Image Points to the buffer where the current image is copied to.
@param[in,out] ImageSize On entry, points to the size of the buffer pointed to by Image, in bytes.
On return, points to the length of the image, in bytes.
@retval EFI_SUCCESS The device was successfully updated with the new image.
@retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to hold the
image. The current buffer size needed to hold the image is returned
in ImageSize.
@retval EFI_INVALID_PARAMETER The Image was NULL.
@retval EFI_NOT_FOUND The current image is not copied to the buffer.
@retval EFI_UNSUPPORTED The operation is not supported.
@retval EFI_SECURITY_VIOLATION The operation could not be completed due to an image corruption.
If the image is able to be read, the Image buffer will be updated
with the retrieved image contents.
@retval EFI_DEVICE_ERROR The image could not be read.
**/
EFI_STATUS
EFIAPI
FmpGetImage (
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
IN UINT8 ImageIndex,
IN OUT VOID *Image,
IN OUT UINTN *ImageSize
)
{
return EFI_UNSUPPORTED;
}
/**
Checks if the firmware image is valid for the device.
This function allows firmware update application to validate the firmware image without
invoking the SetImage() first.
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
@param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
The number is between 1 and DescriptorCount.
@param[in] Image Points to the new image.
@param[in] ImageSize Size of the new image in bytes.
@param[out] ImageUpdatable Indicates if the new image is valid for update. It also provides,
if available, additional information if the image is invalid.
@retval EFI_SUCCESS The image was successfully checked.
@retval EFI_INVALID_PARAMETER The Image was NULL.
@retval EFI_UNSUPPORTED The operation is not supported.
@retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
**/
EFI_STATUS
EFIAPI
FmpCheckImage (
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
IN UINT8 ImageIndex,
IN CONST VOID *Image,
IN UINTN ImageSize,
OUT UINT32 *ImageUpdatable
)
{
return EFI_UNSUPPORTED;
}
/**
Returns information about the firmware package.
This function returns package information.
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
@param[out] PackageVersion A version number that represents all the firmware images in the device.
The format is vendor specific and new version must have a greater value
than the old version. If PackageVersion is not supported, the value is
0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version
comparison is to be performed using PackageVersionName. A value of
0xFFFFFFFD indicates that package version update is in progress.
@param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing
the package version name. The buffer is allocated by this function with
AllocatePool(), and it is the caller's responsibility to free it with a
call to FreePool().
@param[out] PackageVersionNameMaxLen The maximum length of package version name if device supports update of
package version name. A value of 0 indicates the device does not support
update of package version name. Length is the number of Unicode characters,
including the terminating null character.
@param[out] AttributesSupported Package attributes that are supported by this device. See 'Package Attribute
Definitions' for possible returned values of this parameter. A value of 1
indicates the attribute is supported and the current setting value is
indicated in AttributesSetting. A value of 0 indicates the attribute is not
supported and the current setting value in AttributesSetting is meaningless.
@param[out] AttributesSetting Package attributes. See 'Package Attribute Definitions' for possible returned
values of this parameter
@retval EFI_SUCCESS The package information was successfully returned.
@retval EFI_UNSUPPORTED The operation is not supported.
**/
EFI_STATUS
EFIAPI
FmpGetPackageInfo (
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
OUT UINT32 *PackageVersion,
OUT CHAR16 **PackageVersionName,
OUT UINT32 *PackageVersionNameMaxLen,
OUT UINT64 *AttributesSupported,
OUT UINT64 *AttributesSetting
)
{
return EFI_UNSUPPORTED;
}
/**
Updates information about the firmware package.
This function updates package information.
This function returns EFI_UNSUPPORTED if the package information is not updatable.
VendorCode enables vendor to implement vendor-specific package information update policy.
Null if the caller did not specify this policy or use the default policy.
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
@param[in] Image Points to the authentication image.
Null if authentication is not required.
@param[in] ImageSize Size of the authentication image in bytes.
0 if authentication is not required.
@param[in] VendorCode This enables vendor to implement vendor-specific firmware
image update policy.
Null indicates the caller did not specify this policy or use
the default policy.
@param[in] PackageVersion The new package version.
@param[in] PackageVersionName A pointer to the new null-terminated Unicode string representing
the package version name.
The string length is equal to or less than the value returned in
PackageVersionNameMaxLen.
@retval EFI_SUCCESS The device was successfully updated with the new package
information.
@retval EFI_INVALID_PARAMETER The PackageVersionName length is longer than the value
returned in PackageVersionNameMaxLen.
@retval EFI_UNSUPPORTED The operation is not supported.
@retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
**/
EFI_STATUS
EFIAPI
FmpSetPackageInfo (
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
IN CONST VOID *Image,
IN UINTN ImageSize,
IN CONST VOID *VendorCode,
IN UINT32 PackageVersion,
IN CONST CHAR16 *PackageVersionName
)
{
return EFI_UNSUPPORTED;
}
/**
Initialize SystemFmpDriver private data structure.
@param[in] SystemFmpPrivate private data structure to be initialized.
@return EFI_SUCCESS private data is initialized.
**/
EFI_STATUS
InitializePrivateData (
IN SYSTEM_FMP_PRIVATE_DATA *SystemFmpPrivate
)
{
EFI_STATUS VarStatus;
UINTN VarSize;
SystemFmpPrivate->Signature = SYSTEM_FMP_PRIVATE_DATA_SIGNATURE;
SystemFmpPrivate->Handle = NULL;
SystemFmpPrivate->DescriptorCount = 1;
CopyMem (&SystemFmpPrivate->Fmp, &mFirmwareManagementProtocol, sizeof (EFI_FIRMWARE_MANAGEMENT_PROTOCOL));
SystemFmpPrivate->ImageDescriptor = PcdGetPtr (PcdEdkiiSystemFirmwareImageDescriptor);
SystemFmpPrivate->LastAttempt.LastAttemptVersion = 0x0;
SystemFmpPrivate->LastAttempt.LastAttemptStatus = 0x0;
VarSize = sizeof (SystemFmpPrivate->LastAttempt);
VarStatus = gRT->GetVariable (
SYSTEM_FMP_LAST_ATTEMPT_VARIABLE_NAME,
&gSystemFmpLastAttemptVariableGuid,
NULL,
&VarSize,
&SystemFmpPrivate->LastAttempt
);
DEBUG ((DEBUG_INFO, "GetLastAttempt - %r\n", VarStatus));
DEBUG ((DEBUG_INFO, "GetLastAttempt Version - 0x%x, State - 0x%x\n", SystemFmpPrivate->LastAttempt.LastAttemptVersion, SystemFmpPrivate->LastAttempt.LastAttemptStatus));
return EFI_SUCCESS;
}

View file

@ -1,395 +0,0 @@
/** @file
System Firmware update header file.
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#pragma once
#include <PiDxe.h>
#include <Guid/SystemResourceTable.h>
#include <Guid/FirmwareContentsSigned.h>
#include <Guid/WinCertificate.h>
#include <Guid/EdkiiSystemFmpCapsule.h>
#include <Protocol/FirmwareManagement.h>
#include <Protocol/FirmwareVolumeBlock.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/DevicePathLib.h>
#include <Library/HobLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/PlatformFlashAccessLib.h>
#include <Library/EdkiiSystemCapsuleLib.h>
typedef struct {
UINT32 LastAttemptVersion;
UINT32 LastAttemptStatus;
} SYSTEM_FMP_LAST_ATTEMPT_VARIABLE;
#define SYSTEM_FMP_LAST_ATTEMPT_VARIABLE_NAME L"SystemLastAttempVar"
#define SYSTEM_FMP_LAST_ATTEMPT_VARIABLE_GUID {0x2f564d6f, 0xcc2c, 0x4838, { 0xb9, 0xa8, 0xbe, 0x59, 0x48, 0xb0, 0x3d, 0x59 }}
#define SYSTEM_FMP_PRIVATE_DATA_SIGNATURE SIGNATURE_32('S', 'Y', 'S', 'F')
#define SYSTEM_FMP_PROTOCOL_GUID {0x6d16624a, 0x26a6, 0x4cb4, { 0x84, 0xfa, 0x6, 0x78, 0x5a, 0x7e, 0x82, 0x6a }}
//
// SYSTEM FMP private data structure.
//
struct _SYSTEM_FMP_PRIVATE_DATA {
UINT32 Signature;
EFI_FIRMWARE_MANAGEMENT_PROTOCOL Fmp;
EFI_HANDLE Handle;
UINT8 DescriptorCount;
EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor;
SYSTEM_FMP_LAST_ATTEMPT_VARIABLE LastAttempt;
};
typedef struct _SYSTEM_FMP_PRIVATE_DATA SYSTEM_FMP_PRIVATE_DATA;
/**
Returns a pointer to the SYSTEM_FMP_PRIVATE_DATA structure from the input a as Fmp.
If the signatures matches, then a pointer to the data structure that contains
a specified field of that data structure is returned.
@param a Pointer to the field specified by ServiceBinding within
a data structure of type SYSTEM_FMP_PRIVATE_DATA.
**/
#define SYSTEM_FMP_PRIVATE_DATA_FROM_FMP(a) \
CR ( \
(a), \
SYSTEM_FMP_PRIVATE_DATA, \
Fmp, \
SYSTEM_FMP_PRIVATE_DATA_SIGNATURE \
)
//
// Update data
//
typedef struct {
UINTN NumOfUpdates;
} CONFIG_HEADER;
typedef struct {
UINTN Index;
PLATFORM_FIRMWARE_TYPE FirmwareType;
FLASH_ADDRESS_TYPE AddressType;
EFI_GUID FileGuid;
EFI_PHYSICAL_ADDRESS BaseAddress;
UINTN Length;
UINTN ImageOffset;
} UPDATE_CONFIG_DATA;
//
// System Firmware Update SMM Communication
//
#define SYSTEM_FIRMWARE_UPDATE_COMMUNICATION_FUNCTION_SET_IMAGE 1
typedef struct {
UINTN Function;
EFI_STATUS ReturnStatus;
// UINT8 Data[];
} SYSTEM_FIRMWARE_UPDATE_COMMUNICATION_HEAD;
#define ABORT_REASON_MAX_SIZE 0x40 // UnicodeStringSize including final L'\0'
#define CAPSULE_IMAGE_ADDITIONAL_MAX_SIZE (0x20020 + 0xA0000) // Additional size for Capsule Header, FV block alignment + DispatchImage.
typedef struct {
UINT8 ImageIndex;
UINTN ImageSize;
UINTN AbortReasonSize;
UINT32 LastAttemptVersion;
UINT32 LastAttemptStatus;
// UINT8 Data[AbortReasonMaxSize + ImageSize];
} SYSTEM_FIRMWARE_UPDATE_COMMUNICATION_SET_IMAGE;
/**
Returns information about the current firmware image(s) of the device.
This function allows a copy of the current firmware image to be created and saved.
The saved copy could later been used, for example, in firmware image recovery or rollback.
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
@param[in, out] ImageInfoSize A pointer to the size, in bytes, of the ImageInfo buffer.
On input, this is the size of the buffer allocated by the caller.
On output, it is the size of the buffer returned by the firmware
if the buffer was large enough, or the size of the buffer needed
to contain the image(s) information if the buffer was too small.
@param[in, out] ImageInfo A pointer to the buffer in which firmware places the current image(s)
information. The information is an array of EFI_FIRMWARE_IMAGE_DESCRIPTORs.
@param[out] DescriptorVersion A pointer to the location in which firmware returns the version number
associated with the EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] DescriptorCount A pointer to the location in which firmware returns the number of
descriptors or firmware images within this device.
@param[out] DescriptorSize A pointer to the location in which firmware returns the size, in bytes,
of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] PackageVersion A version number that represents all the firmware images in the device.
The format is vendor specific and new version must have a greater value
than the old version. If PackageVersion is not supported, the value is
0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version comparison
is to be performed using PackageVersionName. A value of 0xFFFFFFFD indicates
that package version update is in progress.
@param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing the
package version name. The buffer is allocated by this function with
AllocatePool(), and it is the caller's responsibility to free it with a call
to FreePool().
@retval EFI_SUCCESS The device was successfully updated with the new image.
@retval EFI_BUFFER_TOO_SMALL The ImageInfo buffer was too small. The current buffer size
needed to hold the image(s) information is returned in ImageInfoSize.
@retval EFI_INVALID_PARAMETER ImageInfoSize is NULL.
@retval EFI_DEVICE_ERROR Valid information could not be returned. Possible corrupted image.
**/
EFI_STATUS
EFIAPI
FmpGetImageInfo (
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
IN OUT UINTN *ImageInfoSize,
IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,
OUT UINT32 *DescriptorVersion,
OUT UINT8 *DescriptorCount,
OUT UINTN *DescriptorSize,
OUT UINT32 *PackageVersion,
OUT CHAR16 **PackageVersionName
);
/**
Retrieves a copy of the current firmware image of the device.
This function allows a copy of the current firmware image to be created and saved.
The saved copy could later been used, for example, in firmware image recovery or rollback.
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
@param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
The number is between 1 and DescriptorCount.
@param[in,out] Image Points to the buffer where the current image is copied to.
@param[in,out] ImageSize On entry, points to the size of the buffer pointed to by Image, in bytes.
On return, points to the length of the image, in bytes.
@retval EFI_SUCCESS The device was successfully updated with the new image.
@retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to hold the
image. The current buffer size needed to hold the image is returned
in ImageSize.
@retval EFI_INVALID_PARAMETER The Image was NULL.
@retval EFI_NOT_FOUND The current image is not copied to the buffer.
@retval EFI_UNSUPPORTED The operation is not supported.
@retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
**/
EFI_STATUS
EFIAPI
FmpGetImage (
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
IN UINT8 ImageIndex,
IN OUT VOID *Image,
IN OUT UINTN *ImageSize
);
/**
Updates the firmware image of the device.
This function updates the hardware with the new firmware image.
This function returns EFI_UNSUPPORTED if the firmware image is not updatable.
If the firmware image is updatable, the function should perform the following minimal validations
before proceeding to do the firmware image update.
- Validate the image authentication if image has attribute
IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns
EFI_SECURITY_VIOLATION if the validation fails.
- Validate the image is a supported image for this device. The function returns EFI_ABORTED if
the image is unsupported. The function can optionally provide more detailed information on
why the image is not a supported image.
- Validate the data from VendorCode if not null. Image validation must be performed before
VendorCode data validation. VendorCode data is ignored or considered invalid if image
validation failed. The function returns EFI_ABORTED if the data is invalid.
VendorCode enables vendor to implement vendor-specific firmware image update policy. Null if
the caller did not specify the policy or use the default policy. As an example, vendor can implement
a policy to allow an option to force a firmware image update when the abort reason is due to the new
firmware image version is older than the current firmware image version or bad image checksum.
Sensitive operations such as those wiping the entire firmware image and render the device to be
non-functional should be encoded in the image itself rather than passed with the VendorCode.
AbortReason enables vendor to have the option to provide a more detailed description of the abort
reason to the caller.
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
@param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
The number is between 1 and DescriptorCount.
@param[in] Image Points to the new image.
@param[in] ImageSize Size of the new image in bytes.
@param[in] VendorCode This enables vendor to implement vendor-specific firmware image update policy.
Null indicates the caller did not specify the policy or use the default policy.
@param[in] Progress A function used by the driver to report the progress of the firmware update.
@param[out] AbortReason A pointer to a pointer to a null-terminated string providing more
details for the aborted operation. The buffer is allocated by this function
with AllocatePool(), and it is the caller's responsibility to free it with a
call to FreePool().
@retval EFI_SUCCESS The device was successfully updated with the new image.
@retval EFI_ABORTED The operation is aborted.
@retval EFI_INVALID_PARAMETER The Image was NULL.
@retval EFI_UNSUPPORTED The operation is not supported.
@retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
**/
EFI_STATUS
EFIAPI
FmpSetImage (
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
IN UINT8 ImageIndex,
IN CONST VOID *Image,
IN UINTN ImageSize,
IN CONST VOID *VendorCode,
IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress,
OUT CHAR16 **AbortReason
);
/**
Checks if the firmware image is valid for the device.
This function allows firmware update application to validate the firmware image without
invoking the SetImage() first.
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
@param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
The number is between 1 and DescriptorCount.
@param[in] Image Points to the new image.
@param[in] ImageSize Size of the new image in bytes.
@param[out] ImageUpdatable Indicates if the new image is valid for update. It also provides,
if available, additional information if the image is invalid.
@retval EFI_SUCCESS The image was successfully checked.
@retval EFI_INVALID_PARAMETER The Image was NULL.
@retval EFI_UNSUPPORTED The operation is not supported.
@retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
**/
EFI_STATUS
EFIAPI
FmpCheckImage (
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
IN UINT8 ImageIndex,
IN CONST VOID *Image,
IN UINTN ImageSize,
OUT UINT32 *ImageUpdatable
);
/**
Returns information about the firmware package.
This function returns package information.
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
@param[out] PackageVersion A version number that represents all the firmware images in the device.
The format is vendor specific and new version must have a greater value
than the old version. If PackageVersion is not supported, the value is
0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version
comparison is to be performed using PackageVersionName. A value of
0xFFFFFFFD indicates that package version update is in progress.
@param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing
the package version name. The buffer is allocated by this function with
AllocatePool(), and it is the caller's responsibility to free it with a
call to FreePool().
@param[out] PackageVersionNameMaxLen The maximum length of package version name if device supports update of
package version name. A value of 0 indicates the device does not support
update of package version name. Length is the number of Unicode characters,
including the terminating null character.
@param[out] AttributesSupported Package attributes that are supported by this device. See 'Package Attribute
Definitions' for possible returned values of this parameter. A value of 1
indicates the attribute is supported and the current setting value is
indicated in AttributesSetting. A value of 0 indicates the attribute is not
supported and the current setting value in AttributesSetting is meaningless.
@param[out] AttributesSetting Package attributes. See 'Package Attribute Definitions' for possible returned
values of this parameter
@retval EFI_SUCCESS The package information was successfully returned.
@retval EFI_UNSUPPORTED The operation is not supported.
**/
EFI_STATUS
EFIAPI
FmpGetPackageInfo (
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
OUT UINT32 *PackageVersion,
OUT CHAR16 **PackageVersionName,
OUT UINT32 *PackageVersionNameMaxLen,
OUT UINT64 *AttributesSupported,
OUT UINT64 *AttributesSetting
);
/**
Updates information about the firmware package.
This function updates package information.
This function returns EFI_UNSUPPORTED if the package information is not updatable.
VendorCode enables vendor to implement vendor-specific package information update policy.
Null if the caller did not specify this policy or use the default policy.
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
@param[in] Image Points to the authentication image.
Null if authentication is not required.
@param[in] ImageSize Size of the authentication image in bytes.
0 if authentication is not required.
@param[in] VendorCode This enables vendor to implement vendor-specific firmware
image update policy.
Null indicates the caller did not specify this policy or use
the default policy.
@param[in] PackageVersion The new package version.
@param[in] PackageVersionName A pointer to the new null-terminated Unicode string representing
the package version name.
The string length is equal to or less than the value returned in
PackageVersionNameMaxLen.
@retval EFI_SUCCESS The device was successfully updated with the new package
information.
@retval EFI_INVALID_PARAMETER The PackageVersionName length is longer than the value
returned in PackageVersionNameMaxLen.
@retval EFI_UNSUPPORTED The operation is not supported.
@retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
**/
EFI_STATUS
EFIAPI
FmpSetPackageInfo (
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
IN CONST VOID *Image,
IN UINTN ImageSize,
IN CONST VOID *VendorCode,
IN UINT32 PackageVersion,
IN CONST CHAR16 *PackageVersionName
);
/**
Initialize SystemFmpDriver private data structure.
@param[in] SystemFmpPrivate private data structure to be initialized.
@return EFI_SUCCESS private data is initialized.
**/
EFI_STATUS
InitializePrivateData (
IN SYSTEM_FMP_PRIVATE_DATA *SystemFmpPrivate
);
extern EFI_GUID gSystemFmpLastAttemptVariableGuid;
extern EFI_GUID mCurrentImageTypeId;
extern EFI_GUID gSystemFmpProtocolGuid;

View file

@ -1,270 +0,0 @@
/** @file
SetImage instance to report system firmware and act as agent to system update.
Caution: This module requires additional review when modified.
This module will have external input - capsule image.
This external input must be validated carefully to avoid security issue like
buffer overflow, integer overflow.
FmpSetImage() will receive untrusted input and do basic validation.
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "SystemFirmwareDxe.h"
//
// SystemFmp driver private data
//
SYSTEM_FMP_PRIVATE_DATA *mSystemFmpPrivate = NULL;
/**
Dispatch system FMP images.
Caution: This function may receive untrusted input.
@param[in] Image The EDKII system FMP capsule image.
@param[in] ImageSize The size of the EDKII system FMP capsule image in bytes.
@param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@retval EFI_SUCCESS Process Capsule Image successfully.
@retval EFI_UNSUPPORTED Capsule image is not supported by the firmware.
@retval EFI_VOLUME_CORRUPTED FV volume in the capsule is corrupted.
@retval EFI_OUT_OF_RESOURCES Not enough memory.
**/
EFI_STATUS
DispatchSystemFmpImages (
IN VOID *Image,
IN UINTN ImageSize,
OUT UINT32 *LastAttemptVersion,
OUT UINT32 *LastAttemptStatus
)
{
EFI_STATUS Status;
VOID *AuthenticatedImage;
UINTN AuthenticatedImageSize;
VOID *DispatchFvImage;
UINTN DispatchFvImageSize;
EFI_HANDLE FvProtocolHandle;
EFI_FIRMWARE_VOLUME_HEADER *FvImage;
BOOLEAN Result;
AuthenticatedImage = NULL;
AuthenticatedImageSize = 0;
DEBUG ((DEBUG_INFO, "DispatchSystemFmpImages\n"));
//
// Verify
//
Status = CapsuleAuthenticateSystemFirmware (Image, ImageSize, FALSE, LastAttemptVersion, LastAttemptStatus, &AuthenticatedImage, &AuthenticatedImageSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "SystemFirmwareAuthenticateImage - %r\n", Status));
return Status;
}
//
// Get FV
//
Result = ExtractDriverFvImage (AuthenticatedImage, AuthenticatedImageSize, &DispatchFvImage, &DispatchFvImageSize);
if (Result) {
DEBUG ((DEBUG_INFO, "ExtractDriverFvImage\n"));
//
// Dispatch
//
if (((EFI_FIRMWARE_VOLUME_HEADER *)DispatchFvImage)->FvLength == DispatchFvImageSize) {
FvImage = AllocatePages (EFI_SIZE_TO_PAGES (DispatchFvImageSize));
if (FvImage != NULL) {
CopyMem (FvImage, DispatchFvImage, DispatchFvImageSize);
Status = gDS->ProcessFirmwareVolume (
(VOID *)FvImage,
(UINTN)FvImage->FvLength,
&FvProtocolHandle
);
DEBUG ((DEBUG_INFO, "ProcessFirmwareVolume - %r\n", Status));
if (!EFI_ERROR (Status)) {
gDS->Dispatch ();
DEBUG ((DEBUG_INFO, "Dispatch Done\n"));
}
}
}
}
return EFI_SUCCESS;
}
/**
Updates the firmware image of the device.
This function updates the hardware with the new firmware image.
This function returns EFI_UNSUPPORTED if the firmware image is not updatable.
If the firmware image is updatable, the function should perform the following minimal validations
before proceeding to do the firmware image update.
- Validate the image authentication if image has attribute
IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns
EFI_SECURITY_VIOLATION if the validation fails.
- Validate the image is a supported image for this device. The function returns EFI_ABORTED if
the image is unsupported. The function can optionally provide more detailed information on
why the image is not a supported image.
- Validate the data from VendorCode if not null. Image validation must be performed before
VendorCode data validation. VendorCode data is ignored or considered invalid if image
validation failed. The function returns EFI_ABORTED if the data is invalid.
VendorCode enables vendor to implement vendor-specific firmware image update policy. Null if
the caller did not specify the policy or use the default policy. As an example, vendor can implement
a policy to allow an option to force a firmware image update when the abort reason is due to the new
firmware image version is older than the current firmware image version or bad image checksum.
Sensitive operations such as those wiping the entire firmware image and render the device to be
non-functional should be encoded in the image itself rather than passed with the VendorCode.
AbortReason enables vendor to have the option to provide a more detailed description of the abort
reason to the caller.
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
@param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
The number is between 1 and DescriptorCount.
@param[in] Image Points to the new image.
@param[in] ImageSize Size of the new image in bytes.
@param[in] VendorCode This enables vendor to implement vendor-specific firmware image update policy.
Null indicates the caller did not specify the policy or use the default policy.
@param[in] Progress A function used by the driver to report the progress of the firmware update.
@param[out] AbortReason A pointer to a pointer to a null-terminated string providing more
details for the aborted operation. The buffer is allocated by this function
with AllocatePool(), and it is the caller's responsibility to free it with a
call to FreePool().
@retval EFI_SUCCESS The device was successfully updated with the new image.
@retval EFI_ABORTED The operation is aborted.
@retval EFI_INVALID_PARAMETER The Image was NULL.
@retval EFI_UNSUPPORTED The operation is not supported.
@retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
**/
EFI_STATUS
EFIAPI
FmpSetImage (
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
IN UINT8 ImageIndex,
IN CONST VOID *Image,
IN UINTN ImageSize,
IN CONST VOID *VendorCode,
IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress,
OUT CHAR16 **AbortReason
)
{
SYSTEM_FMP_PRIVATE_DATA *SystemFmpPrivate;
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *SystemFmp;
EFI_STATUS Status;
EFI_STATUS VarStatus;
if ((Image == NULL) || (ImageSize == 0) || (AbortReason == NULL)) {
return EFI_INVALID_PARAMETER;
}
SystemFmpPrivate = SYSTEM_FMP_PRIVATE_DATA_FROM_FMP (This);
*AbortReason = NULL;
if ((ImageIndex == 0) || (ImageIndex > SystemFmpPrivate->DescriptorCount)) {
return EFI_INVALID_PARAMETER;
}
//
// Process FV
//
Status = DispatchSystemFmpImages ((VOID *)Image, ImageSize, &SystemFmpPrivate->LastAttempt.LastAttemptVersion, &SystemFmpPrivate->LastAttempt.LastAttemptStatus);
DEBUG ((DEBUG_INFO, "(Agent)SetImage - LastAttempt Version - 0x%x, State - 0x%x\n", SystemFmpPrivate->LastAttempt.LastAttemptVersion, SystemFmpPrivate->LastAttempt.LastAttemptStatus));
if (EFI_ERROR (Status)) {
VarStatus = gRT->SetVariable (
SYSTEM_FMP_LAST_ATTEMPT_VARIABLE_NAME,
&gSystemFmpLastAttemptVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof (SystemFmpPrivate->LastAttempt),
&SystemFmpPrivate->LastAttempt
);
DEBUG ((DEBUG_INFO, "(Agent)SetLastAttempt - %r\n", VarStatus));
return Status;
}
//
// Pass Thru to System FMP Protocol on same handle as FMP Protocol
//
Status = gBS->HandleProtocol (
SystemFmpPrivate->Handle,
&gSystemFmpProtocolGuid,
(VOID **)&SystemFmp
);
if (EFI_ERROR (Status)) {
Status = gBS->LocateProtocol (
&gSystemFmpProtocolGuid,
NULL,
(VOID **)&SystemFmp
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "(Agent)SetImage - SystemFmpProtocol - %r\n", Status));
SystemFmpPrivate->LastAttempt.LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT;
VarStatus = gRT->SetVariable (
SYSTEM_FMP_LAST_ATTEMPT_VARIABLE_NAME,
&gSystemFmpLastAttemptVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof (SystemFmpPrivate->LastAttempt),
&SystemFmpPrivate->LastAttempt
);
DEBUG ((DEBUG_INFO, "(Agent)SetLastAttempt - %r\n", VarStatus));
return Status;
}
}
return SystemFmp->SetImage (SystemFmp, ImageIndex, Image, ImageSize, VendorCode, Progress, AbortReason);
}
/**
System FMP module entrypoint
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@return EFI_SUCCESS System FMP module is initialized.
**/
EFI_STATUS
EFIAPI
SystemFirmwareReportMainDxe (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
//
// Initialize SystemFmpPrivateData
//
mSystemFmpPrivate = AllocateZeroPool (sizeof (SYSTEM_FMP_PRIVATE_DATA));
if (mSystemFmpPrivate == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = InitializePrivateData (mSystemFmpPrivate);
if (EFI_ERROR (Status)) {
FreePool (mSystemFmpPrivate);
mSystemFmpPrivate = NULL;
return Status;
}
//
// Install FMP protocol.
//
Status = gBS->InstallProtocolInterface (
&mSystemFmpPrivate->Handle,
&gEfiFirmwareManagementProtocolGuid,
EFI_NATIVE_INTERFACE,
&mSystemFmpPrivate->Fmp
);
if (EFI_ERROR (Status)) {
FreePool (mSystemFmpPrivate);
mSystemFmpPrivate = NULL;
return Status;
}
return Status;
}

View file

@ -1,62 +0,0 @@
## @file
# SystemFirmware FMP report driver.
#
# Produce FMP instance to report system firmware EFI_FIRMWARE_IMAGE_DESCRIPTOR.
#
# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SystemFirmwareReportDxe
MODULE_UNI_FILE = SystemFirmwareReportDxe.uni
FILE_GUID = BC1A046C-7DBD-41F2-94E5-D7595554CAF4
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = SystemFirmwareReportMainDxe
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = X64
#
[Sources]
SystemFirmwareDxe.h
SystemFirmwareCommonDxe.c
SystemFirmwareReportDxe.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SignedCapsulePkg/SignedCapsulePkg.dec
[LibraryClasses]
BaseLib
UefiLib
BaseMemoryLib
DebugLib
PcdLib
MemoryAllocationLib
UefiBootServicesTableLib
HobLib
UefiRuntimeServicesTableLib
UefiDriverEntryPoint
DxeServicesTableLib
EdkiiSystemCapsuleLib
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid ## CONSUMES
gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareImageDescriptor ## CONSUMES
[Protocols]
gEfiFirmwareManagementProtocolGuid ## PRODUCES
[Depex]
gEfiVariableArchProtocolGuid
[UserExtensions.TianoCore."ExtraFiles"]
SystemFirmwareReportDxeExtra.uni

View file

@ -1,15 +0,0 @@
// /** @file
// SystemFirmware FMP report driver.
//
// Produce FMP instance to report system firmware EFI_FIRMWARE_IMAGE_DESCRIPTOR.
//
// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "SystemFirmware FMP report driver."
#string STR_MODULE_DESCRIPTION #language en-US "Produce FMP instance to report system firmware EFI_FIRMWARE_IMAGE_DESCRIPTOR."

View file

@ -1,14 +0,0 @@
// /** @file
// SystemFirmwareReportDxe Localized Strings and Content
//
// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_PROPERTIES_MODULE_NAME
#language en-US
"SystemFirmwareReport DXE Driver"

View file

@ -1,901 +0,0 @@
/** @file
SetImage instance to update system firmware.
Caution: This module requires additional review when modified.
This module will have external input - capsule image.
This external input must be validated carefully to avoid security issue like
buffer overflow, integer overflow.
FmpSetImage() will receive untrusted input and do basic validation.
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "SystemFirmwareDxe.h"
//
// SystemFmp driver private data
//
SYSTEM_FMP_PRIVATE_DATA *mSystemFmpPrivate = NULL;
EFI_GUID mCurrentImageTypeId;
BOOLEAN mNvRamUpdated = FALSE;
/**
Parse Config data file to get the updated data array.
@param[in] DataBuffer Config raw file buffer.
@param[in] BufferSize Size of raw buffer.
@param[in, out] ConfigHeader Pointer to the config header.
@param[in, out] UpdateArray Pointer to the config of update data.
@retval EFI_NOT_FOUND No config data is found.
@retval EFI_OUT_OF_RESOURCES No enough memory is allocated.
@retval EFI_SUCCESS Parse the config file successfully.
**/
EFI_STATUS
ParseUpdateDataFile (
IN UINT8 *DataBuffer,
IN UINTN BufferSize,
IN OUT CONFIG_HEADER *ConfigHeader,
IN OUT UPDATE_CONFIG_DATA **UpdateArray
);
/**
Update System Firmware image component.
@param[in] SystemFirmwareImage Points to the System Firmware image.
@param[in] SystemFirmwareImageSize The length of the System Firmware image in bytes.
@param[in] ConfigData Points to the component configuration structure.
@param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[in] Progress A function used by the driver to report the progress of the firmware update.
@param[in] StartPercentage The start completion percentage value that may be used to report progress during the flash write operation.
@param[in] EndPercentage The end completion percentage value that may be used to report progress during the flash write operation.
@retval EFI_SUCCESS The System Firmware image is updated.
@retval EFI_WRITE_PROTECTED The flash device is read only.
**/
EFI_STATUS
PerformUpdate (
IN VOID *SystemFirmwareImage,
IN UINTN SystemFirmwareImageSize,
IN UPDATE_CONFIG_DATA *ConfigData,
OUT UINT32 *LastAttemptVersion,
OUT UINT32 *LastAttemptStatus,
IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress,
IN UINTN StartPercentage,
IN UINTN EndPercentage
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "PlatformUpdate:"));
DEBUG ((DEBUG_INFO, " BaseAddress - 0x%lx,", ConfigData->BaseAddress));
DEBUG ((DEBUG_INFO, " ImageOffset - 0x%x,", ConfigData->ImageOffset));
DEBUG ((DEBUG_INFO, " Legnth - 0x%x\n", ConfigData->Length));
if (Progress != NULL) {
Progress (StartPercentage);
}
Status = PerformFlashWriteWithProgress (
ConfigData->FirmwareType,
ConfigData->BaseAddress,
ConfigData->AddressType,
(VOID *)((UINTN)SystemFirmwareImage + (UINTN)ConfigData->ImageOffset),
ConfigData->Length,
Progress,
StartPercentage,
EndPercentage
);
if (Progress != NULL) {
Progress (EndPercentage);
}
if (!EFI_ERROR (Status)) {
*LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
if (ConfigData->FirmwareType == PlatformFirmwareTypeNvRam) {
mNvRamUpdated = TRUE;
}
} else {
*LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
}
return Status;
}
/**
Update System Firmware image.
@param[in] SystemFirmwareImage Points to the System Firmware image.
@param[in] SystemFirmwareImageSize The length of the System Firmware image in bytes.
@param[in] ConfigImage Points to the config file image.
@param[in] ConfigImageSize The length of the config file image in bytes.
@param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[in] Progress A function used by the driver to report the progress of the firmware update.
@retval EFI_SUCCESS The System Firmware image is updated.
@retval EFI_WRITE_PROTECTED The flash device is read only.
**/
EFI_STATUS
UpdateImage (
IN VOID *SystemFirmwareImage,
IN UINTN SystemFirmwareImageSize,
IN VOID *ConfigImage,
IN UINTN ConfigImageSize,
OUT UINT32 *LastAttemptVersion,
OUT UINT32 *LastAttemptStatus,
IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress
)
{
EFI_STATUS Status;
UPDATE_CONFIG_DATA *ConfigData;
UPDATE_CONFIG_DATA *UpdateConfigData;
CONFIG_HEADER ConfigHeader;
UINTN Index;
UINTN TotalSize;
UINTN BytesWritten;
UINTN StartPercentage;
UINTN EndPercentage;
if (ConfigImage == NULL) {
DEBUG ((DEBUG_INFO, "PlatformUpdate (NoConfig):"));
DEBUG ((DEBUG_INFO, " BaseAddress - 0x%x,", 0));
DEBUG ((DEBUG_INFO, " Length - 0x%x\n", SystemFirmwareImageSize));
// ASSUME the whole System Firmware include NVRAM region.
StartPercentage = 0;
EndPercentage = 100;
if (Progress != NULL) {
Progress (StartPercentage);
}
Status = PerformFlashWriteWithProgress (
PlatformFirmwareTypeNvRam,
0,
FlashAddressTypeRelativeAddress,
SystemFirmwareImage,
SystemFirmwareImageSize,
Progress,
StartPercentage,
EndPercentage
);
if (Progress != NULL) {
Progress (EndPercentage);
}
if (!EFI_ERROR (Status)) {
*LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
mNvRamUpdated = TRUE;
} else {
*LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
}
return Status;
}
DEBUG ((DEBUG_INFO, "PlatformUpdate (With Config):\n"));
ConfigData = NULL;
ZeroMem (&ConfigHeader, sizeof (ConfigHeader));
Status = ParseUpdateDataFile (
ConfigImage,
ConfigImageSize,
&ConfigHeader,
&ConfigData
);
DEBUG ((DEBUG_INFO, "ParseUpdateDataFile - %r\n", Status));
if (EFI_ERROR (Status)) {
*LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
return EFI_INVALID_PARAMETER;
}
DEBUG ((DEBUG_INFO, "ConfigHeader.NumOfUpdates - 0x%x\n", ConfigHeader.NumOfUpdates));
DEBUG ((DEBUG_INFO, "PcdEdkiiSystemFirmwareFileGuid - %g\n", PcdGetPtr (PcdEdkiiSystemFirmwareFileGuid)));
TotalSize = 0;
for (Index = 0; Index < ConfigHeader.NumOfUpdates; Index++) {
if (CompareGuid (&ConfigData[Index].FileGuid, PcdGetPtr (PcdEdkiiSystemFirmwareFileGuid))) {
TotalSize = TotalSize + ConfigData[Index].Length;
}
}
BytesWritten = 0;
Index = 0;
UpdateConfigData = ConfigData;
while (Index < ConfigHeader.NumOfUpdates) {
if (CompareGuid (&UpdateConfigData->FileGuid, PcdGetPtr (PcdEdkiiSystemFirmwareFileGuid))) {
DEBUG ((DEBUG_INFO, "FileGuid - %g (processing)\n", &UpdateConfigData->FileGuid));
StartPercentage = (BytesWritten * 100) / TotalSize;
EndPercentage = ((BytesWritten + UpdateConfigData->Length) * 100) / TotalSize;
Status = PerformUpdate (
SystemFirmwareImage,
SystemFirmwareImageSize,
UpdateConfigData,
LastAttemptVersion,
LastAttemptStatus,
Progress,
StartPercentage,
EndPercentage
);
//
// Shall updates be serialized so that if an update is not successfully completed,
// the remaining updates won't be performed.
//
if (EFI_ERROR (Status)) {
break;
}
} else {
DEBUG ((DEBUG_INFO, "FileGuid - %g (ignored)\n", &UpdateConfigData->FileGuid));
}
BytesWritten += UpdateConfigData->Length;
Index++;
UpdateConfigData++;
}
return Status;
}
/**
Authenticate and update System Firmware image.
Caution: This function may receive untrusted input.
@param[in] Image The EDKII system FMP capsule image.
@param[in] ImageSize The size of the EDKII system FMP capsule image in bytes.
@param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
@param[in] Progress A function used by the driver to report the progress of the firmware update.
@retval EFI_SUCCESS EDKII system FMP capsule passes authentication and the System Firmware image is updated.
@retval EFI_SECURITY_VIOLATION EDKII system FMP capsule fails authentication and the System Firmware image is not updated.
@retval EFI_WRITE_PROTECTED The flash device is read only.
**/
EFI_STATUS
SystemFirmwareAuthenticatedUpdate (
IN VOID *Image,
IN UINTN ImageSize,
OUT UINT32 *LastAttemptVersion,
OUT UINT32 *LastAttemptStatus,
IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress
)
{
EFI_STATUS Status;
VOID *SystemFirmwareImage;
UINTN SystemFirmwareImageSize;
VOID *ConfigImage;
UINTN ConfigImageSize;
VOID *AuthenticatedImage;
UINTN AuthenticatedImageSize;
AuthenticatedImage = NULL;
AuthenticatedImageSize = 0;
DEBUG ((DEBUG_INFO, "SystemFirmwareAuthenticatedUpdate...\n"));
Status = CapsuleAuthenticateSystemFirmware (Image, ImageSize, FALSE, LastAttemptVersion, LastAttemptStatus, &AuthenticatedImage, &AuthenticatedImageSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "SystemFirmwareAuthenticateImage - %r\n", Status));
return Status;
}
DEBUG ((DEBUG_INFO, "ExtractSystemFirmwareImage ...\n"));
ExtractSystemFirmwareImage (AuthenticatedImage, AuthenticatedImageSize, &SystemFirmwareImage, &SystemFirmwareImageSize);
DEBUG ((DEBUG_INFO, "ExtractConfigImage ...\n"));
ExtractConfigImage (AuthenticatedImage, AuthenticatedImageSize, &ConfigImage, &ConfigImageSize);
DEBUG ((DEBUG_INFO, "UpdateImage ...\n"));
Status = UpdateImage (SystemFirmwareImage, SystemFirmwareImageSize, ConfigImage, ConfigImageSize, LastAttemptVersion, LastAttemptStatus, Progress);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "UpdateImage - %r\n", Status));
return Status;
}
DEBUG ((DEBUG_INFO, "SystemFirmwareAuthenticatedUpdate Done\n"));
return EFI_SUCCESS;
}
/**
This code finds variable in storage blocks (Volatile or Non-Volatile).
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[out] Attributes Attribute value of the variable found.
@param[in, out] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[out] Data Data pointer.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_SUCCESS Find the specified variable.
@return EFI_NOT_FOUND Not found.
@return EFI_BUFFER_TO_SMALL DataSize is too small for the result.
**/
EFI_STATUS
EFIAPI
GetVariableHook (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT UINT32 *Attributes OPTIONAL,
IN OUT UINTN *DataSize,
OUT VOID *Data
)
{
DEBUG ((DEBUG_INFO, "GetVariableHook - %S, %g\n", VariableName, VendorGuid));
return EFI_NOT_AVAILABLE_YET;
}
/**
This code Finds the Next available variable.
@param[in, out] VariableNameSize Size of the variable name.
@param[in, out] VariableName Pointer to variable name.
@param[in, out] VendorGuid Variable Vendor Guid.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_SUCCESS Find the specified variable.
@return EFI_NOT_FOUND Not found.
@return EFI_BUFFER_TO_SMALL DataSize is too small for the result.
**/
EFI_STATUS
EFIAPI
GetNextVariableNameHook (
IN OUT UINTN *VariableNameSize,
IN OUT CHAR16 *VariableName,
IN OUT EFI_GUID *VendorGuid
)
{
DEBUG ((DEBUG_INFO, "GetNextVariableNameHook - %S, %g\n", VariableName, VendorGuid));
return EFI_NOT_AVAILABLE_YET;
}
/**
This code sets variable in storage blocks (Volatile or Non-Volatile).
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Attributes Attribute value of the variable found
@param[in] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[in] Data Data pointer.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_SUCCESS Set successfully.
@return EFI_OUT_OF_RESOURCES Resource not enough to set variable.
@return EFI_NOT_FOUND Not found.
@return EFI_WRITE_PROTECTED Variable is read-only.
**/
EFI_STATUS
EFIAPI
SetVariableHook (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINT32 Attributes,
IN UINTN DataSize,
IN VOID *Data
)
{
DEBUG ((DEBUG_INFO, "SetVariableHook - %S, %g, 0x%x (0x%x)\n", VariableName, VendorGuid, Attributes, DataSize));
return EFI_NOT_AVAILABLE_YET;
}
/**
This code returns information about the EFI variables.
@param[in] Attributes Attributes bitmask to specify the type of variables
on which to return information.
@param[out] MaximumVariableStorageSize Pointer to the maximum size of the storage space available
for the EFI variables associated with the attributes specified.
@param[out] RemainingVariableStorageSize Pointer to the remaining size of the storage space available
for EFI variables associated with the attributes specified.
@param[out] MaximumVariableSize Pointer to the maximum size of an individual EFI variables
associated with the attributes specified.
@return EFI_SUCCESS Query successfully.
**/
EFI_STATUS
EFIAPI
QueryVariableInfoHook (
IN UINT32 Attributes,
OUT UINT64 *MaximumVariableStorageSize,
OUT UINT64 *RemainingVariableStorageSize,
OUT UINT64 *MaximumVariableSize
)
{
DEBUG ((DEBUG_INFO, "QueryVariableInfoHook - 0x%x\n", Attributes));
return EFI_NOT_AVAILABLE_YET;
}
/**
Updates the firmware image of the device.
This function updates the hardware with the new firmware image.
This function returns EFI_UNSUPPORTED if the firmware image is not updatable.
If the firmware image is updatable, the function should perform the following minimal validations
before proceeding to do the firmware image update.
- Validate the image authentication if image has attribute
IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns
EFI_SECURITY_VIOLATION if the validation fails.
- Validate the image is a supported image for this device. The function returns EFI_ABORTED if
the image is unsupported. The function can optionally provide more detailed information on
why the image is not a supported image.
- Validate the data from VendorCode if not null. Image validation must be performed before
VendorCode data validation. VendorCode data is ignored or considered invalid if image
validation failed. The function returns EFI_ABORTED if the data is invalid.
VendorCode enables vendor to implement vendor-specific firmware image update policy. Null if
the caller did not specify the policy or use the default policy. As an example, vendor can implement
a policy to allow an option to force a firmware image update when the abort reason is due to the new
firmware image version is older than the current firmware image version or bad image checksum.
Sensitive operations such as those wiping the entire firmware image and render the device to be
non-functional should be encoded in the image itself rather than passed with the VendorCode.
AbortReason enables vendor to have the option to provide a more detailed description of the abort
reason to the caller.
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
@param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
The number is between 1 and DescriptorCount.
@param[in] Image Points to the new image.
@param[in] ImageSize Size of the new image in bytes.
@param[in] VendorCode This enables vendor to implement vendor-specific firmware image update policy.
Null indicates the caller did not specify the policy or use the default policy.
@param[in] Progress A function used by the driver to report the progress of the firmware update.
@param[out] AbortReason A pointer to a pointer to a null-terminated string providing more
details for the aborted operation. The buffer is allocated by this function
with AllocatePool(), and it is the caller's responsibility to free it with a
call to FreePool().
@retval EFI_SUCCESS The device was successfully updated with the new image.
@retval EFI_ABORTED The operation is aborted.
@retval EFI_INVALID_PARAMETER The Image was NULL.
@retval EFI_UNSUPPORTED The operation is not supported.
@retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
**/
EFI_STATUS
EFIAPI
FmpSetImage (
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
IN UINT8 ImageIndex,
IN CONST VOID *Image,
IN UINTN ImageSize,
IN CONST VOID *VendorCode,
IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress,
OUT CHAR16 **AbortReason
)
{
EFI_STATUS Status;
EFI_STATUS VarStatus;
SYSTEM_FMP_PRIVATE_DATA *SystemFmpPrivate;
if ((Image == NULL) || (ImageSize == 0) || (AbortReason == NULL)) {
return EFI_INVALID_PARAMETER;
}
SystemFmpPrivate = SYSTEM_FMP_PRIVATE_DATA_FROM_FMP (This);
*AbortReason = NULL;
if ((ImageIndex == 0) || (ImageIndex > SystemFmpPrivate->DescriptorCount)) {
return EFI_INVALID_PARAMETER;
}
Status = SystemFirmwareAuthenticatedUpdate ((VOID *)Image, ImageSize, &SystemFmpPrivate->LastAttempt.LastAttemptVersion, &SystemFmpPrivate->LastAttempt.LastAttemptStatus, Progress);
DEBUG ((DEBUG_INFO, "SetImage - LastAttempt Version - 0x%x, State - 0x%x\n", SystemFmpPrivate->LastAttempt.LastAttemptVersion, SystemFmpPrivate->LastAttempt.LastAttemptStatus));
//
// If NVRAM is updated, we should no longer touch variable services, because
// the current variable driver may not manage the new NVRAM region.
//
if (mNvRamUpdated) {
DEBUG ((DEBUG_INFO, "NvRamUpdated, Update Variable Services\n"));
gRT->GetVariable = GetVariableHook;
gRT->GetNextVariableName = GetNextVariableNameHook;
gRT->SetVariable = SetVariableHook;
gRT->QueryVariableInfo = QueryVariableInfoHook;
gRT->Hdr.CRC32 = 0;
gBS->CalculateCrc32 (
(UINT8 *)&gRT->Hdr,
gRT->Hdr.HeaderSize,
&gRT->Hdr.CRC32
);
}
VarStatus = gRT->SetVariable (
SYSTEM_FMP_LAST_ATTEMPT_VARIABLE_NAME,
&gSystemFmpLastAttemptVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof (SystemFmpPrivate->LastAttempt),
&SystemFmpPrivate->LastAttempt
);
DEBUG ((DEBUG_INFO, "SetLastAttempt - %r\n", VarStatus));
return Status;
}
/**
Get the set of EFI_FIRMWARE_IMAGE_DESCRIPTOR structures from an FMP Protocol.
@param[in] Handle Handle with an FMP Protocol or a System FMP
Protocol.
@param[in] ProtocolGuid Pointer to the FMP Protocol GUID or System FMP
Protocol GUID.
@param[out] FmpImageInfoCount Pointer to the number of
EFI_FIRMWARE_IMAGE_DESCRIPTOR structures.
@param[out] DescriptorSize Pointer to the size, in bytes, of each
EFI_FIRMWARE_IMAGE_DESCRIPTOR structure.
@return NULL No EFI_FIRMWARE_IMAGE_DESCRIPTOR structures found.
@return !NULL Pointer to a buffer of EFI_FIRMWARE_IMAGE_DESCRIPTOR structures
allocated using AllocatePool(). Caller must free buffer with
FreePool().
**/
EFI_FIRMWARE_IMAGE_DESCRIPTOR *
GetFmpImageDescriptors (
IN EFI_HANDLE Handle,
IN EFI_GUID *ProtocolGuid,
OUT UINT8 *FmpImageInfoCount,
OUT UINTN *DescriptorSize
)
{
EFI_STATUS Status;
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
UINTN ImageInfoSize;
EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
UINT32 FmpImageInfoDescriptorVer;
UINT32 PackageVersion;
CHAR16 *PackageVersionName;
*FmpImageInfoCount = 0;
*DescriptorSize = 0;
Status = gBS->HandleProtocol (
Handle,
ProtocolGuid,
(VOID **)&Fmp
);
if (EFI_ERROR (Status)) {
return NULL;
}
//
// Determine the size required for the set of EFI_FIRMWARE_IMAGE_DESCRIPTORs.
//
ImageInfoSize = 0;
Status = Fmp->GetImageInfo (
Fmp, // FMP Pointer
&ImageInfoSize, // Buffer Size (in this case 0)
NULL, // NULL so we can get size
&FmpImageInfoDescriptorVer, // DescriptorVersion
FmpImageInfoCount, // DescriptorCount
DescriptorSize, // DescriptorSize
&PackageVersion, // PackageVersion
&PackageVersionName // PackageVersionName
);
if (Status != EFI_BUFFER_TOO_SMALL) {
DEBUG ((DEBUG_ERROR, "SystemFirmwareUpdateDxe: Unexpected Failure. Status = %r\n", Status));
return NULL;
}
//
// Allocate buffer for the set of EFI_FIRMWARE_IMAGE_DESCRIPTORs.
//
FmpImageInfoBuf = NULL;
FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
if (FmpImageInfoBuf == NULL) {
DEBUG ((DEBUG_ERROR, "SystemFirmwareUpdateDxe: Failed to allocate memory for descriptors.\n"));
return NULL;
}
//
// Retrieve the set of EFI_FIRMWARE_IMAGE_DESCRIPTORs.
//
PackageVersionName = NULL;
Status = Fmp->GetImageInfo (
Fmp,
&ImageInfoSize, // ImageInfoSize
FmpImageInfoBuf, // ImageInfo
&FmpImageInfoDescriptorVer, // DescriptorVersion
FmpImageInfoCount, // DescriptorCount
DescriptorSize, // DescriptorSize
&PackageVersion, // PackageVersion
&PackageVersionName // PackageVersionName
);
//
// Free unused PackageVersionName return buffer
//
if (PackageVersionName != NULL) {
FreePool (PackageVersionName);
PackageVersionName = NULL;
}
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "SystemFirmwareUpdateDxe: Failure in GetImageInfo. Status = %r\n", Status));
if (FmpImageInfoBuf != NULL) {
FreePool (FmpImageInfoBuf);
}
return NULL;
}
return FmpImageInfoBuf;
}
/**
Search for handles with an FMP protocol whose EFI_FIRMWARE_IMAGE_DESCRIPTOR
ImageTypeId matches the ImageTypeId produced by this module.
@param[in] ProtocolGuid Pointer to the GUID of the protocol to search.
@param[out] HandleCount Pointer to the number of returned handles.
@return NULL No matching handles found.
@return !NULL Pointer to a buffer of handles allocated using AllocatePool().
Caller must free buffer with FreePool().
**/
EFI_HANDLE *
FindMatchingFmpHandles (
IN EFI_GUID *ProtocolGuid,
OUT UINTN *HandleCount
)
{
EFI_STATUS Status;
UINTN TempHandleCount;
EFI_HANDLE *HandleBuffer;
UINTN Index;
UINTN Index2;
UINTN Index3;
EFI_FIRMWARE_IMAGE_DESCRIPTOR *OriginalFmpImageInfoBuf;
EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
UINT8 FmpImageInfoCount;
UINTN DescriptorSize;
BOOLEAN MatchFound;
*HandleCount = 0;
TempHandleCount = 0;
HandleBuffer = NULL;
Status = gBS->LocateHandleBuffer (
ByProtocol,
ProtocolGuid,
NULL,
&TempHandleCount,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return NULL;
}
for (Index = 0; Index < TempHandleCount; Index++) {
OriginalFmpImageInfoBuf = GetFmpImageDescriptors (
HandleBuffer[Index],
ProtocolGuid,
&FmpImageInfoCount,
&DescriptorSize
);
//
// Loop through the set of EFI_FIRMWARE_IMAGE_DESCRIPTORs.
//
MatchFound = FALSE;
if (OriginalFmpImageInfoBuf != NULL) {
FmpImageInfoBuf = OriginalFmpImageInfoBuf;
for (Index2 = 0; Index2 < FmpImageInfoCount; Index2++) {
for (Index3 = 0; Index3 < mSystemFmpPrivate->DescriptorCount; Index3++) {
MatchFound = CompareGuid (
&FmpImageInfoBuf->ImageTypeId,
&mSystemFmpPrivate->ImageDescriptor[Index3].ImageTypeId
);
if (MatchFound) {
break;
}
}
if (MatchFound) {
break;
}
//
// Increment the buffer pointer ahead by the size of the descriptor
//
FmpImageInfoBuf = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)(((UINT8 *)FmpImageInfoBuf) + DescriptorSize);
}
if (MatchFound) {
HandleBuffer[*HandleCount] = HandleBuffer[Index];
(*HandleCount)++;
}
FreePool (OriginalFmpImageInfoBuf);
}
}
if ((*HandleCount) == 0) {
//
// No any matching handle.
//
FreePool (HandleBuffer);
return NULL;
}
return HandleBuffer;
}
/**
Uninstall System FMP Protocol instances that may have been installed by
SystemFirmwareUpdateDxe drivers dispatches by other capsules.
@retval EFI_SUCCESS All System FMP Protocols found were uninstalled.
@return Other One or more System FMP Protocols could not be uninstalled.
**/
EFI_STATUS
UninstallMatchingSystemFmpProtocols (
VOID
)
{
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer;
UINTN HandleCount;
UINTN Index;
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *SystemFmp;
//
// Uninstall SystemFmpProtocol instances that may have been produced by
// the SystemFirmwareUpdate drivers in FVs dispatched by other capsules.
//
HandleBuffer = FindMatchingFmpHandles (
&gSystemFmpProtocolGuid,
&HandleCount
);
DEBUG ((DEBUG_INFO, "SystemFirmwareUpdateDxe: Found %d matching System FMP instances\n", HandleCount));
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gSystemFmpProtocolGuid,
(VOID **)&SystemFmp
);
if (EFI_ERROR (Status)) {
continue;
}
DEBUG ((DEBUG_INFO, "SystemFirmwareUpdateDxe: Uninstall SystemFmp produced by another capsule\n"));
Status = gBS->UninstallProtocolInterface (
HandleBuffer[Index],
&gSystemFmpProtocolGuid,
SystemFmp
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "SystemFirmwareUpdateDxe: Failed to uninstall SystemFmp %r. Exiting.\n", Status));
FreePool (HandleBuffer);
return Status;
}
}
if (HandleBuffer != NULL) {
FreePool (HandleBuffer);
}
return EFI_SUCCESS;
}
/**
System FMP module entrypoint
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS System FMP module is initialized.
@retval EFI_OUT_OF_RESOURCES There are not enough resources avaulable to
initialize this module.
@retval Other System FMP Protocols could not be uninstalled.
@retval Other System FMP Protocol could not be installed.
@retval Other FMP Protocol could not be installed.
**/
EFI_STATUS
EFIAPI
SystemFirmwareUpdateMainDxe (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer;
UINTN HandleCount;
//
// Initialize SystemFmpPrivateData
//
mSystemFmpPrivate = AllocateZeroPool (sizeof (SYSTEM_FMP_PRIVATE_DATA));
if (mSystemFmpPrivate == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = InitializePrivateData (mSystemFmpPrivate);
if (EFI_ERROR (Status)) {
FreePool (mSystemFmpPrivate);
mSystemFmpPrivate = NULL;
return Status;
}
//
// Uninstall SystemFmpProtocol instances that may have been produced by
// the SystemFirmwareUpdate drivers in FVs dispatched by other capsules.
//
Status = UninstallMatchingSystemFmpProtocols ();
if (EFI_ERROR (Status)) {
FreePool (mSystemFmpPrivate);
mSystemFmpPrivate = NULL;
return Status;
}
//
// Look for a handle with matching Firmware Management Protocol
//
HandleCount = 0;
HandleBuffer = FindMatchingFmpHandles (
&gEfiFirmwareManagementProtocolGuid,
&HandleCount
);
DEBUG ((DEBUG_INFO, "SystemFirmwareUpdateDxe: Found %d matching FMP instances\n", HandleCount));
switch (HandleCount) {
case 0:
//
// Install FMP protocol onto a new handle.
//
DEBUG ((DEBUG_INFO, "SystemFirmwareUpdateDxe: Install FMP onto a new handle\n"));
Status = gBS->InstallMultipleProtocolInterfaces (
&mSystemFmpPrivate->Handle,
&gEfiFirmwareManagementProtocolGuid,
&mSystemFmpPrivate->Fmp,
NULL
);
break;
case 1:
//
// Install System FMP protocol onto handle with matching FMP Protocol
//
DEBUG ((DEBUG_INFO, "SystemFirmwareUpdateDxe: Install System FMP onto matching FMP handle\n"));
mSystemFmpPrivate->Handle = HandleBuffer[0];
Status = gBS->InstallMultipleProtocolInterfaces (
&HandleBuffer[0],
&gSystemFmpProtocolGuid,
&mSystemFmpPrivate->Fmp,
NULL
);
break;
default:
//
// More than one matching handle is not expected. Unload driver.
//
DEBUG ((DEBUG_ERROR, "SystemFirmwareUpdateDxe: More than one matching FMP handle. Unload driver.\n"));
Status = EFI_DEVICE_ERROR;
break;
}
if (HandleBuffer != NULL) {
FreePool (HandleBuffer);
}
if (EFI_ERROR (Status)) {
FreePool (mSystemFmpPrivate);
mSystemFmpPrivate = NULL;
}
return Status;
}

View file

@ -1,66 +0,0 @@
## @file
# SystemFirmware FMP update driver.
#
# Produce FMP instance to update system firmware.
#
# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SystemFirmwareUpdateDxe
MODULE_UNI_FILE = SystemFirmwareUpdateDxe.uni
FILE_GUID = 0A2FBD15-1C25-407E-8915-60C5652BC2AA
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = SystemFirmwareUpdateMainDxe
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = X64
#
[Sources]
SystemFirmwareDxe.h
SystemFirmwareCommonDxe.c
SystemFirmwareUpdateDxe.c
ParseConfigProfile.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SignedCapsulePkg/SignedCapsulePkg.dec
[LibraryClasses]
BaseLib
UefiLib
BaseMemoryLib
DebugLib
PcdLib
MemoryAllocationLib
UefiBootServicesTableLib
HobLib
UefiRuntimeServicesTableLib
UefiDriverEntryPoint
EdkiiSystemCapsuleLib
PlatformFlashAccessLib
IniParsingLib
PrintLib
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid ## CONSUMES
gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid ## CONSUMES
gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareImageDescriptor ## CONSUMES
[Protocols]
gEfiFirmwareManagementProtocolGuid ## PRODUCES
[Depex]
gEfiVariableArchProtocolGuid
[UserExtensions.TianoCore."ExtraFiles"]
SystemFirmwareUpdateDxeExtra.uni

View file

@ -1,15 +0,0 @@
// /** @file
// SystemFirmware FMP update driver.
//
// Produce FMP instance to update system firmware.
//
// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "SystemFirmware FMP update driver."
#string STR_MODULE_DESCRIPTION #language en-US "Produce FMP instance to update system firmware."

View file

@ -1,14 +0,0 @@
// /** @file
// SystemFirmwareUpdateDxe Localized Strings and Content
//
// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_PROPERTIES_MODULE_NAME
#language en-US
"SystemFirmwareUpdate DXE Driver"