summaryrefslogtreecommitdiff
path: root/Core/EM/SecurityPkg/SecFlashUpd
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/SecurityPkg/SecFlashUpd')
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.c325
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.dxs89
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/IsSecRecovery.c390
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.cif17
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.mak176
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.sdl152
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.c276
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.dxs58
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/VerifyFwCapsule.c974
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 **
+//** **
+//*************************************************************************
+//*************************************************************************