alder_lake_bios/Insyde/InsydeModulePkg/Library/VariableSupportLib/SecureBootSupport.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;
}