Fix the Windows/WinPE secure boot version check failed issue.

Conditions:
1. Secure boot is enabled.
2. Select ByPass policy in Ventoy.
3. With BIOS update to latest. (Windows CA2011 revocated)

Error message is like follows:
Security Error: Secure boot version check failed.
Your system security may be compromised!

Current version: 1.0 - Minimum allowed version: xx.0
Visit https://aka.ms/secure-boot-version-violation for more information.

The system will shutdown in 10 seconds.

......
This commit is contained in:
longpanda
2026-08-06 11:13:37 +08:00
parent 7cbdc5cf69
commit 021c237920
3 changed files with 98 additions and 6 deletions
@@ -21,6 +21,7 @@
#include <Protocol/LoadedImage.h> #include <Protocol/LoadedImage.h>
#include <Guid/FileInfo.h> #include <Guid/FileInfo.h>
#include <Guid/FileSystemInfo.h> #include <Guid/FileSystemInfo.h>
#include <Guid/ImageAuthentication.h>
#include <Protocol/BlockIo.h> #include <Protocol/BlockIo.h>
#include <Protocol/RamDisk.h> #include <Protocol/RamDisk.h>
#include <Protocol/SimpleFileSystem.h> #include <Protocol/SimpleFileSystem.h>
@@ -43,6 +44,8 @@ STATIC UINT8 gVtoyGrubSha256Hash[32] __attribute__((aligned(32))) = {
STATIC BOOLEAN gGrubLaunched = FALSE; STATIC BOOLEAN gGrubLaunched = FALSE;
STATIC EFI_GUID gShimLockGUID = SHIM_LOCK_GUID; STATIC EFI_GUID gShimLockGUID = SHIM_LOCK_GUID;
STATIC EFI_GUID gMsftDBXSVNOwnerGUID = MSFT_DBX_SVN_OWN_GUID;
STATIC EFI_GUID gBootMgrDBXSVNGUID = EFI_BOOTMGR_DBXSVN_GUID;
STATIC EFI_SECURITY_FILE_AUTHENTICATION_STATE gSysSecFileAuth = NULL; STATIC EFI_SECURITY_FILE_AUTHENTICATION_STATE gSysSecFileAuth = NULL;
STATIC EFI_SECURITY2_FILE_AUTHENTICATION gSysSec2FileAuth = NULL; STATIC EFI_SECURITY2_FILE_AUTHENTICATION gSysSec2FileAuth = NULL;
STATIC BOOLEAN gVtoyByPassSB = FALSE; /* must be FALSE by default for revoke */ STATIC BOOLEAN gVtoyByPassSB = FALSE; /* must be FALSE by default for revoke */
@@ -560,6 +563,60 @@ END:
return Status; return Status;
} }
STATIC EFI_STATUS EFIAPI VtoyHookDBX(UINTN DataSize, VOID *Data)
{
UINT32 i = 0;
UINT32 Count = 0;
UINTN Offset = 0;
EFI_SIGNATURE_LIST *pstCurSig = NULL;
EFI_SIGNATURE_DATA *pstSigData = NULL;
for (Offset = 0; Offset + sizeof(EFI_SIGNATURE_LIST) <= DataSize; Offset += pstCurSig->SignatureListSize)
{
pstCurSig = (EFI_SIGNATURE_LIST *)((UINT8 *)Data + Offset);
if (pstCurSig->SignatureSize == 0 || pstCurSig->SignatureListSize == 0 ||
Offset + pstCurSig->SignatureListSize > DataSize ||
pstCurSig->SignatureListSize < sizeof(EFI_SIGNATURE_LIST) + pstCurSig->SignatureHeaderSize)
{
break;
}
if (!CompareGuid(&pstCurSig->SignatureType, &gEfiCertSha256Guid))
{
continue;
}
pstSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)pstCurSig + sizeof(EFI_SIGNATURE_LIST) + pstCurSig->SignatureHeaderSize);
Count = (pstCurSig->SignatureListSize - sizeof(EFI_SIGNATURE_LIST) - pstCurSig->SignatureHeaderSize) / pstCurSig->SignatureSize;
#if 0
if (Count > 0 && pstCurSig->SignatureSize == 48)
{
vDbg(L"Make a fake SVN signature for test");
CopyMem(&pstSigData->SignatureOwner, &gMsftDBXSVNOwnerGUID, sizeof(EFI_GUID));
ZeroMem(pstSigData->SignatureData, pstCurSig->SignatureSize);
CopyMem(&pstSigData->SignatureData + 1, &gBootMgrDBXSVNGUID, sizeof(EFI_GUID));
pstSigData->SignatureData[0] = 1;
DBX_SVN_SET(pstSigData->SignatureData, 100);
break;
}
#endif
for (i = 0; i < Count; i++)
{
if (CompareGuid(&pstSigData->SignatureOwner, &gMsftDBXSVNOwnerGUID) &&
CompareGuid((CONST EFI_GUID *)(pstSigData->SignatureData + 1), &gBootMgrDBXSVNGUID))
{
DBX_SVN_SET(pstSigData->SignatureData, 1);
return EFI_SUCCESS;
}
pstSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)pstSigData + pstCurSig->SignatureSize);
}
}
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI VtoyGetVariable EFI_STATUS EFIAPI VtoyGetVariable
( (
IN CHAR16 *VariableName, IN CHAR16 *VariableName,
@@ -572,19 +629,22 @@ EFI_STATUS EFIAPI VtoyGetVariable
BOOLEAN bChk = FALSE; BOOLEAN bChk = FALSE;
EFI_STATUS Status; EFI_STATUS Status;
if (gVtoyByPassSB && VariableName && VendorGuid && DataSize && Data && (*DataSize) > 0) if (gVtoyByPassSB && VariableName && VendorGuid && DataSize && Data)
{ {
bChk = TRUE; bChk = TRUE;
} }
Status = gSysGetVariable(VariableName, VendorGuid, Attributes, DataSize, Data); Status = gSysGetVariable(VariableName, VendorGuid, Attributes, DataSize, Data);
if (bChk && (!EFI_ERROR(Status))) if (bChk && EFI_SUCCESS == Status)
{ {
if (CompareMem(&gShimLockGUID, VendorGuid, 16) == 0 && if (EFI_VAR_MATCH(&gShimLockGUID, L"MokSBState"))
StrCmp(VariableName, L"MokSBState") == 0)
{ {
*(UINT8 *)Data = 1; *(UINT8 *)Data = 1;
} }
else if (EFI_VAR_MATCH(&gEfiImageSecurityDatabaseGuid, L"dbx"))
{
VtoyHookDBX(*DataSize, Data);
}
} }
return Status; return Status;
@@ -592,6 +652,9 @@ EFI_STATUS EFIAPI VtoyGetVariable
STATIC VOID EFIAPI UnHookSystemService(VOID) STATIC VOID EFIAPI UnHookSystemService(VOID)
{ {
UINT32 uiNewCRC = 0;
EFI_TABLE_HEADER *Hdr = &gST->RuntimeServices->Hdr;
if (gSysExitBootServices) if (gSysExitBootServices)
{ {
gBS->ExitBootServices = gSysExitBootServices; gBS->ExitBootServices = gSysExitBootServices;
@@ -602,6 +665,10 @@ STATIC VOID EFIAPI UnHookSystemService(VOID)
{ {
gST->RuntimeServices->GetVariable = gSysGetVariable; gST->RuntimeServices->GetVariable = gSysGetVariable;
gSysGetVariable = NULL; gSysGetVariable = NULL;
Hdr->CRC32 = 0;
gBS->CalculateCrc32(Hdr, Hdr->HeaderSize, &uiNewCRC);
Hdr->CRC32 = uiNewCRC;
} }
} }
@@ -626,11 +693,18 @@ STATIC EFI_STATUS EFIAPI VtoyExitBootServices
STATIC VOID EFIAPI HookSystemService(VOID) STATIC VOID EFIAPI HookSystemService(VOID)
{ {
UINT32 uiNewCRC = 0;
EFI_TABLE_HEADER *Hdr = &gST->RuntimeServices->Hdr;
gSysExitBootServices = gBS->ExitBootServices; gSysExitBootServices = gBS->ExitBootServices;
gBS->ExitBootServices = VtoyExitBootServices; gBS->ExitBootServices = VtoyExitBootServices;
gSysGetVariable = gST->RuntimeServices->GetVariable; gSysGetVariable = gST->RuntimeServices->GetVariable;
gST->RuntimeServices->GetVariable = VtoyGetVariable; gST->RuntimeServices->GetVariable = VtoyGetVariable;
Hdr->CRC32 = 0;
gBS->CalculateCrc32(Hdr, Hdr->HeaderSize, &uiNewCRC);
Hdr->CRC32 = uiNewCRC;
} }
EFI_STATUS EFIAPI VtoyShimEfiMain EFI_STATUS EFIAPI VtoyShimEfiMain
@@ -22,7 +22,23 @@
/* The following definations are copied from shim source code */ /* The following definations are copied from shim source code */
#define SHIM_LOCK_GUID {0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } }; #define SHIM_LOCK_GUID {0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } }
#define MSFT_DBX_SVN_OWN_GUID { 0x9d132b6c, 0x59d5, 0x4388, {0xab, 0x1c, 0x18, 0x5c, 0xfc, 0xb2, 0xeb, 0x92}}
#define EFI_BOOTMGR_DBXSVN_GUID { 0x9d132b61, 0x59d5, 0x4388, {0xab, 0x1c, 0x18, 0x5c, 0x3c, 0xb2, 0xeb, 0x92}}
#define EFI_VAR_MATCH(pguid, name) \
(CompareMem((pguid), VendorGuid, 16) == 0 && StrCmp(VariableName, (name)) == 0)
#define DBX_SVN_SET(SigData, SVN) \
do { \
SigData[17] = 0; \
SigData[18] = 0; \
SigData[19] = (SVN); \
SigData[20] = 0; \
} while (0)
typedef typedef
EFI_STATUS EFI_STATUS
@@ -88,7 +104,7 @@ typedef VOID (*shim_void_func_pf)(VOID);
#define VtoySleep(sec) gBS->Stall(1000000 * (sec)) #define VtoySleep(sec) gBS->Stall(1000000 * (sec))
#define vLog(fmt, ...) VtoyLog(fmt "\r\n", ##__VA_ARGS__) #define vLog(fmt, ...) VtoyLog(fmt "\r\n", ##__VA_ARGS__)
#define vErr(fmt, ...) VtoyLog(fmt "\r\n", ##__VA_ARGS__); VtoySleep(5) #define vErr(fmt, ...) VtoyLog(fmt "\r\n", ##__VA_ARGS__); VtoySleep(5)
#define vDbg(fmt, ...) VtoyLog(fmt "\r\n", ##__VA_ARGS__); VtoySleep(2) #define vDbg(fmt, ...) VtoyLog(fmt "\r\n", ##__VA_ARGS__); VtoySleep(1)
#define CheckFreePool(p) \ #define CheckFreePool(p) \
do { \ do { \
@@ -46,6 +46,8 @@
[Guids] [Guids]
gEfiGlobalVariableGuid gEfiGlobalVariableGuid
gEfiImageSecurityDatabaseGuid
gEfiCertSha256Guid
gShellVariableGuid gShellVariableGuid
gEfiVirtualCdGuid gEfiVirtualCdGuid
gEfiFileInfoGuid gEfiFileInfoGuid