695 lines
22 KiB
C
695 lines
22 KiB
C
/** @file
|
|
Common secure boot relative supports functions
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2012 - 2017, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include <Library/VariableSupportLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/BaseLib.h>
|
|
|
|
#include <Guid/GlobalVariable.h>
|
|
#include <Guid/ImageAuthentication.h>
|
|
#include <Guid/AdmiSecureBoot.h>
|
|
#include <Guid/DebugMask.h>
|
|
|
|
#include <Pi/PiFirmwareVolume.h>
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is secure database relative variable.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is secure database relative variable.
|
|
@retval FALSE This isn't secure database relative variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsSecureDatabaseVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
|
|
if (IsPkVariable (VariableName, VendorGuid) || IsKekVariable (VariableName, VendorGuid) ||
|
|
IsImageSecureDatabaseVariable (VariableName, VendorGuid)) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is image secure database relative variable.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is image secure database relative variable.
|
|
@retval FALSE This isn't image secure database relative variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsImageSecureDatabaseVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (IsDbVariable (VariableName, VendorGuid) || IsDbxVariable (VariableName, VendorGuid) ||
|
|
IsDbtVariable (VariableName, VendorGuid)|| IsDbrVariable (VariableName, VendorGuid)) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is AuditMode or not.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is AuditMode variable.
|
|
@retval FALSE This isn't AuditMode variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsAuditModeVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_AUDIT_MODE_VARIABLE_NAME) == 0 && CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is DeployedMode or not.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is DeployedMode variable.
|
|
@retval FALSE This isn't DeployedMode variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsDeployedModeVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_DEPLOYED_MODE_VARIABLE_NAME) == 0 && CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is PK or not.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is PK variable.
|
|
@retval FALSE This isn't PK variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsPkVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_PLATFORM_KEY_NAME) == 0 && CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is KEK or not.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is KEK variable.
|
|
@retval FALSE This isn't KEK variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsKekVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0 && CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is db or not.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is db variable.
|
|
@retval FALSE This isn't db variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsDbVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0 && CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is dbx or not.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is dbx variable.
|
|
@retval FALSE This isn't dbx variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsDbxVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0 && CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is dbt or not.
|
|
|
|
@param VariableName Name of Variable to be found.
|
|
@param VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is dbt variable.
|
|
@retval FALSE This isn't dbt variable.
|
|
|
|
--*/
|
|
BOOLEAN
|
|
IsDbtVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0 && CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is dbr or not.
|
|
|
|
@param VariableName Name of Variable to be found.
|
|
@param VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is dbr variable.
|
|
@retval FALSE This isn't dbt variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsDbrVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE3) == 0 && CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
Check if a Unicode character is a hexadecimal character.
|
|
|
|
This function checks if a Unicode character is a
|
|
hexadecimal character. The valid hexadecimal character is
|
|
L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
|
|
|
|
@param[in] Char The character to check against.
|
|
|
|
@retval TRUE If the Char is a hexadecmial character.
|
|
@retval FALSE If the Char is not a hexadecmial character.
|
|
**/
|
|
STATIC
|
|
BOOLEAN
|
|
EFIAPI
|
|
IsHexaDecimalDigitCharacter (
|
|
IN CHAR16 Char
|
|
)
|
|
{
|
|
return (BOOLEAN) ((Char >= L'0' && Char <= L'9') || (Char >= L'A' && Char <= L'F'));
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is OsRecovery#### or not.
|
|
|
|
@param VariableName Name of Variable to be found.
|
|
|
|
@retval TRUE This is OsRecovery#### variable.
|
|
@retval FALSE This isn't OsRecovery#### variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsOsRecoveryVariable (
|
|
IN CONST CHAR16 *VariableName
|
|
)
|
|
{
|
|
UINTN NameLength;
|
|
|
|
if (VariableName == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
NameLength = StrLen (L"OsRecovery");
|
|
if (StrLen (VariableName) == StrLen (L"OsRecovery####") &&
|
|
StrnCmp (VariableName, L"OsRecovery", StrLen (L"OsRecovery")) == 0 &&
|
|
IsHexaDecimalDigitCharacter (VariableName[NameLength]) &&
|
|
IsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&
|
|
IsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&
|
|
IsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is OsRecoveryOrder or not.
|
|
|
|
@param VariableName Name of Variable to be found.
|
|
@param VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is OsRecoveryOrder variable.
|
|
@retval FALSE This isn't OsRecoveryOrder variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsOsRecoveryOrderVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_OS_RECOVERY_ORDER_VARIABLE_NAME) == 0 && CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is secure boot policy variable or not.
|
|
|
|
@param VariableName Name of Variable to be found.
|
|
@param VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is secure boot policy variable variable.
|
|
@retval FALSE This isn't secure boot policy variable variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsSecureBootPolicyVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName == NULL || VendorGuid == NULL) {
|
|
return FALSE;
|
|
}
|
|
if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) ||
|
|
IsPkVariable (VariableName, VendorGuid) || IsKekVariable (VariableName, VendorGuid) ||
|
|
IsOsRecoveryOrderVariable (VariableName, VendorGuid) || IsOsRecoveryVariable (VariableName)) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is secure database default
|
|
relative variable.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is secure database default relative variable.
|
|
@retval FALSE This isn't secure database default relative variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsSecureDatabaseDefaultVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (IsPkDefaultVariable (VariableName, VendorGuid) || IsKekDefaultVariable (VariableName, VendorGuid) ||
|
|
IsImageSecureDatabaseDefaultVariable (VariableName, VendorGuid)) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is image secure database default relative variable.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is image secure database default relative variable.
|
|
@retval FALSE This isn't image secure database default relative variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsImageSecureDatabaseDefaultVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (IsDbDefaultVariable (VariableName, VendorGuid) || IsDbxDefaultVariable (VariableName, VendorGuid) ||
|
|
IsDbtDefaultVariable (VariableName, VendorGuid)|| IsDbrDefaultVariable (VariableName, VendorGuid)) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is PKDefault or not.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is PKDefault variable.
|
|
@retval FALSE This isn't PKDefault variable.
|
|
|
|
--*/
|
|
BOOLEAN
|
|
IsPkDefaultVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_PK_DEFAULT_VARIABLE_NAME) == 0 && CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is KEKDefault or not.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is KEKDefault variable.
|
|
@retval FALSE This isn't KEKDefault variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsKekDefaultVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_KEK_DEFAULT_VARIABLE_NAME) == 0 && CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is dbDefault or not.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is dbDefault variable.
|
|
@retval FALSE This isn't dbDefault variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsDbDefaultVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_DB_DEFAULT_VARIABLE_NAME) == 0 && CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is dbxDefault or not.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is dbxDefault variable.
|
|
@retval FALSE This isn't dbxDefault variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsDbxDefaultVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_DBX_DEFAULT_VARIABLE_NAME) == 0 && CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is dbtDefault or not.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is dbtDefault variable.
|
|
@retval FALSE This isn't dbtDefault variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsDbtDefaultVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_DBT_DEFAULT_VARIABLE_NAME) == 0 && CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is dbrDefault or not.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is dbrDefault variable.
|
|
@retval FALSE This isn't dbrDefault variable.
|
|
--*/
|
|
BOOLEAN
|
|
IsDbrDefaultVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_DBR_DEFAULT_VARIABLE_NAME) == 0 && CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine the variable is CustomSecurity or not.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is CustomSecurity variable.
|
|
@retval FALSE This isn't CustomSecurity variable.
|
|
--*/
|
|
STATIC
|
|
BOOLEAN
|
|
IsCustomSecurityVariable (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
if (VariableName != NULL && VendorGuid != NULL) {
|
|
if (StrCmp (VariableName, EFI_CUSTOM_SECURITY_NAME) == 0 && CompareGuid (VendorGuid, &gEfiGenericVariableGuid)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
According to variable name and GUID to Determine this variable whether need reserve during
|
|
restore factory default process.
|
|
|
|
@param[in] VariableName Name of Variable to be found.
|
|
@param[in] VendorGuid Variable vendor GUID.
|
|
|
|
@retval TRUE This is CustomSecurity variable.
|
|
@retval FALSE This isn't CustomSecurity variable.
|
|
--*/
|
|
STATIC
|
|
BOOLEAN
|
|
VariableNeedReserve (
|
|
IN CONST CHAR16 *VariableName,
|
|
IN CONST EFI_GUID *VendorGuid
|
|
)
|
|
{
|
|
//
|
|
// Needn't reserve EFI_CUSTOM_SECURITY_NAME, and then system will create new variable to indicate system is in
|
|
// standard mode.
|
|
//
|
|
if (IsSecureDatabaseVariable (VariableName, VendorGuid) || IsCustomSecurityVariable (VariableName, VendorGuid)) {
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
Merge all of variables aren't secure boot relative variables and doesn't saved in factory copy
|
|
region from variable store to factory copy region.
|
|
|
|
@param[in, out] FactorycopyBuffer [in]:The buffer contained all of factory copy data.
|
|
[out]:The buffer has been appended data from VariableBuffer.
|
|
@param[in, out] FactoryBufferLength [in]:The size of FactorycopyBuffer.
|
|
[out]:The total used size in FactorycopyBuffer.
|
|
@param[in] VariableBuffer Buffer to save all of variable data.
|
|
@param[in] VariableBufferLength The size of VariableBuffer.
|
|
|
|
@retval EFI_SUCCESS Merge varialbe data to factory copy region successful.
|
|
@retval EFI_INVALID_PARAMETER FactorycopyBuffer, FactoryBufferLength or VariableBuffer is NULL.
|
|
The data in FactorycopyBuffer in incorrect.
|
|
@retval EFI_BUFFER_TOO_SMALL FactoryBufferLength is too small to contain merged data.
|
|
--*/
|
|
EFI_STATUS
|
|
MergeVariableToFactoryCopy (
|
|
IN OUT UINT8 *FactorycopyBuffer,
|
|
IN OUT UINTN *FactoryBufferLength,
|
|
IN CONST UINT8 *VariableBuffer,
|
|
IN UINTN VariableBufferLength
|
|
)
|
|
{
|
|
|
|
UINTN LastVariableOffset;
|
|
UINTN VariableSize;
|
|
UINTN HeaderSize;
|
|
VARIABLE_HEADER *VariableHeader;
|
|
VARIABLE_HEADER *NextVariable;
|
|
EFI_STATUS Status;
|
|
|
|
|
|
if (FactorycopyBuffer == NULL || FactoryBufferLength == NULL || VariableBuffer == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Check the factory defualt data is whether valid
|
|
//
|
|
for (LastVariableOffset = *FactoryBufferLength; LastVariableOffset > 0; LastVariableOffset--) {
|
|
if (FactorycopyBuffer[LastVariableOffset - 1] != 0xFF) {
|
|
break;
|
|
}
|
|
}
|
|
HeaderSize = sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY) + GetVariableStoreHeaderSize ();
|
|
if (LastVariableOffset + 1 < HeaderSize) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Find last variable offset in working buffer
|
|
//
|
|
NextVariable = (VARIABLE_HEADER *) (FactorycopyBuffer + HeaderSize);
|
|
while (IsValidVariableHeader (NextVariable)) {
|
|
NextVariable = GetNextVariablePtr (NextVariable);
|
|
}
|
|
LastVariableOffset = (UINTN) NextVariable - (UINTN) FactorycopyBuffer;
|
|
//
|
|
// Copy original firmware volume and variable store header information to exported factory default buffer.
|
|
// This action can prevent from the information of firmware volume header and variable store header in
|
|
// factory default region is incorrect.
|
|
//
|
|
CopyMem (FactorycopyBuffer, VariableBuffer, HeaderSize);
|
|
//
|
|
// merge variable data to working buffer
|
|
//
|
|
Status = EFI_SUCCESS;
|
|
VariableHeader = (VARIABLE_HEADER *) (VariableBuffer + HeaderSize);
|
|
while (IsValidVariableHeader (VariableHeader)) {
|
|
NextVariable = GetNextVariablePtr (VariableHeader);
|
|
//
|
|
// Collect all of valid variables. these variables should include variable state in added state and in deleted transition state.
|
|
// We also can remove the variable with deleted transition if variable store has the variable with added state.
|
|
// For current design, variable should do this check, so we needn't do this check here.
|
|
//
|
|
if (VariableHeader->State == VAR_ADDED || VariableHeader->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION)) {
|
|
if (VariableNeedReserve ((CHAR16 *) (VariableHeader + 1), &VariableHeader->VendorGuid) &&
|
|
!DoesVariableExist ((CHAR16 *) (VariableHeader + 1), &VariableHeader->VendorGuid, FactorycopyBuffer, *FactoryBufferLength)) {
|
|
VariableSize = (UINTN) NextVariable - (UINTN) VariableHeader;
|
|
if (LastVariableOffset + VariableSize <= VariableBufferLength - 1) {
|
|
CopyMem (&FactorycopyBuffer[LastVariableOffset], VariableHeader, VariableSize);
|
|
}
|
|
LastVariableOffset += VariableSize;
|
|
}
|
|
}
|
|
VariableHeader = NextVariable;
|
|
}
|
|
|
|
if (LastVariableOffset > VariableBufferLength) {
|
|
Status = EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
*FactoryBufferLength = LastVariableOffset;
|
|
return Status;
|
|
} |