[BOOTMGFW]: Implement additional startup logic

[BOOTLIB]: Implement initial SecureBoot support.
[BOOTLIB]: Implement UEFI Variable query support.

svn path=/trunk/; revision=70543
This commit is contained in:
Alex Ionescu 2016-01-08 06:03:55 +00:00
parent 3bfe54c38c
commit 44ab46cfa9
5 changed files with 525 additions and 6 deletions

View file

@ -1041,6 +1041,16 @@ BmpBgDisplayClearScreen (
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
BlXmiWrite (
_In_ PWCHAR XmlTag
)
{
/* Sigh */
EfiPrintf(L"XML: %s\r\n", XmlTag);
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
BlXmiInitialize (
_In_ PWCHAR Stylesheet
@ -1082,17 +1092,77 @@ BmFwVerifySelfIntegrity (
VOID
)
{
EfiPrintf(L"Device Type %d Local Type %d\r\n", BlpBootDevice->DeviceType, BlpBootDevice->Local.Type);
/* Check if we're booted by UEFI off the DVD directlry */
if ((BlpBootDevice->DeviceType == LocalDevice) &&
(BlpBootDevice->Local.Type == CdRomDevice) &&
(BlpApplicationFlags & BL_APPLICATION_FLAG_CONVERTED_FROM_EFI))
{
/* Windows actually bypasses integrity checks in this case. Works for us */
return STATUS_SUCCESS;
}
/* Our binaries aren't signed, so always return failure */
return 0xC0000428;
}
NTSTATUS
BmFwRegisterRevocationList (
VOID
)
{
NTSTATUS Status;
BOOLEAN SecureBootEnabled;
/* Is SecureBoot enabled? */
Status = BlSecureBootIsEnabled(&SecureBootEnabled);
if ((NT_SUCCESS(Status)) && (SecureBootEnabled))
{
EfiPrintf(L"SB not implemented revok\r\n");
return STATUS_NOT_IMPLEMENTED;
}
else
{
/* Nothing to do without SecureBoot */
Status = STATUS_SUCCESS;
}
/* Return revocation result back to caller */
return Status;
}
NTSTATUS
BmResumeFromHibernate (
_Out_ PHANDLE BcdResumeHandle
)
{
NTSTATUS Status;
BOOLEAN AttemptResume;
/* Should we attempt to resume from hibernation? */
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
BcdBootMgrBoolean_AttemptResume,
&AttemptResume);
if (!NT_SUCCESS(Status))
{
/* Nope. Is automatic restart on crash enabled? */
AttemptResume = FALSE;
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
BcdOSLoaderBoolean_DisableCrashAutoReboot,
&AttemptResume);
AttemptResume = (NT_SUCCESS(Status) && (AttemptResume));
}
/* Don't do anything if there's no need to resume anything */
if (!AttemptResume)
{
return STATUS_SUCCESS;
}
/* Not yet implemented */
EfiPrintf(L"Resume not supported\r\n");
return STATUS_NOT_IMPLEMENTED;
}
/*++
* @name BmMain
*
@ -1116,7 +1186,7 @@ BmMain (
PBL_RETURN_ARGUMENTS ReturnArguments;
BOOLEAN RebootOnError;
PGUID AppIdentifier;
HANDLE BcdHandle;
HANDLE BcdHandle, ResumeBcdHandle;
PBL_BCD_OPTION EarlyOptions;
PWCHAR Stylesheet;
BOOLEAN XmlLoaded, DisableIntegrity, TestSigning;
@ -1267,14 +1337,36 @@ BmMain (
}
}
// BlXmiWrite(L"<bootmgr/>");
/* Write out the first XML tag */
BlXmiWrite(L"<bootmgr/>");
//BlSecureBootCheckForFactoryReset();
/* Check for factory resset */
BlSecureBootCheckForFactoryReset();
/* Load the revocation list */
Status = BmFwRegisterRevocationList();
if (!NT_SUCCESS(Status))
{
goto Failure;
}
/* Register our custom progress routine */
BlUtlRegisterProgressRoutine();
/* Display state is not currently cached */
BmDisplayStateCached = FALSE;
/* Check if w need to resume from hibernate */
Status = BmResumeFromHibernate(&ResumeBcdHandle);
if (!NT_SUCCESS(Status))
{
goto Failure;
}
/* do more stuff!! */
EfiPrintf(BlResourceFindMessage(BM_MSG_TEST));
EfiPrintf(Stylesheet);
//EfiPrintf(BlResourceFindMessage(BM_MSG_TEST));
//EfiPrintf(Stylesheet);
EfiStall(10000000);
Failure:

View file

@ -39,6 +39,7 @@
#include <UgaDraw.h>
#include <BlockIo.h>
#include <Acpi.h>
#include <GlobalVariable.h>
/* Registry Headers */
#define __FREELDR_H
@ -1528,6 +1529,11 @@ BlUtlInitialize (
VOID
);
NTSTATUS
BlUtlRegisterProgressRoutine (
VOID
);
VOID
BlFwReboot (
VOID
@ -1538,6 +1544,21 @@ BlGetApplicationIdentifier (
VOID
);
NTSTATUS
BlpSecureBootEFIIsEnabled (
VOID
);
NTSTATUS
BlSecureBootIsEnabled (
_Out_ PBOOLEAN SecureBootEnabled
);
NTSTATUS
BlSecureBootCheckForFactoryReset (
VOID
);
NTSTATUS
BlGetApplicationBaseAndSize (
_Out_ PVOID* ImageBase,
@ -2302,6 +2323,7 @@ extern EFI_GUID EfiBlockIoProtocol;
extern EFI_GUID EfiSimpleTextInputExProtocol;
extern EFI_GUID EfiRootAcpiTableGuid;
extern EFI_GUID EfiRootAcpiTable10Guid;
extern EFI_GUID EfiGlobalVariable;
extern ULONG ConsoleGraphicalResolutionListFlags;
extern BL_DISPLAY_MODE ConsoleGraphicalResolutionList[];
extern BL_DISPLAY_MODE ConsoleTextResolutionList[];

View file

@ -0,0 +1,192 @@
/** @file
GUID for EFI (NVRAM) Variables.
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@par Revision Reference:
GUID defined in UEFI 2.1
**/
#ifndef __GLOBAL_VARIABLE_GUID_H__
#define __GLOBAL_VARIABLE_GUID_H__
#define EFI_GLOBAL_VARIABLE \
{ \
0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C } \
}
extern EFI_GUID gEfiGlobalVariableGuid;
//
// Follow UEFI 2.4 spec:
// To prevent name collisions with possible future globally defined variables,
// other internal firmware data variables that are not defined here must be
// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
// any other GUID defined by the UEFI Specification. Implementations must
// only permit the creation of variables with a UEFI Specification-defined
// VendorGuid when these variables are documented in the UEFI Specification.
//
// Note: except the globally defined variables defined below, the spec also defines
// L"Boot####" - A boot load option.
// L"Driver####" - A driver load option.
// L"SysPrep####" - A System Prep application load option.
// L"Key####" - Describes hot key relationship with a Boot#### load option.
// The attribute for them is NV+BS+RT, #### is a printed hex value, and no 0x or h
// is included in the hex value. They can not be expressed as a #define like other globally
// defined variables, it is because we can not list the Boot0000, Boot0001, etc one by one.
//
///
/// The language codes that the firmware supports. This value is deprecated.
/// Its attribute is BS+RT.
///
#define EFI_LANG_CODES_VARIABLE_NAME L"LangCodes"
///
/// The language code that the system is configured for. This value is deprecated.
/// Its attribute is NV+BS+RT.
///
#define EFI_LANG_VARIABLE_NAME L"Lang"
///
/// The firmware's boot managers timeout, in seconds, before initiating the default boot selection.
/// Its attribute is NV+BS+RT.
///
#define EFI_TIME_OUT_VARIABLE_NAME L"Timeout"
///
/// The language codes that the firmware supports.
/// Its attribute is BS+RT.
///
#define EFI_PLATFORM_LANG_CODES_VARIABLE_NAME L"PlatformLangCodes"
///
/// The language code that the system is configured for.
/// Its attribute is NV+BS+RT.
///
#define EFI_PLATFORM_LANG_VARIABLE_NAME L"PlatformLang"
///
/// The device path of the default input/output/error output console.
/// Its attribute is NV+BS+RT.
///
#define EFI_CON_IN_VARIABLE_NAME L"ConIn"
#define EFI_CON_OUT_VARIABLE_NAME L"ConOut"
#define EFI_ERR_OUT_VARIABLE_NAME L"ErrOut"
///
/// The device path of all possible input/output/error output devices.
/// Its attribute is BS+RT.
///
#define EFI_CON_IN_DEV_VARIABLE_NAME L"ConInDev"
#define EFI_CON_OUT_DEV_VARIABLE_NAME L"ConOutDev"
#define EFI_ERR_OUT_DEV_VARIABLE_NAME L"ErrOutDev"
///
/// The ordered boot option load list.
/// Its attribute is NV+BS+RT.
///
#define EFI_BOOT_ORDER_VARIABLE_NAME L"BootOrder"
///
/// The boot option for the next boot only.
/// Its attribute is NV+BS+RT.
///
#define EFI_BOOT_NEXT_VARIABLE_NAME L"BootNext"
///
/// The boot option that was selected for the current boot.
/// Its attribute is BS+RT.
///
#define EFI_BOOT_CURRENT_VARIABLE_NAME L"BootCurrent"
///
/// The types of boot options supported by the boot manager. Should be treated as read-only.
/// Its attribute is BS+RT.
///
#define EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME L"BootOptionSupport"
///
/// The ordered driver load option list.
/// Its attribute is NV+BS+RT.
///
#define EFI_DRIVER_ORDER_VARIABLE_NAME L"DriverOrder"
///
/// The ordered System Prep Application load option list.
/// Its attribute is NV+BS+RT.
///
#define EFI_SYS_PREP_ORDER_VARIABLE_NAME L"SysPrepOrder"
///
/// Identifies the level of hardware error record persistence
/// support implemented by the platform. This variable is
/// only modified by firmware and is read-only to the OS.
/// Its attribute is NV+BS+RT.
///
#define EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME L"HwErrRecSupport"
///
/// Whether the system is operating in setup mode (1) or not (0).
/// All other values are reserved. Should be treated as read-only.
/// Its attribute is BS+RT.
///
#define EFI_SETUP_MODE_NAME L"SetupMode"
///
/// The Key Exchange Key Signature Database.
/// Its attribute is NV+BS+RT+AT.
///
#define EFI_KEY_EXCHANGE_KEY_NAME L"KEK"
///
/// The public Platform Key.
/// Its attribute is NV+BS+RT+AT.
///
#define EFI_PLATFORM_KEY_NAME L"PK"
///
/// Array of GUIDs representing the type of signatures supported
/// by the platform firmware. Should be treated as read-only.
/// Its attribute is BS+RT.
///
#define EFI_SIGNATURE_SUPPORT_NAME L"SignatureSupport"
///
/// Whether the platform firmware is operating in Secure boot mode (1) or not (0).
/// All other values are reserved. Should be treated as read-only.
/// Its attribute is BS+RT.
///
#define EFI_SECURE_BOOT_MODE_NAME L"SecureBoot"
///
/// The OEM's default Key Exchange Key Signature Database. Should be treated as read-only.
/// Its attribute is BS+RT.
///
#define EFI_KEK_DEFAULT_VARIABLE_NAME L"KEKDefault"
///
/// The OEM's default public Platform Key. Should be treated as read-only.
/// Its attribute is BS+RT.
///
#define EFI_PK_DEFAULT_VARIABLE_NAME L"PKDefault"
///
/// The OEM's default secure boot signature store. Should be treated as read-only.
/// Its attribute is BS+RT.
///
#define EFI_DB_DEFAULT_VARIABLE_NAME L"dbDefault"
///
/// The OEM's default secure boot blacklist signature store. Should be treated as read-only.
/// Its attribute is BS+RT.
///
#define EFI_DBX_DEFAULT_VARIABLE_NAME L"dbxDefault"
///
/// The OEM's default secure boot timestamp signature store. Should be treated as read-only.
/// Its attribute is BS+RT.
///
#define EFI_DBT_DEFAULT_VARIABLE_NAME L"dbtDefault"
///
/// Allows the firmware to indicate supported features and actions to the OS.
/// Its attribute is BS+RT.
///
#define EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME L"OsIndicationsSupported"
///
/// Allows the OS to request the firmware to enable certain features and to take certain actions.
/// Its attribute is NV+BS+RT.
///
#define EFI_OS_INDICATIONS_VARIABLE_NAME L"OsIndications"
///
/// Whether the system is configured to use only vendor provided
/// keys or not. Should be treated as read-only.
/// Its attribute is BS+RT.
///
#define EFI_VENDOR_KEYS_VARIABLE_NAME L"VendorKeys"
#endif

View file

@ -33,9 +33,14 @@ EFI_GUID EfiSimpleTextInputExProtocol = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
EFI_GUID EfiBlockIoProtocol = EFI_BLOCK_IO_PROTOCOL_GUID;
EFI_GUID EfiRootAcpiTableGuid = EFI_ACPI_20_TABLE_GUID;
EFI_GUID EfiRootAcpiTable10Guid = EFI_ACPI_TABLE_GUID;
EFI_GUID EfiGlobalVariable = EFI_GLOBAL_VARIABLE;
EFI_GUID BlpEfiSecureBootPrivateNamespace = { 0x77FA9ABD , 0x0359, 0x4D32, { 0xBD, 0x60, 0x28, 0xF4, 0xE7, 0x8F, 0x78, 0x4B } };
WCHAR BlScratchBuffer[8192];
BOOLEAN BlpFirmwareChecked;
BOOLEAN BlpFirmwareEnabled;
/* FUNCTIONS *****************************************************************/
EFI_DEVICE_PATH *
@ -268,6 +273,159 @@ EfiCloseProtocol (
return Status;
}
NTSTATUS
EfiGetVariable (
_In_ PWCHAR VariableName,
_In_ EFI_GUID* VendorGuid,
_Out_opt_ PULONG Attributes,
_Inout_ PULONG DataSize,
_Out_ PVOID Data
)
{
EFI_STATUS EfiStatus;
NTSTATUS Status;
BL_ARCH_MODE OldMode;
ULONG LocalAttributes;
/* Are we in protected mode? */
OldMode = CurrentExecutionContext->Mode;
if (OldMode != BlRealMode)
{
/* FIXME: Not yet implemented */
return STATUS_NOT_IMPLEMENTED;
}
/* Call the runtime API */
EfiStatus = EfiRT->GetVariable(VariableName,
VendorGuid,
(UINT32*)&LocalAttributes,
(UINTN*)DataSize,
Data);
/* Switch back to protected mode if we came from there */
if (OldMode != BlRealMode)
{
BlpArchSwitchContext(OldMode);
}
/* Return attributes back to the caller if asked to */
if (Attributes)
{
*Attributes = LocalAttributes;
}
/* Convert the errot to an NTSTATUS and return it */
Status = EfiGetNtStatusCode(EfiStatus);
return Status;
}
NTSTATUS
BlpSecureBootEFIIsEnabled (
VOID
)
{
NTSTATUS Status;
BOOLEAN SetupMode, SecureBoot;
ULONG DataSize;
/* Assume setup mode enabled, and no secure boot */
SecureBoot = FALSE;
SetupMode = TRUE;
/* Get the SetupMode variable */
DataSize = sizeof(SetupMode);
Status = EfiGetVariable(L"SetupMode",
&EfiGlobalVariable,
NULL,
&DataSize,
&SetupMode);
if (NT_SUCCESS(Status))
{
/* If it worked, get the SecureBoot variable */
DataSize = sizeof(SecureBoot);
Status = EfiGetVariable(L"SecureBoot",
&EfiGlobalVariable,
NULL,
&DataSize,
&SecureBoot);
if (NT_SUCCESS(Status))
{
/* In setup mode or without secureboot turned on, return failure */
if ((SecureBoot != TRUE) || (SetupMode))
{
Status = STATUS_INVALID_SIGNATURE;
}
// BlpSbdiStateFlags |= 8u;
}
}
/* Return secureboot status */
return Status;
}
NTSTATUS
BlSecureBootIsEnabled (
_Out_ PBOOLEAN SecureBootEnabled
)
{
NTSTATUS Status;
/* Have we checked before ? */
if (!BlpFirmwareChecked)
{
/* First time checking */
Status = BlpSecureBootEFIIsEnabled();
if NT_SUCCESS(Status)
{
/* Yep, it's on */
BlpFirmwareEnabled = TRUE;
}
/* Don't check again */
BlpFirmwareChecked = TRUE;
}
/* Return the firmware result */
*SecureBootEnabled = BlpFirmwareEnabled;
return STATUS_SUCCESS;
}
NTSTATUS
BlSecureBootCheckForFactoryReset (
VOID
)
{
BOOLEAN SecureBootEnabled;
NTSTATUS Status;
ULONG DataSize;
/* Initialize locals */
DataSize = 0;
SecureBootEnabled = FALSE;
/* Check if secureboot is enabled */
Status = BlSecureBootIsEnabled(&SecureBootEnabled);
if (!(NT_SUCCESS(Status)) || !(SecureBootEnabled))
{
/* It's not. Check if there's a revocation list */
Status = EfiGetVariable(L"RevocationList",
&BlpEfiSecureBootPrivateNamespace,
NULL,
&DataSize,
NULL);
if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_TOO_SMALL))
{
/* We don't support this yet */
EfiPrintf(L"Not yet supported\r\n");
Status = STATUS_NOT_IMPLEMENTED;
}
}
/* Return back to the caller */
return Status;
}
NTSTATUS
EfiConInReset (
VOID

View file

@ -28,6 +28,8 @@ ULONG UtlNextUpdatePercentage;
BOOLEAN UtlProgressNeedsInfoUpdate;
PVOID UtlProgressInfo;
/* FUNCTIONS *****************************************************************/
NTSTATUS
@ -176,6 +178,7 @@ BlUtlGetAcpiTable (
return STATUS_NOT_FOUND;
}
VOID
BlUtlUpdateProgress (
_In_ ULONG Percentage,
@ -216,6 +219,58 @@ BlUtlInitialize (
return STATUS_SUCCESS;
}
VOID
BmUpdateProgressInfo (
_In_ PVOID Uknown,
_In_ PWCHAR ProgressInfo
)
{
EfiPrintf(L"Progress Info: %s\r\n", ProgressInfo);
}
VOID
BmUpdateProgress (
_In_ PVOID Unknown,
_In_ ULONG Percent,
_Out_ PBOOLEAN Completed
)
{
EfiPrintf(L"Progress: %d\r\n", Percent);
if (Completed)
{
*Completed = TRUE;
}
}
NTSTATUS
BlUtlRegisterProgressRoutine (
VOID
)
{
/* One shouldn't already exist */
if (UtlProgressRoutine)
{
return STATUS_UNSUCCESSFUL;
}
/* Set the routine, and no context */
UtlProgressRoutine = BmUpdateProgress;
UtlProgressContext = NULL;
/* Progress increases by one */
UtlProgressGranularity = 1;
/* Set progress to zero for now */
UtlCurrentPercentComplete = 0;
UtlNextUpdatePercentage = 0;
/* Set the info routine if there is one */
UtlProgressInfoRoutine = BmUpdateProgressInfo;
/* All good */
return STATUS_SUCCESS;
}
PVOID
BlTblFindEntry (
_In_ PVOID *Table,