alder_lake_bios/Intel/AlderLake/AlderLakeChipsetPkg/IhisiSmm/ImageCheck.c

890 lines
27 KiB
C

/** @file
;******************************************************************************
;* Copyright (c) 2018 - 2021, 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 "ImageCheck.h"
#include "IhisiSmm.h"
AUTHENTICATION_CHECK_FUNCTION
mImageCheckTableBootGuard[] = {
ImageCheckBootGuardCheckLegacyBoot,
ImageCheckBootGuardRequestFITP,
ImageCheckBootGuardRequestFIT,
ImageCheckBootGuardValidateFIT,
ImageCheckBootGuardCollectFITInfo,
ImageCheckBootGuardRequestBPM,
ImageCheckBootGuardValidateBPM,
ImageCheckBootGuardCheckBPSVN,
ImageCheckBootGuardRequestACM,
ImageCheckBootGuardCheckACMSVN,
ImageCheckBootGuardFindKM,
ImageCheckBootGuardCheckKMSVN,
NULL
};
AUTHENTICATION_CHECK_FUNCTION
mImageCheckTableNullTable[] = {
NULL
};
AUTHENTICATION_CHECK_TABLE
mImageCheckTable[] = {
{ FBTS_IMAGE_CHECK_FAILURE_CODE_BOOT_GUARD, mImageCheckTableBootGuard },
{ FBTS_IMAGE_CHECK_FAILURE_CODE_NONE, mImageCheckTableNullTable }
};
STATIC UINTN mImageCheckTableIndex = 0;
STATIC UINTN mImageCheckFunctionIndex = 0;
STATIC UINTN mRequestedLength = 0;
STATIC UINTN mFITPointer = 0;
STATIC LOCATION_INFO mLocationInfoBPM = { 0 };
STATIC LOCATION_INFO mLocationInfoACM = { 0 };
STATIC LOCATION_INFO_LIST *mLocationInfoListKM = NULL;
STATIC LOCATION_INFO_LIST *mCurrentLocationInfoListKM = NULL;
/**
IHISI Function 4Dh.
Arguments :
None
Returns :
EFI_SUCCESS - Image is valid so far
EFI_UNSUPPORTED - Image is valid and the last check is bypassed
EFI_BAD_BUFFER_SIZE - Invalid data size
Other - Image is invalid
@param None
**/
EFI_STATUS
ImageCheck (
VOID
)
{
EFI_STATUS Status;
IHISI_STATUS_CODE ReturnStatus;
UINTN Address;
UINTN Length;
BOOLEAN FurtherDataRequired;
BOOLEAN Repeat;
UINTN ErrorIndication;
BOOLEAN IsValid;
Status = EFI_SUCCESS;
Address = (UINTN) mH2OIhisi->ReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
Length = (UINTN) mH2OIhisi->ReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
FurtherDataRequired = FALSE;
Repeat = FALSE;
ErrorIndication = 0;
//
// If the Length is zero, it means input block size is by query action.
//
if (Length == 0) {
IsValid = mH2OIhisi->BufferInCmdBuffer ((VOID *) Address, FBTS_IMAGE_CHECK_IMAGE_SIZE_MAX);
} else {
IsValid = mH2OIhisi->BufferInCmdBuffer ((VOID *) Address, Length);
}
// ENCODE_IHISI_STATUS
if (!IsValid) {
mH2OIhisi->WriteCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI, FBTS_IMAGE_CHECK_FAILURE_CODE_BOOT_GUARD);
return IHISI_FBTS_PERMISSION_DENIED;
}
//
// Check if the first calling
//
if (Length == 0) {
mImageCheckTableIndex = 0;
mImageCheckFunctionIndex = 0;
mRequestedLength = 0;
// if (FixedPcdGetBool (PcdBootGuardEnable)) {
mFITPointer = 0;
mLocationInfoBPM.Address = 0;
mLocationInfoBPM.Length = 0;
mLocationInfoACM.Address = 0;
mLocationInfoACM.Length = 0;
ImageCheckFreeLocationInfoList (mLocationInfoListKM);
mLocationInfoListKM = NULL;
mCurrentLocationInfoListKM = NULL;
// }
}
if ((Length < mRequestedLength) || (Length > FBTS_IMAGE_CHECK_IMAGE_SIZE_MAX)) {
mH2OIhisi->WriteCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI, FBTS_IMAGE_CHECK_FAILURE_CODE_BOOT_GUARD);
return IHISI_FBTS_PERMISSION_DENIED;
}
while (mImageCheckTableIndex < (sizeof (mImageCheckTable) / sizeof (AUTHENTICATION_CHECK_TABLE))) {
Status = EFI_SUCCESS;
FurtherDataRequired = FALSE;
Repeat = FALSE;
while ((!EFI_ERROR (Status)) && (!FurtherDataRequired) && (mImageCheckTable[mImageCheckTableIndex].Function[mImageCheckFunctionIndex] != NULL)) {
Status = mImageCheckTable[mImageCheckTableIndex].Function[mImageCheckFunctionIndex] (&Address, &Length, &FurtherDataRequired, &Repeat);
if (Length > FBTS_IMAGE_CHECK_IMAGE_SIZE_MAX) {
Status = EFI_BAD_BUFFER_SIZE;
}
if (EFI_ERROR (Status)) {
FurtherDataRequired = FALSE;
break;
}
if (!Repeat) {
mImageCheckFunctionIndex = mImageCheckFunctionIndex + 1;
}
}
if (FurtherDataRequired) {
break;
}
if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) {
ErrorIndication = mImageCheckTable[mImageCheckTableIndex].TableCode;
break;
}
mImageCheckTableIndex = mImageCheckTableIndex + 1;
mImageCheckFunctionIndex = 0;
}
if (FurtherDataRequired) {
mH2OIhisi->WriteCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI, (UINT32)Address);
mH2OIhisi->WriteCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX, (UINT32)Length);
mRequestedLength = mH2OIhisi->ReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
}
mH2OIhisi->WriteCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI, (UINT32) ErrorIndication);
ReturnStatus = FurtherDataRequired ? IHISI_FBTS_NEXT_BLOCK : ImageCheckStatusTranslation (Status);
return ReturnStatus;
}
/**
To free the location info buffers allocated.
Arguments :
LocationInfoList - Pointer of the list of the location info buffers
Returns :
EFI_SUCCESS - Process complete
Other - Process can't be done
@param [in, out] LocationInfoList Pointer of the list of the location info buffers
**/
EFI_STATUS
ImageCheckFreeLocationInfoList (
IN OUT LOCATION_INFO_LIST *LocationInfoList
)
{
EFI_STATUS Status;
Status = EFI_SUCCESS;
if (LocationInfoList == NULL) {
return EFI_SUCCESS;
}
if (LocationInfoList->NextPtr != NULL) {
Status = ImageCheckFreeLocationInfoList (LocationInfoList->NextPtr);
}
if (!EFI_ERROR (Status)) {
Status = gSmst->SmmFreePool (LocationInfoList);
}
return Status;
}
/**
To translate the EFI Status to the corresponding IHISI Status for the ImageCheck function.
Arguments :
Status - EFI Status
Returns :
IHISI Status
@param [in] Status EFI Status
@param [out] ReturnStatus IHISI_SUCCESS continue
IHISI_END_FUNCTION_CHAIN Pass Ihisi 4Dh check
IHISI_FBTS_PERMISSION_DENIED Ihisi 4Dh check fail
**/
IHISI_STATUS_CODE
ImageCheckStatusTranslation (
IN EFI_STATUS Status
)
{
IHISI_STATUS_CODE ReturnStatus;
switch (Status) {
case EFI_SUCCESS:
case EFI_UNSUPPORTED:
ReturnStatus = IHISI_SUCCESS;
break;
case EFI_END_OF_FILE:
ReturnStatus = IHISI_END_FUNCTION_CHAIN;
break;
default:
ReturnStatus = IHISI_FBTS_PERMISSION_DENIED;
break;
}
return ReturnStatus;
}
/**
To check if the Boot State of Boot Guard is Legacy Boot(Profile 0).
Arguments :
Address - Address of the input buffer, or of the requesting data
Length - Length of the input buffer, or of the requesting data
FurtherDataRequired - Indicate to request further data
Repeat - Indicate to enter this function again
Returns :
EFI_SUCCESS - Not Legacy Boot
EFI_UNSUPPORTED - Legacy Boot
@param [in, out] Address Address of the input buffer, or of the requesting data
@param [in, out] Length Length of the input buffer, or of the requesting data
@param [out] FurtherDataRequired Indicate to request further data
@param [out] Repeat Indicate to enter this function again
**/
EFI_STATUS
ImageCheckBootGuardCheckLegacyBoot (
IN OUT UINTN *Address,
IN OUT UINTN *Length,
OUT BOOLEAN *FurtherDataRequired,
OUT BOOLEAN *Repeat
)
{
EFI_STATUS Status;
REVOCATION_VALUE Revocation;
UINTN Size;
UINT32 MeStatus;
*FurtherDataRequired = FALSE;
*Repeat = FALSE;
Status = BootGuardPlatformLibGetMeStatus (&MeStatus);
if ((EFI_ERROR(Status))) {
MeStatus = ME_NOT_READY;
}
if ((MeStatus & 0x0f) == ME_READY){
return (BootGuardPlatformLibDetermineBootState () == BootGuardBootStateLegacyBoot ) ? EFI_END_OF_FILE : EFI_SUCCESS;
} else {
Size = sizeof (Revocation);
Status = RestoreLockBox (&gArbSvnInfoGuid, &Revocation, &Size);
if (!EFI_ERROR (Status)) {
return ((Revocation.BootGuardStatus) == BootGuardBootStateLegacyBoot) ? EFI_END_OF_FILE : EFI_SUCCESS;
}
}
return EFI_DEVICE_ERROR;
}
/**
To request FITP.
Arguments :
Address - Address of the input buffer, or of the requesting data
Length - Length of the input buffer, or of the requesting data
FurtherDataRequired - Indicate to request further data
Repeat - Indicate to enter this function again
Returns :
EFI_SUCCESS - FITP requested
@param [in, out] Address Address of the input buffer, or of the requesting data
@param [in, out] Length Length of the input buffer, or of the requesting data
@param [out] FurtherDataRequired Indicate to request further data
@param [out] Repeat Indicate to enter this function again
**/
EFI_STATUS
ImageCheckBootGuardRequestFITP (
IN OUT UINTN *Address,
IN OUT UINTN *Length,
OUT BOOLEAN *FurtherDataRequired,
OUT BOOLEAN *Repeat
)
{
*Address = ( UINTN )R_FITP;
*Length = S_FITP;
*FurtherDataRequired = TRUE;
*Repeat = FALSE;
return EFI_SUCCESS;
}
/**
To request FIT.
Arguments :
Address - Address of the input buffer, or of the requesting data
Length - Length of the input buffer, or of the requesting data
FurtherDataRequired - Indicate to request further data
Repeat - Indicate to enter this function again
Returns :
EFI_SUCCESS - FIT requested
EFI_DEVICE_ERROR - FIT is unavailable
@param [in, out] Address Address of the input buffer, or of the requesting data
@param [in, out] Length Length of the input buffer, or of the requesting data
@param [out] FurtherDataRequired Indicate to request further data
@param [out] Repeat Indicate to enter this function again
**/
EFI_STATUS
ImageCheckBootGuardRequestFIT (
IN OUT UINTN *Address,
IN OUT UINTN *Length,
OUT BOOLEAN *FurtherDataRequired,
OUT BOOLEAN *Repeat
)
{
EFI_STATUS Status;
FIT_ENTRY *FIT;
FIT = NULL;
if (mFITPointer == 0) {
mFITPointer = (UINTN)(*(UINT32 *)((UINTN)(*Address)));
*Address = (UINTN)mFITPointer;
*Length = (UINTN)(sizeof (FIT_ENTRY));
*FurtherDataRequired = TRUE;
*Repeat = TRUE;
return EFI_SUCCESS;
}
FIT = (FIT_ENTRY *)((UINTN)(*Address));
Status = FITPlatformLibValidateFITHeaderAddress (FIT);
if (EFI_ERROR (Status)) {
*FurtherDataRequired = FALSE;
*Repeat = FALSE;
return EFI_DEVICE_ERROR;
}
*Address = (UINTN)mFITPointer;
*Length = (UINTN )(((FIT->Size[2] << 16) | (FIT->Size[1] << 8) | (FIT->Size[0] << 0)) * V_FIT_ENTRY_FIT_HEADER_SIZE_GRANULARITY);
*FurtherDataRequired = TRUE;
*Repeat = FALSE;
return Status;
}
/**
To validate FIT.
Arguments :
Address - Address of the input buffer, or of the requesting data
Length - Length of the input buffer, or of the requesting data
FurtherDataRequired - Indicate to request further data
Repeat - Indicate to enter this function again
Returns :
EFI_SUCCESS - Valid
EFI_DEVICE_ERROR - Invalid
@param [in, out] Address Address of the input buffer, or of the requesting data
@param [in, out] Length Length of the input buffer, or of the requesting data
@param [out] FurtherDataRequired Indicate to request further data
@param [out] Repeat Indicate to enter this function again
**/
EFI_STATUS
ImageCheckBootGuardValidateFIT (
IN OUT UINTN *Address,
IN OUT UINTN *Length,
OUT BOOLEAN *FurtherDataRequired,
OUT BOOLEAN *Repeat
)
{
EFI_STATUS Status;
FIT_ENTRY *FIT;
FIT = (FIT_ENTRY *)((UINTN)(*Address));
Status = FITPlatformLibValidateFIT (FIT);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
}
*FurtherDataRequired = FALSE;
*Repeat = FALSE;
return Status;
}
/**
To collect information of the components in FIT.
Arguments :
Address - Address of the input buffer, or of the requesting data
Length - Length of the input buffer, or of the requesting data
FurtherDataRequired - Indicate to request further data
Repeat - Indicate to enter this function again
Returns :
EFI_SUCCESS - Information collected
EFI_BAD_BUFFER_SIZE - Error on allocating saving buffer
@param [in, out] Address Address of the input buffer, or of the requesting data
@param [in, out] Length Length of the input buffer, or of the requesting data
@param [out] FurtherDataRequired Indicate to request further data
@param [out] Repeat Indicate to enter this function again
**/
EFI_STATUS
ImageCheckBootGuardCollectFITInfo (
IN OUT UINTN *Address,
IN OUT UINTN *Length,
OUT BOOLEAN *FurtherDataRequired,
OUT BOOLEAN *Repeat
)
{
EFI_STATUS Status;
FIT_ENTRY *FIT;
UINTN FITEntryMaxIndex;
UINTN Index;
LOCATION_INFO_LIST **LocationInfoListKM;
UINT8 ElementsCheck;
Status = EFI_SUCCESS;
FIT = (FIT_ENTRY *)((UINTN)(*Address));
FITEntryMaxIndex = ((( FIT->Size[2] << 16) | (FIT->Size[1] << 8) | (FIT->Size[0] << 0)) * 0x10) / (sizeof (FIT_ENTRY));
Index = 0;
LocationInfoListKM = &mLocationInfoListKM;
ElementsCheck = 0;
for (Index = 0; Index < FITEntryMaxIndex; Index = Index + 1) {
if (FIT[Index].Type == V_FIT_ENTRY_TYPE_KEY_MANIFEST) {
Status = gSmst->SmmAllocatePool (EfiRuntimeServicesData, sizeof (LOCATION_INFO_LIST), (VOID**)LocationInfoListKM);
if (EFI_ERROR (Status) || *LocationInfoListKM == NULL) {
Status = EFI_BAD_BUFFER_SIZE;
ASSERT_EFI_ERROR (Status);
break;
}
(*LocationInfoListKM)->LocationInfo.Address = (UINTN)FIT[Index].Address;
(*LocationInfoListKM)->LocationInfo.Length = (UINTN)((FIT[Index].Size[2] << 16) | (FIT[Index].Size[1] << 8) | (FIT[Index].Size[0] << 0));
(*LocationInfoListKM)->NextPtr = NULL;
LocationInfoListKM = &((*LocationInfoListKM )->NextPtr);
ElementsCheck |= BIT0;
}
if (FIT[Index].Type == V_FIT_ENTRY_TYPE_BOOT_POLICY_MANIFEST) {
mLocationInfoBPM.Address = (UINTN)FIT[Index].Address;
mLocationInfoBPM.Length = (UINTN)((FIT[Index].Size[2] << 16) | (FIT[Index].Size[1] << 8) | (FIT[Index].Size[0] << 0));
ElementsCheck |= BIT1;
}
if (FIT[Index].Type == V_FIT_ENTRY_TYPE_STARTUP_AC_MODULE) {
mLocationInfoACM.Address = (UINTN)FIT[Index].Address;
mLocationInfoACM.Length = (UINTN)((FIT[Index].Size[2] << 16) | (FIT[Index].Size[1] << 8) | (FIT[Index].Size[0] << 0));
ElementsCheck |= BIT2;
}
}
*FurtherDataRequired = FALSE;
*Repeat = FALSE;
if (ElementsCheck != 7) { //BIT0 | BIT1 | BIT2
*FurtherDataRequired = TRUE;
Status = EFI_DEVICE_ERROR;
}
return Status;
}
/**
To request BPM.
Arguments :
Address - Address of the input buffer, or of the requesting data
Length - Length of the input buffer, or of the requesting data
FurtherDataRequired - Indicate to request further data
Repeat - Indicate to enter this function again
Returns :
EFI_SUCCESS - BPM requested
EFI_NOT_FOUND - BPM is unavailable
@param [in, out] Address Address of the input buffer, or of the requesting data
@param [in, out] Length Length of the input buffer, or of the requesting data
@param [out] FurtherDataRequired Indicate to request further data
@param [out] Repeat Indicate to enter this function again
**/
EFI_STATUS
ImageCheckBootGuardRequestBPM (
IN OUT UINTN *Address,
IN OUT UINTN *Length,
OUT BOOLEAN *FurtherDataRequired,
OUT BOOLEAN *Repeat
)
{
if ((mLocationInfoBPM.Address == 0) || (mLocationInfoBPM.Length == 0)) {
return EFI_NOT_FOUND;
}
*Address = (UINTN)mLocationInfoBPM.Address;
*Length = (UINTN)mLocationInfoBPM.Length;
*FurtherDataRequired = TRUE;
*Repeat = FALSE;
return EFI_SUCCESS;
}
/**
To validate BPM.
Arguments :
Address - Address of the input buffer, or of the requesting data
Length - Length of the input buffer, or of the requesting data
FurtherDataRequired - Indicate to request further data
Repeat - Indicate to enter this function again
Returns :
EFI_SUCCESS - Valid
EFI_DEVICE_ERROR - Invalid
@param [in, out] Address Address of the input buffer, or of the requesting data
@param [in, out] Length Length of the input buffer, or of the requesting data
@param [out] FurtherDataRequired Indicate to request further data
@param [out] Repeat Indicate to enter this function again
**/
EFI_STATUS
ImageCheckBootGuardValidateBPM (
IN OUT UINTN *Address,
IN OUT UINTN *Length,
OUT BOOLEAN *FurtherDataRequired,
OUT BOOLEAN *Repeat
)
{
EFI_STATUS Status;
BOOT_POLICY_MANIFEST_HEADER *BPMH;
BPMH = (BOOT_POLICY_MANIFEST_HEADER *)((UINTN)(*Address));
Status = BootGuardPlatformLibValidateBPMStructureID (BPMH);
if ( EFI_ERROR ( Status ) ) {
Status = EFI_DEVICE_ERROR;
}
*FurtherDataRequired = FALSE;
*Repeat = FALSE;
return Status;
}
/**
To check BPSVN.
Arguments :
Address - Address of the input buffer, or of the requesting data
Length - Length of the input buffer, or of the requesting data
FurtherDataRequired - Indicate to request further data
Repeat - Indicate to enter this function again
Returns :
EFI_SUCCESS - BPSVN is valid
EFI_SECURITY_VIOLATION - BPSVN is invalid
EFI_UNSUPPORTED - Revocation values are unavailable
@param [in, out] Address Address of the input buffer, or of the requesting data
@param [in, out] Length Length of the input buffer, or of the requesting data
@param [out] FurtherDataRequired Indicate to request further data
@param [out] Repeat Indicate to enter this function again
**/
EFI_STATUS
ImageCheckBootGuardCheckBPSVN (
IN OUT UINTN *Address,
IN OUT UINTN *Length,
OUT BOOLEAN *FurtherDataRequired,
OUT BOOLEAN *Repeat
)
{
EFI_STATUS Status;
BOOT_POLICY_MANIFEST_HEADER *BPMH;
REVOCATION_VALUE Revocation;
UINTN Size;
BPMH = (BOOT_POLICY_MANIFEST_HEADER *)((UINTN)(*Address));
//
// Restore BPM SVN value from LockBox.
//
Size = sizeof (Revocation);
Status = RestoreLockBox (&gArbSvnInfoGuid, &Revocation, &Size);
if (EFI_ERROR (Status)) {
Status = EFI_UNSUPPORTED;
} else {
if (BPMH->BpmRevocation < Revocation.BPMSVN) {
Status = EFI_SECURITY_VIOLATION;
}
}
*FurtherDataRequired = FALSE;
*Repeat = FALSE;
return Status;
}
/**
To request ACM.
Arguments :
Address - Address of the input buffer, or of the requesting data
Length - Length of the input buffer, or of the requesting data
FurtherDataRequired - Indicate to request further data
Repeat - Indicate to enter this function again
Returns :
EFI_SUCCESS - ACM requested
EFI_NOT_FOUND - ACM is unavailable
@param [in, out] Address Address of the input buffer, or of the requesting data
@param [in, out] Length Length of the input buffer, or of the requesting data
@param [out] FurtherDataRequired Indicate to request further data
@param [out] Repeat Indicate to enter this function again
**/
EFI_STATUS
ImageCheckBootGuardRequestACM (
IN OUT UINTN *Address,
IN OUT UINTN *Length,
OUT BOOLEAN *FurtherDataRequired,
OUT BOOLEAN *Repeat
)
{
// FIT table. ACM length == 0
if (mLocationInfoACM.Address == 0) {
return EFI_NOT_FOUND;
}
*Address = (UINTN)mLocationInfoACM.Address;
*Length = (UINTN)mLocationInfoACM.Length;
if (*Length == 0 || *Length < sizeof (ACM_HEADER)) {
*Length = sizeof (ACM_HEADER);
}
*FurtherDataRequired = TRUE;
*Repeat = FALSE;
return EFI_SUCCESS;
}
/**
To check ACMSVN.
Arguments :
Address - Address of the input buffer, or of the requesting data
Length - Length of the input buffer, or of the requesting data
FurtherDataRequired - Indicate to request further data
Repeat - Indicate to enter this function again
Returns :
EFI_SUCCESS - ACMSVN is valid
EFI_SECURITY_VIOLATION - ACMSVN is invalid
EFI_UNSUPPORTED - Revocation values are unavailable
@param [in, out] Address Address of the input buffer, or of the requesting data
@param [in, out] Length Length of the input buffer, or of the requesting data
@param [out] FurtherDataRequired Indicate to request further data
@param [out] Repeat Indicate to enter this function again
**/
EFI_STATUS
ImageCheckBootGuardCheckACMSVN (
IN OUT UINTN *Address,
IN OUT UINTN *Length,
OUT BOOLEAN *FurtherDataRequired,
OUT BOOLEAN *Repeat
)
{
EFI_STATUS Status;
ACM_HEADER *ACMH;
REVOCATION_VALUE Revocation;
UINTN Size;
ACMH = (ACM_HEADER *)((UINTN)(*Address));
//
// Restore ACM SVN value from LockBox.
//
Size = sizeof (Revocation);
Status = RestoreLockBox (&gArbSvnInfoGuid, &Revocation, &Size);
if (EFI_ERROR (Status)) {
Status = EFI_NOT_FOUND;
} else {
if (ACMH->AcmSvn < Revocation.ACMSVN) {
Status = EFI_SECURITY_VIOLATION;
}
}
*FurtherDataRequired = FALSE;
*Repeat = FALSE;
return Status;
}
/**
To find KM.
Arguments :
Address - Address of the input buffer, or of the requesting data
Length - Length of the input buffer, or of the requesting data
FurtherDataRequired - Indicate to request further data
Repeat - Indicate to enter this function again
Returns :
EFI_SUCCESS - KM is found, or to request the next block
EFI_NOT_FOUND - KM is unavailable
EFI_UNSUPPORTED - KMID is unavailable
@param [in, out] Address Address of the input buffer, or of the requesting data
@param [in, out] Length Length of the input buffer, or of the requesting data
@param [out] FurtherDataRequired Indicate to request further data
@param [out] Repeat Indicate to enter this function again
**/
EFI_STATUS
ImageCheckBootGuardFindKM (
IN OUT UINTN *Address,
IN OUT UINTN *Length,
OUT BOOLEAN *FurtherDataRequired,
OUT BOOLEAN *Repeat
)
{
EFI_STATUS Status;
KEY_MANIFEST *KM;
UINT8 KMID;
REVOCATION_VALUE Revocation;
UINTN Size;
KM = NULL;
KMID = 0;
Status = BootGuardPlatformLibGetKMID (&KMID);
if (EFI_ERROR (Status)) {
//
// Restore KMID value from LockBox.
//
Size = sizeof (Revocation);
Status = RestoreLockBox (&gArbSvnInfoGuid, &Revocation, &Size);
if (EFI_ERROR (Status)) {
Status = EFI_NOT_FOUND;
} else {
KMID = Revocation.KMID;
}
}
if (!EFI_ERROR (Status)) {
if (mLocationInfoListKM == NULL) {
Status = EFI_NOT_FOUND;
}
}
if (!EFI_ERROR (Status)) {
if (mCurrentLocationInfoListKM == NULL) {
mCurrentLocationInfoListKM = mLocationInfoListKM;
} else {
KM = (KEY_MANIFEST *)((UINTN)(*Address));
Status = BootGuardPlatformLibValidateKMStructureID (KM);
if (!EFI_ERROR (Status)) {
if (KM->KeyManifestId == KMID) {
*FurtherDataRequired = FALSE;
*Repeat = FALSE;
return Status;
}
}
Status = EFI_SUCCESS;
if (mCurrentLocationInfoListKM->NextPtr == NULL) {
Status = EFI_NOT_FOUND;
}
mCurrentLocationInfoListKM = mCurrentLocationInfoListKM->NextPtr;
}
}
if (EFI_ERROR (Status)) {
*FurtherDataRequired = FALSE;
*Repeat = FALSE;
return Status;
}
*Address = (UINTN)mCurrentLocationInfoListKM->LocationInfo.Address;
*Length = (UINTN)mCurrentLocationInfoListKM->LocationInfo.Length;
*FurtherDataRequired = TRUE;
*Repeat = TRUE;
return Status;
}
/**
To check KMSVN.
Arguments :
Address - Address of the input buffer, or of the requesting data
Length - Length of the input buffer, or of the requesting data
FurtherDataRequired - Indicate to request further data
Repeat - Indicate to enter this function again
Returns :
EFI_SUCCESS - KMSVN is valid
EFI_SECURITY_VIOLATION - KMSVN is invalid
EFI_UNSUPPORTED - Revocation values are unavailable
@param [in, out] Address Address of the input buffer, or of the requesting data
@param [in, out] Length Length of the input buffer, or of the requesting data
@param [out] FurtherDataRequired Indicate to request further data
@param [out] Repeat Indicate to enter this function again
**/
EFI_STATUS
ImageCheckBootGuardCheckKMSVN (
IN OUT UINTN *Address,
IN OUT UINTN *Length,
OUT BOOLEAN *FurtherDataRequired,
OUT BOOLEAN *Repeat
)
{
EFI_STATUS Status;
KEY_MANIFEST *KM;
REVOCATION_VALUE Revocation;
UINTN Size;
KM = (KEY_MANIFEST *)((UINTN)(*Address));
//
// Restore KM SVN value from LockBox.
//
Size = sizeof (Revocation);
Status = RestoreLockBox (&gArbSvnInfoGuid, &Revocation, &Size);
if (EFI_ERROR (Status)) {
Status = EFI_NOT_FOUND;
} else {
if (KM->KmSvn < Revocation.KMSVN) {
Status = EFI_SECURITY_VIOLATION;
}
}
*FurtherDataRequired = FALSE;
*Repeat = FALSE;
return Status;
}