SecurityPkg: SecureBootConfigDxe: SecureBoot UI for Customized SecureBoot Mode

Add SecureBoot UI support for Customized SecureBoot Mode transition according to Mantis 1263. User can do secure boot mode transition through UI.
  https://mantis.uefi.org/mantis/view.php?id=1263

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chao Zhang <chao.b.zhang@intel.com>
Reviewed-by: Zeng Star <star.zeng@intel.com>
Reviewed-by: Long Qin <qin.long@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19134 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Chao Zhang
2015-12-07 06:20:36 +00:00
committed by czhang46
parent 4fc08e8d68
commit 96832eefea
4 changed files with 474 additions and 66 deletions

View File

@ -49,6 +49,8 @@ HII_VENDOR_DEVICE_PATH mSecureBootHiiVendorDevicePath = {
BOOLEAN mIsEnterSecureBootForm = FALSE;
BOOLEAN mIsSelectedSecureBootModeForm = FALSE;
BOOLEAN mIsSecureBootModeChanged = FALSE;
//
// OID ASN.1 Value for Hash Algorithms
@ -2808,6 +2810,256 @@ ON_EXIT:
);
}
/**
Perform secure boot mode transition from User Mode by setting AuditMode
or DeployedMode variable.
@param[in] NewMode New secure boot mode.
@retval EFI_SUCCESS Secure Boot mode transition is successful.
**/
EFI_STATUS
TransitionFromUserMode(
IN UINT8 NewMode
)
{
UINT8 Data;
EFI_STATUS Status;
if (NewMode == SECURE_BOOT_MODE_AUDIT_MODE) {
Data = 1;
Status = gRT->SetVariable(
EFI_AUDIT_MODE_NAME,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof(UINT8),
&Data
);
return Status;
} else if (NewMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {
Data = 1;
Status = gRT->SetVariable(
EFI_DEPLOYED_MODE_NAME,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof(UINT8),
&Data
);
return Status;
}
//
// Other case do nothing here. May Goto enroll PK page.
//
return EFI_SUCCESS;
}
/**
Perform secure boot mode transition from Setup Mode by setting AuditMode
variable.
@param[in] NewMode New secure boot mode.
@retval EFI_SUCCESS Secure Boot mode transition is successful.
**/
EFI_STATUS
TransitionFromSetupMode(
IN UINT8 NewMode
)
{
UINT8 Data;
EFI_STATUS Status;
Status = EFI_INVALID_PARAMETER;
if (NewMode == SECURE_BOOT_MODE_AUDIT_MODE) {
Data = 1;
Status = gRT->SetVariable(
EFI_AUDIT_MODE_NAME,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof(UINT8),
&Data
);
return Status;
}
//
// Other case do nothing here. May Goto enroll PK page.
//
return EFI_SUCCESS;
}
/**
Perform secure boot mode transition from Audit Mode. Nothing is done here,
should goto enroll PK page.
@param[in] NewMode New secure boot mode.
@retval EFI_SUCCESS Secure Boot mode transition is successful.
**/
EFI_STATUS
TransitionFromAuditMode(
IN UINT8 NewMode
)
{
//
// Other case do nothing here. Should Goto enroll PK page.
//
return EFI_SUCCESS;
}
/**
Perform secure boot mode transition from Deployed Mode by setting Deployed Mode
variable to 0.
@param[in] NewMode New secure boot mode.
@retval EFI_SUCCESS Secure Boot mode transition is successful.
**/
EFI_STATUS
TransitionFromDeployedMode(
IN UINT8 NewMode
)
{
UINT8 Data;
EFI_STATUS Status;
//
// Platform specific logic. when physical presence, Allow to set DeployedMode =:0
// to switch back to UserMode
//
if (NewMode == SECURE_BOOT_MODE_USER_MODE) {
Data = 0;
Status = gRT->SetVariable(
EFI_DEPLOYED_MODE_NAME,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof(UINT8),
&Data
);
DEBUG((EFI_D_INFO, "DeployedMode Status %x\n", Status));
return Status;
}
return EFI_SUCCESS;
}
/**
Perform main secure boot mode transition.
@param[in] CurMode New secure boot mode.
@param[in] NewMode New secure boot mode.
@retval EFI_SUCCESS Secure Boot mode transition is successful.
**/
EFI_STATUS
SecureBootModeTransition(
IN UINT8 CurMode,
IN UINT8 NewMode
)
{
EFI_STATUS Status;
//
// Set platform to be customized mode to ensure platform specific mode switch sucess
//
Status = SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE);
if (EFI_ERROR (Status)) {
return Status;
}
//
// SecureBootMode transition
//
switch (CurMode) {
case SECURE_BOOT_MODE_USER_MODE:
Status = TransitionFromUserMode(NewMode);
break;
case SECURE_BOOT_MODE_SETUP_MODE:
Status = TransitionFromSetupMode(NewMode);
break;
case SECURE_BOOT_MODE_AUDIT_MODE:
Status = TransitionFromAuditMode(NewMode);
break;
case SECURE_BOOT_MODE_DEPLOYED_MODE:
Status = TransitionFromDeployedMode(NewMode);
break;
default:
Status = EFI_INVALID_PARAMETER;
ASSERT(FALSE);
}
return Status;
}
/**
Get current secure boot mode by retrieve data from SetupMode/AuditMode/DeployedMode.
@param[out] SecureBootMode Current secure boot mode.
**/
VOID
ExtractSecureBootModeFromVariable(
OUT UINT8 *SecureBootMode
)
{
UINT8 *SetupMode;
UINT8 *AuditMode;
UINT8 *DeployedMode;
SetupMode = NULL;
AuditMode = NULL;
DeployedMode = NULL;
//
// Get AuditMode/DeployedMode from variable
//
GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL);
GetVariable2 (EFI_AUDIT_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&AuditMode, NULL);
GetVariable2 (EFI_DEPLOYED_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&DeployedMode, NULL);
if (SetupMode != NULL && AuditMode != NULL && DeployedMode != NULL) {
if (*SetupMode == 0 && *AuditMode == 0 && *DeployedMode == 0) {
//
// User Mode
//
*SecureBootMode = SECURE_BOOT_MODE_USER_MODE;
} else if (*SetupMode == 1 && *AuditMode == 0 && *DeployedMode == 0) {
//
// Setup Mode
//
*SecureBootMode = SECURE_BOOT_MODE_SETUP_MODE;
} else if (*SetupMode == 1 && *AuditMode == 1 && *DeployedMode == 0) {
//
// Audit Mode
//
*SecureBootMode = SECURE_BOOT_MODE_AUDIT_MODE;
} else if (*SetupMode == 0 && *AuditMode == 0 && *DeployedMode == 1) {
//
// Deployed Mode
//
*SecureBootMode = SECURE_BOOT_MODE_DEPLOYED_MODE;
} else {
ASSERT(FALSE);
}
}else {
ASSERT(FALSE);
}
if (SetupMode != NULL) {
FreePool (SetupMode);
}
if (DeployedMode != NULL) {
FreePool (DeployedMode);
}
if (AuditMode != NULL) {
FreePool (AuditMode);
}
}
/**
This function extracts configuration from variable.
@ -2820,12 +3072,10 @@ SecureBootExtractConfigFromVariable (
)
{
UINT8 *SecureBootEnable;
UINT8 *SetupMode;
UINT8 *SecureBootMode;
EFI_TIME CurrTime;
SecureBootEnable = NULL;
SetupMode = NULL;
SecureBootMode = NULL;
//
@ -2865,16 +3115,6 @@ SecureBootExtractConfigFromVariable (
ConfigData->PhysicalPresent = FALSE;
}
//
// If there is no PK then the Delete Pk button will be gray.
//
GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL);
if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) {
ConfigData->HasPk = FALSE;
} else {
ConfigData->HasPk = TRUE;
}
//
// Get the SecureBootMode from CustomMode variable.
//
@ -2885,12 +3125,24 @@ SecureBootExtractConfigFromVariable (
ConfigData->SecureBootMode = *(SecureBootMode);
}
//
// Extact current Secure Boot Mode
//
ExtractSecureBootModeFromVariable(&ConfigData->CurSecureBootMode);
//
// If there is no PK then the Delete Pk button will be gray.
//
if (ConfigData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE || ConfigData->CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE) {
ConfigData->HasPk = FALSE;
} else {
ConfigData->HasPk = TRUE;
}
if (SecureBootEnable != NULL) {
FreePool (SecureBootEnable);
}
if (SetupMode != NULL) {
FreePool (SetupMode);
}
if (SecureBootMode != NULL) {
FreePool (SecureBootMode);
}
@ -2965,16 +3217,28 @@ SecureBootExtractConfig (
SecureBootExtractConfigFromVariable (&Configuration);
//
// Update current secure boot state.
// Get current secure boot state.
//
GetVariable2 (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SecureBoot, NULL);
if (SecureBoot != NULL && *SecureBoot == SECURE_BOOT_MODE_ENABLE) {
HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT), L"Enabled", NULL);
} else {
HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT), L"Disabled", NULL);
}
if (SecureBoot != NULL) {
FreePool (SecureBoot);
//
// Get current secure boot mode
//
DEBUG((EFI_D_INFO, "Configuration.CurSecureBootMode %d\n", Configuration.CurSecureBootMode));
if (Configuration.CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE) {
HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"UserMode", NULL);
} else if (Configuration.CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE) {
HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"SetupMode", NULL);
} else if (Configuration.CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE) {
HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"AuditMode", NULL);
} else if (Configuration.CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {
HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"DeployedMode", NULL);
}
BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
@ -3021,6 +3285,10 @@ SecureBootExtractConfig (
*Progress = Request + StrLen (Request);
}
if (SecureBoot != NULL) {
FreePool (SecureBoot);
}
return Status;
}
@ -3142,43 +3410,16 @@ SecureBootCallback (
UINT16 LabelId;
UINT8 *SecureBootEnable;
UINT8 *SecureBootMode;
UINT8 *SetupMode;
CHAR16 PromptString[100];
UINT8 CurSecureBootMode;
Status = EFI_SUCCESS;
SecureBootEnable = NULL;
SecureBootMode = NULL;
SetupMode = NULL;
if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
if (QuestionId == KEY_SECURE_BOOT_MODE) {
mIsEnterSecureBootForm = TRUE;
}
return EFI_SUCCESS;
}
if (Action == EFI_BROWSER_ACTION_RETRIEVE) {
Status = EFI_UNSUPPORTED;
if (QuestionId == KEY_SECURE_BOOT_MODE) {
if (mIsEnterSecureBootForm) {
Value->u8 = SECURE_BOOT_MODE_STANDARD;
Status = EFI_SUCCESS;
}
}
return Status;
}
if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
(Action != EFI_BROWSER_ACTION_CHANGING) &&
(Action != EFI_BROWSER_ACTION_FORM_CLOSE) &&
(Action != EFI_BROWSER_ACTION_DEFAULT_STANDARD)) {
return EFI_UNSUPPORTED;
}
Private = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);
//
@ -3190,10 +3431,46 @@ SecureBootCallback (
return EFI_OUT_OF_RESOURCES;
}
Status = EFI_SUCCESS;
HiiGetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, BufferSize, (UINT8 *) IfrNvData);
if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
if (QuestionId == KEY_SECURE_BOOT_MODE) {
mIsEnterSecureBootForm = TRUE;
} else if (QuestionId == KEY_TRANS_SECURE_BOOT_MODE){
//
// Secure Boot Policy variable changes after tranistion. Re-sync CurSecureBootMode
//
ExtractSecureBootModeFromVariable(&IfrNvData->CurSecureBootMode);
mIsSelectedSecureBootModeForm = TRUE;
mIsSecureBootModeChanged = FALSE;
}
goto EXIT;
}
if (Action == EFI_BROWSER_ACTION_RETRIEVE) {
Status = EFI_UNSUPPORTED;
if (QuestionId == KEY_SECURE_BOOT_MODE) {
if (mIsEnterSecureBootForm) {
Value->u8 = SECURE_BOOT_MODE_STANDARD;
Status = EFI_SUCCESS;
}
} else if (QuestionId == KEY_TRANS_SECURE_BOOT_MODE) {
if (mIsSelectedSecureBootModeForm) {
Value->u8 = IfrNvData->CurSecureBootMode;
Status = EFI_SUCCESS;
}
}
goto EXIT;
}
if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
(Action != EFI_BROWSER_ACTION_CHANGING) &&
(Action != EFI_BROWSER_ACTION_FORM_CLOSE) &&
(Action != EFI_BROWSER_ACTION_DEFAULT_STANDARD)) {
Status = EFI_UNSUPPORTED;
goto EXIT;
}
if (Action == EFI_BROWSER_ACTION_CHANGING) {
switch (QuestionId) {
@ -3419,6 +3696,66 @@ SecureBootCallback (
);
}
break;
case KEY_TRANS_SECURE_BOOT_MODE:
//
// Pop up to alert user want to change secure boot mode
//
if ((IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE &&
(Value->u8 == SECURE_BOOT_MODE_AUDIT_MODE || Value->u8 == SECURE_BOOT_MODE_DEPLOYED_MODE))
||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE &&
Value->u8 == SECURE_BOOT_MODE_AUDIT_MODE)
||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE &&
Value->u8 == SECURE_BOOT_MODE_USER_MODE && IfrNvData->PhysicalPresent == 1)){
CreatePopUp (
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
&Key,
L"Are you sure you want to switch secure boot mode?",
L"Press 'Y' to switch secure boot mode, 'N' to discard change and return",
NULL
);
if (Key.UnicodeChar != 'y' && Key.UnicodeChar != 'Y') {
//
// If not 'Y'/''y' restore to defualt secure boot mode
//
Value->u8 = IfrNvData->CurSecureBootMode;
goto EXIT;
}
} else if ((IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE && Value->u8 == SECURE_BOOT_MODE_USER_MODE)
||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE && Value->u8 == SECURE_BOOT_MODE_SETUP_MODE)
||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE && Value->u8 == SECURE_BOOT_MODE_DEPLOYED_MODE)
||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE && Value->u8 == SECURE_BOOT_MODE_SETUP_MODE)) {
CreatePopUp (
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
&Key,
L"Secure boot mode tranistion requires PK change",
L"Please go to link below to update PK",
NULL
);
} else {
Status = EFI_INVALID_PARAMETER;
goto EXIT;
}
Status = SecureBootModeTransition(IfrNvData->CurSecureBootMode, Value->u8);
//
// Secure Boot Policy variable may change after tranistion. Re-sync CurSecureBootMode
//
ExtractSecureBootModeFromVariable(&CurSecureBootMode);
if (IfrNvData->CurSecureBootMode != CurSecureBootMode) {
IfrNvData->CurSecureBootMode = CurSecureBootMode;
mIsSecureBootModeChanged = TRUE;
if (IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE) {
HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"UserMode", NULL);
} else if (IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE) {
HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"SetupMode", NULL);
} else if (IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE) {
HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"AuditMode", NULL);
} else if (IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {
HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"DeployedMode", NULL);
}
}
break;
default:
if (QuestionId >= FILE_OPTION_GOTO_OFFSET) {
@ -3509,7 +3846,13 @@ SecureBootCallback (
case KEY_SECURE_BOOT_MODE:
mIsEnterSecureBootForm = FALSE;
break;
case KEY_TRANS_SECURE_BOOT_MODE:
mIsSelectedSecureBootModeForm = FALSE;
if (mIsSecureBootModeChanged) {
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;
}
mIsSecureBootModeChanged = FALSE;
break;
case KEY_SECURE_BOOT_KEK_GUID:
case KEY_SECURE_BOOT_SIGNATURE_GUID_DB:
case KEY_SECURE_BOOT_SIGNATURE_GUID_DBX:
@ -3528,8 +3871,7 @@ SecureBootCallback (
break;
case KEY_SECURE_BOOT_DELETE_PK:
GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL);
if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) {
if (IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE || IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {
IfrNvData->DeletePk = TRUE;
IfrNvData->HasPk = FALSE;
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
@ -3538,9 +3880,6 @@ SecureBootCallback (
IfrNvData->HasPk = TRUE;
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
}
if (SetupMode != NULL) {
FreePool (SetupMode);
}
break;
default:
if (QuestionId >= FILE_OPTION_OFFSET && QuestionId < FILE_OPTION_GOTO_OFFSET) {
@ -3575,10 +3914,13 @@ SecureBootCallback (
}
}
EXIT:
if (!EFI_ERROR (Status)) {
BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
HiiSetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, BufferSize, (UINT8*) IfrNvData, NULL);
}
FreePool (IfrNvData);
return EFI_SUCCESS;