/**
* SecureBootDXE.c - UEFI Secure Boot DXE Driver
*
* Module: SecureBootDXE.efi
* Image Size: 0x1ce0
* SHA256: ebec12a0eba5a2ff026b85a0f7dddf2a03eb167c35bc015f873d9b2962c715f0
* Source: Lenovo HR650X BIOS
*
* This DXE driver manages Secure Boot policy on Lenovo HR650X platforms.
* It handles initialization of UEFI standard table pointers, HOB list
* discovery, reading the proprietary "SecureBootSetup" variable to determine
* Secure Boot enable/disable state, provisioning default Secure Boot
* databases (db, dbx, dbt, dbr, KEK, PK) from firmware volumes into UEFI
* Runtime Variables, and setting up the SetupMode variable based on
* provisioning state.
*
* Architecture: x86-64, UEFI DXE_DRIVER
* Build: VS2015, X64, DEBUG
* Source: e:\hs\AmiModulePkg\GenericSio\SioDxeInit.c (build path)
* e:\hs\Build\HR6N0XMLK\DEBUG_VS2015\X64\...\AutoGen.c
*/
#include <Uefi.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/DxeServicesLib.h>
#include <Library/UefiMemoryAllocationLib.h>
#include <Library/DxeHobLib.h>
#include <Guid/GlobalVariable.h>
#include <Protocol/FirmwareVolume2.h>
#include <Protocol/Rng.h>
#include "SecureBootDXE.h"
/******************** Module-Level Static Data ********************/
STATIC EFI_SYSTEM_TABLE *gST; /* 0x1A78 */
STATIC EFI_BOOT_SERVICES *gBS; /* 0x1A80 */
STATIC EFI_HANDLE gImageHandle; /* 0x1A88 */
STATIC EFI_RUNTIME_SERVICES *gRT; /* 0x1A90 */
STATIC EFI_RUNTIME_SERVICES *mRuntimeServices; /* 0x1AA8 */
STATIC EFI_BOOT_SERVICES *mBootServices; /* 0x1AB0 */
STATIC EFI_SYSTEM_TABLE *mSystemTable; /* 0x1AB8 */
STATIC UINT8 mDebugLevel; /* 0x1AC0 */
STATIC VOID *gHobList; /* 0x1AA0 */
STATIC EFI_STATUS mDebugPrintProtocol; /* 0x1A98 */
/******************** GUID Constants ********************/
/* 5B1B31A1-9562-11D2-8E3F-00A0C969723B */
STATIC CONST EFI_GUID mDxeServicesProtocolGuid =
{ 0x5B1B31A1, 0x9562, 0x11D2, { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } };
/* 8BE4DF61-93CA-11D2-AA0D-00E098032B8C (gEfiGlobalVariableGuid) */
STATIC CONST EFI_GUID mGlobalVariableGuid =
{ 0x8BE4DF61, 0x93CA, 0x11D2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C } };
/* 7B59104A-C00D-4158-87FF-F04D6396A915 (proprietary SecureBootSetup) */
STATIC CONST EFI_GUID mSecureBootSetupVarGuid =
{ 0x7B59104A, 0xC00D, 0x4158, { 0x87, 0xFF, 0xF0, 0x4D, 0x63, 0x96, 0xA9, 0x15 } };
/* 220E73B6-6BDB-4413-8405-B974B108619A (gEfiFirmwareVolume2ProtocolGuid) */
STATIC CONST EFI_GUID mFirmwareVolume2ProtocolGuid =
{ 0x220E73B6, 0x6BDB, 0x4413, { 0x84, 0x05, 0xB9, 0x74, 0xB1, 0x08, 0x61, 0x9A } };
/* D719B2CB-3D3A-4596-A3BC-DAD00E67656F (proprietary storage GUID) */
STATIC CONST EFI_GUID mVarStorageGuid =
{ 0xD719B2CB, 0x3D3A, 0x4596, { 0xA3, 0xBC, 0xDA, 0xD0, 0x0E, 0x67, 0x65, 0x6F } };
/* 7739F24C-93D7-11D4-9A3A-0090273FC14D (gEfiHobListGuid) */
STATIC CONST EFI_GUID mHobListGuid =
{ 0x7739F24C, 0x93D7, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } };
/* RNG algorithms */
STATIC CONST EFI_GUID mRngAlgoHash256 =
{ 0x4AAFD29D, 0x68DF, 0x49EE, { 0x8A, 0xA9, 0x34, 0x7D, 0x37, 0x56, 0x65, 0xA7 } };
STATIC CONST EFI_GUID mRngAlgoHmac256 =
{ 0x7D34A98A, 0x5637, 0xA765, { 0xBF, 0xFB, 0x46, 0xC2, 0x5C, 0xF7, 0xF7, 0x43 } };
/* Certificate type GUIDs for Secure Boot databases */
STATIC CONST EFI_GUID mCertSha256Guid =
{ 0x9D7A05E9, 0xF740, 0x44C3, { 0x85, 0x8B, 0x75, 0x58, 0x6A, 0x8F, 0x9C, 0x8E } };
STATIC CONST EFI_GUID mCertX509Guid =
{ 0xC246FBBF, 0xF75C, 0x43F7, { 0x88, 0xA6, 0xB5, 0xFD, 0x0C, 0xF1, 0xDB, 0x7F } };
STATIC CONST EFI_GUID mCertRsa2048Sha256Guid =
{ 0x5F7CE43D, 0x565A, 0x4420, { 0xB4, 0xF8, 0x22, 0xEC, 0xA7, 0x24, 0x57, 0x55 } };
STATIC CONST EFI_GUID mCertRsa2048Sha1Guid =
{ 0xFBF95065, 0x427F, 0x47B3, { 0x80, 0x77, 0xD1, 0x3C, 0x60, 0x71, 0x09, 0x98 } };
STATIC CONST EFI_GUID mCertSha384Guid =
{ 0xCC0F8A3F, 0x3DEA, 0x4376, { 0x96, 0x79, 0x54, 0x26, 0xBA, 0x0A, 0x90, 0x7E } };
STATIC CONST EFI_GUID mCertSha224Guid =
{ 0x9FE7DE69, 0x0AEA, 0x470A, { 0xB5, 0x0A, 0x13, 0x98, 0x13, 0x64, 0x91, 0x89 } };
/******************** Variable Name Strings ********************/
STATIC CONST CHAR16 *mDbVarName = L"dbx";
STATIC CONST CHAR16 *mDbtVarName = L"dbt";
STATIC CONST CHAR16 *mDbrVarName = L"dbr";
STATIC CONST CHAR16 *mDbVarName2 = L"db";
STATIC CONST CHAR16 *mKekVarName = L"KEK";
STATIC CONST CHAR16 *mPkVarName = L"PK";
STATIC CONST CHAR16 *mDbxDefaultName = L"dbxDefault";
STATIC CONST CHAR16 *mDbtDefaultName = L"dbtDefault";
STATIC CONST CHAR16 *mDbrDefaultName = L"dbrDefault";
STATIC CONST CHAR16 *mDbDefaultName = L"dbDefault";
STATIC CONST CHAR16 *mKekDefaultName = L"KEKDefault";
STATIC CONST CHAR16 *mPkDefaultName = L"PKDefault";
/******************** Forward Declarations ********************/
EFI_STATUS EFIAPI
SecureBootEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable);
STATIC EFI_STATUS SecureBootDriverMain (IN EFI_SYSTEM_TABLE *SystemTable);
STATIC EFI_STATUS GetDebugPrintProtocol (VOID);
STATIC VOID DebugPrint (IN UINTN ErrorLevel, IN CONST CHAR8 *Format, ...);
STATIC VOID AssertBreakPoint (IN CONST CHAR8 *File, IN UINTN Line, IN CONST CHAR8 *Desc);
STATIC UINT64 ReadUnaligned64 (IN CONST VOID *Buffer);
STATIC UINT64 WriteUnaligned64 (OUT VOID *Buffer, IN UINT64 Value);
STATIC UINTN GetDebugLevel (VOID);
STATIC VOID *GetHobList (VOID);
STATIC BOOLEAN IsGuidMatch (IN CONST EFI_CONFIGURATION_TABLE *Entry);
STATIC VOID *GetConfigurationTable (IN EFI_SYSTEM_TABLE *SystemTable);
STATIC VOID *GetFirmwareVolumeProtocol (VOID);
STATIC VOID *GetSectionFromFv (IN CONST EFI_GUID *NameGuid, OUT VOID **Buffer, OUT UINTN *Size);
STATIC EFI_STATUS GetSectionFromAnyFv (IN CONST EFI_GUID *NameGuid, OUT VOID **Buffer, OUT UINTN *Size);
STATIC VOID *AllocatePool (IN UINTN Size);
STATIC VOID GenerateRandomTime (OUT VOID *Buffer);
STATIC EFI_STATUS SetSecureBootVariable (IN UINT16 Flags, IN CONST CHAR16 *Name,
IN CONST CHAR16 *DefaultName, IN CONST EFI_GUID *Guid,
IN VOID *Data, IN UINTN DataSize);
STATIC EFI_STATUS ProvisionSecureBootDatabases (IN UINT16 Flags, IN UINT32 Fmt, IN UINT32 Auth);
/******************** Utility Functions ********************/
STATIC UINT64
ReadUnaligned64 (IN CONST VOID *Buffer)
{
ASSERT (Buffer != NULL);
return *(volatile UINT64 *)Buffer;
}
STATIC UINT64
WriteUnaligned64 (OUT VOID *Buffer, IN UINT64 Value)
{
ASSERT (Buffer != NULL);
*(volatile UINT64 *)Buffer = Value;
return Value;
}
STATIC UINTN
GetDebugLevel (VOID)
{
UINT8 SavedIdx, Value;
UINT32 Result;
SavedIdx = IoRead8 (0x70);
IoWrite8 (0x70, (SavedIdx & 0x80) | 0x4B);
Value = IoRead8 (0x71);
if (Value > 3) {
if (Value == 0)
Value = (*(volatile UINT8 *)0xFDAF0490 & 2) | 1;
}
if ((Value - 1) > 0xFD)
return 0;
return (Value == 1) ? 0x80000004 : 0x8000000C;
}
STATIC EFI_STATUS
GetDebugPrintProtocol (VOID)
{
if (mDebugPrintProtocol) {
if (mDebugLevel > 0x10) {
// ...
}
}
return mDebugPrintProtocol;
}
STATIC VOID
DebugPrint (IN UINTN ErrorLevel, IN CONST CHAR8 *Format, ...)
{
VA_LIST Va;
VA_START (Va, Format);
VA_END (Va);
}
STATIC VOID
AssertBreakPoint (IN CONST CHAR8 *File, IN UINTN Line, IN CONST CHAR8 *Desc)
{
/* Stub: calls DebugPrint then CpuDeadLoop typically */
}
/******************** HOB List ********************/
STATIC VOID *
GetHobList (VOID)
{
if (gHobList != NULL)
return gHobList;
gHobList = NULL;
if (gST->NumberOfTableEntries > 0) {
UINTN Index;
EFI_CONFIGURATION_TABLE *Entry = gST->ConfigurationTable;
for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
if (CompareMem (&Entry[Index].VendorGuid, &mHobListGuid, sizeof (EFI_GUID)) == 0) {
gHobList = Entry[Index].VendorTable;
return gHobList;
}
}
DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", EFI_NOT_FOUND));
ASSERT (!EFI_ERROR (EFI_NOT_FOUND));
}
if (gHobList == NULL)
ASSERT (gHobList != NULL);
return gHobList;
}
/******************** Configuration Table Lookup ********************/
STATIC BOOLEAN
IsGuidMatch (IN CONST EFI_CONFIGURATION_TABLE *Entry)
{
return CompareMem (&Entry->VendorGuid, &mHobListGuid, sizeof (EFI_GUID)) == 0;
}
STATIC VOID *
GetConfigurationTable (IN EFI_SYSTEM_TABLE *SystemTable)
{
UINTN Index;
for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++)
if (IsGuidMatch (&SystemTable->ConfigurationTable[Index]))
return SystemTable->ConfigurationTable[Index].VendorTable;
return NULL;
}
/******************** Firmware Volume Protocol ********************/
STATIC VOID *
GetFirmwareVolumeProtocol (VOID)
{
EFI_STATUS Status;
VOID *Interface = NULL;
if (gImageHandle) {
Status = gBS->OpenProtocol (gImageHandle, &mFirmwareVolume2ProtocolGuid,
&Interface, gImageHandle, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
}
if (Interface == NULL) {
Status = gBS->LocateProtocol (&mFirmwareVolume2ProtocolGuid, NULL, &Interface);
}
if (Interface == NULL) {
EFI_HANDLE *Buffer;
UINTN Count;
Status = gBS->LocateHandleBuffer (ByProtocol, &mFirmwareVolume2ProtocolGuid,
NULL, &Count, &Buffer);
if (!EFI_ERROR (Status)) {
UINTN i;
for (i = 0; i < Count; i++) {
Status = gBS->OpenProtocol (Buffer[i], &mFirmwareVolume2ProtocolGuid,
&Interface, gImageHandle, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (!EFI_ERROR (Status)) break;
Interface = NULL;
}
gBS->FreePool (Buffer);
}
}
return Interface;
}
/******************** Section Extraction from FV ********************/
STATIC VOID *
GetSectionFromFv (IN CONST EFI_GUID *NameGuid, OUT VOID **Buffer, OUT UINTN *Size)
{
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
UINT32 AuthenticationStatus;
ASSERT (NameGuid != NULL && Buffer != NULL && Size != NULL);
*Buffer = NULL; *Size = 0;
Fv = GetFirmwareVolumeProtocol ();
if (Fv == NULL) return NULL;
EFI_STATUS Status;
Status = Fv->ReadSection (Fv, NameGuid, EFI_SECTION_RAW, 0, Buffer,
(UINTN *)Size, &AuthenticationStatus);
if (EFI_ERROR (Status)) { *Buffer = NULL; *Size = 0; }
return (VOID *)(UINTN)Status;
}
STATIC EFI_STATUS
GetSectionFromAnyFv (IN CONST EFI_GUID *NameGuid, OUT VOID **Buffer, OUT UINTN *Size)
{
EFI_STATUS Status;
Status = (EFI_STATUS)(UINTN)GetSectionFromFv (NameGuid, Buffer, Size);
if (EFI_ERROR (Status))
Status = (EFI_STATUS)(UINTN)GetSectionFromFv (NameGuid, Buffer, Size);
if (Status == EFI_NOT_FOUND) Status = EFI_NOT_FOUND;
return Status;
}
/******************** Pool Allocation ********************/
STATIC VOID *
AllocatePool (IN UINTN Size)
{
VOID *Buf = NULL;
EFI_STATUS Status = gBS->AllocatePool (EfiBootServicesData, Size, &Buf);
ASSERT (!EFI_ERROR (Status));
return Buf;
}
/******************** Random Time Generation ********************/
STATIC VOID
GenerateRandomTime (OUT VOID *Buffer)
{
EFI_TIME Now;
UINT8 TimeSeed[16];
ZeroMem (TimeSeed, sizeof (TimeSeed));
TimeSeed[0] = 4; /* default month */
if (mRuntimeServices != NULL)
mRuntimeServices->GetTime (&Now, NULL);
TimeSeed[0] = (UINT8)(Now.Year & 0xFF);
TimeSeed[1] = (UINT8)((Now.Year >> 8) & 0xFF);
TimeSeed[2] = (UINT8)Now.Month;
TimeSeed[3] = (UINT8)Now.Day;
TimeSeed[4] = (UINT8)Now.Hour;
TimeSeed[5] = (UINT8)Now.Minute;
TimeSeed[6] = (UINT8)Now.Second;
TimeSeed[7] = 0;
DEBUG ((EFI_D_INFO,
"EfiTime Now : (Year=%d Month=%d Day=%d Hour=%d Min=%d Sec=%d)\n",
TimeSeed[0] | ((UINT16)TimeSeed[1] << 8),
TimeSeed[2], TimeSeed[3], TimeSeed[4], TimeSeed[5], TimeSeed[6]));
CopyMem (Buffer, TimeSeed, 16);
*(UINT16 *)((UINT8 *)Buffer + 16) = 24;
*(UINT32 *)((UINT8 *)Buffer + 20) = 250675712;
/* Append 16 bytes of RNG data */
{
EFI_RNG_PROTOCOL *Rng;
EFI_STATUS Status;
Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&Rng);
if (Rng) {
UINT64 RngBuf[2];
Status = Rng->GetRNG (Rng, &mRngAlgoHash256, 16, (UINT8 *)&RngBuf);
if (EFI_ERROR (Status))
Status = Rng->GetRNG (Rng, &mRngAlgoHmac256, 16, (UINT8 *)&RngBuf);
if (!EFI_ERROR (Status)) {
WriteUnaligned64 ((UINT8 *)Buffer + 24, RngBuf[0]);
WriteUnaligned64 ((UINT8 *)Buffer + 32, RngBuf[1]);
}
}
}
}
/******************** Secure Boot Variable Set ********************/
STATIC EFI_STATUS
SetSecureBootVariable (
IN UINT16 Flags,
IN CONST CHAR16 *Name,
IN CONST CHAR16 *DefaultName,
IN CONST EFI_GUID *Guid,
IN VOID *Data,
IN UINTN DataSize)
{
EFI_STATUS Status;
UINTN OldSize = 0, NewSize = 0;
UINT32 Attr;
UINTN VarSize = 0;
if (Name == NULL || (DataSize == 0 && Data == NULL))
return EFI_INVALID_PARAMETER;
if ((Flags & 4) && (DefaultName == NULL || Guid == NULL))
return EFI_INVALID_PARAMETER;
Status = mRuntimeServices->GetVariable ((CHAR16 *)Name, (EFI_GUID *)Guid,
&Attr, &VarSize, NULL);
if (Status == EFI_NOT_FOUND && (Flags & 1)) {
GenerateRandomTime (&VarSize); /* stack buffer via local var */
UINT8 ClearBuf[40];
GenerateRandomTime (ClearBuf);
VarSize = 39; Attr = 40;
Status = mRuntimeServices->SetVariable ((CHAR16 *)Name, (EFI_GUID *)Guid,
VarSize, Attr, ClearBuf);
DEBUG ((EFI_D_INFO, "Clear NV Var %s(%r)\n", Name, Status));
if (EFI_ERROR (Status)) return Status;
}
if (Status != EFI_BUFFER_TOO_SMALL) OldSize = VarSize;
if ((Flags & 4)) {
UINT32 *Hdr = (UINT32 *)Data;
Status = mRuntimeServices->SetVariable ((CHAR16 *)DefaultName,
(EFI_GUID *)&mVarStorageGuid, VarSize,
DataSize - (Hdr[4] + 16), (UINT8 *)Data + Hdr[4] + 16);
DEBUG ((EFI_D_INFO, "Set RT Var %s(%r)\n", DefaultName, Status));
}
if ((Flags & 2)) {
Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
if (!(Flags & 8)) Attr |= 0x40; /* time-based */
Status = mRuntimeServices->SetVariable ((CHAR16 *)Name, (EFI_GUID *)Guid,
Attr, DataSize, Data);
DEBUG ((EFI_D_INFO, "Set NV Var %s(%r)\n", Name, Status));
if (Status == EFI_WRITE_PROTECTED) return EFI_SUCCESS;
if (!EFI_ERROR (Status)) {
mRuntimeServices->GetVariable ((CHAR16 *)Name, (EFI_GUID *)Guid,
&Attr, &NewSize, NULL);
DEBUG ((EFI_D_INFO, "Old Var Size %Xh\nNew Var size %Xh\n", OldSize, NewSize));
if ((Flags & 8) && OldSize == NewSize) return EFI_ALREADY_STARTED;
}
}
return Status;
}
/******************** Database Provisioning ********************/
STATIC EFI_STATUS
ProvisionSecureBootDatabases (
IN UINT16 Flags,
IN UINT32 Fmt,
IN UINT32 Auth)
{
struct { CONST CHAR16 *Name; CONST CHAR16 *Def; CONST EFI_GUID *Type; } DB[] = {
{ L"dbx", L"dbxDefault", &mCertSha256Guid },
{ L"dbt", L"dbtDefault", &mCertX509Guid },
{ L"dbr", L"dbrDefault", &mCertRsa2048Sha256Guid },
{ L"db", L"dbDefault", &mCertRsa2048Sha1Guid },
{ L"KEK", L"KEKDefault", &mCertX509Guid },
{ L"PK", L"PKDefault", &mCertSha384Guid },
};
UINTN i;
for (i = 0; i < ARRAY_SIZE (DB); i++) {
EFI_STATUS Status;
VOID *RawData = NULL;
UINTN DataSize = 0;
Status = GetSectionFromAnyFv (DB[i].Type, &RawData, &DataSize);
if (EFI_ERROR (Status)) { RawData = NULL; DataSize = 0; }
DEBUG ((EFI_D_INFO, "Get Raw image %s(%r), sz = %x\n", DB[i].Name, Status, DataSize));
SetSecureBootVariable (Flags, DB[i].Name, DB[i].Def, DB[i].Type, RawData, DataSize);
if (RawData) gBS->FreePool (RawData);
}
return EFI_SUCCESS;
}
/******************** Secure Boot Driver Main ********************/
STATIC EFI_STATUS
SecureBootDriverMain (IN EFI_SYSTEM_TABLE *SystemTable)
{
EFI_STATUS Status;
SECURE_BOOT_SETUP_VAR Setup;
UINTN VarSize;
UINT32 Attributes;
UINT8 SetupModeVal;
UINTN SetupModeSize;
if (mSystemTable == NULL) {
mSystemTable = SystemTable;
mBootServices = SystemTable->BootServices;
mRuntimeServices = SystemTable->RuntimeServices;
}
VarSize = sizeof (Setup);
Status = mRuntimeServices->GetVariable (L"SecureBootSetup",
(EFI_GUID *)&mSecureBootSetupVarGuid, &Attributes,
&VarSize, &Setup);
DEBUG ((EFI_D_INFO,
"SecureBootSetup (%r) Attrib=%x,\nSecBoot-%d, SecMode-%d, DefaultProvision-%d\n",
Status, Attributes, Setup.SecureBoot, Setup.SecureBootMode,
Setup.DefaultProvisioning));
GetConfigurationTable (SystemTable);
if (Setup.DefaultProvisioning == 1) {
ProvisionSecureBootDatabases (2, 0, 0);
SetupModeSize = 1;
mRuntimeServices->GetVariable (L"SetupMode",
(EFI_GUID *)&mGlobalVariableGuid, &Attributes,
&SetupModeSize, &SetupModeVal);
/* Clear SetupMode */
SetupModeVal = 0;
SetupModeSize = 1; Attributes = 0;
mRuntimeServices->SetVariable (L"SetupMode",
(EFI_GUID *)&mGlobalVariableGuid, Attributes,
&SetupModeSize, &SetupModeVal);
SetupModeSize = 1;
mRuntimeServices->GetVariable (L"SetupMode",
(EFI_GUID *)&mGlobalVariableGuid, &Attributes,
&SetupModeSize, &SetupModeVal);
if (SetupModeVal == 0 && Setup.SecureBoot == 1) {
mRuntimeServices->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
}
}
ProvisionSecureBootDatabases (4, 0, 0);
return EFI_SUCCESS;
}
/******************** Module Entry Point ********************/
EFI_STATUS
EFIAPI
SecureBootEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable)
{
gImageHandle = ImageHandle; ASSERT (gImageHandle != NULL);
gST = SystemTable; ASSERT (gST != NULL);
gBS = SystemTable->BootServices; ASSERT (gBS != NULL);
gRT = SystemTable->RuntimeServices; ASSERT (gRT != NULL);
GetHobList ();
return SecureBootDriverMain (SystemTable);
}