Optimization for secure boot process.
Some checks failed
Ventoy CI / build (push) Has been cancelled
Mirror GitHub to Gitee / Sync-GitHub-to-Gitee (push) Has been cancelled

This commit is contained in:
longpanda
2026-06-28 21:48:32 +08:00
parent 2915e197e9
commit 3d0d6c3147
6 changed files with 212 additions and 221 deletions

View File

@@ -79,11 +79,15 @@ STATIC VOID EFIAPI DumpDevicePath(const EFI_DEVICE_PATH_PROTOCOL *DevicePath)
{
CHAR16 *DPStr = NULL;
DPStr = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
if (DevicePath)
{
DPStr = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
}
if (DPStr)
{
vLog(L"%s", DPStr);
gBS->FreePool(DPStr);
FreePool(DPStr);
}
else
{
@@ -98,7 +102,7 @@ STATIC VOID EFIAPI ShowSBWarning(const EFI_DEVICE_PATH_PROTOCOL *DevicePath)
DumpDevicePath(DevicePath);
vLog(L"\r\n####### Security Boot Violation ##########\r\n");
vLog(L"\r\n####### Ventoy Security Boot Violation ##########\r\n");
vLog(L"=======================================================");
vLog(L"=======================================================");
@@ -208,179 +212,33 @@ END:
}
STATIC EFI_STATUS EFIAPI ReadAuthFile
(
const EFI_DEVICE_PATH_PROTOCOL *DevicePathConst,
VOID **Buffer,
UINT32 *Size
)
{
EFI_STATUS Status;
UINTN TmpSize = 0;
CHAR16 *DpStr = NULL;
EFI_HANDLE Handle = NULL;
EFI_DEVICE_PATH *DevPath = NULL;
EFI_DEVICE_PATH *TmpPath = NULL;
EFI_FILE_IO_INTERFACE *FileIO = NULL;
EFI_FILE *File = NULL;
EFI_FILE *Root = NULL;
UINT8 *FileData = NULL;
EFI_FILE_INFO *FInfo = NULL;
UINT8 Buf[1024];
DevPath = TmpPath = DuplicateDevicePath(DevicePathConst);
if (!DevPath)
{
Status = EFI_OUT_OF_RESOURCES;
goto END;
}
Status = gBS->LocateDevicePath(&gEfiSimpleFileSystemProtocolGuid, &DevPath, &Handle);
if (EFI_ERROR(Status))
{
vLog(L"Failed to locate simple file protocol %lx", Status);
goto END;
}
DpStr = ConvertDevicePathToText(DevPath, FALSE, TRUE);
if (!DpStr)
{
Status = EFI_OUT_OF_RESOURCES;
goto END;
}
Status = gBS->HandleProtocol(Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&FileIO);
if (EFI_ERROR(Status))
{
vLog(L"Failed to handle simple file protocol %lx", Status);
goto END;
}
Status = FileIO->OpenVolume(Handle, &Root);
if (EFI_ERROR(Status))
{
vLog(L"Failed to open drive volume (%lx)\n", Status);
goto END;
}
Status = Root->Open(Root, &File, DpStr, EFI_FILE_MODE_READ, 0);
if (EFI_ERROR(Status))
{
vLog(L"Failed to open file (%s) (%lx)\n", DpStr, Status);
goto END;
}
FInfo = (EFI_FILE_INFO *)Buf;
TmpSize = sizeof(Buf);
ZeroMem(FInfo, sizeof(EFI_FILE_INFO));
Status = File->GetInfo(File, &gEfiFileInfoGuid, &TmpSize, FInfo);
if (EFI_ERROR(Status) || FInfo->FileSize == 0 || FInfo->FileSize >= 0xFFFFFFFFUL)
{
vLog(L"Failed to open file (%s) (%lx) Size(%ld)\n", DpStr, Status, (UINTN)FInfo->FileSize);
goto END;
}
FileData = AllocatePool(FInfo->FileSize);
if (!FileData)
{
Status = EFI_OUT_OF_RESOURCES;
goto END;
}
TmpSize = FInfo->FileSize;
Status = File->Read(File, &TmpSize, FileData);
if (EFI_ERROR(Status) || TmpSize != (UINTN)FInfo->FileSize)
{
vLog(L"Failed to read file (%lx) Read:%ld Size:%ld\n", Status, TmpSize, (UINTN)FInfo->FileSize);
goto END;
}
END:
if (File)
{
File->Close(File);
}
if (Root)
{
Root->Close(Root);
}
CheckFreePool(TmpPath);
CheckFreePool(DpStr);
if (EFI_ERROR(Status))
{
CheckFreePool(FileData);
}
else
{
*Buffer = FileData;
*Size = (UINT32)FInfo->FileSize;
}
return Status;
}
STATIC EFI_STATUS EFIAPI CheckVtoyGrub
(
VOID *FileBuffer,
UINTN FileSize
)
{
UINTN Index = 0;
EFI_STATUS Status = EFI_SECURITY_VIOLATION;
PE_COFF_LOADER_IMAGE_CONTEXT Ctx;
UINT8 Sha256Hash[64];
UINT8 Sha1Hash[64];
ZeroMem(&Ctx, sizeof(Ctx));
ZeroMem(Sha1Hash, sizeof(Sha1Hash));
if (!FileBuffer || FileSize < sizeof(EFI_IMAGE_DOS_HEADER))
{
vErr(L"Invalid FileBuffer:%p or size:%ld", FileBuffer, FileSize);
return EFI_SECURITY_VIOLATION;
}
ZeroMem(Sha256Hash, sizeof(Sha256Hash));
Status = gShimLock.Context(FileBuffer, FileSize, &Ctx);
if (EFI_ERROR(Status))
{
vErr(L"Cannot get shim context %lx", Status);
goto END;
}
Status = gShimLock.Hash(FileBuffer, FileSize, &Ctx, Sha256Hash, Sha1Hash);
if (EFI_ERROR(Status))
{
vErr(L"Cannot get shim hash %lx", Status);
goto END;
}
calc_sha256(FileBuffer, (UINT64)FileSize, Sha256Hash);
if (CompareMem(Sha256Hash, gVtoyGrubSha256Hash, 32) != 0)
{
vErr(L"Ventoy hash check failed.");
goto END;
}
Status = EFI_SUCCESS;
END:
if (EFI_ERROR(Status))
{
vLog(L"\r\n###### Press Enter to reboot... ######");
if (gST->ConIn)
{
gST->ConIn->Reset(gST->ConIn, FALSE);
gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &Index);
}
gRT->ResetSystem(EfiResetWarm, EFI_SECURITY_VIOLATION, 0, NULL);
return EFI_SECURITY_VIOLATION;
}
return Status;
return EFI_SUCCESS;
}
STATIC EFI_STATUS EFIAPI SecurityPolicyAuth
(
const EFI_SECURITY_ARCH_PROTOCOL *This,
@@ -388,66 +246,17 @@ STATIC EFI_STATUS EFIAPI SecurityPolicyAuth
const EFI_DEVICE_PATH_PROTOCOL *DevicePathConst
)
{
EFI_STATUS Status;
UINT32 Size = 0;
VOID *Buffer = NULL;
/* Just return OK if the user choose to bypass SB */
if (gVtoyByPassSB)
{
return EFI_SUCCESS;
}
if (!gGrubLaunched)
{
Status = ReadAuthFile(DevicePathConst, &Buffer, &Size);
if (EFI_ERROR(Status))
{
return EFI_SECURITY_VIOLATION;
}
Status = CheckVtoyGrub(Buffer, Size);
FreePool(Buffer);
return Status;
}
/*
* Step 1:
* Use original UEFI firmware auth API.
* If it's OK, it may be signed with Microsoft UEFI CA. (e.g. bootmgr/shim/...)
* Some old UEFI firmware (without Security2 protocol) will hang when run OpenVolume.
* So finally I decide not to support such UEFI firmware.
* It means that for UEFI firmware before 2.5 (about 2015) Ventoy only supports Bypass policy.
*
*/
if (gSysSecFileAuth)
{
Status = gSysSecFileAuth(This, AuthenticationStatus, DevicePathConst);
if (!EFI_ERROR(Status))
{
return EFI_SUCCESS;
}
}
/*
* Step 2:
* Use shim verify API.
* If it's OK, it may be signed with a MOK key. (e.g. Ventoy EFI files)
*/
if (gShimLock.Verify)
{
Status = ReadAuthFile(DevicePathConst, &Buffer, &Size);
if (!EFI_ERROR(Status))
{
Status = gShimLock.Verify(Buffer, Size);
FreePool(Buffer);
if (!EFI_ERROR(Status))
{
return EFI_SUCCESS;
}
}
}
ShowSBWarning(DevicePathConst);
return EFI_SECURITY_VIOLATION;
(VOID)This;
(VOID)AuthenticationStatus;
(VOID)DevicePathConst;
return EFI_SUCCESS;
}
STATIC EFI_STATUS EFIAPI Security2PolicyAuth