1987 lines
72 KiB
C
1987 lines
72 KiB
C
/** @file
|
|
The secure boot manager implementation
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2012 - 2021, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include "SecureBootMgr.h"
|
|
#include "EnrollHash.h"
|
|
#include "SecureBootVar.h"
|
|
|
|
#include <KernelSetupConfig.h>
|
|
#include <Protocol/SmmBase2.h>
|
|
#include <SmiTable.h>
|
|
#include <Library/VariableLib.h>
|
|
|
|
|
|
typedef struct _INDEX_NAME_MAP {
|
|
UINT8 FunctionIndex;
|
|
CHAR16 *VariableName;
|
|
} INDEX_NAME_MAP;
|
|
|
|
STATIC INDEX_NAME_MAP mIndexNameMap [] = { {UPDATE_DB_FUN_NUM, EFI_IMAGE_SECURITY_DATABASE},
|
|
{UPDATE_DBX_FUN_NUM, EFI_IMAGE_SECURITY_DATABASE1},
|
|
{UPDATE_DBT_FUN_NUM, EFI_IMAGE_SECURITY_DATABASE2},
|
|
{UPDATE_DBR_FUN_NUM, EFI_IMAGE_SECURITY_DATABASE3}
|
|
};
|
|
|
|
/**
|
|
This function uses to check system whether supports SMM mode or not.
|
|
|
|
@retval TRUE System supports SMM mode
|
|
@retval FALSE System doesn't support SMM mode.
|
|
**/
|
|
STATIC
|
|
BOOLEAN
|
|
IsSmmModeSupported (
|
|
VOID
|
|
);
|
|
|
|
|
|
EFI_GUID mSecureBootGuid = SECURE_BOOT_FORMSET_GUID;
|
|
BOOLEAN mReadyToBootSignaled = FALSE;
|
|
EFI_SEND_FORM2 mOrgSendForm = NULL;
|
|
BOOLEAN mNeedInitializePrivateData = TRUE;
|
|
|
|
SECURE_BOOT_MANAGER_CALLBACK_DATA mSecureBootPrivate = {
|
|
SECURE_BOOT_CALLBACK_DATA_SIGNATURE,
|
|
NULL,
|
|
NULL,
|
|
{
|
|
SecureBootExtractConfig,
|
|
SecureBootRouteConfig,
|
|
SecureBootCallback
|
|
}
|
|
};
|
|
|
|
STATIC HII_VENDOR_DEVICE_PATH mSecureBootHiiVendorDevicePath = {
|
|
{
|
|
{
|
|
HARDWARE_DEVICE_PATH,
|
|
HW_VENDOR_DP,
|
|
{
|
|
(UINT8) (sizeof (VENDOR_DEVICE_PATH)),
|
|
(UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
|
|
}
|
|
},
|
|
SECURE_BOOT_FORMSET_GUID
|
|
},
|
|
{
|
|
END_DEVICE_PATH_TYPE,
|
|
END_ENTIRE_DEVICE_PATH_SUBTYPE,
|
|
{
|
|
(UINT8) (END_DEVICE_PATH_LENGTH),
|
|
(UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
|
|
}
|
|
}
|
|
};
|
|
|
|
EFI_LOAD_FILE_PROTOCOL mSecureBootMgrLoadFile = {SecureBootMgrLoadFile};
|
|
|
|
STATIC UINT8 mDefaultAthenData[] = {
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xdd, 0x26, 0x02, 0x97, 0x9d, 0x44, 0x1f, 0x64, 0x95, 0xf8, 0x88, 0x46, 0xef, 0x9f, 0xb2,
|
|
0xa1, 0x6c, 0xbc, 0x89, 0x1c, 0x29, 0xad, 0x4e, 0x5f, 0x67, 0xe0, 0xdb, 0xeb, 0x2f, 0xa4, 0xc0, 0x3f, 0x44, 0x72, 0x5c, 0x93, 0x39, 0x6d, 0xe5, 0x1c, 0xe2, 0x2b, 0xcb, 0x76, 0x11, 0x71, 0x4f,
|
|
0xc7, 0xe7, 0xa2, 0xde, 0x1e, 0x07, 0x56, 0x92, 0xfc, 0x63, 0x61, 0xf1, 0x06, 0xbb, 0x77, 0x26, 0xb8, 0x99, 0x7c, 0x0e, 0xb8, 0x81, 0x24, 0x2e, 0x72, 0x78, 0x8c, 0xfa, 0x6a, 0x71, 0x5d, 0x08,
|
|
0x42, 0xda, 0xde, 0x86, 0xfe, 0x99, 0x92, 0xf7, 0xf8, 0xa0, 0x3d, 0x1f, 0x52, 0x0b, 0xb8, 0xc6, 0x1b, 0xd5, 0x39, 0xcb, 0x34, 0xdb, 0x2b, 0x25, 0x57, 0x44, 0x72, 0x02, 0x93, 0x67, 0x2a, 0x82,
|
|
0x90, 0xa2, 0x5a, 0x76, 0xcb, 0x81, 0x7d, 0x42, 0x39, 0x1a, 0xf8, 0x54, 0xe0, 0x42, 0xbf, 0x49, 0x36, 0x1c, 0x4e, 0x88, 0xda, 0x5c, 0x7b, 0xd4, 0x67, 0xf6, 0x82, 0x30, 0xe4, 0x18, 0xf9, 0xb3,
|
|
0xe8, 0xab, 0xa4, 0xca, 0x53, 0x82, 0xcf, 0xf4, 0xac, 0x83, 0x4b, 0xd6, 0xd4, 0xa1, 0xc0, 0x01, 0xfc, 0x16, 0x9d, 0xca, 0xc5, 0x17, 0x2e, 0x70, 0xff, 0xaf, 0x86, 0xc8, 0x43, 0x02, 0xde, 0x52,
|
|
0xb1, 0x23, 0xf0, 0x2f, 0xd8, 0x0a, 0x46, 0xd3, 0xaf, 0x6b, 0x7e, 0x77, 0xf6, 0x72, 0x00, 0x66, 0x69, 0x66, 0x37, 0x71, 0x19, 0xc7, 0x7b, 0xf0, 0xd1, 0x41, 0xfd, 0x2b, 0x9b, 0xa1, 0x14, 0xb5,
|
|
0xb3, 0x55, 0xb9, 0x96, 0x53, 0x9f, 0x29, 0x63, 0xb2, 0x38, 0x2e, 0x29, 0x10, 0x16, 0x8a, 0xbd, 0x2e, 0xed, 0x3b, 0xdc, 0xb5, 0x40, 0x6f, 0xab, 0x26, 0xea, 0xb5, 0x28, 0x36, 0x6b, 0x4a, 0x68,
|
|
0x85, 0xd2, 0xb1, 0xff, 0xbf, 0xe6, 0x0a, 0xd3, 0x8c, 0xe5, 0x01, 0xda, 0xfd, 0x65, 0x75, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
|
|
};
|
|
|
|
STRING_DEPOSITORY *mSecureBootFileOptionStrDepository;
|
|
STATIC UINT8 mEnrollHashSha256Data[] = {
|
|
// EFI_VARIABLE_AUTHENTICATION_2
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x18, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// EFI_SIGNATURE_LIST
|
|
0x26, 0x16, 0xc4, 0xc1, 0x4c, 0x50, 0x92, 0x40, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28, // gEfiCertSha256Guid
|
|
0x4c, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x30, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
|
|
STATIC UINT8 mEnrollHashSha1Data[] = {
|
|
// EFI_VARIABLE_AUTHENTICATION_2
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x18, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// EFI_SIGNATURE_LIST
|
|
0x12, 0xa5, 0x6c, 0x82, 0x10, 0xcf, 0xc9, 0x4a, 0xb1, 0x87, 0xbe, 0x01, 0x49, 0x66, 0x31, 0xbd, // gEfiCertSha1Guid
|
|
0x40, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x24, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
LIST_ENTRY mSecureBootHashLinkList = INITIALIZE_LIST_HEAD_VARIABLE (mSecureBootHashLinkList);
|
|
|
|
//
|
|
// Following are the sameple code for how to update PK, KEK, db and dbx variable using Administer Secure Boot interface.
|
|
//
|
|
STATIC UINT8 mDefaultHeaderData[] = {
|
|
// EFI_VARIABLE_AUTHENTICATION_2
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x19, 0x00, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
|
|
0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7, // gEfiCertPkcs7Guid
|
|
0x00 // one byte for update type
|
|
// EFI_SIGNATURE_LIST
|
|
};
|
|
//
|
|
//STATIC UINT8 mTestCert [] = {
|
|
//0x30, 0x82, 0x02, 0xF0, 0x30, 0x82, 0x01, 0xDC, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x1D,
|
|
//0x30, 0x50, 0xAC, 0xFD, 0xFF, 0xB5, 0xB7, 0x4E, 0xFF, 0xAC, 0x38, 0x0E, 0x0F, 0x19, 0xB5, 0x30,
|
|
//0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1D, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0F,
|
|
//0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x08, 0x74, 0x65, 0x73, 0x74, 0x6B, 0x65, 0x79, 0x32, 0x30,
|
|
//0x1E, 0x17, 0x0D, 0x31, 0x30, 0x30, 0x33, 0x33, 0x31, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5A,
|
|
//0x17, 0x0D, 0x32, 0x30, 0x30, 0x35, 0x32, 0x39, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x30,
|
|
//0x13, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x08, 0x74, 0x65, 0x73, 0x74,
|
|
//0x6B, 0x65, 0x79, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
|
|
//0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A,
|
|
//0x02, 0x82, 0x01, 0x01, 0x00, 0xAA, 0x2D, 0x41, 0x1A, 0xE7, 0x19, 0x3A, 0xE0, 0xD3, 0x43, 0x72,
|
|
//0x7D, 0x50, 0x02, 0x0D, 0xDF, 0x98, 0x05, 0x18, 0x45, 0xF2, 0x93, 0x51, 0x6F, 0xB6, 0x81, 0x93,
|
|
//0x2E, 0x64, 0x89, 0x31, 0x20, 0x58, 0x14, 0x30, 0x2D, 0x95, 0x1A, 0xA4, 0x40, 0x75, 0xD9, 0xEB,
|
|
//0x67, 0xAD, 0x13, 0xF4, 0x11, 0x2D, 0xDF, 0x40, 0x91, 0xED, 0xCA, 0xE7, 0xEC, 0x99, 0x7D, 0x7A,
|
|
//0x84, 0x71, 0x61, 0x9F, 0x77, 0x9A, 0xC5, 0x93, 0x8D, 0x14, 0x15, 0x5E, 0x51, 0x2B, 0xF4, 0x64,
|
|
//0x60, 0x17, 0xFB, 0x03, 0x7F, 0x3C, 0x5D, 0xE7, 0x66, 0x77, 0x67, 0xA5, 0xFC, 0xD1, 0x10, 0x3C,
|
|
//0x23, 0x91, 0x27, 0x46, 0x9A, 0x8E, 0xF3, 0x51, 0xB6, 0x90, 0x30, 0xCC, 0x6E, 0xD6, 0x15, 0x6F,
|
|
//0x77, 0x58, 0x68, 0xE7, 0x4D, 0xD2, 0x59, 0xE7, 0x55, 0x20, 0x06, 0xC7, 0xBC, 0x89, 0x66, 0x67,
|
|
//0x93, 0xDD, 0xD2, 0x26, 0x32, 0x43, 0x47, 0xEC, 0x67, 0x36, 0x66, 0x40, 0xF9, 0x46, 0x16, 0x6B,
|
|
//0xE8, 0x27, 0x1A, 0xC3, 0x73, 0xD4, 0x39, 0x08, 0x91, 0xCB, 0xA7, 0xEA, 0x03, 0x15, 0x1E, 0xF2,
|
|
//0xCF, 0x49, 0x1A, 0x1D, 0xB3, 0x99, 0x07, 0x83, 0x48, 0x5A, 0x6E, 0x56, 0xE7, 0x4D, 0x6F, 0xAD,
|
|
//0x6E, 0x84, 0x61, 0xC6, 0x04, 0xFA, 0x32, 0x01, 0x27, 0x00, 0xF0, 0x4E, 0xEF, 0x04, 0x78, 0x38,
|
|
//0xA4, 0xC7, 0x85, 0x15, 0x08, 0x40, 0x32, 0x6F, 0x64, 0x10, 0x01, 0x53, 0x75, 0x18, 0x7B, 0x60,
|
|
//0xDE, 0x66, 0x9F, 0x94, 0xF0, 0x35, 0x03, 0x07, 0x64, 0x67, 0xC3, 0x37, 0x28, 0x9D, 0x70, 0x27,
|
|
//0x98, 0x7A, 0xC0, 0x7B, 0xCD, 0x74, 0x97, 0x88, 0xB3, 0x1C, 0x86, 0xB2, 0xCF, 0x29, 0x74, 0x8B,
|
|
//0x0A, 0xEA, 0xBF, 0x7E, 0xF9, 0x1B, 0x81, 0x15, 0xE9, 0x78, 0x1C, 0xC7, 0x55, 0x25, 0xD6, 0x41,
|
|
//0x72, 0xED, 0xC4, 0x88, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x48, 0x30, 0x46, 0x30, 0x44,
|
|
//0x06, 0x03, 0x55, 0x1D, 0x01, 0x04, 0x3D, 0x30, 0x3B, 0x80, 0x10, 0x06, 0x65, 0x0F, 0xFD, 0x3D,
|
|
//0xB0, 0xA6, 0x4C, 0xD6, 0x81, 0xE8, 0x66, 0x39, 0xA4, 0x67, 0x44, 0xA1, 0x15, 0x30, 0x13, 0x31,
|
|
//0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x08, 0x74, 0x65, 0x73, 0x74, 0x6B, 0x65,
|
|
//0x79, 0x32, 0x82, 0x10, 0x1D, 0x30, 0x50, 0xAC, 0xFD, 0xFF, 0xB5, 0xB7, 0x4E, 0xFF, 0xAC, 0x38,
|
|
//0x0E, 0x0F, 0x19, 0xB5, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1D, 0x05, 0x00, 0x03,
|
|
//0x82, 0x01, 0x01, 0x00, 0x1C, 0x74, 0x76, 0x2D, 0x9E, 0x02, 0xB3, 0xFB, 0xFE, 0x00, 0x57, 0x07,
|
|
//0xB4, 0x55, 0x8D, 0x94, 0x24, 0x54, 0xD4, 0x03, 0x2B, 0xBB, 0x7E, 0x22, 0x6F, 0x1F, 0x38, 0x26,
|
|
//0x0A, 0x6B, 0x09, 0x02, 0xB9, 0x37, 0x98, 0x81, 0x5C, 0xF4, 0x71, 0x68, 0xF6, 0xA3, 0x7D, 0x17,
|
|
//0x18, 0xED, 0x00, 0x1D, 0x58, 0xA1, 0xD2, 0x6D, 0x81, 0xF0, 0xC0, 0x27, 0x6C, 0x8F, 0x08, 0xEC,
|
|
//0x00, 0x64, 0xB0, 0xD4, 0x8A, 0x47, 0x70, 0xFD, 0xE2, 0xFC, 0xAF, 0x87, 0x08, 0xC9, 0x23, 0x2F,
|
|
//0xA1, 0x65, 0xC1, 0xA1, 0x70, 0xF1, 0xB0, 0x76, 0x68, 0x7C, 0x6C, 0xEC, 0x24, 0x71, 0x1F, 0x39,
|
|
//0x97, 0x2E, 0xC1, 0xCD, 0x50, 0x22, 0x5B, 0x26, 0xDD, 0xDD, 0xAB, 0x97, 0x83, 0x65, 0x14, 0xBA,
|
|
//0x30, 0x1F, 0x5E, 0xDF, 0x27, 0x17, 0xDA, 0x2F, 0xE6, 0x81, 0x9A, 0x44, 0xAC, 0xD2, 0x72, 0x63,
|
|
//0x4C, 0x8D, 0x63, 0xF5, 0x24, 0x61, 0xA4, 0x52, 0x22, 0x57, 0x42, 0x1C, 0x35, 0x00, 0xCE, 0xED,
|
|
//0xAB, 0xC2, 0x53, 0xAB, 0xE0, 0x1B, 0x04, 0x43, 0x2D, 0xC9, 0x94, 0xB3, 0x02, 0xB6, 0x26, 0x53,
|
|
//0xC2, 0xF7, 0xB9, 0xA6, 0xB9, 0x10, 0xFB, 0xAF, 0x88, 0x0A, 0xE2, 0xBE, 0x67, 0x5E, 0xAE, 0x9D,
|
|
//0xB9, 0x20, 0x9E, 0xFD, 0x52, 0x15, 0x59, 0x34, 0x40, 0x65, 0xDB, 0xB3, 0xEB, 0x9E, 0x69, 0x5F,
|
|
//0xB6, 0x8C, 0x86, 0xF9, 0xA1, 0x5F, 0xD7, 0x8C, 0xAA, 0x5A, 0x98, 0x48, 0x11, 0x95, 0x05, 0xCA,
|
|
//0x7B, 0xDB, 0xD0, 0x3A, 0xC0, 0x8A, 0x1D, 0xF1, 0x4C, 0x92, 0x80, 0x90, 0xAA, 0x58, 0x81, 0x60,
|
|
//0x7F, 0xEC, 0x86, 0x69, 0x58, 0xE8, 0xAF, 0xDA, 0xAB, 0x06, 0xED, 0xAA, 0x2A, 0xEB, 0x63, 0xD5,
|
|
//0x46, 0xF9, 0x51, 0x3B, 0x76, 0x55, 0x0B, 0xE3, 0xFE, 0xD5, 0x53, 0x36, 0x14, 0x25, 0xEA, 0x09,
|
|
//0xEC, 0x7C, 0x17, 0x54
|
|
//};
|
|
//
|
|
//
|
|
///**
|
|
//Internal function uses input certificate, certificate size and update type to create
|
|
//output EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
//
|
|
//@param[in] InputBuffer The content of input certificate.
|
|
//@param[in] InputSize The size in bytes of the input certificate.
|
|
//@param[in] OwnerGuid Input owner guid for the input signature owner. If OwnerGuid is NULL, the owner GUID
|
|
// will be set to all ZERO.
|
|
//@param[in] UpdateType The Input update type. This update type should be UPDATE_AUTHENTICATED_VARIABLE
|
|
// or APPEND_AUTHENTICATED_VARIABLE.
|
|
//@param[out] OutputBuffer A pointer to the output buffer to save the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
// This buffer is allocated with a call to the Boot Service AllocatePool(). It is the
|
|
// caller's responsibility to call the Boot Service FreePool() when the caller no longer
|
|
// requires the contents of Buffer.
|
|
//@param[out] OutPutSize The size in bytes of the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
//
|
|
//@retval EFI_SUCCESS Create EFI_VARIABLE_AUTHENTICATION_2 descriptor successfully.
|
|
//@retval EFI_INVALID_PARAMETER Any input parameter in incorrect.
|
|
//@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
//**/
|
|
//STATIC
|
|
//EFI_STATUS
|
|
//CreateAuthenData (
|
|
//IN UINT8 *InputBuffer,
|
|
//IN UINTN InputSize,
|
|
//IN EFI_GUID *OwnerGuid, OPTIONAL
|
|
//IN UINTN UpdateType,
|
|
//OUT UINT8 **OutputBuffer,
|
|
//OUT UINTN *OutPutSize
|
|
//)
|
|
//{
|
|
//UINTN BufferSize;
|
|
//UINT8 *Buffer;
|
|
//EFI_SIGNATURE_LIST *SigList;
|
|
//EFI_SIGNATURE_DATA *SigData;
|
|
//
|
|
//if (OutputBuffer == NULL || OutPutSize == NULL) {
|
|
// return EFI_INVALID_PARAMETER;
|
|
//}
|
|
//
|
|
//if (UpdateType != UPDATE_AUTHENTICATED_VARIABLE && UpdateType != APPEND_AUTHENTICATED_VARIABLE) {
|
|
// return EFI_INVALID_PARAMETER;
|
|
//}
|
|
//if (InputBuffer == NULL) {
|
|
// InputSize = 0;
|
|
//}
|
|
//
|
|
//if (InputSize != 0) {
|
|
// BufferSize = sizeof (mDefaultHeaderData) + sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + InputSize;
|
|
//} else {
|
|
// BufferSize = sizeof (mDefaultHeaderData);
|
|
//}
|
|
//Buffer = AllocateZeroPool (BufferSize);
|
|
//if (Buffer == NULL) {
|
|
// return EFI_OUT_OF_RESOURCES;
|
|
//}
|
|
////
|
|
//// Update header data and set udpate type (update or append)
|
|
////
|
|
//CopyMem (Buffer, mDefaultHeaderData, sizeof (mDefaultHeaderData));
|
|
//*(Buffer + sizeof (mDefaultHeaderData) - sizeof (UINT8)) = (UINT8) UpdateType;
|
|
//
|
|
//if (InputSize != 0) {
|
|
// SigList = (EFI_SIGNATURE_LIST *) (Buffer + sizeof (mDefaultHeaderData));
|
|
// CopyMem (&SigList->SignatureType, &gEfiCertX509Guid, sizeof (EFI_GUID));
|
|
// SigList->SignatureListSize = (UINT32) (InputSize + sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1);
|
|
// SigList->SignatureSize = (UINT32) (InputSize + sizeof (EFI_GUID));
|
|
//
|
|
// SigData = (EFI_SIGNATURE_DATA*) (SigList + 1);
|
|
// //
|
|
// // Set signature owner according to input owner GUID. Otherwise, keep this signature owner GUID
|
|
// // as all zero.
|
|
// //
|
|
// if (OwnerGuid != NULL) {
|
|
// CopyMem (&SigData->SignatureOwner, OwnerGuid, sizeof (EFI_GUID));
|
|
// }
|
|
// CopyMem (SigData->SignatureData, InputBuffer, InputSize);
|
|
//}
|
|
//*OutputBuffer = Buffer;
|
|
//*OutPutSize = BufferSize;
|
|
//return EFI_SUCCESS;
|
|
//}
|
|
/**
|
|
Internal function uses input variable data, variable data size and update type to create
|
|
output EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
|
|
@param[in] VarData The content of input variable data.
|
|
@param[in] VarDataSize The size in bytes of the input variable data.
|
|
@param[in] UpdateType The Input update type. This update type should be UPDATE_AUTHENTICATED_VARIABLE
|
|
or APPEND_AUTHENTICATED_VARIABLE.
|
|
@param[out] AuthenVarData A pointer to the output buffer to save the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
This buffer is allocated with a call to the Boot Service AllocatePool(). It is the
|
|
caller's responsibility to call the Boot Service FreePool() when the caller no longer
|
|
requires the contents of Buffer.
|
|
@param[out] AuthenVarDataSize The size in bytes of the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
|
|
@retval EFI_SUCCESS Create EFI_VARIABLE_AUTHENTICATION_2 descriptor successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter in incorrect.
|
|
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
CreateAuthenVarData (
|
|
IN UINT8 *VarData,
|
|
IN UINTN VarDataSize,
|
|
IN UINTN UpdateType,
|
|
OUT UINT8 **AuthenVarData,
|
|
OUT UINTN *AuthenVarDataSize
|
|
)
|
|
{
|
|
UINTN BufferSize;
|
|
UINT8 *Buffer;
|
|
|
|
if (AuthenVarData == NULL || AuthenVarDataSize == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (VarData == NULL) {
|
|
VarDataSize = 0;
|
|
}
|
|
|
|
BufferSize = sizeof (mDefaultHeaderData) + VarDataSize;
|
|
Buffer = AllocateZeroPool (BufferSize);
|
|
if (Buffer == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
CopyMem (Buffer, mDefaultHeaderData, sizeof (mDefaultHeaderData));
|
|
*(Buffer + sizeof (mDefaultHeaderData) - sizeof (UINT8)) = (UINT8) UpdateType;
|
|
CopyMem (Buffer + sizeof (mDefaultHeaderData), VarData, VarDataSize);
|
|
|
|
*AuthenVarData = Buffer;
|
|
*AuthenVarDataSize = BufferSize;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Function uses input variable data and size to update PK variable through SMI.
|
|
This update will not do any certification check no matter system is in setup mode or
|
|
user mode.
|
|
|
|
@param[in] VarData The content of input variable data.
|
|
@param[in] VarDataSize The size in bytes of the input variable data.
|
|
|
|
@retval EFI_SUCCESS Update input variable data to PK variable successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter in incorrect.
|
|
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
**/
|
|
EFI_STATUS
|
|
UpdatePkVariable (
|
|
IN UINT8 *VarData,
|
|
IN UINTN VarDataSize
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 *Buffer;
|
|
UINTN BufferSize;
|
|
|
|
Status = CreateAuthenVarData (VarData, VarDataSize, UPDATE_AUTHENTICATED_VARIABLE, &Buffer, &BufferSize);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (IsSmmModeSupported ()) {
|
|
SmmSecureBootCallWithRuntimeMemory (
|
|
Buffer,
|
|
BufferSize,
|
|
UPDATE_PK_FUN_NUM
|
|
);
|
|
} else {
|
|
Status = gRT->SetVariable (
|
|
EFI_PLATFORM_KEY_NAME,
|
|
&gEfiGlobalVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
|
|
BufferSize,
|
|
Buffer
|
|
);
|
|
}
|
|
|
|
FreePool (Buffer);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Function uses input variable data and size to update KEK variable through SMI.
|
|
This update will not do any certification check no matter system is in setup mode or
|
|
user mode.
|
|
|
|
@param[in] VarData The content of input variable data.
|
|
@param[in] VarDataSize The size in bytes of the input variable data.
|
|
@param[in] UpdateType The Input update type. This update type should be UPDATE_AUTHENTICATED_VARIABLE
|
|
or APPEND_AUTHENTICATED_VARIABLE.
|
|
|
|
@retval EFI_SUCCESS Update input variable data to KEK variable successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter in incorrect.
|
|
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
**/
|
|
EFI_STATUS
|
|
UpdateKekVariable (
|
|
IN UINT8 *VarData,
|
|
IN UINTN VarDataSize,
|
|
IN UINTN UpdateType
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 *Buffer;
|
|
UINTN BufferSize;
|
|
UINT32 Attribute;
|
|
|
|
if (UpdateType != UPDATE_AUTHENTICATED_VARIABLE && UpdateType != APPEND_AUTHENTICATED_VARIABLE) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = CreateAuthenVarData (VarData, VarDataSize, UpdateType, &Buffer, &BufferSize);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (IsSmmModeSupported ()) {
|
|
SmmSecureBootCallWithRuntimeMemory (
|
|
Buffer,
|
|
BufferSize,
|
|
UPDATE_KEK_FUN_NUM
|
|
);
|
|
} else {
|
|
Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
|
|
if (UpdateType == APPEND_AUTHENTICATED_VARIABLE) {
|
|
Attribute |= EFI_VARIABLE_APPEND_WRITE;
|
|
}
|
|
Status = gRT->SetVariable (
|
|
EFI_KEY_EXCHANGE_KEY_NAME,
|
|
&gEfiGlobalVariableGuid,
|
|
Attribute,
|
|
BufferSize,
|
|
Buffer
|
|
);
|
|
}
|
|
|
|
FreePool (Buffer);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Get variable name based on input function index.
|
|
|
|
@param[in] FunctionIndex Input function index.
|
|
|
|
return Variable name or NULL if input function index isn't supported.
|
|
**/
|
|
STATIC
|
|
CHAR16 *
|
|
GetVariableNameFromFunctionIndex (
|
|
IN UINT8 FunctionIndex
|
|
)
|
|
{
|
|
UINTN Index;
|
|
UINTN Count;
|
|
|
|
Count = sizeof (mIndexNameMap) / sizeof (INDEX_NAME_MAP);
|
|
|
|
for (Index = 0; Index < Count; Index++) {
|
|
if (FunctionIndex == mIndexNameMap[Index].FunctionIndex) {
|
|
return mIndexNameMap[Index].VariableName;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
Function uses input variable data and size to update common secure boot variable through SMI.
|
|
This update will not do any certification check no matter system is in setup mode or
|
|
user mode.
|
|
|
|
@param[in] VarData The content of input variable data.
|
|
@param[in] VarDataSize The size in bytes of the input variable data.
|
|
@param[in] UpdateType The Input update type. This update type should be UPDATE_AUTHENTICATED_VARIABLE
|
|
or APPEND_AUTHENTICATED_VARIABLE.
|
|
@param[in] FunctionIndex Input function index.
|
|
|
|
@retval EFI_SUCCESS Update input variable data to common secure boot variable variable successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter in incorrect.
|
|
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
UpdateCommonSecureBootVariable (
|
|
IN UINT8 *VarData,
|
|
IN UINTN VarDataSize,
|
|
IN UINTN UpdateType,
|
|
IN UINT8 FunctionIndex
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 *Buffer;
|
|
UINTN BufferSize;
|
|
UINT32 Attribute;
|
|
|
|
if (UpdateType != UPDATE_AUTHENTICATED_VARIABLE && UpdateType != APPEND_AUTHENTICATED_VARIABLE) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (FunctionIndex != UPDATE_DB_FUN_NUM && FunctionIndex != UPDATE_DBX_FUN_NUM &&
|
|
FunctionIndex != UPDATE_DBT_FUN_NUM && FunctionIndex != UPDATE_DBR_FUN_NUM) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = CreateAuthenVarData (VarData, VarDataSize, UpdateType, &Buffer, &BufferSize);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (IsSmmModeSupported ()) {
|
|
SmmSecureBootCallWithRuntimeMemory (
|
|
Buffer,
|
|
BufferSize,
|
|
FunctionIndex
|
|
);
|
|
} else {
|
|
Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
|
|
if (UpdateType == APPEND_AUTHENTICATED_VARIABLE) {
|
|
Attribute |= EFI_VARIABLE_APPEND_WRITE;
|
|
}
|
|
Status = gRT->SetVariable (
|
|
GetVariableNameFromFunctionIndex (FunctionIndex),
|
|
&gEfiImageSecurityDatabaseGuid,
|
|
Attribute,
|
|
BufferSize,
|
|
Buffer
|
|
);
|
|
}
|
|
|
|
FreePool (Buffer);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Function uses input variable data and size to update db variable through SMI.
|
|
This update will not do any certification check no matter system is in setup mode or
|
|
user mode.
|
|
|
|
@param[in] VarData The content of input variable data.
|
|
@param[in] VarDataSize The size in bytes of the input variable data.
|
|
@param[in] UpdateType The Input update type. This update type should be UPDATE_AUTHENTICATED_VARIABLE
|
|
or APPEND_AUTHENTICATED_VARIABLE.
|
|
|
|
@retval EFI_SUCCESS Update input variable data to db variable successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter in incorrect.
|
|
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
**/
|
|
EFI_STATUS
|
|
UpdateDbVariable (
|
|
IN UINT8 *VarData,
|
|
IN UINTN VarDataSize,
|
|
IN UINTN UpdateType
|
|
)
|
|
{
|
|
return UpdateCommonSecureBootVariable (VarData, VarDataSize, UpdateType, UPDATE_DB_FUN_NUM);
|
|
}
|
|
|
|
/**
|
|
Function uses input variable data and size to update dbx variable through SMI.
|
|
This update will not do any certification check no matter system is in setup mode or
|
|
user mode.
|
|
|
|
@param[in] InputBuffer The content of input certificate.
|
|
@param[in] InputSize The size in bytes of the input certificate.
|
|
@param[in] OwnerGuid Input owner guid for the input signature owner. If OwnerGuid is NULL, the owner GUID
|
|
will be set to all ZERO.
|
|
@param[in] UpdateType The Input update type. This update type should be UPDATE_AUTHENTICATED_VARIABLE
|
|
or APPEND_AUTHENTICATED_VARIABLE.
|
|
|
|
@retval EFI_SUCCESS Update input certificate to dbx variable successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter in incorrect.
|
|
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
**/
|
|
EFI_STATUS
|
|
UpdateDbxVariable (
|
|
IN UINT8 *VarData,
|
|
IN UINTN VarDataSize,
|
|
IN UINTN UpdateType
|
|
)
|
|
{
|
|
return UpdateCommonSecureBootVariable (VarData, VarDataSize, UpdateType, UPDATE_DBX_FUN_NUM);
|
|
}
|
|
|
|
/**
|
|
Function uses input variable data and size to update dbt variable through SMI.
|
|
This update will not do any certification check no matter system is in setup mode or
|
|
user mode.
|
|
|
|
@param[in] InputBuffer The content of input certificate.
|
|
@param[in] InputSize The size in bytes of the input certificate.
|
|
@param[in] OwnerGuid Input owner guid for the input signature owner. If OwnerGuid is NULL, the owner GUID
|
|
will be set to all ZERO.
|
|
@param[in] UpdateType The Input update type. This update type should be UPDATE_AUTHENTICATED_VARIABLE
|
|
or APPEND_AUTHENTICATED_VARIABLE.
|
|
|
|
@retval EFI_SUCCESS Update input certificate to dbx variable successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter in incorrect.
|
|
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
**/
|
|
EFI_STATUS
|
|
UpdateDbtVariable (
|
|
IN UINT8 *VarData,
|
|
IN UINTN VarDataSize,
|
|
IN UINTN UpdateType
|
|
)
|
|
{
|
|
return UpdateCommonSecureBootVariable (VarData, VarDataSize, UpdateType, UPDATE_DBT_FUN_NUM);
|
|
}
|
|
|
|
|
|
/**
|
|
Function uses input input variable data and size to update dbr variable through SMI.
|
|
This update will not do any certification check no matter system is in setup mode or
|
|
user mode.
|
|
|
|
@param[in] InputBuffer The content of input certificate.
|
|
@param[in] InputSize The size in bytes of the input certificate.
|
|
@param[in] OwnerGuid Input owner guid for the input signature owner. If OwnerGuid is NULL, the owner GUID
|
|
will be set to all ZERO.
|
|
@param[in] UpdateType The Input update type. This update type should be UPDATE_AUTHENTICATED_VARIABLE
|
|
or APPEND_AUTHENTICATED_VARIABLE.
|
|
|
|
@retval EFI_SUCCESS Update input certificate to dbx variable successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter in incorrect.
|
|
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
|
**/
|
|
EFI_STATUS
|
|
UpdateDbrVariable (
|
|
IN UINT8 *VarData,
|
|
IN UINTN VarDataSize,
|
|
IN UINTN UpdateType
|
|
)
|
|
{
|
|
return UpdateCommonSecureBootVariable (VarData, VarDataSize, UpdateType, UPDATE_DBR_FUN_NUM);
|
|
}
|
|
|
|
/**
|
|
This function uses to check system whether supports SMM mode or not.
|
|
|
|
@retval TRUE System supports SMM mode
|
|
@retval FALSE System doesn't support SMM mode.
|
|
**/
|
|
STATIC
|
|
BOOLEAN
|
|
IsSmmModeSupported (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_SMM_BASE2_PROTOCOL *SmmBase;
|
|
BOOLEAN SmmSupport;
|
|
EFI_STATUS Status;
|
|
|
|
SmmSupport =FALSE;
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiSmmBase2ProtocolGuid,
|
|
NULL,
|
|
(VOID **) &SmmBase
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
SmmSupport = TRUE;
|
|
}
|
|
|
|
return SmmSupport;
|
|
}
|
|
|
|
/**
|
|
Check if the input question ID is a VFR goto question or not.
|
|
|
|
@param[in] QuestionId The question ID
|
|
|
|
@retval TRUE The input question ID is a VFR goto question.
|
|
@retval FALSE The input question ID is not a VFR goto question.
|
|
**/
|
|
STATIC
|
|
BOOLEAN
|
|
IsGotoQuestion (
|
|
IN EFI_QUESTION_ID QuestionId
|
|
)
|
|
{
|
|
if (QuestionId == KEY_ENROLL_HASH ||
|
|
QuestionId == KEY_ENROLL_PK ||
|
|
QuestionId == KEY_ENROLL_KEK ||
|
|
QuestionId == KEY_ENROLL_DB ||
|
|
QuestionId == KEY_ENROLL_DBX ||
|
|
QuestionId == KEY_ENROLL_DBT ||
|
|
QuestionId == KEY_ENROLL_DBR ||
|
|
QuestionId == KEY_PK_FORM ||
|
|
QuestionId == KEY_KEK_FORM ||
|
|
QuestionId == KEY_DB_FORM ||
|
|
QuestionId == KEY_DBX_FORM ||
|
|
QuestionId == KEY_DBT_FORM ||
|
|
QuestionId == KEY_DBR_FORM) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
Update AddHashImage variable by enumerating all hash images from hash linked list.
|
|
|
|
@retval EFI_SUCCESS Update AddHashImage variable successfully.
|
|
**/
|
|
EFI_STATUS
|
|
UpdateAddHashImageVariable (
|
|
VOID
|
|
)
|
|
{
|
|
LIST_ENTRY *Link;
|
|
HASH_LINK_LIST *HashLink;
|
|
UINTN BufferSize;
|
|
|
|
while (!IsListEmpty (&mSecureBootHashLinkList)) {
|
|
Link = mSecureBootHashLinkList.ForwardLink;
|
|
HashLink = CR (Link, HASH_LINK_LIST, Link, HASH_LINK_LIST_SIGNATURE);
|
|
if (HashLink->ShaType == HASHALG_SHA256) {
|
|
BufferSize = sizeof (mEnrollHashSha256Data);
|
|
CopyMem (
|
|
(VOID *) &mEnrollHashSha256Data[BufferSize - sizeof (EFI_SHA256_HASH)],
|
|
(VOID*) HashLink->Hash,
|
|
sizeof (EFI_SHA256_HASH)
|
|
);
|
|
if (IsSmmModeSupported ()) {
|
|
SmmSecureBootCallWithRuntimeMemory (
|
|
mEnrollHashSha256Data,
|
|
BufferSize,
|
|
ADD_HASH_IMAGE_FUN_NUM
|
|
);
|
|
} else {
|
|
gRT->SetVariable (
|
|
EFI_ADD_HASH_IMMAGE_NAME,
|
|
&gEfiGenericVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
|
|
| EFI_VARIABLE_APPEND_WRITE,
|
|
BufferSize,
|
|
mEnrollHashSha256Data
|
|
);
|
|
}
|
|
} else {
|
|
BufferSize = sizeof (mEnrollHashSha1Data);
|
|
CopyMem (
|
|
(VOID *) &mEnrollHashSha1Data[BufferSize - sizeof (EFI_SHA1_HASH)],
|
|
(VOID*) HashLink->Hash,
|
|
sizeof (EFI_SHA1_HASH)
|
|
);
|
|
if (IsSmmModeSupported ()) {
|
|
SmmSecureBootCallWithRuntimeMemory (
|
|
mEnrollHashSha1Data,
|
|
BufferSize,
|
|
ADD_HASH_IMAGE_FUN_NUM
|
|
);
|
|
} else {
|
|
gRT->SetVariable (
|
|
EFI_ADD_HASH_IMMAGE_NAME,
|
|
&gEfiGenericVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
|
|
| EFI_VARIABLE_APPEND_WRITE,
|
|
BufferSize,
|
|
mEnrollHashSha1Data
|
|
);
|
|
|
|
}
|
|
}
|
|
RemoveEntryList (Link);
|
|
FreePool (HashLink);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This function uses to save all of administer secure boot settings
|
|
|
|
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
|
|
|
@retval EFI_SUCCESS The Results is processed successfully.
|
|
@retval EFI_INVALID_PARAMETER Configuration is NULL.
|
|
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
SecureBootSaveChange (
|
|
IN EFI_HII_CONFIG_ACCESS_PROTOCOL *This
|
|
)
|
|
{
|
|
SECURE_BOOT_MANAGER_CALLBACK_DATA *PrivateData;
|
|
UINTN BufferSize;
|
|
UINT8 EnforceSecureBoot;
|
|
UINT8 ResotreFactory;
|
|
|
|
if (This == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
PrivateData = SECURE_BOOT_CALLBACK_DATA_FROM_THIS (This);
|
|
HiiGetBrowserData (NULL, NULL, sizeof (SECURE_BOOT_NV_DATA), (UINT8 *) &PrivateData->SecureBootData);
|
|
|
|
if (PcdGetBool (PcdH2OUefiCaCertificateSetupAddSupported)) {
|
|
if (PrivateData->SecureBootData.AddUefiCaCertificate != PrivateData->BackupSecureBootData.AddUefiCaCertificate &&
|
|
PrivateData->SecureBootData.AddUefiCaCertificate == 1) {
|
|
AddUefiCaCertificateToDb ();
|
|
PrivateData->BackupSecureBootData.UefiCaCertificateInDb = PrivateData->SecureBootData.UefiCaCertificateInDb;
|
|
}
|
|
}
|
|
|
|
SecureBootVarSaveChange ();
|
|
UpdateAddHashImageVariable ();
|
|
|
|
if (PcdGetBool (PcdH2OSecureBootDisableSupported) &&
|
|
PrivateData->SecureBootData.EnforceSecureBoot != PrivateData->BackupSecureBootData.EnforceSecureBoot) {
|
|
EnforceSecureBoot = PrivateData->SecureBootData.EnforceSecureBoot;
|
|
BufferSize = sizeof (mDefaultAthenData);
|
|
mDefaultAthenData[BufferSize - 1] = (EnforceSecureBoot == 1) ? 1 : 0;
|
|
if (IsSmmModeSupported ()) {
|
|
SmmSecureBootCallWithRuntimeMemory (
|
|
mDefaultAthenData,
|
|
BufferSize,
|
|
SECURE_BOOT_ENFORCE_FUN_NUM
|
|
);
|
|
} else {
|
|
gRT->SetVariable (
|
|
EFI_SECURE_BOOT_ENFORCE_NAME,
|
|
&gEfiGenericVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,
|
|
BufferSize,
|
|
mDefaultAthenData
|
|
);
|
|
}
|
|
PrivateData->BackupSecureBootData.EnforceSecureBoot = PrivateData->SecureBootData.EnforceSecureBoot;
|
|
}
|
|
|
|
if (PcdGetBool (PcdH2OSecureBootDisableSupported) && PrivateData->SecureBootData.ClearSecureSettings == 1) {
|
|
if (IsSmmModeSupported ()) {
|
|
SmmSecureBootCallWithRuntimeMemory (
|
|
NULL,
|
|
0,
|
|
CLEAR_ALL_SECURE_SETTINGS_FUN_NUM
|
|
);
|
|
} else {
|
|
BufferSize = sizeof (mDefaultAthenData);
|
|
mDefaultAthenData[BufferSize - 1] = 1;
|
|
gRT->SetVariable (
|
|
EFI_CLEAR_ALL_SECURE_SETTINGS_NAME,
|
|
&gEfiGenericVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,
|
|
BufferSize,
|
|
mDefaultAthenData
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Move saved restore factory default to the last. This action can make sure system can set CustomSecurity variable to 0 correctly,
|
|
// even if user also changes ClearSecureSettings or add hash to db.
|
|
//
|
|
if (PrivateData->SecureBootData.ResotreFactorySettings != PrivateData->BackupSecureBootData.ResotreFactorySettings) {
|
|
ResotreFactory = PrivateData->SecureBootData.ResotreFactorySettings;
|
|
BufferSize = sizeof (mDefaultAthenData);
|
|
mDefaultAthenData[BufferSize - 1] = (ResotreFactory == 1) ? 1 : 0;
|
|
if (IsSmmModeSupported ()) {
|
|
SmmSecureBootCallWithRuntimeMemory (
|
|
mDefaultAthenData,
|
|
BufferSize,
|
|
RESTORE_FACTORY_DEFAULT_FUN_NUM
|
|
);
|
|
} else {
|
|
gRT->SetVariable (
|
|
EFI_RESTORE_FACTORY_DEFAULT_NAME,
|
|
&gEfiGenericVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,
|
|
BufferSize,
|
|
mDefaultAthenData
|
|
);
|
|
}
|
|
PrivateData->BackupSecureBootData.ResotreFactorySettings = PrivateData->SecureBootData.ResotreFactorySettings;
|
|
}
|
|
|
|
if (!FeaturePcdGet (PcdH2OCustomizedSecureBootSupported)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if (PrivateData->SecureBootData.SelectSecureBootMode != PrivateData->SecureBootData.BackupSelectSecureBootMode) {
|
|
BufferSize = sizeof (mDefaultAthenData);
|
|
mDefaultAthenData[BufferSize - 1] = PrivateData->SecureBootData.SelectSecureBootMode;
|
|
SmmSecureBootCallWithRuntimeMemory (
|
|
mDefaultAthenData,
|
|
BufferSize,
|
|
SELECT_SECURE_BOOT_MODE_FUN_NUM
|
|
);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This function uses to get current secur boot mode.
|
|
|
|
@return SecureBootMode Current secure boot mode.
|
|
**/
|
|
STATIC
|
|
UINT8
|
|
GetSecureBootMode (
|
|
VOID
|
|
)
|
|
{
|
|
if (mSecureBootPrivate.SecureBootData.DeployedMode == 1) {
|
|
return H2O_DEPLOYED_MODE;
|
|
} else if (mSecureBootPrivate.SecureBootData.AuditMode == 1) {
|
|
return H2O_AUDIT_MODE;
|
|
} else if (mSecureBootPrivate.SecureBootData.SetupMode == 0) {
|
|
return H2O_USER_MODE;
|
|
} else {
|
|
return H2O_SETUP_MODE;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
Initialize all of system status in Administer Secure Boot menu.
|
|
|
|
@retval EFI_SUCCESS Initialize secure boot system status successful.
|
|
@retval EFI_NOT_FOUND Cannot find any variable for secure boot system status.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
InitializeSystemStatus (
|
|
VOID
|
|
)
|
|
{
|
|
UINTN BufferSize;
|
|
UINT8 Data;
|
|
EFI_STATUS Status;
|
|
LIST_ENTRY *Link;
|
|
HASH_LINK_LIST *HashLink;
|
|
|
|
while (!IsListEmpty (&mSecureBootHashLinkList)) {
|
|
Link = mSecureBootHashLinkList.ForwardLink;
|
|
HashLink = CR (Link, HASH_LINK_LIST, Link, HASH_LINK_LIST_SIGNATURE);
|
|
RemoveEntryList (Link);
|
|
FreePool (HashLink);
|
|
}
|
|
|
|
SecureBootVarInit ();
|
|
|
|
BufferSize = sizeof (UINT8);
|
|
Status = gRT->GetVariable (
|
|
EFI_SETUP_MODE_NAME,
|
|
&gEfiGlobalVariableGuid,
|
|
NULL,
|
|
&BufferSize,
|
|
&Data
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mSecureBootPrivate.SecureBootData.SetupMode = Data;
|
|
mSecureBootPrivate.BackupSecureBootData.SetupMode = Data;
|
|
|
|
|
|
mSecureBootPrivate.SecureBootData.AddUefiCaCertificate = 0;
|
|
mSecureBootPrivate.BackupSecureBootData.AddUefiCaCertificate = 0;
|
|
if (!IsUefiCaCertificateInDb () && Data == 0) {
|
|
mSecureBootPrivate.SecureBootData.UefiCaCertificateInDb = 0;
|
|
mSecureBootPrivate.BackupSecureBootData.UefiCaCertificateInDb = 0;
|
|
} else {
|
|
mSecureBootPrivate.SecureBootData.UefiCaCertificateInDb = 1;
|
|
mSecureBootPrivate.BackupSecureBootData.UefiCaCertificateInDb = 1;
|
|
}
|
|
|
|
BufferSize = sizeof (UINT8);
|
|
Status = gRT->GetVariable (
|
|
EFI_SECURE_BOOT_MODE_NAME,
|
|
&gEfiGlobalVariableGuid,
|
|
NULL,
|
|
&BufferSize,
|
|
&Data
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mSecureBootPrivate.SecureBootData.SecureBoot = Data;
|
|
mSecureBootPrivate.BackupSecureBootData.SecureBoot = Data;
|
|
|
|
BufferSize = sizeof (UINT8);
|
|
Status = gRT->GetVariable (
|
|
EFI_CUSTOM_SECURITY_NAME,
|
|
&gEfiGenericVariableGuid,
|
|
NULL,
|
|
&BufferSize,
|
|
&Data
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mSecureBootPrivate.SecureBootData.CustomSecurity = Data;
|
|
mSecureBootPrivate.BackupSecureBootData.CustomSecurity = Data;
|
|
|
|
mSecureBootPrivate.SecureBootData.ClearSecureSettings = 0;
|
|
mSecureBootPrivate.BackupSecureBootData.ClearSecureSettings = 0;
|
|
|
|
BufferSize = sizeof (UINT8);
|
|
Status = gRT->GetVariable (
|
|
EFI_RESTORE_FACTORY_DEFAULT_NAME,
|
|
&gEfiGenericVariableGuid,
|
|
NULL,
|
|
&BufferSize,
|
|
&Data
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
Data = 0;
|
|
}
|
|
mSecureBootPrivate.SecureBootData.ResotreFactorySettings = Data;
|
|
mSecureBootPrivate.BackupSecureBootData.ResotreFactorySettings = Data;
|
|
|
|
//
|
|
// Initialize secure boot data
|
|
//
|
|
mSecureBootPrivate.SecureBootData.EnforceSecureBoot = 1;
|
|
mSecureBootPrivate.BackupSecureBootData.EnforceSecureBoot = 1;
|
|
BufferSize = sizeof (UINT8);
|
|
Status = gRT->GetVariable (
|
|
EFI_SECURE_BOOT_ENFORCE_NAME,
|
|
&gEfiGenericVariableGuid,
|
|
NULL,
|
|
&BufferSize,
|
|
&Data
|
|
);
|
|
if (!EFI_ERROR (Status) && Data == 0) {
|
|
mSecureBootPrivate.SecureBootData.EnforceSecureBoot = 0;
|
|
mSecureBootPrivate.BackupSecureBootData.EnforceSecureBoot = 0;
|
|
}
|
|
|
|
if (!FeaturePcdGet (PcdH2OCustomizedSecureBootSupported)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
BufferSize = sizeof (UINT8);
|
|
Status = gRT->GetVariable (
|
|
L"AuditMode",
|
|
&gEfiGlobalVariableGuid,
|
|
NULL,
|
|
&BufferSize,
|
|
&Data
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mSecureBootPrivate.SecureBootData.AuditMode = Data;
|
|
mSecureBootPrivate.BackupSecureBootData.AuditMode = Data;
|
|
|
|
BufferSize = sizeof (UINT8);
|
|
Status = gRT->GetVariable (
|
|
L"DeployedMode",
|
|
&gEfiGlobalVariableGuid,
|
|
NULL,
|
|
&BufferSize,
|
|
&Data
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mSecureBootPrivate.SecureBootData.DeployedMode = Data;
|
|
mSecureBootPrivate.BackupSecureBootData.DeployedMode = Data;
|
|
|
|
mSecureBootPrivate.SecureBootData.SelectSecureBootMode = GetSecureBootMode ();
|
|
mSecureBootPrivate.SecureBootData.BackupSelectSecureBootMode = GetSecureBootMode ();
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
Initialize HII information for the FrontPage
|
|
|
|
@retval EFI_SUCCESS Initialize HII information successful
|
|
|
|
**/
|
|
EFI_STATUS
|
|
InitializeSecureBoot (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
//
|
|
// Install Device Path Protocol and Config Access protocol to driver handle
|
|
//
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
&mSecureBootPrivate.DriverHandle,
|
|
&gEfiDevicePathProtocolGuid,
|
|
&mSecureBootHiiVendorDevicePath,
|
|
&gEfiHiiConfigAccessProtocolGuid,
|
|
&mSecureBootPrivate.ConfigAccess,
|
|
NULL
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//
|
|
// Publish our HII data
|
|
//
|
|
mSecureBootPrivate.HiiHandle = HiiAddPackages (
|
|
&mSecureBootGuid,
|
|
mSecureBootPrivate.DriverHandle,
|
|
SecureBootMgrVfrBin,
|
|
SecureBootMgrDxeStrings,
|
|
SecureBootMgrDxeImages,
|
|
NULL
|
|
);
|
|
if (mSecureBootPrivate.HiiHandle == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
Status = gBS->LocateProtocol (
|
|
&gH2ODialogProtocolGuid,
|
|
NULL,
|
|
(VOID **) &mSecureBootPrivate.H2ODialog
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
InitializeListHead (&mSecureBootFsOptionMenu.Head);
|
|
InitializeListHead (&mSecureBootDirectoryMenu.Head);
|
|
|
|
mSecureBootFileOptionStrDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY));
|
|
mSecureBootSigOptionStrDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY));
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Clear the enroll signature GUID sting in HII database and NV data.
|
|
|
|
@param[in] PrivateData Pointer to SECURE_BOOT_MANAGER_CALLBACK_DATA instance
|
|
@param[in] EnrollSigGuidStrId String ID of enroll signature GUID
|
|
|
|
@retval EFI_SUCCESS Clear the enroll signature GUID sting successfully.
|
|
@retval EFI_INVALID_PARAMETER Input parameter is NULL or invalid.
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
ClearEnrollSigGuidStrInHiiDatabase (
|
|
IN SECURE_BOOT_MANAGER_CALLBACK_DATA *PrivateData,
|
|
IN EFI_STRING_ID EnrollSigGuidStrId
|
|
)
|
|
{
|
|
if (PrivateData == NULL || EnrollSigGuidStrId == 0) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
HiiSetString (PrivateData->HiiHandle, EnrollSigGuidStrId, L"", NULL);
|
|
|
|
ZeroMem (PrivateData->SecureBootData.EnrollSigGuidStr, sizeof (PrivateData->SecureBootData.EnrollSigGuidStr));
|
|
HiiSetBrowserData (
|
|
NULL,
|
|
NULL,
|
|
sizeof (SECURE_BOOT_NV_DATA),
|
|
(UINT8 *) &PrivateData->SecureBootData,
|
|
NULL
|
|
);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Update the enroll signature GUID of secure boot manager based on input question ID.
|
|
|
|
@param[in] HiiHandle HII handle
|
|
@param[in] EnrollSigGuidStrId String ID of enroll signature GUID
|
|
@param[out] EnrollSigOwnerGuid Returns the enroll signature GUID
|
|
|
|
@retval EFI_SUCCESS Update the enroll signature GUID successfully.
|
|
@retval EFI_INVALID_PARAMETER Input parameter is NULL or invalid.
|
|
@retval EFI_NOT_FOUND Failed to get enroll signature GUID string .
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
UpdateEnrollSigOwnerGuid (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN EFI_STRING_ID EnrollSigGuidStrId,
|
|
OUT EFI_GUID *EnrollSigOwnerGuid
|
|
)
|
|
{
|
|
CHAR16 *String;
|
|
EFI_STATUS Status;
|
|
|
|
if (HiiHandle == NULL || EnrollSigGuidStrId == 0 || EnrollSigOwnerGuid == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
String = HiiGetString (HiiHandle, EnrollSigGuidStrId, NULL);
|
|
if (String == NULL || *String == CHAR_NULL) {
|
|
SecureBootSafeFreePool ((VOID **) &String);
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
Status = SecureBootStrToGuid (String, EnrollSigOwnerGuid);
|
|
if (EFI_ERROR (Status)) {
|
|
SecureBootShowOkConfirmDlg (STRING_TOKEN (STR_INVALID_GUID_STRING_ERROR_MESSAGE));
|
|
}
|
|
|
|
FreePool (String);
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Update the state of secure boot manager based on input question ID.
|
|
|
|
@param[in] QuestionId Question ID
|
|
@param[out] SecureBootMgrState Returns the secure boot manager state
|
|
|
|
@retval EFI_SUCCESS Update secure boot manager state successfully.
|
|
@retval EFI_INVALID_PARAMETER Input parameter is NULL.
|
|
@retval EFI_UNSUPPORTED There is no state value for input question ID.
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
UpdateSecureBootMgrState (
|
|
IN EFI_QUESTION_ID QuestionId,
|
|
OUT SECURE_BOOT_MANAGER_STATE *SecureBootMgrState
|
|
)
|
|
{
|
|
if (SecureBootMgrState == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
switch (QuestionId) {
|
|
|
|
case KEY_PK_FORM:
|
|
*SecureBootMgrState = PkForm;
|
|
break;
|
|
|
|
case KEY_KEK_FORM:
|
|
*SecureBootMgrState = KekForm;
|
|
break;
|
|
|
|
case KEY_DB_FORM:
|
|
*SecureBootMgrState = DbForm;
|
|
break;
|
|
|
|
case KEY_DBX_FORM:
|
|
*SecureBootMgrState = DbxForm;
|
|
break;
|
|
|
|
case KEY_DBT_FORM:
|
|
*SecureBootMgrState = DbtForm;
|
|
break;
|
|
|
|
case KEY_DBR_FORM:
|
|
*SecureBootMgrState = DbrForm;
|
|
break;
|
|
|
|
case KEY_ENROLL_HASH:
|
|
*SecureBootMgrState = HashImageForm;
|
|
break;
|
|
|
|
default:
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This function allows a caller to extract the current configuration for one
|
|
or more named elements from the target driver.
|
|
|
|
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
|
@param Request A null-terminated Unicode string in <ConfigRequest> format.
|
|
@param Progress On return, points to a character in the Request string.
|
|
Points to the string's null terminator if request was successful.
|
|
Points to the most recent '&' before the first failing name/value
|
|
pair (or the beginning of the string if the failure is in the
|
|
first name/value pair) if the request was not successful.
|
|
@param Results A null-terminated Unicode string in <ConfigAltResp> format which
|
|
has all values filled in for the names in the Request string.
|
|
String to be allocated by the called function.
|
|
|
|
@retval EFI_SUCCESS The Results is filled with the requested values.
|
|
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
|
|
@retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
|
|
@retval EFI_NOT_FOUNDv Routing data doesn't match any storage in this driver.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SecureBootExtractConfig (
|
|
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
|
IN CONST EFI_STRING Request,
|
|
OUT EFI_STRING *Progress,
|
|
OUT EFI_STRING *Results
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN BufferSize;
|
|
EFI_STRING ConfigRequestHdr;
|
|
EFI_STRING ConfigRequest;
|
|
BOOLEAN AllocatedRequest;
|
|
UINTN Size;
|
|
EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
|
|
SECURE_BOOT_MANAGER_CALLBACK_DATA *PrivateData;
|
|
|
|
PrivateData = SECURE_BOOT_CALLBACK_DATA_FROM_THIS (This);
|
|
|
|
if (Progress == NULL || Results == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
*Progress = Request;
|
|
if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mSecureBootGuid, SECURE_BOOT_DATA_NAME)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
if (mNeedInitializePrivateData) {
|
|
mNeedInitializePrivateData = FALSE;
|
|
InitializeSystemStatus ();
|
|
}
|
|
|
|
ConfigRequestHdr = NULL;
|
|
ConfigRequest = NULL;
|
|
AllocatedRequest = FALSE;
|
|
Size = 0;
|
|
|
|
//
|
|
// Convert buffer data to <ConfigResp> by helper function BlockToConfig()
|
|
//
|
|
BufferSize = sizeof (SECURE_BOOT_NV_DATA);
|
|
ConfigRequest = Request;
|
|
if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
|
|
//
|
|
// Request has no request element, construct full request string.
|
|
// Allocate and fill a buffer large enough to hold the <ConfigHdr> template
|
|
// followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
|
|
//
|
|
ConfigRequestHdr = HiiConstructConfigHdr (
|
|
&mSecureBootGuid,
|
|
SECURE_BOOT_DATA_NAME,
|
|
mSecureBootPrivate.DriverHandle
|
|
);
|
|
if (ConfigRequestHdr == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
|
|
ConfigRequest = AllocateZeroPool (Size);
|
|
ASSERT (ConfigRequest != NULL);
|
|
AllocatedRequest = TRUE;
|
|
UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
|
|
FreePool (ConfigRequestHdr);
|
|
}
|
|
Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = HiiConfigRouting->BlockToConfig (
|
|
HiiConfigRouting,
|
|
ConfigRequest,
|
|
(UINT8 *) &PrivateData->SecureBootData,
|
|
BufferSize,
|
|
Results,
|
|
Progress
|
|
);
|
|
//
|
|
// Free the allocated config request string.
|
|
//
|
|
if (AllocatedRequest) {
|
|
FreePool (ConfigRequest);
|
|
ConfigRequest = NULL;
|
|
}
|
|
//
|
|
// Set Progress string to the original request string.
|
|
//
|
|
if (Request == NULL) {
|
|
*Progress = NULL;
|
|
} else if (StrStr (Request, L"OFFSET") == NULL) {
|
|
*Progress = Request + StrLen (Request);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
This function processes the results of changes in configuration.
|
|
|
|
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
|
@param Configuration A null-terminated Unicode string in <ConfigResp> format.
|
|
@param Progress A pointer to a string filled in with the offset of the most
|
|
recent '&' before the first failing name/value pair (or the
|
|
beginning of the string if the failure is in the first
|
|
name/value pair) or the terminating NULL if all was successful.
|
|
|
|
@retval EFI_SUCCESS The Results is processed successfully.
|
|
@retval EFI_INVALID_PARAMETER This or Configuration or Progress is NULL.
|
|
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SecureBootRouteConfig (
|
|
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
|
IN CONST EFI_STRING Configuration,
|
|
OUT EFI_STRING *Progress
|
|
)
|
|
{
|
|
SECURE_BOOT_MANAGER_CALLBACK_DATA *PrivateData;
|
|
EFI_STATUS Status;
|
|
UINTN BufferSize;
|
|
EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
|
|
|
|
if (Configuration == NULL || Progress == NULL || This == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
*Progress = Configuration;
|
|
if (!HiiIsConfigHdrMatch (Configuration, &mSecureBootGuid, SECURE_BOOT_DATA_NAME)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
PrivateData = SECURE_BOOT_CALLBACK_DATA_FROM_THIS (This);
|
|
Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
BufferSize = sizeof (PrivateData->SecureBootData);
|
|
HiiConfigRouting->ConfigToBlock (
|
|
HiiConfigRouting,
|
|
Configuration,
|
|
(UINT8 *) &PrivateData->SecureBootData,
|
|
&BufferSize,
|
|
Progress
|
|
);
|
|
|
|
return SecureBootSaveChange ((EFI_HII_CONFIG_ACCESS_PROTOCOL *) This);
|
|
}
|
|
|
|
|
|
/**
|
|
This function processes the results of changes in configuration.
|
|
|
|
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
|
@param Action Specifies the type of action taken by the browser.
|
|
@param QuestionId A unique value which is sent to the original exporting driver
|
|
so that it can identify the type of data to expect.
|
|
@param Type The type of value for the question.
|
|
@param Value A pointer to the data being sent to the original exporting driver.
|
|
@param ActionRequest On return, points to the action requested by the callback function.
|
|
|
|
@retval EFI_SUCCESS The callback successfully handled the action.
|
|
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
|
|
@retval EFI_DEVICE_ERROR The variable could not be saved.
|
|
@retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SecureBootCallback (
|
|
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
|
IN EFI_BROWSER_ACTION Action,
|
|
IN EFI_QUESTION_ID QuestionId,
|
|
IN UINT8 Type,
|
|
IN EFI_IFR_TYPE_VALUE *Value,
|
|
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
|
|
)
|
|
{
|
|
SECURE_BOOT_MANAGER_CALLBACK_DATA *PrivateData;
|
|
UINTN BufferSize;
|
|
EFI_STATUS Status;
|
|
CHAR16 *StringPtr;
|
|
EFI_INPUT_KEY Key;
|
|
|
|
if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
|
|
if (QuestionId == KEY_ROOT_FORM) {
|
|
if (mReadyToBootSignaled) {
|
|
SecureBootShowOkConfirmDlg (STRING_TOKEN (STR_READY_TO_BOOT_SIGNALED_STRING));
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (IsGotoQuestion (QuestionId) && Action == EFI_BROWSER_ACTION_CHANGING) {
|
|
//
|
|
// Because form browser only send changing action for EFI_IFR_REF_OP opcode, change action to changed to make
|
|
// the process of EFI_IFR_REF_OP opcode can be executed.
|
|
//
|
|
Action = EFI_BROWSER_ACTION_CHANGED;
|
|
}
|
|
|
|
if (Action != EFI_BROWSER_ACTION_CHANGED) {
|
|
//
|
|
// All other action return unsupported.
|
|
//
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
PrivateData = SECURE_BOOT_CALLBACK_DATA_FROM_THIS (This);
|
|
BufferSize = sizeof (SECURE_BOOT_NV_DATA);
|
|
|
|
Status = HiiGetBrowserData (
|
|
NULL,
|
|
NULL,
|
|
BufferSize,
|
|
(UINT8 *) &PrivateData->SecureBootData
|
|
);
|
|
|
|
UpdateSecureBootMgrState (QuestionId, &PrivateData->SecureBootMgrState);
|
|
Status = EFI_SUCCESS;
|
|
switch (QuestionId) {
|
|
|
|
case KEY_PK_FORM:
|
|
case KEY_KEK_FORM:
|
|
case KEY_DB_FORM:
|
|
case KEY_DBX_FORM:
|
|
case KEY_DBT_FORM:
|
|
case KEY_DBR_FORM:
|
|
SecureBootVarUpdateForm (PrivateData->SecureBootMgrState);
|
|
break;
|
|
|
|
case KEY_ENROLL_HASH:
|
|
case KEY_ENROLL_PK:
|
|
case KEY_ENROLL_KEK:
|
|
case KEY_ENROLL_DB:
|
|
case KEY_ENROLL_DBX:
|
|
case KEY_ENROLL_DBT:
|
|
case KEY_ENROLL_DBR:
|
|
Status = InitializeEnrollMenu (PrivateData);
|
|
break;
|
|
|
|
case KEY_SCAN_ESC:
|
|
StringPtr = HiiGetString (
|
|
PrivateData->HiiHandle,
|
|
STRING_TOKEN (STR_EXIT_MENU_STRING),
|
|
NULL
|
|
);
|
|
|
|
PrivateData->H2ODialog->ConfirmDialog (
|
|
DlgYesNo,
|
|
FALSE,
|
|
0,
|
|
NULL,
|
|
&Key,
|
|
StringPtr
|
|
);
|
|
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
|
|
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
|
|
}
|
|
|
|
FreePool (StringPtr);
|
|
break;
|
|
|
|
case KEY_SCAN_F10:
|
|
StringPtr = HiiGetString (
|
|
PrivateData->HiiHandle,
|
|
STRING_TOKEN (STR_SAVE_CHANGE_STRING),
|
|
NULL
|
|
);
|
|
|
|
PrivateData->H2ODialog->ConfirmDialog (
|
|
DlgYesNo,
|
|
FALSE,
|
|
0,
|
|
NULL,
|
|
&Key,
|
|
StringPtr
|
|
);
|
|
|
|
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
|
|
SecureBootSaveChange ((EFI_HII_CONFIG_ACCESS_PROTOCOL *) This);
|
|
SecureBootShowOkConfirmDlg (STRING_TOKEN (STR_OPERATION_FINISH_MESSAGE));
|
|
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
|
|
}
|
|
FreePool (StringPtr);
|
|
break;
|
|
|
|
default:
|
|
if (QuestionId >= KEY_DELETE_SIGNATURE_QUESTION_BASE &&
|
|
QuestionId < KEY_DELETE_SIGNATURE_QUESTION_BASE + KEY_DELETE_SIGNATURE_QUESTION_LENGTH) {
|
|
Key.UnicodeChar = CHAR_CARRIAGE_RETURN;
|
|
StringPtr = HiiGetString (
|
|
PrivateData->HiiHandle,
|
|
STRING_TOKEN (STR_DELETE_SIGNATURE_CONFIRM_MESSAGE),
|
|
NULL
|
|
);
|
|
if (StringPtr != NULL) {
|
|
PrivateData->H2ODialog->ConfirmDialog (
|
|
DlgYesNo,
|
|
FALSE,
|
|
0,
|
|
NULL,
|
|
&Key,
|
|
StringPtr
|
|
);
|
|
FreePool (StringPtr);
|
|
}
|
|
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
|
|
Status = SecureBootVarDeleteSignature (
|
|
PrivateData->SecureBootMgrState,
|
|
QuestionId - KEY_DELETE_SIGNATURE_QUESTION_BASE
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (QuestionId >= ENROLL_FILE_OPTION_OFFSET) {
|
|
if (Type == EFI_IFR_TYPE_STRING) {
|
|
//
|
|
// Update enroll signature GUID and then clear string in HII database to prevent from displaying GUID string
|
|
// on the value of enroll file item.
|
|
//
|
|
Status = UpdateEnrollSigOwnerGuid (PrivateData->HiiHandle, Value->string, &PrivateData->EmEnrollSigOwnerGuid);
|
|
ClearEnrollSigGuidStrInHiiDatabase (PrivateData, Value->string);
|
|
if (EFI_ERROR (Status)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (UpdateEmFileExplorer (PrivateData, QuestionId)) {
|
|
PrivateData->EmDisplayContext = EM_UNKNOWN_CONTEXT;
|
|
UpdateEmFileExplorer (PrivateData, 0);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
Provide user interface to control secure boot relative features
|
|
|
|
**/
|
|
VOID
|
|
InternalCallSecureBootMgr (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_BROWSER_ACTION_REQUEST ActionRequest;
|
|
EFI_HII_HANDLE HiiHandle;
|
|
EFI_STATUS Status;
|
|
EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
|
|
CHAR16 *NewString;
|
|
EFI_INPUT_KEY HotKey;
|
|
EFI_FORM_BROWSER_EXTENSION_PROTOCOL *FormBrowserEx;
|
|
|
|
|
|
if (mReadyToBootSignaled) {
|
|
SecureBootShowOkConfirmDlg (STRING_TOKEN (STR_READY_TO_BOOT_SIGNALED_STRING));
|
|
return;
|
|
}
|
|
|
|
|
|
if (IsPasswordExist () && NeedSysPasswordCheck ()) {
|
|
Status = CheckPassword ();
|
|
if (!EFI_ERROR (Status)) {
|
|
DisableSysPasswordCheck ();
|
|
}
|
|
} else {
|
|
UnlockPasswordState (NULL, 0);
|
|
}
|
|
gBS->RestoreTPL (TPL_APPLICATION);
|
|
|
|
|
|
HiiHandle = mSecureBootPrivate.HiiHandle;
|
|
ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
|
|
|
|
Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
Status = gBS->LocateProtocol (&gEdkiiFormBrowserExProtocolGuid, NULL, (VOID **) &FormBrowserEx);
|
|
if (!EFI_ERROR (Status)) {
|
|
//
|
|
// First unregister the default hot key F9 and F10.
|
|
//
|
|
HotKey.UnicodeChar = CHAR_NULL;
|
|
HotKey.ScanCode = SCAN_F9;
|
|
FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL);
|
|
HotKey.ScanCode = SCAN_F10;
|
|
FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL);
|
|
|
|
//
|
|
// Register the default HotKey F9 and F10 again.
|
|
//
|
|
HotKey.ScanCode = SCAN_F10;
|
|
NewString = HiiGetString (HiiHandle, STRING_TOKEN (STR_SAVE_CHANGE_STRING), NULL);
|
|
ASSERT (NewString != NULL);
|
|
FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT | BROWSER_ACTION_EXIT, 0, NewString);
|
|
}
|
|
|
|
Status = FormBrowser2->SendForm (
|
|
FormBrowser2,
|
|
&HiiHandle,
|
|
1,
|
|
&mSecureBootGuid,
|
|
0,
|
|
NULL,
|
|
&ActionRequest
|
|
);
|
|
LockPasswordState ();
|
|
if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
|
|
EnableResetRequired ();
|
|
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
Enter secure boot manager.
|
|
|
|
@param[in] This Protocol instance pointer.
|
|
@param[in] FilePath The device specific path of the file to load.
|
|
@param[in] BootPolicy If TRUE, indicates that the request originates from the boot manager is attempting to
|
|
load FilePath as a boot selection. If FALSE, then FilePath must match as exact file to be loaded.
|
|
@param[in, out] BufferSize On input the size of Buffer in bytes. On output with a return code of EFI_SUCCESS,
|
|
the amount of data transferred to Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
|
|
the size of Buffer required to retrieve the requested file.
|
|
@param[in] Buffer The memory buffer to transfer the file to. IF Buffer is NULL, then no the size of the
|
|
requested file is returned in BufferSize.
|
|
|
|
@retval EFI_NOT_FOUND Always return not found.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SecureBootMgrLoadFile (
|
|
IN EFI_LOAD_FILE_PROTOCOL *This,
|
|
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
|
IN BOOLEAN BootPolicy,
|
|
IN OUT UINTN *BufferSize,
|
|
IN VOID *Buffer OPTIONAL
|
|
)
|
|
{
|
|
if (mSecureBootPrivate.HiiHandle != NULL) {
|
|
InternalCallSecureBootMgr ();
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
/**
|
|
Initialize HII data.
|
|
|
|
@param[in] Event A pointer to the Event that triggered the callback.
|
|
@param[in] Handle Checkpoint handle.
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
SecureBootMgrCpInitNotifyFunc (
|
|
IN EFI_EVENT Event,
|
|
IN H2O_CP_HANDLE Handle
|
|
)
|
|
{
|
|
H2OCpUnregisterHandler (Handle);
|
|
InitializeSecureBoot ();
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SecureBootMgrSendForm (
|
|
IN CONST EFI_FORM_BROWSER2_PROTOCOL *This,
|
|
IN EFI_HII_HANDLE *Handles,
|
|
IN UINTN HandleCount,
|
|
IN EFI_GUID *FormSetGuid OPTIONAL,
|
|
IN UINT16 FormId OPTIONAL,
|
|
IN CONST EFI_SCREEN_DESCRIPTOR *ScreenDimensions OPTIONAL,
|
|
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest OPTIONAL
|
|
)
|
|
{
|
|
mNeedInitializePrivateData = TRUE;
|
|
return mOrgSendForm (
|
|
This,
|
|
Handles,
|
|
HandleCount,
|
|
FormSetGuid,
|
|
FormId,
|
|
ScreenDimensions,
|
|
ActionRequest
|
|
);
|
|
}
|
|
|
|
/**
|
|
Hook SendForm function of FormBrowser2 protocol.
|
|
|
|
@param[in] Event Event whose notification function is being invoked.
|
|
@param[in] Context Pointer to the notification function's context.
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
SecureBootMgrFormBrowser2NotifyFn (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
|
|
EFI_STATUS Status;
|
|
|
|
Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);
|
|
if (EFI_ERROR (Status)) {
|
|
return;
|
|
}
|
|
|
|
mOrgSendForm = FormBrowser2->SendForm;
|
|
FormBrowser2->SendForm = SecureBootMgrSendForm;
|
|
|
|
gBS->CloseEvent (Event);
|
|
}
|
|
|
|
/**
|
|
Ready to boot callback function to change mReadyToBootSignaled state.
|
|
|
|
@param[in] Event Event whose notification function is being invoked.
|
|
@param[in] Context Pointer to the notification function's context.
|
|
**/
|
|
VOID
|
|
SecureBootMgrReadyToBootCallback (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
gBS->CloseEvent (Event);
|
|
mReadyToBootSignaled = TRUE;
|
|
}
|
|
|
|
/**
|
|
Register H2OBdsCpInit notification to initialize HII data.
|
|
Install the instance of the EFI_LOAD_FILE_PROTOCOL and EFI_DEVICE_PATH_PROTOCOL on new handle.
|
|
|
|
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
|
@param[in] SystemTable A pointer to the EFI System Table.
|
|
|
|
@retval EFI_SUCCESS Install protocol successfully.
|
|
@retval other Fail to install protocol instance.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SecureBootMgrEntry (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
H2O_CP_HANDLE CpHandle;
|
|
EFI_HANDLE DriverHandle;
|
|
EFI_STATUS Status;
|
|
EFI_EVENT Event;
|
|
VOID *Registration;
|
|
|
|
if (FeaturePcdGet (PcdH2OBdsCpInitSupported)) {
|
|
Status = H2OCpRegisterHandler (
|
|
&gH2OBdsCpInitGuid,
|
|
SecureBootMgrCpInitNotifyFunc,
|
|
H2O_CP_MEDIUM,
|
|
&CpHandle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG_CP ((DEBUG_ERROR, "Checkpoint Register Fail: %g (%r)\n", &gH2OBdsCpInitGuid, Status));
|
|
return Status;
|
|
}
|
|
DEBUG_CP ((DEBUG_INFO, "Checkpoint Registered: %g (%r)\n", &gH2OBdsCpInitGuid, Status));
|
|
}
|
|
|
|
EfiCreateEventReadyToBootEx (TPL_CALLBACK, SecureBootMgrReadyToBootCallback, NULL, &Event);
|
|
EfiCreateProtocolNotifyEvent (
|
|
&gEfiFormBrowser2ProtocolGuid,
|
|
TPL_CALLBACK,
|
|
SecureBootMgrFormBrowser2NotifyFn,
|
|
NULL,
|
|
&Registration
|
|
);
|
|
|
|
DriverHandle = NULL;
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
&DriverHandle,
|
|
&gEfiDevicePathProtocolGuid,
|
|
&gH2OSecureBootMgrDevicePath,
|
|
&gEfiLoadFileProtocolGuid,
|
|
&mSecureBootMgrLoadFile,
|
|
NULL
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Initial communication buffer header.
|
|
|
|
@param[in] CommunicationBuffer Input communication buffer.
|
|
@param[in] CommunicationBufferSize Size of communication buffer in bytes.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
InitCommunicationBufferHeader (
|
|
IN VOID *CommunicationBuffer,
|
|
IN UINTN CommunicationBufferSize
|
|
)
|
|
{
|
|
EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
|
|
|
|
if (CommunicationBuffer == NULL || CommunicationBufferSize < SMM_COMMUNICATE_HEADER_SIZE + sizeof (SMM_VAR_BUFFER)) {
|
|
return;
|
|
}
|
|
SmmCommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *) CommunicationBuffer;
|
|
ZeroMem (SmmCommunicateHeader, SMM_COMMUNICATE_HEADER_SIZE + sizeof (SMM_VAR_BUFFER));
|
|
CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmVariableProtocolGuid);
|
|
SmmCommunicateHeader->MessageLength = SMM_COMMUNICATE_BUFFER_SIZE;
|
|
}
|
|
|
|
/**
|
|
Using runtime data type memory to communicate information with variable driver
|
|
in SMM.
|
|
|
|
@param[in] InputBuff Buffer to communicate information with variable driver.
|
|
@param[in] DataSize Size of the InPutBuff in bytes.
|
|
@param[in] SubFunNum sub function number.
|
|
|
|
@retval EFI_SUCCESS Communicate information with variable driver successfully.
|
|
@retval EFI_OUT_OF_RESOURCES There are not enough memory to communicate information.
|
|
**/
|
|
EFI_STATUS
|
|
SmmSecureBootCallWithRuntimeMemory (
|
|
IN UINT8 *InputBuff,
|
|
IN UINTN DataSize,
|
|
IN UINT8 SubFunNum
|
|
)
|
|
{
|
|
NON_VOLATILE_VARIABLE_PROTOCOL *NonVolatileVariableProtocol;
|
|
VOID *VariableBuffer;
|
|
UINTN VariableBufferSize;
|
|
EFI_STATUS Status;
|
|
EFI_TPL Tpl;
|
|
EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;
|
|
SMM_VAR_BUFFER *SmmVarBuffer;
|
|
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiNonVolatileVariableProtocolGuid,
|
|
NULL,
|
|
(VOID **) &NonVolatileVariableProtocol
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiSmmCommunicationProtocolGuid,
|
|
NULL,
|
|
(VOID **) &SmmCommunication
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
Status = NonVolatileVariableProtocol->GetRuntimeVariableBuffer (&VariableBuffer, &VariableBufferSize);
|
|
if (EFI_ERROR (Status) || VariableBufferSize < DataSize) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
//
|
|
// Because the VariableBuffer will be used in many places, raise TPL to prevent from the data in this
|
|
// buffer is destroyed in other events.
|
|
//
|
|
Tpl = gBS->RaiseTPL (TPL_NOTIFY);
|
|
InitCommunicationBufferHeader (VariableBuffer, VariableBufferSize);
|
|
SmmVarBuffer = (SMM_VAR_BUFFER *)((UINTN) VariableBuffer + SMM_COMMUNICATE_HEADER_SIZE);
|
|
SmmVarBuffer->DataSize = DataSize;
|
|
SmmVarBuffer->AccessType = SubFunNum;
|
|
SmmVarBuffer->Status = EFI_UNSUPPORTED;
|
|
CopyMem (SmmVarBuffer + 1, InputBuff, DataSize);
|
|
Status = SmmCommunication->Communicate (SmmCommunication, VariableBuffer, &VariableBufferSize);
|
|
gBS->RestoreTPL (Tpl);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|