302 lines
7.7 KiB
C
302 lines
7.7 KiB
C
/** @file
|
|
The secure boot manager misc function implementation.
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2016 - 2020, 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 "SecureBootMisc.h"
|
|
|
|
/**
|
|
Wrap original FreePool gBS call in order to decrease code length.
|
|
**/
|
|
VOID
|
|
SecureBootSafeFreePool (
|
|
IN VOID **Buffer
|
|
)
|
|
{
|
|
if (Buffer != NULL && *Buffer != NULL) {
|
|
FreePool (*Buffer);
|
|
*Buffer = NULL;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Worker function that prints an EFI_GUID into specified Buffer.
|
|
|
|
@param[in] Guid Pointer to GUID to print
|
|
@param[out] Buffer Buffer to print Guid into
|
|
@param[in] BufferSize Size of Buffer
|
|
**/
|
|
VOID
|
|
SecureBootGuidToStr (
|
|
IN EFI_GUID *Guid,
|
|
OUT CHAR16 *Buffer,
|
|
IN UINTN BufferSize
|
|
)
|
|
{
|
|
UnicodeSPrint (
|
|
Buffer,
|
|
BufferSize,
|
|
L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
|
(UINTN)Guid->Data1,
|
|
(UINTN)Guid->Data2,
|
|
(UINTN)Guid->Data3,
|
|
(UINTN)Guid->Data4[0],
|
|
(UINTN)Guid->Data4[1],
|
|
(UINTN)Guid->Data4[2],
|
|
(UINTN)Guid->Data4[3],
|
|
(UINTN)Guid->Data4[4],
|
|
(UINTN)Guid->Data4[5],
|
|
(UINTN)Guid->Data4[6],
|
|
(UINTN)Guid->Data4[7]
|
|
);
|
|
}
|
|
|
|
/**
|
|
Converts a string to GUID value.
|
|
Guid Format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
|
|
@param[in] Str The registry format GUID string that contains the GUID value.
|
|
@param[out] Guid A pointer to the converted GUID value.
|
|
|
|
@retval EFI_SUCCESS The GUID string was successfully converted to the GUID value.
|
|
@retval EFI_UNSUPPORTED The input string is not in registry format.
|
|
@return others Some error occurred when converting part of GUID value.
|
|
**/
|
|
EFI_STATUS
|
|
SecureBootStrToGuid (
|
|
IN CHAR16 *Str,
|
|
OUT EFI_GUID *Guid
|
|
)
|
|
{
|
|
CHAR16 *PtrBuffer;
|
|
CHAR16 *PtrPosition;
|
|
CHAR16 *Buffer;
|
|
UINTN Data;
|
|
UINTN Index;
|
|
UINT16 Digits[3];
|
|
|
|
Buffer = AllocateCopyPool (StrSize (Str), Str);
|
|
if (Buffer == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// The format of GUID string should be L"12345678-1234-1234-1234-1234657890ab".
|
|
//
|
|
PtrBuffer = Buffer;
|
|
PtrPosition = PtrBuffer;
|
|
while (*PtrBuffer != L'\0') {
|
|
if (*PtrBuffer == L'-') {
|
|
break;
|
|
}
|
|
PtrBuffer++;
|
|
}
|
|
if (*PtrBuffer == L'\0') {
|
|
FreePool (Buffer);
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
*PtrBuffer = L'\0';
|
|
Data = StrHexToUintn (PtrPosition);
|
|
Guid->Data1 = (UINT32)Data;
|
|
|
|
//
|
|
// Data2
|
|
//
|
|
PtrBuffer++;
|
|
PtrPosition = PtrBuffer;
|
|
while (*PtrBuffer != L'\0') {
|
|
if (*PtrBuffer == L'-') {
|
|
break;
|
|
}
|
|
PtrBuffer++;
|
|
}
|
|
if (*PtrBuffer == L'\0') {
|
|
FreePool (Buffer);
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
*PtrBuffer = L'\0';
|
|
Data = StrHexToUintn (PtrPosition);
|
|
Guid->Data2 = (UINT16)Data;
|
|
|
|
//
|
|
// Data3
|
|
//
|
|
PtrBuffer++;
|
|
PtrPosition = PtrBuffer;
|
|
while (*PtrBuffer != L'\0') {
|
|
if (*PtrBuffer == L'-') {
|
|
break;
|
|
}
|
|
PtrBuffer++;
|
|
}
|
|
if (*PtrBuffer == L'\0') {
|
|
FreePool (Buffer);
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
*PtrBuffer = L'\0';
|
|
Data = StrHexToUintn (PtrPosition);
|
|
Guid->Data3 = (UINT16)Data;
|
|
|
|
//
|
|
// Data4[0..1]
|
|
//
|
|
for ( Index = 0 ; Index < 2 ; Index++) {
|
|
PtrBuffer++;
|
|
if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
|
|
FreePool (Buffer);
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
Digits[0] = *PtrBuffer;
|
|
PtrBuffer++;
|
|
Digits[1] = *PtrBuffer;
|
|
Digits[2] = L'\0';
|
|
Data = StrHexToUintn (Digits);
|
|
Guid->Data4[Index] = (UINT8)Data;
|
|
}
|
|
|
|
//
|
|
// skip the '-'
|
|
//
|
|
PtrBuffer++;
|
|
if ((*PtrBuffer != L'-' ) || ( *PtrBuffer == L'\0')) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
//
|
|
// Data4[2..7]
|
|
//
|
|
for ( ; Index < 8; Index++) {
|
|
PtrBuffer++;
|
|
if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
|
|
FreePool (Buffer);
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
Digits[0] = *PtrBuffer;
|
|
PtrBuffer++;
|
|
Digits[1] = *PtrBuffer;
|
|
Digits[2] = L'\0';
|
|
Data = StrHexToUintn (Digits);
|
|
Guid->Data4[Index] = (UINT8)Data;
|
|
}
|
|
|
|
FreePool (Buffer);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Reclaim string depository by moving the current node pointer to list head.
|
|
|
|
@param[in] StringDepository Pointer to the string repository
|
|
**/
|
|
VOID
|
|
SecureBootReclaimStrDepository (
|
|
IN STRING_DEPOSITORY *StrDepository
|
|
)
|
|
{
|
|
if (StrDepository != NULL) {
|
|
StrDepository->CurrentNode = StrDepository->ListHead;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Fetch a usable string node from the string depository and return the string token.
|
|
|
|
@param[in] CallbackData Pointer to SECURE_BOOT_MANAGER_CALLBACK_DATA instance
|
|
@param[in] StringDepository Pointer of the string depository
|
|
|
|
@return String token or zero if input parameter is NULL or fail to allocate memory.
|
|
**/
|
|
EFI_STRING_ID
|
|
SecureBootGetStrTokenFromDepository (
|
|
IN SECURE_BOOT_MANAGER_CALLBACK_DATA *CallbackData,
|
|
IN STRING_DEPOSITORY *StringDepository
|
|
)
|
|
{
|
|
STRING_LIST_NODE *CurrentListNode;
|
|
STRING_LIST_NODE *NextListNode;
|
|
|
|
if (CallbackData == NULL || StringDepository == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
CurrentListNode = StringDepository->CurrentNode;
|
|
|
|
if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {
|
|
//
|
|
// Fetch one reclaimed node from the list.
|
|
//
|
|
NextListNode = StringDepository->CurrentNode->Next;
|
|
} else {
|
|
//
|
|
// If there is no usable node in the list, update the list.
|
|
//
|
|
NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));
|
|
if (NextListNode == NULL) {
|
|
return 0;
|
|
}
|
|
NextListNode->StringToken = HiiSetString (
|
|
CallbackData->HiiHandle,
|
|
NextListNode->StringToken,
|
|
L" ",
|
|
NULL
|
|
);
|
|
ASSERT (NextListNode->StringToken != 0);
|
|
|
|
StringDepository->TotalNodeNumber++;
|
|
|
|
if (NULL == CurrentListNode) {
|
|
StringDepository->ListHead = NextListNode;
|
|
} else {
|
|
CurrentListNode->Next = NextListNode;
|
|
}
|
|
}
|
|
|
|
StringDepository->CurrentNode = NextListNode;
|
|
|
|
return StringDepository->CurrentNode->StringToken;
|
|
}
|
|
|
|
/**
|
|
Show H2O confirm dialog with ok button.
|
|
|
|
@param[in] StringId String ID of dialog message
|
|
|
|
@retval EFI_SUCCESS Show H2O confirm dialog successfully.
|
|
@retval EFI_NOT_FOUND Fail to get string.
|
|
**/
|
|
EFI_STATUS
|
|
SecureBootShowOkConfirmDlg (
|
|
IN EFI_STRING_ID StringId
|
|
)
|
|
{
|
|
CHAR16 *String;
|
|
EFI_INPUT_KEY Key;
|
|
|
|
String = HiiGetString (mSecureBootPrivate.HiiHandle, StringId, NULL);
|
|
if (String == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
mSecureBootPrivate.H2ODialog->ConfirmDialog (
|
|
DlgOk,
|
|
FALSE,
|
|
0,
|
|
NULL,
|
|
&Key,
|
|
String
|
|
);
|
|
FreePool (String);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|