890 lines
27 KiB
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;
|
|
}
|
|
|