diff options
Diffstat (limited to 'Core/EM/SecurityPkg/SecFlashUpd')
-rw-r--r-- | Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.c | 325 | ||||
-rw-r--r-- | Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.dxs | 89 | ||||
-rw-r--r-- | Core/EM/SecurityPkg/SecFlashUpd/IsSecRecovery.c | 390 | ||||
-rw-r--r-- | Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.cif | 17 | ||||
-rw-r--r-- | Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.mak | 176 | ||||
-rw-r--r-- | Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.sdl | 152 | ||||
-rw-r--r-- | Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.c | 276 | ||||
-rw-r--r-- | Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.dxs | 58 | ||||
-rw-r--r-- | Core/EM/SecurityPkg/SecFlashUpd/VerifyFwCapsule.c | 974 |
9 files changed, 2457 insertions, 0 deletions
diff --git a/Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.c b/Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.c new file mode 100644 index 0000000..a82e2c7 --- /dev/null +++ b/Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.c @@ -0,0 +1,325 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014 American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/EfiCapsuleRecovery.c 13 3/18/14 3:02p Alexp $ +// +// $Revision: 13 $ +// +// $Date: 3/18/14 3:02p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/EfiCapsuleRecovery.c $ +// +// 13 3/18/14 3:02p Alexp +// year '2014' in file hdr & ftr +// +// 12 2/27/13 6:31p Alexp +// don't assume the Capsule hob starts with FWCapsule header. +// helps to hadle Windows Update Capsule with Ami.rom as payload +// +// 11 12/17/12 2:40p Alexp +// optimized LoadRecoveryCapsule() +// +// 10 8/28/12 4:19p Alexp +// change return NULL to return 0 for EFI_PHYSICAL_ADDRESS types +// +// 8 4/19/12 2:43p Alexp +// EIP:87678: Woking image during Recovery and Capsule Secure Flash Update +// Deffer Publishing of FV DXE to DxeIpl. Launch DXE from original FV on +// Flash updates while in Recovery use DXE form new image +// +// 7 2/14/12 3:24p Alexp +// Replace VOID (32bit) with EFI_PHYSICAL_ADDRESS(64bit) pointer for an +// address of a Recovery Hob data. +// +// 6 12/08/11 12:22p Alexp +// Re-define EFI_HOB_TYPE_CV type as EFI_HOB_TYPE_UEFI_CAPSULE +// for forward compatibility with PI 1.2 Hob.h definitions +// +// 5 11/17/11 10:01a Alexp +// 1. Replace local Capsule pointer with global one. +// 2. Locate FW CApsule includes search in 2 potential Capsule Hob types +// - EFI_HOB_TYPE_GUID_EXTENSION +// - EFI_HOB_TYPE_CV +// +// 4 10/11/11 12:23p Alexp +// re-arrange Function defines and global defines +// +// 3 9/20/11 2:26p Alexp +// do not change BootMode from FlUpdate to Recovery if FwCapsule update is +// pending +// +// 2 7/20/11 7:16p Alexp +// remove dependency on Capsule module +// +// 1 7/01/11 4:39p Alexp +// +// 3 4/29/11 10:28a Alexp +// Capsule Recovery to be invoked sepparately from generic Recovery PPI +// +// +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: EFICapsuleRecovery.c - PEI driver +// +// Description: Implements EFI_PEI_RECOVERY_BLOCK_IO_PPI for Capsule HOB. +// Capsule Recovery to be invoked separately from generic Recovery PPI +//---------------------------------------------------------------------- +//<AMI_FHDR_END> +#include <Token.h> +#include <PPI/RecoveryModule.h> + +#include <AmiPeiLib.h> +#include <AmiHobs.h> +#include <Hob.h> +#include "AmiCertificate.h" +#include <FlashUpd.h> + +// Definitions + +EFI_GUID gFWCapsuleGuid = APTIO_FW_CAPSULE_GUID; +EFI_GUID guidRecoveryModule = EFI_PEI_RECOVERY_MODULE_PPI_GUID; + +#ifndef EFI_HOB_TYPE_CV +#define EFI_HOB_TYPE_CV EFI_HOB_TYPE_UEFI_CAPSULE +typedef EFI_HOB_UEFI_CAPSULE EFI_HOB_CAPSULE_VOLUME; +#endif // PI BACKWARD_COMPATIBLE_MODE + +EFI_PHYSICAL_ADDRESS gCapsuleAddress = 0; +UINT64 gCapsuleLength = 0; +//---------------------------------------------------------------------------- +// Function Prototypes +//---------------------------------------------------------------------------- +EFI_STATUS ReportFV2Dxe( + IN VOID* RecoveryCapsule OPTIONAL, + IN EFI_PEI_SERVICES **PeiServices +); + +EFI_STATUS VerifyFwImage( + IN EFI_PEI_SERVICES **PeiServices, + IN OUT VOID **pCapsule, + IN OUT UINT32 *pCapsuleSize, + IN OUT UINT32 *FailedVTask +); + +//---------------------------------------------------------------------------- +// Function Definitions +//---------------------------------------------------------------------------- +EFI_STATUS LoadRecoveryCapsule( + IN EFI_PEI_SERVICES **PeiServices, + IN struct _EFI_PEI_RECOVERY_MODULE_PPI *This +); + +BOOLEAN IsFlashUpdateS3Capsule ( + EFI_PEI_SERVICES **PeiServices, + EFI_BOOT_MODE *BootMode +); +//---------------------------------------------------------------------------- +// PPI to be installed +//---------------------------------------------------------------------------- +static EFI_PEI_RECOVERY_MODULE_PPI RecoveryModule = +{ + LoadRecoveryCapsule +}; + +//---------------------------------------------------------------------------- +// Notify list that are installed +//---------------------------------------------------------------------------- +static EFI_PEI_PPI_DESCRIPTOR RecoveryPpiList[] = +{ + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &guidRecoveryModule, &RecoveryModule + } +}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// +// Procedure: FindFWCapsuleHOB +// +// Description: Locates Aptio FW Capsule in Capsule Hob +// +// Input: EFI_PEI_SERVICES **PeiServices +// Output: EFI_PHYSICAL_ADDRESS pointer to FW CApsule +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +FindFWCapsuleHOB +( + IN EFI_PEI_SERVICES **PeiServices +){ + EFI_HOB_GUID_TYPE *pHob; + EFI_HOB_CAPSULE_VOLUME *pHob1; + EFI_PHYSICAL_ADDRESS CapsuleAddress; + UINT64 CapsuleLength; + EFI_CAPSULE_HEADER *FWCapsuleVolume; + + (*PeiServices)->GetHobList(PeiServices, &pHob); + pHob1 = (EFI_HOB_CAPSULE_VOLUME*)pHob; +// 1. attempt to locate Capsule by GUID guidAmiCapsuleHob + while (!EFI_ERROR(FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &pHob))) + { + if((pHob->Header.HobType == EFI_HOB_TYPE_GUID_EXTENSION)&& + !(guidcmp(&((AMI_CAPSULE_HOB*)pHob)->CapsuleGuid, &gFWCapsuleGuid))) + { + PEI_TRACE((-1, PeiServices, "FW Capsule found in GUIDed Capsule Hob\n")); + gCapsuleLength = ((AMI_CAPSULE_HOB*)pHob)->CapsuleLength; + gCapsuleAddress = (EFI_PHYSICAL_ADDRESS)(((AMI_CAPSULE_HOB*)pHob)->CapsuleData); + return EFI_SUCCESS; + } + } +// 2. attempt to locate capsule volume hob + while (!EFI_ERROR(FindNextHobByType(EFI_HOB_TYPE_CV, &pHob1))) + { + // if capsule volume hob is found, determine the capsule's location + CapsuleAddress = pHob1->BaseAddress; + CapsuleLength = pHob1->Length; + FWCapsuleVolume = (EFI_CAPSULE_HEADER*) CapsuleAddress; + if(CapsuleLength != 0 && FWCapsuleVolume->CapsuleImageSize <= CapsuleLength && + !(guidcmp(&(FWCapsuleVolume->CapsuleGuid), &gFWCapsuleGuid))) + { + PEI_TRACE((-1, PeiServices, "FW Capsule found in Capsule Volume Hob\n")); + gCapsuleLength = CapsuleLength; + gCapsuleAddress = CapsuleAddress; + return EFI_SUCCESS; + } + } + + PEI_TRACE((-1,PeiServices, "FW capsule HOB not found\n")); + return EFI_NOT_FOUND; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// +// Procedure: LoadRecoveryCapsule +// +// Description: LoadRecoveryCapsule function of EFI_PEI_RECOVERY_MODULE_PPI +// ppi. RecoveryDeviceOrder is a list of guids; each guid +// represents a type of recovery device. We go through +// this list and call FindRecoveryDevice for each type of +// device. +// -This function should not be confused with LoadRecoveryCapsule +// function of the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI ppi. +// -Called by DxeIpl. +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS LoadRecoveryCapsule( + IN EFI_PEI_SERVICES **PeiServices, + IN struct _EFI_PEI_RECOVERY_MODULE_PPI *This +) +{ + EFI_STATUS Status; + static EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID; + RECOVERY_IMAGE_HOB *pRecoveryHob; + UINTN Size; + EFI_PHYSICAL_ADDRESS CapsuleAddress; + + PEI_PROGRESS_CODE(PeiServices,PEI_RECOVERY_STARTED); + + PEI_TRACE((TRACE_DXEIPL, PeiServices, "Loading Recovery Image...")); + +// Locate Capsule Hob + if(!gCapsuleAddress || !gCapsuleLength) return EFI_NOT_FOUND; + + //create HOB that describes location of the Recovery image + Status = (*PeiServices)->CreateHob( + PeiServices, EFI_HOB_TYPE_GUID_EXTENSION, + sizeof(RECOVERY_IMAGE_HOB), &pRecoveryHob + ); + pRecoveryHob->Header.Name = RecoveryHobGuid; + pRecoveryHob->Address = 0; + +// Size = (UINTN)((APTIO_FW_CAPSULE_HEADER*)gFwCapsule)->CapHdr.CapsuleImageSize; + Size = (UINTN)gCapsuleLength; + CapsuleAddress = (EFI_PHYSICAL_ADDRESS)gCapsuleAddress; + Status = VerifyFwImage(PeiServices, (VOID**)&CapsuleAddress, (UINT32*)&Size,(UINT32*)&pRecoveryHob->FailedStage ); + pRecoveryHob->Status = (UINT8)Status; + pRecoveryHob->Address = CapsuleAddress; + if (EFI_ERROR(Status)) { + PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_INVALID_CAPSULE, EFI_ERROR_MAJOR | Status); + } +// < 4.6.5.4 +#if defined(CORE_COMBINED_VERSION) && CORE_COMBINED_VERSION < 0x4028e + else{ + // DxeIpl from 4.6.5.4. will publish Dxe FV + Status = ReportFV2Dxe((VOID *)CapsuleAddress, PeiServices); + } +#endif + + if (EFI_ERROR(Status)) { + PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_NO_CAPSULE, EFI_ERROR_MAJOR); + } + + return Status; + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// +// Procedure: EFICapsuleRecoveryPeimEntry +// +// Description: Entry point. Installs EFI_PEI_RECOVERY_MODULE_PPI ppi +// (which has function LoadRecoveryCapsule). +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +EFICapsuleRecoveryPeimEntry ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices +) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + +// Change the Boot Mode to Recovery from S3_RESUME/BOOT_ON_FLASH_UPDATE + Status = (*PeiServices)->GetBootMode(PeiServices, &BootMode); + PEI_TRACE((-1, PeiServices, "FW Capsule Recovery Module, BootMode 0x%x\n", BootMode)); + if(BootMode == BOOT_ON_S3_RESUME || BootMode == BOOT_ON_FLASH_UPDATE) + { +// Locate Capsule Hob + Status = FindFWCapsuleHOB(PeiServices); + if (EFI_ERROR(Status) || !gCapsuleAddress || !gCapsuleLength) { +// Capsule not found: +// Change the Boot Mode to BOOT_WITH_FULL_CONFIGURATION from BOOT_ON_FLASH_UPDATE + BootMode = BOOT_WITH_FULL_CONFIGURATION; + Status = (*PeiServices)->SetBootMode(PeiServices, BootMode); + } else { + Status = (*PeiServices)->InstallPpi(PeiServices,RecoveryPpiList); + ASSERT_PEI_ERROR (PeiServices, Status); + } + PEI_TRACE((-1, PeiServices, "\tchange mode to 0x%x\n",BootMode)); + } + + return Status; +} +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014 American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.dxs b/Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.dxs new file mode 100644 index 0000000..85dc91e --- /dev/null +++ b/Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.dxs @@ -0,0 +1,89 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/EfiCapsuleRecovery.dxs 6 3/18/14 3:01p Alexp $ +// +// $Revision: 6 $ +// +// $Date: 3/18/14 3:01p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/EfiCapsuleRecovery.dxs $ +// +// 6 3/18/14 3:01p Alexp +// set 2014 in file hdr & ftr +// +// 5 5/31/12 1:18p Alexp +// EIP74625:New Capsule PPI required by latest Intel's MRC code +// New PPI GUID; +// Capsule_2_0 Mailbox does not need extra Cap Hdr +// EIP90678: MonotonicCounter variable guid changed +// Use gAmiGlobalVariableGuid +// +// 4 11/21/11 5:49p Alexp +// include optional GUID dependenccy on Intel Misc Framework +// PEI_CAPSULE_PPI_GUID +// +// 3 11/17/11 10:02a Alexp +// include dependency on AMI_DIGITAL_SIG PPI +// +// 2 7/20/11 7:16p Alexp +// remove dependency on Capsule module +// +// 1 7/01/11 4:39p Alexp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: Recovery.dxs +// +// Description: Dependancy expression for the component +// +//<AMI_FHDR_END> +//********************************************************************** +#include <PPI/LoadFile.h> +#include <PPI/CryptoPPI.h> +#include <FlashUpd.h> +// AMI Capsule PPI (deprecated) +#define EFI_PEI_CAPSULE_PPI_GUID \ + { 0x066785b1, 0xedb8, 0x46dc, 0x84, 0x2f, 0x57, 0x44, 0x04, 0xb8, 0x69, 0x2f } +// Intel Misc Framework PEI_CAPSULE_PPI_GUID +#define PEI_CAPSULE_PPI_GUID \ + { 0x3acf33ee, 0xd892, 0x40f4, 0xa2, 0xfc, 0x38, 0x54, 0xd2, 0xe1, 0x32, 0x3d } +DEPENDENCY_START +EFI_PEI_FV_FILE_LOADER_GUID +AND +EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI +AND +EFI_PEI_BOOT_IN_FLASH_UPDATE_MODE_PEIM_PPI +AND +(EFI_PEI_CAPSULE_PPI_GUID OR PEI_CAPSULE_PPI_GUID) +AND +AMI_DIGITAL_SIGNATURE_PPI_GUID +DEPENDENCY_END +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/SecurityPkg/SecFlashUpd/IsSecRecovery.c b/Core/EM/SecurityPkg/SecFlashUpd/IsSecRecovery.c new file mode 100644 index 0000000..112f655 --- /dev/null +++ b/Core/EM/SecurityPkg/SecFlashUpd/IsSecRecovery.c @@ -0,0 +1,390 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/IsSecRecovery.c 18 10/29/14 5:11p Alexp $ +// +// $Revision: 18 $ +// +// $Date: 10/29/14 5:11p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/IsSecRecovery.c $ +// +// 18 10/29/14 5:11p Alexp +// GetFlashUpdateVar() - set default value of CounterHi= -1 +// for cases when MC variable is available only in pre-boot. +// +// 15 3/18/14 3:02p Alexp +// year '2014' in file hdr & ftr +// +// 14 8/12/13 4:36p Alexp +// fix ChangeBootModeAfterEndofMrc() to change BootMode and install PPI if +// CApsule Upd is pending +// +// 13 4/01/13 9:37a Alexp +// exclude capsule recovery code if FWCAPSULE_RECOVERY_SUPPORT is 0 +// +// 12 2/27/13 6:43p Alexp +// GetFlashUpdateVar() to check for AMI Capsule Variable +// if Ami FwCapsule is pending and update boot mode to +// BOOT_ON_FLASH_UPDATE +// +// 11 7/09/12 5:30p Alexp +// IsFlashUpdateS3Capsule +// Install Capsule Recovery Event whether by checking FlashUpd variable +// or if BOOT_ON_FLASH_UPDATE. It may've already been set by Capsule PEI +// +// +// 9 6/01/12 10:44a Alexp +// EIP74625:New Capsule PPI required by latest Intel's MRC code +// New PPI GUID; +// Capsule_2_0 Mailbox does not need extra Cap Hdr +// EIP90678: MonotonicCounter variable guid changed +// Use AMI_GLOBAL_VARIABLE_GUID +// +// 7 12/08/11 4:51p Alexp +// Change method of calling IsSecRecovery init routine. +// Replaced IsSecRecovery PEI with function call IsFlashUpdateRecovery +// from PeiCoreInitialize +// +// 6 11/10/11 7:10p Alexp +// minor optimizations +// +// 5 11/03/11 6:41p Alexp +// Add provision to build file as .FFS with new function to install +// callback on gAmiPeiAfterMrcGuid event +// Update BootMode to BOOT_ON_FLASH_UPDATE if Capsule update is detected +// +// 4 10/17/11 11:33a Alexp +// Replace old method to detect FlashUpd with single IsFlashUpdate() hook +// to be called from SbPei.c ->GetBootMode +// +// 3 10/11/11 12:23p Alexp +// removed comments +// +// 2 7/20/11 7:16p Alexp +// remove dependency on Capsule module +// +// 1 7/01/11 4:39p Alexp +// +// +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: IsSecRecovery.c - PEI recovery services +// +// Description: File contains hook to determine if BootMode needs to follow +// recovery path due to pending Flash Update +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> +// Module specific Includes +#include "Efi.h" +#include "Pei.h" +#include "token.h" +#include <AmiPeiLib.h> +#include <Hob.h> +#include <Ppi\ReadOnlyVariable.h> +#include <FlashUpd.h> +#if FWCAPSULE_RECOVERY_SUPPORT == 1 +#include "AmiCertificate.h" +#include <Capsule.h> + +// Definitions +static EFI_GUID gFWCapsuleGuid = APTIO_FW_CAPSULE_GUID; +static EFI_GUID gEfiCapsuleVendorGuid = EFI_CAPSULE_AMI_GUID; +#endif +static EFI_GUID gFlashUpdBootModeGuid = EFI_PEI_BOOT_IN_FLASH_UPDATE_MODE_PEIM_PPI; +// PPI that are installed +static EFI_PEI_PPI_DESCRIPTOR mFlashUpdateModePpi[] = + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gFlashUpdBootModeGuid, + NULL +}; + +static EFI_GUID gPeiReadOnlyVariablePpiGuid = EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID; +static EFI_GUID gFlashUpdGuid = FLASH_UPDATE_GUID; +// must be defined in AmiLib.h (Core 4.6.5.4 +) +#if defined(AMI_GLOBAL_VARIABLE_GUID) +static EFI_GUID guidVar = AMI_GLOBAL_VARIABLE_GUID; +#else +static EFI_GUID guidVar = EFI_GLOBAL_VARIABLE; +#endif + +#if FWCAPSULE_RECOVERY_SUPPORT == 1 +/////////////////////////////////////////////////////// +// {64C96700-6B4C-480C-A3E1-B8BDE8F602B2} +#define AMI_PEI_AFTER_MRC_GUID \ + {0x64c96700, 0x6b4c, 0x480c, 0xa3, 0xe1, 0xb8, 0xbd, 0xe8, 0xf6, 0x2, 0xb2} + +static EFI_GUID gAmiPeiAfterMrcGuid = AMI_PEI_AFTER_MRC_GUID; + +EFI_STATUS ChangeBootModeAfterEndofMrc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi +); + +static EFI_PEI_NOTIFY_DESCRIPTOR EndOfMrcNotifyList[] = { + { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | \ + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gAmiPeiAfterMrcGuid, ChangeBootModeAfterEndofMrc }, +}; +#endif +//-------------------------------------------------------------------------- +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetFlashUpdateVar +// +// Description: +// This function checks if recovery flow is needed due to pending Flash Update +// +// Input: +// PeiServices Pointer to the PEI services table +// +// Output: +// TRUE - recovery is requested +// FALSE - recovery is not requested +// +// Notes: +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN +GetFlashUpdateVar ( + EFI_PEI_SERVICES **PeiServices, + AMI_FLASH_UPDATE_BLOCK *FlashUpdDesc, + UINT32 *CounterHi +){ + EFI_STATUS Status; + UINTN Size; + EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariable; +#if FWCAPSULE_RECOVERY_SUPPORT == 1 + EFI_PHYSICAL_ADDRESS IoData; + EFI_CAPSULE_HEADER *CapsuleHeader; + EFI_CAPSULE_BLOCK_DESCRIPTOR *pCapsuleMailboxPtr; +#endif +// Check FlashOp variable for Recovery Flash operation +// Detect if we are in Flash Update mode and set some recovery global variables +// Read "FlashOp" Variable to update global RecoveryFileName, Size + Status = (*PeiServices)->LocatePpi( PeiServices, + &gPeiReadOnlyVariablePpiGuid, + 0, + NULL, + &ReadOnlyVariable ); + if(EFI_ERROR(Status)) + return FALSE; + + Size = sizeof(AMI_FLASH_UPDATE_BLOCK); + Status = ReadOnlyVariable->GetVariable( PeiServices, + FLASH_UPDATE_VAR, + &gFlashUpdGuid, + NULL, + &Size, + FlashUpdDesc ); + if (!EFI_ERROR(Status)) + { + Size = sizeof(UINT32); + Status = ReadOnlyVariable->GetVariable(PeiServices, + L"MonotonicCounter", + &guidVar, + NULL, + &Size, + CounterHi); + if (EFI_ERROR(Status) || FlashUpdDesc->MonotonicCounter == 0xffffffff) + *CounterHi = 0xffffffff; + + return TRUE; +#if FWCAPSULE_RECOVERY_SUPPORT == 1 + } else { + Size=sizeof(EFI_PHYSICAL_ADDRESS); + Status = ReadOnlyVariable->GetVariable( PeiServices, + CAPSULE_UPDATE_VAR, &gEfiCapsuleVendorGuid, + NULL, + &Size, + &IoData ); + if (!EFI_ERROR(Status)) + { + // verify the FW capsule is in memory. May first check if pCapsuleMailboxPtr == IoData + pCapsuleMailboxPtr = (EFI_CAPSULE_BLOCK_DESCRIPTOR*)IoData; + CapsuleHeader = (EFI_CAPSULE_HEADER*)pCapsuleMailboxPtr[0].DataBlock; + // + // Compare GUID with APTIO_FW_CAPSULE_GUID + // + if (guidcmp (&CapsuleHeader->CapsuleGuid, &gFWCapsuleGuid)==0) { + FlashUpdDesc->FlashOpType = FlCapsule; + return TRUE; + } + } +#endif + } + + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: IsFlashUpdate +// +// Description: +// This function returns proper BootMode if Flash Update mode is pending +// +// Input: +// **PeiServices - Pointer to the PEI services table +// *BootMode - Pointer to a BootMode variable +// +// Output: +// BOOLEAN +// TRUE - recovery is requested +// FALSE - recovery is not requested +// BootMode - updated BootMode value if TRUE +// +// Notes: +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN +IsFlashUpdate( + EFI_PEI_SERVICES **PeiServices, + EFI_BOOT_MODE *BootMode +){ + UINT32 CounterHi = 0; + AMI_FLASH_UPDATE_BLOCK FlashUpdDesc; + + FlashUpdDesc.MonotonicCounter = 0; + FlashUpdDesc.FlashOpType = FlDisabled; + +//SetMode should have set FlashUpd var even if no MC var detected. +// MC check should fail Recovery + if(/**BootMode != BOOT_IN_RECOVERY_MODE && */ + GetFlashUpdateVar(PeiServices, &FlashUpdDesc, &CounterHi) && + CounterHi==(UINT32)FlashUpdDesc.MonotonicCounter) + { + if(FlashUpdDesc.FlashOpType == FlRecovery) + { + *BootMode = BOOT_IN_RECOVERY_MODE; + return TRUE; + } + if(FlashUpdDesc.FlashOpType == FlCapsule/* && *BootMode == BOOT_ON_S3_RESUME*/) + { + *BootMode = BOOT_ON_FLASH_UPDATE; + return TRUE; + } + } + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: IsFlashUpdateRecovery +// +// Description: +// This function checks if recovery flow is needed due to pending Flash Update +// +// Input: +// PeiServices Pointer to the PEI services table +// +// Output: +// TRUE - recovery is requested +// FALSE - recovery is not requested +// +// Notes: +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN +IsFlashUpdateRecovery ( + EFI_PEI_SERVICES **PeiServices +){ + EFI_BOOT_MODE BootMode; + if(IsFlashUpdate(PeiServices, &BootMode) && BootMode == BOOT_IN_RECOVERY_MODE) + return TRUE; + return FALSE; +} + +#if FWCAPSULE_RECOVERY_SUPPORT == 1 + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ChangeBootModeAfterEndofMrc +// +// Description: Change BootMode to BOOT_ON_FLASH_UPDATE if Capsule update is pending +// +// Input: PeiServices - Pointer to the PEI services table +// NotifyDescriptor - Pointer to the descriptor for the +// notification event. +// InvokePpi - Pointer to the PPI that was installed +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ChangeBootModeAfterEndofMrc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + + Status = (*PeiServices)->GetBootMode( PeiServices, &BootMode ); +// if (!EFI_ERROR(Status) && (BootMode != BOOT_IN_RECOVERY_MODE)) +// BOOT_ON_FLASH_UPDATE may already be set by Capsule PEI + if(!EFI_ERROR(Status) && (BootMode == BOOT_ON_S3_RESUME || BootMode == BOOT_ON_FLASH_UPDATE)) + { + // Change the Boot Mode to Recovery from S3_RESUME/BOOT_ON_FLASH_UPDATE + if (IsFlashUpdate(PeiServices, &BootMode) && BootMode == BOOT_ON_FLASH_UPDATE) + (*PeiServices)->SetBootMode(PeiServices, BootMode); + } + //install Flash Update Boot Mode PPI + if(BootMode == BOOT_ON_FLASH_UPDATE) + (*PeiServices)->InstallPpi( PeiServices, mFlashUpdateModePpi); + + return EFI_SUCCESS; +} +#endif +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// +// Procedure: IsFlashUpdateCapsuleInit +// +// Description: Installs callback to ChangeBootModeAfterEndofMrc +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +IsFlashUpdateCapsuleInit ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices +) +{ +#if FWCAPSULE_RECOVERY_SUPPORT == 1 + return (*PeiServices)->NotifyPpi( PeiServices, EndOfMrcNotifyList); +#else + return EFI_SUCCESS; +#endif + +} +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.cif b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.cif new file mode 100644 index 0000000..aecb88d --- /dev/null +++ b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.cif @@ -0,0 +1,17 @@ +<component> + name = "Secure Flash Update" + category = ModulePart + LocalRoot = "Core\EM\SecurityPkg\SecFlashUpd\" + RefName = "SecFlashUpd" +[files] +"SecFlashUpd.sdl" +"SecFlashUpd.mak" +"VerifyFwCapsule.c" +"IsSecRecovery.c" +"EfiCapsuleRecovery.c" +"EfiCapsuleRecovery.dxs" +"SecFlashUpdDxe.c" +"SecFlashUpdDxe.dxs" +[parts] +"FlashUpdInc" +<endComponent> diff --git a/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.mak b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.mak new file mode 100644 index 0000000..f44a380 --- /dev/null +++ b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.mak @@ -0,0 +1,176 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2014, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/SecFlashUpd.mak 17 9/30/14 3:34p Alexp $ +# +# $Revision: 17 $ +# +# $Date: 9/30/14 3:34p $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/SecFlashUpd.mak $ +# +# 17 9/30/14 3:34p Alexp +# EIP185686:Build error with Recovery_SUPPORT = 0 +# +# 16 3/18/14 3:02p Alexp +# year '2014' in file hdr & ftr +# +# 15 4/19/13 4:48p Alexp +# add external define +# +# 14 11/21/12 10:36a Alexp +# don not link cryptolib +# +# 13 10/31/12 10:09a Alexp +# EIP#100418: Make SecureFlashPkg build independent +# from Core's ReFlash driver Support +# +# 12 9/06/12 6:15p Alexp +# EIP#100418: Make SecureFlashPkg build independant from ReFlash-Support +# +# 11 7/13/12 12:11p Alexp +# Replace custom _EFI_CAPSULE_BLOCK_DESCRIPTOR_ with +# generic EFI_CAPSULE_BLOCK_DESCRIPTOR +# +# 10 5/18/12 4:22p Alexp +# 1. Link Crypto Library with VerifyFwCap in Recovery boot flow.Use Hash +# functions only +# 2. Pass SEC_FLASH_GUID_DEFINES containing unique FwCap Ffs Guid and +# Section guids +# +# 9 12/08/11 4:51p Alexp +# Change method of calling IsSecRecovery init routine -> +# ->Replaced IsSecRecovery PEI with function call IsFlashUpdateRecovery +# from PeiCoreInitialize +# +# 8 11/10/11 4:36p Alexp +# Add build rules to generate SecFlashDxe driver +# +# 7 11/03/11 6:38p Alexp +# create build rules for IsSecRecovery.ffs PEI module +# +# 6 10/17/11 11:33a Alexp +# Replace old method to detect FlashUpd with single IsFlashUpdate() hook +# to be called from SbPei.c ->GetBootMode +# +# 5 8/22/11 5:22p Alexp +# removed build rules for SecFlash Setup pages +# +# 4 8/18/11 4:45p Alexp +# removed unused build target:SecFlashUpdDxeBin +# +# 3 8/05/11 3:18p Alexp +# removed Flash Policy driver, files, Protocol; Flash Policy is hardwired +# via SDL +# +# 2 7/20/11 7:16p Alexp +# remove dependency on Capsule module +# +# 1 7/01/11 4:39p Alexp +# +# +#************************************************************************* +#<AMI_FHDR_START> +# +# Name: SecFlashUpd.mak +# +# Description: +# +# +#<AMI_FHDR_END> +#************************************************************************* +SecureModule: SecureFlashUpdate + +SecureFlashUpdate : $(BUILD_DIR)\SecFlashUpd.mak SecFlashUpdDxeBin \ +!IF $(Recovery_SUPPORT) == 1 +FwCapsuleRecoveryPPIBin +!ENDIF + +$(BUILD_DIR)\SecFlashUpd.mak : $(SecFlashUpd_DIR)\SecFlashUpd.cif $(SecFlashUpd_DIR)\SecFlashUpd.mak $(BUILD_RULES) + $(CIF2MAK) $(SecFlashUpd_DIR)\SecFlashUpd.cif $(CIF2MAK_DEFAULTS) + +BUILD_SecFlashUpd_DIR = $(BUILD_DIR)\$(SecFlashUpd_DIR) + +!IFDEF ReFlash_SUPPORT +SecFlashUpd_DEFINES= \ + /D ReFlash_SUPPORT=$(ReFlash_SUPPORT) +!ENDIF + +SecFlashUpd_INCLUDES= \ + /I $(SecFlashUpd_DIR)\ + $(SEC_FLASH_GUID_DEFINES)\ +!IFDEF ReFlash_DIR + /I $(ReFlash_DIR)\ +!ENDIF + /I$(CORE_DIR) + +AMI_CSP_LIB_INCLUDE_FILES = "Include\FlashUpd.h" + \ +$(AMI_CSP_LIB_INCLUDE_FILES) + +AMI_CSP_LIB_OBJS = $(AMI_CSP_LIB_OBJS) \ +$(BUILD_DIR)\IsSecRecovery.obj +#----------------------------------------------------------------------- +# Auxilary library files compilation +#----------------------------------------------------------------------- +RecoveryBin FwCapsuleRecoveryPPIBin : $(BUILD_DIR)\VerifyFwCapsule.obj $(CRYPTOLIBPEI) + +{$(SecFlashUpd_DIR)}.c{$(BUILD_DIR)}.obj:: + $(CC) $(CFLAGS) $(SEC_FLASH_GUID_DEFINES) /I $(SecFlashUpd_DIR) /Fo$(BUILD_DIR)\ $< + +SecFlashUpdDxeBin : $(AMIDXELIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\SecFlashUpd.mak all\ + NAME=SecFlashUpdDxe\ + MAKEFILE=$(BUILD_DIR)\SecFlashUpd.mak \ + GUID=A0EF80E3-F9AB-4CBA-98FD-704620F4048D \ + ENTRY_POINT=SecFlashUpdDxe_Init\ + DEPEX1=$(SecFlashUpd_DIR)\SecFlashUpdDxe.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\ + "MY_INCLUDES=$(SecFlashUpd_INCLUDES) "\ + "CFLAGS=$(CFLAGS) $(SecFlashUpd_DEFINES)" \ + OBJECTS="$(BUILD_SecFlashUpd_DIR)\SecFlashUpdDxe.obj" \ + TYPE=RT_DRIVER COMPRESS=1 + +!IF $(CORE_COMBINED_VERSION) < 0x4028e +FwCapsuleRecoveryPPIBin : $(AMIPEILIB) $(BUILD_DIR)\$(BOARD_DIR)\ReportFV2.obj +!ELSE +FwCapsuleRecoveryPPIBin : $(AMIPEILIB) +!ENDIF + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\SecFlashUpd.mak all\ + NAME=FwCapsuleRecoveryPPI\ + MAKEFILE=$(BUILD_DIR)\SecFlashUpd.mak \ + GUID=83FA5AED-5171-4949-BDC9-0CBC9E123663 \ + ENTRY_POINT=EFICapsuleRecoveryPeimEntry \ +# "MY_INCLUDES=$(SecFlashUpd_INCLUDES) /I $(Recovery_DIR)"\ + "MY_INCLUDES=$(SecFlashUpd_INCLUDES)"\ + OBJECTS="$(BUILD_SecFlashUpd_DIR)\EfiCapsuleRecovery.obj" \ + DEPEX1=$(SecFlashUpd_DIR)\EfiCapsuleRecovery.DXS DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \ + TYPE=PEIM COMPRESS=1 + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2014, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.sdl b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.sdl new file mode 100644 index 0000000..a21f769 --- /dev/null +++ b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.sdl @@ -0,0 +1,152 @@ +TOKEN + Name = "SecFlashUpd_SUPPORT" + Value = "1" + Help = "Main switch to enable Secured FlashUpdate support in Project" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes + Master = Yes +End + +TOKEN + Name = "FlashUpdatePolicy" + Value = "7" + Help = "Flash update policy bitmap\0-Disabled, \bit0-Cold Reboot(recovery),bit1-Warm Reboot(capsule),bit2-Runtime,\bits 3..31-Reserved" + TokenType = Integer + TargetH = Yes +End + +TOKEN + Name = "BBUpdatePolicy" + Value = "7" + Help = "Select Boot Block (CRTM) Flash update policy." + TokenType = Integer + TargetH = Yes +End + +TOKEN + Name = "IGNORE_IMAGE_ROLLBACK" + Value = "0" + Help = "1-FW Capsule Validate logic will skip image Revision check" + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "IGNORE_RUNTIME_UPDATE_IMAGE_REVISION_CHECK" + Value = "0" + Help = "When set, FW Capsule Validate logic will skip image Revision check during Runtime updates" + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "IGNORE_RUNTIME_UPDATE_IMAGE_REVISION_CHECK" + Value = "1" + Help = "Force Ignore_runtime. if master Ignore_image_rollback is set" + TokenType = Boolean + TargetH = Yes + Token = "IGNORE_IMAGE_ROLLBACK" "=" "1" +End + +TOKEN + Name = "RUNTIME_SECURE_UPDATE_FLOW" + Value = "1" + Help = "Force security checks during runtime SMM flash update process" + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "FWCAPSULE_RECOVERY_SUPPORT" + Value = "0" + Help = "Enable APTIO FW Capsule recovery PPI" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "FWCAPSULE_RECOVERY_SUPPORT" + Value = "1" + Help = "Don't modify this value!" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes + Token = "Recovery_SUPPORT" "=" "1" + Token = "CAPSULE_SUPPORT" "=" "1" + Token = "WARM_BOOT_SUPPORT" "=" "1" + Token = "UEFI_2_0_CAPSULE" "=" "1" +End + +TOKEN + Name = "FWCAPSULE_RECOVERY_SUPPORT" + Value = "1" + Help = "Don't modify this value!" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes + Token = "Recovery_SUPPORT" "=" "1" + Token = "CAPSULE2_0_SUPPORT" "=" "1" + Token = "SUPPORT_UPDATE_CAPSULE_RESET" "=" "1" +End + +TOKEN + Name = "FWCAPSULE_2_0_SUPPORT" + Value = "1" + Help = "Older Aptio Capsule formats expected extra Cap Hdr in Mailbox" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes + Token = "CAPSULE2_0_SUPPORT" "=" "1" +End + +TOKEN + Name = "FLASH_LOCK_EVENT_NOTIFY" + Value = "1" + Help = "1:Issue Flash Ready to Lock Event" + TokenType = Boolean + TargetH = Yes +End + +PATH + Name = "SecFlashUpd_DIR" + Help = "Path to FlashUpdate Module in Project" +End + +MODULE + File = "SecFlashUpd.mak" +End + +ELINK + Name = "$(BUILD_DIR)\FwCapsuleRecoveryPPI.ffs" + Parent = "FV_BB" + Token = "FWCAPSULE_RECOVERY_SUPPORT" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "IsFlashUpdateRecovery," + Parent = "IsRecovery" + InvokeOrder = AfterParent +End + +ELINK + Name = "IsFlashUpdateCapsuleInit," + Parent = "PeiCoreInitialize" + Token = "FWCAPSULE_RECOVERY_SUPPORT" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "FwCapsuleInfo" + Parent = "AmiGetRecoveryFileInfo" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\SecFlashUpdDxe.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + diff --git a/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.c b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.c new file mode 100644 index 0000000..8ce7d3f --- /dev/null +++ b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.c @@ -0,0 +1,276 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/SecFlashUpdDxe.c 10 3/18/14 3:01p Alexp $ +// +// $Revision: 10 $ +// +// $Date: 3/18/14 3:01p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/SecFlashUpdDxe.c $ +// +// 10 3/18/14 3:01p Alexp +// set 2014 in file hdr & ftr +// +// 9 5/09/13 10:37a Alexp +// EIP#123379 : Disabling FLASH_LOCK_EVENT_NOTIFY causes build error +// +// 8 10/31/12 1:36p Alexp +// removed #ifdef for CAPSULE_SUPPORTbefore checks for capsule variable. +// +// 7 9/06/12 6:15p Alexp +// EIP#100418: Make SecureFlashPkg build independant from ReFlash-Support +// +// 6 1/06/12 10:37a Alexp +// Streamlined the code for Setup.AutoFlash variable update if FlashUpdate +// is pending +// +// 4 11/17/11 10:02a Alexp +// Use Core 4.6.5.2 provided name AMI_EVENT_FLASH_WRITE_LOCK as GUID +// define for Flash Lock event +// +// 3 11/10/11 4:38p Alexp +// 1. UpdateAutoFlash() updates the AutoFlash Variable installed by +// ReFlash driver in Recovery/Flash Update flows +// 2. Issue FlashReadyToLock Event notification based on the Flash Update +// policy. +// +// 2 7/20/11 7:16p Alexp +// remove dependency on Capsule module +// +// 1 7/01/11 4:39p Alexp +// +// +//********************************************************************** +#include <Token.h> +#include <AmiDxeLib.h> +#include <AmiHobs.h> +#include <FlashUpd.h> + +#include <Flash.h> +#if (defined ReFlash_SUPPORT) && (ReFlash_SUPPORT == 1) +#include "ReFlash.h" +#endif +#include "Capsule.h" + +// +// Global variables +// +extern EFI_BOOT_SERVICES *pBS; + +#if FLASH_LOCK_EVENT_NOTIFY == 1 + +VOID *gSbHobList = NULL; +static EFI_GUID gHobListGuid = HOB_LIST_GUID; + +// Core 4.6.5.2 sources GUID +#ifndef AMI_EVENT_FLASH_WRITE_LOCK +// {49D34AE7-1348-4551-8F71-467D8C0E4EF5} +#define AMI_EVENT_FLASH_WRITE_LOCK \ + { 0x49D34AE7, 0x9454, 0x4551, 0x8F, 0x71, 0x46, 0x7D, 0x8C, 0x0E, 0x4E, 0xF5 } +#endif + +#define BDS_CONNECT_DRIVERS_PROTOCOL_GUID \ + { 0x3aa83745, 0x9454, 0x4f7a, 0xa7, 0xc0, 0x90, 0xdb, 0xd0, 0x2f, 0xab, 0x8e } + +EFI_GUID gBiosLockEnableEventGuid = AMI_EVENT_FLASH_WRITE_LOCK; +EFI_GUID gBdsConnectDriversProtocolGuid = BDS_CONNECT_DRIVERS_PROTOCOL_GUID; + +EFI_EVENT mSecureModEvent; +VOID *mSecureModReg; +#endif //#if FLASH_LOCK_EVENT_NOTIFY == 1 + +//---------------------------------------------------------------------------- +// Function definitions +//---------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ReadyToLockCallback +// +// Description: ready to Lock Flash part +// Signal a event for ready to lock. +// +// Input: Event - The event that triggered this notification function +// ParentImageHandle - Pointer to the notification functions context +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +#if FLASH_LOCK_EVENT_NOTIFY == 1 +VOID +ReadyToLockCallback ( + EFI_EVENT Event, + VOID *ParentImageHandle + ) +{ + EFI_HANDLE Handle = NULL; + TRACE((-1,"\nSecure Fl Upd: FlashReadyToLock callback\n")); + +// Signal Event..... + pBS->InstallProtocolInterface ( + &Handle, &gBiosLockEnableEventGuid, EFI_NATIVE_INTERFACE,NULL + ); + pBS->UninstallProtocolInterface ( + Handle,&gBiosLockEnableEventGuid, NULL + ); + // + //Kill the Event + // + pBS->CloseEvent(Event); +} + +#endif //#if FLASH_LOCK_EVENT_NOTIFY == 1 + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: UpdateAutoFlash +// +// Description: This is the standard EFI driver entry point called for +// Recovery flash module initlaization +// Input: IN EFI_HANDLE ImageHandle - ImageHandle of the loaded driver +// IN EFI_SYSTEM_TABLE SystemTable - Pointer to the System Table +// +// Output: EFI_SUCCESS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS UpdateAutoFlash () +{ + EFI_STATUS Status; + UINT32 Attributes; + UINTN Size; +#if (defined ReFlash_SUPPORT) && (ReFlash_SUPPORT == 1) + AUTOFLASH AutoFlash; + static EFI_GUID guidReFlash = RECOVERY_FORM_SET_GUID; +#endif //#if (defined ReFlash_SUPPORT) && (ReFlash_SUPPORT == 1) + static EFI_GUID FlashUpdGuid = FLASH_UPDATE_GUID; + static EFI_GUID CapsuleBootModeGuid = EFI_CAPSULE_AMI_GUID; + AMI_FLASH_UPDATE_BLOCK FlashUpdDesc; + +// Prep the FlashOp variable + Attributes = 0; + Size = sizeof(AMI_FLASH_UPDATE_BLOCK); + Status = pRS->GetVariable( FLASH_UPDATE_VAR,&FlashUpdGuid,&Attributes,&Size, &FlashUpdDesc); + if(!EFI_ERROR(Status)) + { + // Erase Flash Var + pRS->SetVariable (FLASH_UPDATE_VAR,&FlashUpdGuid,Attributes,0,NULL); + // Clear pending Capsule Update Var + // only if FlashOp is pending. We don't want to interfere with other types of Capsule Upd + Size = 0; + if(pRS->GetVariable(CAPSULE_UPDATE_VAR,&CapsuleBootModeGuid, &Attributes, &Size, NULL)==EFI_BUFFER_TOO_SMALL) + pRS->SetVariable(CAPSULE_UPDATE_VAR,&CapsuleBootModeGuid, Attributes, 0, NULL); +#if (defined ReFlash_SUPPORT) && (ReFlash_SUPPORT == 1) + // Update ReFlash parameters + Size = sizeof(AUTOFLASH); + Status = pRS->GetVariable(L"Setup",&guidReFlash, &Attributes, &Size, &AutoFlash); + if(!EFI_ERROR(Status)) + { + + AutoFlash.UpdateNv = (FlashUpdDesc.ROMSection & (1<<FV_NV)) ? 1 : 0; + AutoFlash.UpdateBb = (FlashUpdDesc.ROMSection & (1<<FV_BB)) ? 1 : 0; + AutoFlash.UpdateMain=(FlashUpdDesc.ROMSection & (1<<FV_MAIN)) ? 1 : 0; + // EC block +#if (defined EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT) && (EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT == 1) + AutoFlash.UpdateEC =(FlashUpdDesc.ROMSection & (1<<ROM_EC)) ? 1 : 0; +#endif + pRS->SetVariable(L"Setup",&guidReFlash, Attributes, sizeof(AUTOFLASH), &AutoFlash); + } +#endif //#if (defined ReFlash_SUPPORT) && (ReFlash_SUPPORT == 1) + } + + return EFI_SUCCESS; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SecFlashUpdDxe_Init +// +// Description: Entry point of Flash Update Policy driver +// +// Input: EFI_HANDLE ImageHandle, +// EFI_SYSTEM_TABLE *SystemTable +// +// Output: EFI_STATUS +// +// Modified: +// +// Referrals: +// +// Notes: +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +SecFlashUpdDxe_Init ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_STATUS Status; + + InitAmiLib(ImageHandle, SystemTable); + + Status = UpdateAutoFlash(); +/////////////////////////////////////////////////////////////////////////////// +// +// Create Flash Lock event. +// +/////////////////////////////////////////////////////////////////////////////// +#if FLASH_LOCK_EVENT_NOTIFY == 1 + // Get Hob List + gSbHobList = GetEfiConfigurationTable(SystemTable, &gHobListGuid); + if (!gSbHobList) + return EFI_INVALID_PARAMETER; + +// Locking SPI before BDS Connect on normal boot + if (((EFI_HOB_HANDOFF_INFO_TABLE*)gSbHobList)->BootMode!=BOOT_IN_RECOVERY_MODE && + ((EFI_HOB_HANDOFF_INFO_TABLE*)gSbHobList)->BootMode!=BOOT_ON_FLASH_UPDATE + ) + Status = RegisterProtocolCallback ( &gBdsConnectDriversProtocolGuid, \ + ReadyToLockCallback, \ + NULL, \ + &mSecureModEvent, \ + &mSecureModReg ); +// Locking SPI after ReFlash(BDS) if in Recoovery/Flash Upd mode + else + Status = CreateReadyToBootEvent ( TPL_CALLBACK, + ReadyToLockCallback, + NULL, + &mSecureModEvent); + + ASSERT_EFI_ERROR (Status); +#endif + + return Status; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.dxs b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.dxs new file mode 100644 index 0000000..f55eee7 --- /dev/null +++ b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.dxs @@ -0,0 +1,58 @@ +//**************************************************************************** +//**************************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone (770)-246-8600 ** +//** ** +//**************************************************************************** +//**************************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/SecFlashUpdDxe.dxs 4 3/18/14 3:01p Alexp $ +// +// $Revision: 4 $ +// +// $Date: 3/18/14 3:01p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/SecFlashUpdDxe.dxs $ +// +// 4 3/18/14 3:01p Alexp +// set 2014 in file hdr & ftr +// +// 3 11/10/11 4:38p Alexp +// 1. UpdateAutoFlash() updates the AutoFlash Variable installed by +// ReFlash driver in Recovery/Flash Update flows +// 2. Issue FlashReadyToLock Event notification based on the Flash Update +// policy. +// +// 2 7/20/11 7:16p Alexp +// remove dependency on Capsule module +// +// 1 7/01/11 4:39p Alexp +// +//********************************************************************** +#include <Protocol/AmiDigitalSignature.h> + +DEPENDENCY_START + AMI_DIGITAL_SIGNATURE_PROTOCOL_GUID +DEPENDENCY_END + +//**************************************************************************** +//**************************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone (770)-246-8600 ** +//** ** +//**************************************************************************** +//**************************************************************************** diff --git a/Core/EM/SecurityPkg/SecFlashUpd/VerifyFwCapsule.c b/Core/EM/SecurityPkg/SecFlashUpd/VerifyFwCapsule.c new file mode 100644 index 0000000..9bc9693 --- /dev/null +++ b/Core/EM/SecurityPkg/SecFlashUpd/VerifyFwCapsule.c @@ -0,0 +1,974 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/VerifyFwCapsule.c 41 9/30/14 3:34p Alexp $ +// +// $Revision: 41 $ +// +// $Date: 9/30/14 3:34p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/VerifyFwCapsule.c $ +// +// 41 9/30/14 3:34p Alexp +// EIP185686:Build error with Recovery_SUPPORT = 0 +// +// 40 7/03/14 10:15a Alexp +// EIP176297: Fix bug in condition expresison inside For loops. +// +// [Files] VerifyFwCapsule.c +// +// 39 6/13/14 10:08a Alexp +// VerifyFwCapsule(): With dummy FwKey function returns no error but with +// set Key flag. +// The Recovery page must display the warning and user prompt. +// +// 38 4/24/14 3:17p Alexp +// Fix build error when REFLASH_INTERACTIVE is 0 +// +// 37 3/20/14 11:34a Alexp +// 1. EIP149817: don't override a default Recovery file name defined by +// RECOVERY_ROM +// 2. Add logic to ignore Capsule Verify error if dummy FwKey is detected. +// The feature is activated only when REFLASH_INTERACTIVE mode is ON +// 3. VerifyFwCapsule: FwCap RomImageOffset checked against max size +// (FWCAPSULE_IMAGE_SIZE-FLASH_SIZE) +// +// 36 12/12/13 10:11a Alexp +// +// 34 8/22/13 11:36a Alexp +// VerifyFwCertRsa2048Sha256() - Break a loop after RootCert Verify +// if key match is found. Old code would cycle through all root certs. +// +// 33 8/12/13 4:35p Alexp +// 1. Add check for an end of Certificate block +// 2. Chnage Ignore_rollback behavior. Won't skip Project Tag check +// +// 32 7/11/13 3:39p Alexp +// Removed check for FWCAPSULE_MAX_HDR_SIZE. Replaced it with fixed 0x8000 +// value +// +// 31 6/28/13 12:01p Alexp +// restore logic to return FwCapsule file name as expected Recovery file +// name +// +// 30 6/21/13 11:02a Alexp +// HashFwRomMapImage() - add check for 32bit address overflow +// +// 29 6/12/13 3:48p Alexp +// VerifyFwCertRsa2048Sha256() - parse multiple chained RootKey +// certificate structures in FwCert header +// +// 28 5/01/13 6:16p Alexp +// VerifyFwImage() - ignore verification if no FwKey file is detected in +// FV_BB +// +// 26 2/21/13 4:00p Alexp +// update IGNORE_IMAGE_ROLLBACK logic. +// +// 25 1/24/13 4:05p Alexp +// Made IGNORE_IMAGE_ROLLBACK depend on REFLASH_INTERACTIVE +// Disable revision rollback check if interactive flag is set +// +// 24 12/17/12 2:45p Alexp +// fix cppcheck style check finds +// +// 23 11/21/12 10:38a Alexp +// EIP#105015: Add support for Pkcs7# Certificates in Aptio Fw Capsule +// update packages +// +// 22 11/20/12 3:32p Alexp +// EIP[104046]: Findings from Security review on Aptio4 Image verification +// Includes the fix for item #10: hardening of RomMap parsing oin +// FwCapsule update +// +// 21 11/13/12 3:29p Alexp +// 1. Calculate offset to RomLayout table within FwCapsHdr instead of +// using hardwired location. Pkcs#7 cert may overlap fixed RomMap field +// 2. Remove dependency on FWSIG_SIGNHDR flag. Use Capsule flags instead. +// +// 20 10/18/12 10:43a Alexp +// VerifyFwImage: +// sanity check for buffer overruns. +// Applied for FwCapsules with Hdr on top of the Payload +// +// 19 9/18/12 6:59p Alexp +// Bug: Recovery update was broken for FwCapsule with embedded signature +// and FwSig_hdr token 0. +// Fix: FindCapHdrFFS() change Ffs Hdr size testing +// +// 18 7/26/12 3:26p Alexp +// replaced #if FWSIG_PADDING == 0 with #if FWSIG_SIGNHDR == 1. +// Flag in the FwCap Hdr to switch between PKCS1_5 and PSS padding is +// available only if #if FWSIG_SIGNHDR == 1 +// +// 17 5/18/12 4:35p Alexp +// 1. Add support for Embedded FwSignature file +// 2. EIP:89687 Replace Hash PPI calls with calls to Crypto lib functions. +// Allows to support RomMap tables in FwCaps Hdr with unlimited number of +// entries +// 3. VerifyFwVersion. a)Moved the call after Rom image signature is +// verified.; b) search FID struct only in signed FVs with PEI or DXE +// attributes +// +// 16 4/25/12 2:12p Alexp +// New logic extends search for matching Platform FW Key inside Signing +// and then RootKey +// certificates in the Cap Hdr +// +// 14 3/09/12 11:16a Alexp +// VerifyFwImage-> fixed logic to process RomMap entries. +// Number of signed elements in RomMap may not exceed max_num_elem +// constant. +// Overall number of elements in th RomMap may not exceed max_num_elem x 2 +// +// 13 2/29/12 4:11p Alexp +// Update format of Capsule signiing: +// 1. Entire Cap Hdr and FW_Cert Hdr are included in SigCert Signature +// calculation. Improves Cap image security +// 2. RootKey signs only SignKey buffer and not entire Sign Certificate. +// No nee dfor resigning of RootCert each time SignCert is being created +// +// 12 2/13/12 2:07p Alexp +// GetFidData: Use 1 byte alligned pointer in searching "Section Guid". +// Fixes the issue with RomMap entries that are not 4 byte alligned +// +// 11 12/29/11 3:59p Alexp +// VerifyProjectId(). +// Calculate size of ProjectId string based on SDL Token PROJECT_TAG +// +// 10 11/30/11 8:02p Alexp +// FW Revision searched inside FID structure. +// Simplified the search throughout FW block by 4byte aligned $FID +// signature only +// +// 9 11/08/11 3:08p Alexp +// match the name "FW"CAPSULE_FILE_NAME to one defined in SDL token +// +// 8 11/03/11 6:39p Alexp +// restored FwCapsuleInfo() +// +// 7 10/17/11 11:33a Alexp +// Replace old method to detect FlashUpd with single IsFlashUpdate() hook +// to be called from SbPei.c ->GetBootMode +// +// 6 10/11/11 12:24p Alexp +// VerifyFwRevision(): removed unused input parameter: **PeiServices +// +// 5 9/29/11 3:25p Alexp +// Bug fix. EIP#71244: No Rollback support +// +// 4 9/20/11 2:25p Alexp +// change BootMode from Recovery to BOOT_ON_FLASH_UPDATE if FlUpdate is +// pending. +// +// 3 8/05/11 3:19p Alexp +// add condition to skip Revision check. Ignore rollback protection +// +// 2 7/20/11 7:16p Alexp +// remove dependency on Capsule module +// +// 1 7/01/11 4:39p Alexp +// +//********************************************************************** +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: VerifyFwCapsule.c - PEI secured recovery services +// +// Description: File contains VerifyFwCapsule hook to evaluate Fw Capsule +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> + +//---------------------------------------------------------------------------- +// Includes +// Statements that include other files +#include "Efi.h" +#include "Pei.h" +#include "token.h" +#include <AmiPeiLib.h> +#include <Hob.h> +#include <RomLayout.h> +#include <Ffs.h> +#include <Ppi\ReadOnlyVariable.h> +#include <FlashUpd.h> +#include <PPI\CryptoPPI.h> +#include <PPI\FwVersion.h> +#include <Protocol\Hash.h> +#include "AmiCertificate.h" +#include <BaseCryptLib.h> + +//---------------------------------------------------------------------------- +// Function Externs + +//---------------------------------------------------------------------------- +// Local prototypes +EFI_STATUS +FwCapsuleInfo ( + IN EFI_PEI_SERVICES **PeiServices, + IN OUT VOID **pCapsuleName, + IN OUT UINTN *pCapsuleSize, + OUT BOOLEAN *ExtendedVerification +); + +//---------------------------------------------------------------------------- +typedef struct { + EFI_FFS_FILE_HEADER FfsHdr; + EFI_COMMON_SECTION_HEADER SecHdr; + EFI_GUID SectionGuid; + UINT8 FwCapHdr[0]; +} AMI_FFS_COMMON_SECTION_HEADER; + +typedef struct _FID_SECTION { + EFI_GUID Guid; + FW_VERSION FwVersion; +} FID_SECTION; + +//---------------------------------------------------------------------------- +// Local Variables +static EFI_GUID FwCapFfsGuid = AMI_FW_CAPSULE_FFS_GUID; +static EFI_GUID FwCapSectionGuid = AMI_FW_CAPSULE_SECTION_GUID; +static EFI_GUID FidSectionGuid = \ + { 0x2EBE0275, 0x6458, 0x4AF9, 0x91, 0xed, 0xD3, 0xF4, 0xED, 0xB1, 0x00, 0xAA }; + +const UINT8 *FidSignature = "$FID"; + +EFI_PEI_SERVICES **gPeiServices; +static AMI_CRYPT_DIGITAL_SIGNATURE_PPI *gpAmiSigPPI=NULL; + +//static EFI_GUID gAmiDigitalSignaturePPIGuid = AMI_DIGITAL_SIGNATURE_PPI_GUID; +static EFI_GUID gFWCapsuleGuid = APTIO_FW_CAPSULE_GUID; +static EFI_GUID gEfiCertRsa2048Guid = EFI_CERT_RSA2048_GUID; +static EFI_GUID gFWkeyGuid = PR_KEY_GUID; +static EFI_GUID gEfiHashAlgorithmSha256Guid = EFI_HASH_ALGORITHM_SHA256_GUID; +static EFI_GUID gEfiCertX509Guid = EFI_CERT_X509; +static EFI_GUID gEfiCertTypePkcs7Guid = EFI_CERT_TYPE_PKCS7_GUID; + +static EFI_GUID gPeiReadOnlyVariablePpiGuid = EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID; +static AMI_FLASH_UPDATE_BLOCK gFlashUpdDesc; + +//const char *RecoveryCapFileName = CONVERT_TO_STRING(FWCAPSULE_FILE_NAME); +const UINTN RecoveryCapImageSize = FWCAPSULE_IMAGE_SIZE; + +static UINT8 gHashDB[SHA256_DIGEST_SIZE]; +// Allocate Hash Descr table +static UINTN *gAddrList=NULL; +static UINTN *gLenList=NULL; +static UINTN gHashNumElem=0; + +//---------------------------------------------------------------------------- +// Function Definitions + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: VerifyProjectId +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN +VerifyProjectId ( + IN FW_VERSION *FwVersionData, + IN OUT UINT32 *FailedVTask +) +{ + char *strProjectId = CONVERT_TO_STRING(PROJECT_TAG); + UINTN Size = sizeof(CONVERT_TO_STRING(PROJECT_TAG)); +/* +CHAR8 BiosTag[9]; //BIOS Tag +EFI_GUID FirmwareGuid; //Firmware GUID +CHAR8 CoreMajorVersion[3]; +CHAR8 CoreMinorVersion[3]; +CHAR8 ProjectMajorVersion[3]; +CHAR8 ProjectMinorVersion[3]; +*/ + *FailedVTask = Ver; +// Project ID, Major, Minor rev +PEI_TRACE((-1, gPeiServices, "\nOrgBiosTag=%s,NewBiosTag=%s\nPrjMajVer=%02d, NewMajVer=%s\nPrjMinorVer=%02d, NewMinorVer=%s\n", +FwVersionData->BiosTag, strProjectId, +PROJECT_MAJOR_VERSION, FwVersionData->ProjectMajorVersion, +PROJECT_MINOR_VERSION, FwVersionData->ProjectMinorVersion +)); + if (Size==0 || MemCmp (FwVersionData->BiosTag, strProjectId, Size-1)) return FALSE; +#if IGNORE_IMAGE_ROLLBACK == 0 +// Physically present user may override roll back protection from Setup screen + if(Atoi(FwVersionData->ProjectMajorVersion) < PROJECT_MAJOR_VERSION || + Atoi(FwVersionData->ProjectMinorVersion) < PROJECT_MINOR_VERSION) +#if (defined(REFLASH_INTERACTIVE) && REFLASH_INTERACTIVE==1) + return TRUE; +#else + return FALSE; +#endif +#endif + + *FailedVTask = 0; + + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetFidData +// +// Description: Function to read FFS FID data structure from the given data buffer +// +// Input: OUT FW_VERSION **Fid - pointer to output buffer +// IN VOID *pFV - pointer to data buffer to read from +// +// Output: EFI_SUCCESS if FID data is retrieved +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN GetFidData( + IN VOID *pFV, + IN UINT32 Size, + OUT FW_VERSION **FwVersionData +) +{ +// UINT32 Signature; + UINT8* SearchPointer; + FID_SECTION *Section; + +// Simplified search by $FID signature only. +// SearchPointer = (UINT32 *)((UINT8 *)pFV + sizeof(EFI_GUID)); +// Signature = FidSectionGuid.Data1; + SearchPointer = (UINT8 *)pFV; + + do { +// if(*SearchPointer == Signature) { + Section = (FID_SECTION *)SearchPointer; + if(!guidcmp(&FidSectionGuid, &(Section->Guid)) && + (*((UINT32*)(&Section->FwVersion.FirmwareID[0])) == *(UINT32*)FidSignature)){ + *FwVersionData = &Section->FwVersion; + return TRUE; + } +// } + } while( SearchPointer++ < (UINT8*)((UINT32)pFV+Size)); + + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: VerifyFwRevision +// +// Description: Verify Fw revision compatibility +// NewVer > OldVer, newProjectTAGid = oldProjectTAGid +// +// Input: +// IN OUT UINT8 *pCapsule +// Output: +// EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +VerifyFwRevision ( + IN APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr, + IN UINT8 *RomData, + IN OUT UINT32 *FailedVTask +) +{ + ROM_AREA *Area; + EFI_PHYSICAL_ADDRESS FvAddress; + FW_VERSION *FwVersionData; + + *FailedVTask = Ver; + + Area = (ROM_AREA *)(UINTN)((UINT32)FWCapsuleHdr+FWCapsuleHdr->RomLayoutOffset); + for (Area; Area->Size != 0; Area++) { + if (!(Area->Attributes & ROM_AREA_FV_SIGNED)) + continue; + // $FID can be in FV with either PEI or DXE + if (!(Area->Attributes & (ROM_AREA_FV_PEI+ROM_AREA_FV_DXE))) + continue; + + FvAddress = (EFI_PHYSICAL_ADDRESS)RomData + (Area->Offset); + if (GetFidData((UINT8*)FvAddress, Area->Size, &FwVersionData)){ + if(VerifyProjectId(FwVersionData, FailedVTask)) + return EFI_SUCCESS; + break; + } + } +// At least one FW block must be signed OR no $FID structure found in the new FW image + return EFI_SECURITY_VIOLATION; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: FindCapHdrFFS +// +// Description: Function to read FW Cap Sig data from Ffs +// +// Input: OUT UINT8 **pFwCapHdr - pointer to output buffer +// IN VOID *pCapsule - pointer to data buffer to read from +// +// Output: EFI_SUCCESS if Capsule Hdr with Signature is retrieved +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS FindCapHdrFFS( + IN VOID *pCapsule, + OUT UINT8 **pFfsData +) +{ + UINT32 Signature; + UINT32 *SearchPointer; + AMI_FFS_COMMON_SECTION_HEADER *FileSection; + APTIO_FW_CAPSULE_HEADER *pFwCapHdr; + + SearchPointer = (UINT32 *)((UINT8 *)pCapsule - sizeof(AMI_FFS_COMMON_SECTION_HEADER) + FLASH_SIZE); + Signature = FwCapFfsGuid.Data1; + + do { + if(*SearchPointer == Signature) { + FileSection = (AMI_FFS_COMMON_SECTION_HEADER *)SearchPointer; + if(!guidcmp(&FwCapFfsGuid, &(FileSection->FfsHdr.Name)) && + !guidcmp(&FwCapSectionGuid, &(FileSection->SectionGuid)) + ){ + pFwCapHdr = (APTIO_FW_CAPSULE_HEADER*)(FileSection->FwCapHdr); + // just a sanity check - Cap Size must match the Section size + if(((*(UINT32 *)FileSection->FfsHdr.Size) & 0xffffff) >= + pFwCapHdr->CapHdr.HeaderSize + sizeof(AMI_FFS_COMMON_SECTION_HEADER) && + !guidcmp((EFI_GUID*)&pFwCapHdr->CapHdr.CapsuleGuid, &gFWCapsuleGuid) + ){ + *pFfsData = (UINT8*)pFwCapHdr; + return EFI_SUCCESS; + } + } + } + } while(SearchPointer-- != pCapsule); + + return EFI_NOT_FOUND; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: HashFwRomMapImage +// +// Description: The Rom image hash is calculated based on info from the Rom Area map +// +// Input: +// Payload - pointer to a FW Image +// FwCapsuleHdr - pointer to a FW Capsule Hdr +// RomSize - Size of Rom Image +// +// Output: EFI_SUCCESS - capsule processed successfully +// EFI_DEVICE_ERROR - capsule processing failed +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS HashFwRomMapImage ( + IN APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr, + IN UINT8 *Payload, + IN UINTN RomSize, + OUT UINT8 *gHashDB +){ + EFI_STATUS Status = EFI_SUCCESS; + ROM_AREA *RomAreaTbl; + + UINTN i, RomMap_size, max_num_elem, num_elem; + + RomAreaTbl = (ROM_AREA *)(UINTN)((UINT32)FWCapsuleHdr+FWCapsuleHdr->RomLayoutOffset); + + RomMap_size = FWCapsuleHdr->RomImageOffset-FWCapsuleHdr->RomLayoutOffset; + max_num_elem = RomMap_size/sizeof(ROM_AREA); + +// assume max size of RomMap array = RomMap_size/sizeof(ROM_AREA); +// or better yet ...calculate exact number + num_elem = 0; + for (i=0; i < max_num_elem && RomAreaTbl[i].Size != 0; i++ ) + { + if (RomAreaTbl[i].Attributes & ROM_AREA_FV_SIGNED) + num_elem++; + } + max_num_elem=i; + num_elem+=2; // add 2 extra entries + + if(!gAddrList || !gHashNumElem || gHashNumElem<num_elem) { + gHashNumElem = num_elem; + i = num_elem*sizeof(UINTN); + Status = (*gPeiServices)->AllocatePool(gPeiServices, i*2, &gAddrList); + ASSERT_PEI_ERROR (gPeiServices, Status); + if(EFI_ERROR(Status)) return Status; + gLenList = (UINTN*)((UINT8*)gAddrList + i); + } + num_elem = 0; + for(i=0; i < max_num_elem && num_elem < gHashNumElem && RomAreaTbl[i].Size != 0; i++) + { + if (!(RomAreaTbl[i].Attributes & ROM_AREA_FV_SIGNED)) + continue; + // sanity check for buffer overruns + if(RomAreaTbl[i].Offset > RomSize || + (UINT64)RomAreaTbl[i].Offset + RomAreaTbl[i].Size > RomSize) + return EFI_SECURITY_VIOLATION; + // RomArea only holds offsets within a payload + gAddrList[num_elem] = (UINTN)((UINTN)Payload + RomAreaTbl[i].Offset); + gLenList[num_elem] = RomAreaTbl[i].Size; + + num_elem++; + + } + if(num_elem >= gHashNumElem) return EFI_SECURITY_VIOLATION; +// +// Hash of Capsule Hdr + FW Certificate Hdr +// + if(FWCapsuleHdr->CapHdr.Flags & CAPSULE_FLAGS_CAPHDR_IN_SIGNCERT) { + gAddrList[num_elem] = (UINTN) FWCapsuleHdr; + gLenList[num_elem] = (UINTN)&FWCapsuleHdr->FWCert.SignCert.CertData - (UINTN)FWCapsuleHdr; + num_elem++; + if(num_elem >= gHashNumElem) return EFI_SECURITY_VIOLATION; + } +// +// Hash of the ROM_MAP table +// + gAddrList[num_elem] = (UINTN)RomAreaTbl; + gLenList[num_elem] = (i+1)*sizeof(ROM_AREA); + num_elem++; + + Status = gpAmiSigPPI->Hash(gpAmiSigPPI, &gEfiHashAlgorithmSha256Guid, + num_elem, (const UINT8**)gAddrList, (const UINTN*)gLenList, gHashDB ); + +// PEI_TRACE((-1, gPeiServices, "Hash the FW Image %r\n", Status)); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: VerifyFwCertPkcs7 +// +// Description: This code verifies FW Capsule is genuine, +// and performs following checks on the image: +// 1. Signing certificate is signed with trusted Root Platform key +// 2. Integrity check. Image Signature verification +// +// Input: +// Payload - pointer to a FW Image +// FwCapsuleHdr - pointer to a FW Capsule Hdr +// RomSize - Size of Rom Image +// +// Output: EFI_SUCCESS - capsule processed successfully +// EFI_DEVICE_ERROR - capsule processing failed +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS VerifyFwCertPkcs7 ( + IN APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr, + IN UINT8 *Payload, + IN UINTN RomSize, + IN PEI_CRYPT_HANDLE *PubKeyHndl, + IN OUT UINT32 *FailedVTask +){ + EFI_STATUS Status; + UINT8 *Pkcs7Cert, *pDigest; + UINTN Pkcs7Cert_len, DigestLen; + +// +// 1. Validate Root Key +// + *FailedVTask = Key; + + if( PubKeyHndl->Blob==NULL) + return EFI_SECURITY_VIOLATION; + + if(guidcmp(&PubKeyHndl->AlgGuid, &gEfiCertX509Guid)) + return EFI_UNSUPPORTED; + +// 2. Verify Signing Cert Signature +// +// 2.1 The Rom image hash is calculated based on info from the Rom Area map +// + *FailedVTask = Sig; + + Status = HashFwRomMapImage(FWCapsuleHdr, Payload, RomSize, gHashDB); + if (EFI_ERROR(Status)) return Status; + +// 2.2 Verify Fw Certificate + pDigest = &gHashDB[0]; + DigestLen = SHA256_DIGEST_SIZE; + Pkcs7Cert = (UINT8*)&FWCapsuleHdr->FWCert.SignCert.CertData; + Pkcs7Cert_len = FWCapsuleHdr->FWCert.SignCert.Hdr.Hdr.dwLength-sizeof(WIN_CERTIFICATE_UEFI_GUID_1); + + return gpAmiSigPPI->VerifyPkcs7Sig( gpAmiSigPPI, + Pkcs7Cert, Pkcs7Cert_len, // Pkcs7Cert + PubKeyHndl->Blob, PubKeyHndl->BlobSize, // TrustCert + &pDigest, &DigestLen // In/OutData + ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: VerifyFwCertRsa2048Sha256 +// +// Description: This code verifies FW Capsule is genuine, +// and performs following checks on the image: +// 1. Signing certificate is signed with trusted Root Platform key +// 2. Integrity check. Image Signature verification +// +// Input: +// Payload - pointer to a FW Image +// FwCapsuleHdr - pointer to a FW Capsule Hdr +// RomSize - Size of Rom Image +// +// Output: EFI_SUCCESS - capsule processed successfully +// EFI_DEVICE_ERROR - capsule processing failed +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS VerifyFwCertRsa2048Sha256 ( + IN APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr, + IN UINT8 *Payload, + IN UINTN RomSize, + IN OUT UINT32 *FailedVTask +){ + EFI_STATUS Status; + PEI_CRYPT_HANDLE HashHndl; + PEI_CRYPT_HANDLE PubKeyHndl; + UINT8 *pSig; + UINT32 Flags=0; + UINT8 *Addr; + UINTN Size; + EFI_CERT_BLOCK_RSA_2048_SHA256* pRootCert; + +// Versions 010 and later support extended flags +// if(FWCapsuleHdr->CapHdr.Flags & CAPSULE_FLAGS_CAPHDR_IN_SIGNCERT) + if(FWCapsuleHdr->CapHdr.HeaderSize == FWCapsuleHdr->RomImageOffset) + { + if(FWCapsuleHdr->CapHdr.Flags & CAPSULE_FLAGS_RSA_PSS_PADDING_SCHEME) + Flags = EFI_CRYPT_RSASSA_PSS; + else + Flags = EFI_CRYPT_RSASSA_PKCS1V15; + } + else + Flags = EFI_CRYPT_RSASSA_PSS; + + HashHndl.AlgGuid = gEfiHashAlgorithmSha256Guid; + HashHndl.BlobSize = SHA256_DIGEST_SIZE; + HashHndl.Blob = (UINT8*)&gHashDB; +// +// 1. Compare Capsule's Sign Cert key with Platform Root Key +// + *FailedVTask = Key; + + PubKeyHndl.BlobSize = DEFAULT_RSA_KEY_MODULUS_LEN; + PubKeyHndl.AlgGuid = gEfiCertRsa2048Guid; + PubKeyHndl.Blob = (UINT8*)FWCapsuleHdr->FWCert.SignCert.CertData.PublicKey; + Status = gpAmiSigPPI->VerifyKey(gpAmiSigPPI, &gFWkeyGuid, &PubKeyHndl); + PEI_TRACE((-1, gPeiServices, "Compare Platform and SignCert Keys : %r\n", Status)); +// Skip the RootCert key checking if SignCert Key and PR Key are matching + if(EFI_ERROR(Status)) { +// +// 1.1 Compare Platform Root with Capsule's Key from a Root Key store +// + for (pRootCert = &FWCapsuleHdr->FWCert.RootCert; + (UINT8*)pRootCert < + (UINT8*)&FWCapsuleHdr->FWCert+FWCapsuleHdr->FWCert.SignCert.Hdr.Hdr.dwLength && + pRootCert->PublicKey[0]!=0; + pRootCert++) + { + PubKeyHndl.Blob = (UINT8*)pRootCert->PublicKey; + Status = gpAmiSigPPI->VerifyKey(gpAmiSigPPI, &gFWkeyGuid, &PubKeyHndl); + PEI_TRACE((-1, gPeiServices, "Compare Platform and RootCert Keys : %r\n", Status)); + if (EFI_ERROR(Status)) continue; + + // 2. Verify RootCert.Signature + // + // 2.1 Compute FWCert.SignCert.PublicKey Hash + // + if(FWCapsuleHdr->CapHdr.Flags & CAPSULE_FLAGS_SIGNKEY_IN_ROOTCERT) + { + Addr = (UINT8*)FWCapsuleHdr->FWCert.SignCert.CertData.PublicKey; + Size = DEFAULT_RSA_KEY_MODULUS_LEN; + } else + // 2.2 Compute FWCert.SignCert Hash + { + Addr = (UINT8*)&FWCapsuleHdr->FWCert.SignCert; + Size = sizeof(AMI_CERTIFICATE_RSA2048_SHA256); + } + + Status = gpAmiSigPPI->Hash(gpAmiSigPPI,&gEfiHashAlgorithmSha256Guid, 1,&Addr,(const UINTN*)&Size, gHashDB); + if (EFI_ERROR(Status)) break; + + pSig = (void*)pRootCert->Signature; + Status = gpAmiSigPPI->VerifySig(gpAmiSigPPI, &PubKeyHndl, &HashHndl, pSig, DEFAULT_RSA_SIG_LEN, Flags ); + PEI_TRACE((-1, gPeiServices, "Verify Root Cert : %r\n", Status)); + break; + } + } + if (EFI_ERROR(Status)) return EFI_SECURITY_VIOLATION; +// +// 3. Verify Signing Cert +// + *FailedVTask = Sig; +// +// 3.1 The Rom image hash is calculated based on info from the Rom Area map +// + Status = HashFwRomMapImage(FWCapsuleHdr, Payload, RomSize, gHashDB); + if (EFI_ERROR(Status)) return Status; + + pSig = (void*)FWCapsuleHdr->FWCert.SignCert.CertData.Signature; + PubKeyHndl.Blob = (UINT8*)FWCapsuleHdr->FWCert.SignCert.CertData.PublicKey; + + return gpAmiSigPPI->VerifySig(gpAmiSigPPI, &PubKeyHndl, &HashHndl, pSig, DEFAULT_RSA_SIG_LEN, Flags); +} + +//********************************************************************** +//<AMI_PHDR_START> +// +// Procedure: VerifyFwImage +// +// Description: Function verifies various sections of the FW Capsule +// +// 0. Locate protocol AMI_CRYPT_DIGITAL_SIGNATURE_PPI +// 1. Check if FV GUID matches Aptio FW Capsule. +// - Yes - +// update Payload ptr to beginning of BIOS ROM data +// continue with Image Varify +// - Not found at offs 0 - assume Cap Hdr is in FFS +// locate FFS by Hole GUID, Sec GUID +// update FWCapsuleHdr ptr, +// continue with Image Varify +// 2. Validate Root Certificate +// -Compare PubKey in Root Certificate Hdr with local FW Platform Key +// -Hash SignCert.PubKey +// -VerifySig for RootCert.Signature and compare with SignCert.Key hash +// 3. Validate Sign Certificate +// -Hash the ROM image inside the FW Capsule +// -VerifySig for SignCert.Signature and compare with ROM hash +// 4. Update pCapsuleSize = FwPayload and set pCapsule to point to FW Payload +// +// Input: +// PeiServices Pointer to PeiServices instance. +// pCapsule Points to the start of the Aptio FW Capsule. +// pCapsuleSize The size of buffer, in bytes. +// FailedVTask Specifies additional flags to further customize the signing/verifying behavior. +// +// Output: +// pCapsule ptr is set to start of Capsule's Payload - ROM image +// pCapsuleSize return ROM image size +// EFI_SUCCESS The signature is successfully verified. +// EFI_SECURITY_VIOLATION The signature does not match the given message. +// EFI_ACCESS_DENIED The key could not be used in signature operation. +// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria +// of the underlying signature algorithm. +//<AMI_PHDR_END> +//********************************************************************** +EFI_STATUS +VerifyFwImage( + IN EFI_PEI_SERVICES **PeiServices, + IN OUT VOID **pCapsule, + IN OUT UINT32 *pCapsuleSize, + IN OUT UINT32 *FailedVTask +){ + EFI_STATUS Status; + APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr; + UINT8 *Payload; + UINTN RomSize; + PEI_CRYPT_HANDLE PubKeyHndl; + UINT8 Byte; + UINTN Size; + + gPeiServices = PeiServices; + + PEI_TRACE((-1, PeiServices, "\nValidate FW Capsule ...\n")); + +// Predefined bit mask of checks to perform on Aptio FW Capsule + *FailedVTask = Cap; + + Status = (*PeiServices)->LocatePpi(PeiServices, &gAmiDigitalSignaturePPIGuid, 0, NULL, &gpAmiSigPPI); + if(EFI_ERROR(Status)) return Status; + + // ignore Verification if FwKey is not detected in the FW. + // Works with unsigned Aptio.ROM image or Signed ROM with embedded sig. + PubKeyHndl.BlobSize = 0; + PubKeyHndl.Blob = NULL; + Status = gpAmiSigPPI->GetKey(gpAmiSigPPI, &gFWkeyGuid, &PubKeyHndl); + PEI_TRACE((-1, PeiServices, "Get Root Cert Key (%r),0x%8X (%d bytes)\n", Status, (*(UINT32*)PubKeyHndl.Blob), PubKeyHndl.BlobSize)); + if(EFI_ERROR(Status)) + { +#if (defined(REFLASH_INTERACTIVE) && REFLASH_INTERACTIVE==1) + if(Status == EFI_NOT_FOUND) + return EFI_SUCCESS; +#endif + *FailedVTask = Key; + return Status; + } + + FWCapsuleHdr = *pCapsule; + Payload = (UINT8*)*pCapsule; + RomSize = (UINTN)*pCapsuleSize; + +// verify Capsule Mailbox points to FW_CAPSULE hdr + if(guidcmp((EFI_GUID*)&FWCapsuleHdr->CapHdr.CapsuleGuid, &gFWCapsuleGuid)) + { +// looking FwCap hdr inside BIOS.ROM + if(EFI_ERROR(FindCapHdrFFS(Payload, (UINT8**)&FWCapsuleHdr))) + return EFI_SECURITY_VIOLATION; + } + PEI_TRACE((-1, PeiServices, "FW Capsule Hdr Detected...\n")); + +// Aptio FW Capsule only supporting WIN_CERT_TYPE_EFI_GUID + if(FWCapsuleHdr->FWCert.SignCert.Hdr.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) + return EFI_SECURITY_VIOLATION; + +// Applied for FwCapsules with Hdr on top of the Payload + if( (UINT8*)*pCapsule ==(UINT8*) FWCapsuleHdr) { + if(FWCapsuleHdr->CapHdr.CapsuleImageSize > *pCapsuleSize) + return EFI_SECURITY_VIOLATION; + // Update pFwCapsule to point to beginning of Bios ROM + Payload = (UINT8*)((UINT32)FWCapsuleHdr + FWCapsuleHdr->RomImageOffset); + RomSize = (FWCapsuleHdr->CapHdr.CapsuleImageSize - FWCapsuleHdr->RomImageOffset); + } + +// Capsule Hdr sanity checks + if((RomSize > *pCapsuleSize) || + (FWCapsuleHdr->RomImageOffset > (FWCAPSULE_IMAGE_SIZE-FLASH_SIZE)) || // 16k is a MAX possible FwCap Hdr size + (FWCapsuleHdr->CapHdr.HeaderSize > FWCapsuleHdr->RomImageOffset) || + (FWCapsuleHdr->RomLayoutOffset > FWCapsuleHdr->RomImageOffset) || + (FWCapsuleHdr->FWCert.SignCert.Hdr.Hdr.dwLength + offsetof(APTIO_FW_CAPSULE_HEADER, FWCert) > + FWCapsuleHdr->RomLayoutOffset ) + ) + return EFI_SECURITY_VIOLATION; + + // If dummy FWkey - skip integrity check - only test the Capsule's structure + Byte = PubKeyHndl.Blob[0]; + for(Size = 1; Size < PubKeyHndl.BlobSize && (Byte == PubKeyHndl.Blob[Size]); Size++); + if(Size == PubKeyHndl.BlobSize) { + *FailedVTask = Key; + PEI_TRACE((-1, PeiServices, "Dummy FW Key detected. Skip image verification...\n")); + } else + { +// Begin Authentication + if(!guidcmp((EFI_GUID*)&FWCapsuleHdr->FWCert.SignCert.Hdr.CertType, &gEfiCertTypePkcs7Guid)) + Status = VerifyFwCertPkcs7(FWCapsuleHdr, Payload, RomSize, &PubKeyHndl, FailedVTask); + else + Status = VerifyFwCertRsa2048Sha256(FWCapsuleHdr, Payload, RomSize, FailedVTask); + + PEI_TRACE((-1, gPeiServices, "Verify Sign Certificate Sig : %r\n", Status)); + if (EFI_ERROR(Status)) return Status; + + *FailedVTask = 0; + +// Local PEI $FID is linked with CspLib. extern FW_VERSION FwVersionData; +// Find $FID in new Fw FVs. Any instance found should do for us. Use RomMap from Capsule's Hdr +// compare local BB and Main $Fid BIOS Major/Minor revs with New one. + Status = VerifyFwRevision(FWCapsuleHdr, Payload, FailedVTask); + PEI_TRACE((-1, PeiServices, "FW Revision test %r (FailedVTask = %x)\n", Status, *FailedVTask)); + } + + *pCapsule = (UINT32*)Payload; + *pCapsuleSize = RomSize; + + return Status; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// +// Procedure: FwCapsuleInfo +// +// Description: Updates the Recovery File name and size if defaults are +// overriden in FlashUpd EFI Var. +// Called from Recovery LoadRecoveryCapsule. +// +// pCapsuleName Pointer to the variable containing a Recovery File name +// pCapsuleSize Pointer to the size of recovery image capsule, in bytes. +// ExtendedVerification Indicates to Recovery module whether Fw Capsule +// Recovery path will perform image size check. +// +// Output: +// EFI_SUCCESS +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +FwCapsuleInfo ( + IN EFI_PEI_SERVICES **PeiServices, + IN OUT VOID **pCapsuleName, + IN OUT UINTN *pCapsuleSize, + OUT BOOLEAN *ExtendedVerification +){ + EFI_STATUS Status; + UINTN Size; + EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariable = NULL; + EFI_GUID FlashUpdGuid = FLASH_UPDATE_GUID; + + if(!pCapsuleName && !pCapsuleSize && !ExtendedVerification ) + return EFI_UNSUPPORTED; + + if(ExtendedVerification != NULL) + *ExtendedVerification = TRUE; + + if(pCapsuleSize != NULL) + { + *pCapsuleSize = RecoveryCapImageSize; + + if(pCapsuleName != NULL) + { +// EIP149817: don't override a default recovery file name +// *pCapsuleName = (VOID*)RecoveryCapFileName; + + // Detect if we are in Flash Update mode and set some recovery global variables + // Read "FlashOp" Variable to update global RecoveryFileName, Size + Status = (*PeiServices)->LocatePpi( PeiServices, + &gPeiReadOnlyVariablePpiGuid, + 0, + NULL, + &ReadOnlyVariable ); + // ASSERT_PEI_ERROR (PeiServices, Status); + if(EFI_ERROR(Status)) + return Status; + + Size = sizeof(AMI_FLASH_UPDATE_BLOCK); + Status = ReadOnlyVariable->GetVariable( PeiServices, + FLASH_UPDATE_VAR, + &FlashUpdGuid, + NULL, + &Size, + &gFlashUpdDesc ); + if(!EFI_ERROR(Status)) + { + if(gFlashUpdDesc.FlashOpType == FlRecovery && gFlashUpdDesc.FwImage.AmiRomFileName[0] != 0) + *pCapsuleName = (VOID*)gFlashUpdDesc.FwImage.AmiRomFileName; + + *pCapsuleSize = gFlashUpdDesc.ImageSize; + Status = (*PeiServices)->SetBootMode(PeiServices, BOOT_ON_FLASH_UPDATE); + } + PEI_TRACE((-1, PeiServices, "FW Capsule update %r\nImage Name %s, Size %x\n", Status, *pCapsuleName, *pCapsuleSize)); + } + } + return EFI_SUCCESS; +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* |