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 00:24:59 +08:00
parent 9bf8393cdf
commit 2915e197e9
5 changed files with 107 additions and 68 deletions

View File

@@ -34,8 +34,14 @@
#define CUR_SBAT_VER 1 #define CUR_SBAT_VER 1
STATIC BOOLEAN gPolicySetFlag = FALSE; STATIC UINT8 gVtoyGrubSha256Hash[32] __attribute__((aligned(32))) = {
STATIC EFI_GUID gVtoySbatGUID = { 0xf755068a, 0xe04f, 0x452b, { 0x9d, 0x6d, 0x7c, 0x55, 0x96, 0xb3, 0xc0, 0x7d }}; 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26
};
STATIC BOOLEAN gGrubLaunched = FALSE;
STATIC EFI_GUID gShimLockGUID = SHIM_LOCK_GUID; STATIC EFI_GUID gShimLockGUID = SHIM_LOCK_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;
@@ -85,10 +91,8 @@ STATIC VOID EFIAPI DumpDevicePath(const EFI_DEVICE_PATH_PROTOCOL *DevicePath)
} }
} }
STATIC VOID EFIAPI ShowSBWarning(BOOLEAN Reboot, const EFI_DEVICE_PATH_PROTOCOL *DevicePath) STATIC VOID EFIAPI ShowSBWarning(const EFI_DEVICE_PATH_PROTOCOL *DevicePath)
{ {
UINTN Index = 0;
vLog(L"\r\n======================================================="); vLog(L"\r\n=======================================================");
vLog(L"=======================================================\r\n"); vLog(L"=======================================================\r\n");
@@ -99,21 +103,8 @@ STATIC VOID EFIAPI ShowSBWarning(BOOLEAN Reboot, const EFI_DEVICE_PATH_PROTOCOL
vLog(L"======================================================="); vLog(L"=======================================================");
vLog(L"======================================================="); vLog(L"=======================================================");
if (Reboot)
{
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);
}
else
{
VtoySleep(5); VtoySleep(5);
} }
}
STATIC VOID * EFIAPI FindShimFuncAddr(UINT64 FuncOffset) STATIC VOID * EFIAPI FindShimFuncAddr(UINT64 FuncOffset)
@@ -335,28 +326,61 @@ END:
return Status; 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];
STATIC BOOLEAN VtoyCheckRevoke(VOID *Buffer, UINTN Size) ZeroMem(&Ctx, sizeof(Ctx));
{ ZeroMem(Sha1Hash, sizeof(Sha1Hash));
UINT32 uiVer = 0; ZeroMem(Sha256Hash, sizeof(Sha256Hash));
EFI_IMAGE_DOS_HEADER *DosHead = (EFI_IMAGE_DOS_HEADER *)Buffer;
if (Size > sizeof(EFI_IMAGE_DOS_HEADER) && DosHead->e_magic == 0x5A4D) Status = gShimLock.Context(FileBuffer, FileSize, &Ctx);
if (EFI_ERROR(Status))
{ {
if (CompareMem(DosHead->e_res2, &gVtoySbatGUID, 16) == 0) vErr(L"Cannot get shim context %lx", Status);
{ goto END;
CopyMem(&uiVer, DosHead->e_res2 + 8, 4);
if (uiVer < CUR_SBAT_VER)
{
vLog(L"Ventoy EFI file revoke (%u < %u)", uiVer, CUR_SBAT_VER);
return FALSE;
}
}
} }
return TRUE; Status = gShimLock.Hash(FileBuffer, FileSize, &Ctx, Sha256Hash, Sha1Hash);
if (EFI_ERROR(Status))
{
vErr(L"Cannot get shim hash %lx", Status);
goto END;
} }
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 Status;
}
STATIC EFI_STATUS EFIAPI SecurityPolicyAuth STATIC EFI_STATUS EFIAPI SecurityPolicyAuth
( (
const EFI_SECURITY_ARCH_PROTOCOL *This, const EFI_SECURITY_ARCH_PROTOCOL *This,
@@ -365,7 +389,6 @@ STATIC EFI_STATUS EFIAPI SecurityPolicyAuth
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
BOOLEAN bRevokeChkOK = TRUE;
UINT32 Size = 0; UINT32 Size = 0;
VOID *Buffer = NULL; VOID *Buffer = NULL;
@@ -375,9 +398,17 @@ STATIC EFI_STATUS EFIAPI SecurityPolicyAuth
return EFI_SUCCESS; return EFI_SUCCESS;
} }
if (!gPolicySetFlag) if (!gGrubLaunched)
{ {
goto SHIM_CHECK; Status = ReadAuthFile(DevicePathConst, &Buffer, &Size);
if (EFI_ERROR(Status))
{
return EFI_SECURITY_VIOLATION;
}
Status = CheckVtoyGrub(Buffer, Size);
FreePool(Buffer);
return Status;
} }
/* /*
@@ -395,8 +426,6 @@ STATIC EFI_STATUS EFIAPI SecurityPolicyAuth
} }
SHIM_CHECK:
/* /*
* Step 2: * Step 2:
* Use shim verify API. * Use shim verify API.
@@ -408,20 +437,15 @@ SHIM_CHECK:
if (!EFI_ERROR(Status)) if (!EFI_ERROR(Status))
{ {
Status = gShimLock.Verify(Buffer, Size); Status = gShimLock.Verify(Buffer, Size);
FreePool(Buffer);
if (!EFI_ERROR(Status)) if (!EFI_ERROR(Status))
{ {
bRevokeChkOK = VtoyCheckRevoke(Buffer, Size);
if (bRevokeChkOK)
{
FreePool(Buffer);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
} }
FreePool(Buffer);
}
} }
ShowSBWarning(!bRevokeChkOK, DevicePathConst); ShowSBWarning(DevicePathConst);
return EFI_SECURITY_VIOLATION; return EFI_SECURITY_VIOLATION;
} }
@@ -436,7 +460,6 @@ STATIC EFI_STATUS EFIAPI Security2PolicyAuth
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
BOOLEAN bRevokeChkOK = TRUE;
/* Just return OK if the user choose to bypass SB */ /* Just return OK if the user choose to bypass SB */
if (gVtoyByPassSB) if (gVtoyByPassSB)
@@ -444,9 +467,9 @@ STATIC EFI_STATUS EFIAPI Security2PolicyAuth
return EFI_SUCCESS; return EFI_SUCCESS;
} }
if (!gPolicySetFlag) if (!gGrubLaunched)
{ {
goto SHIM_CHECK; return CheckVtoyGrub(FileBuffer, FileSize);
} }
/* /*
@@ -464,7 +487,6 @@ STATIC EFI_STATUS EFIAPI Security2PolicyAuth
} }
SHIM_CHECK:
/* /*
* Step 2: * Step 2:
* Use shim verify API. * Use shim verify API.
@@ -476,17 +498,13 @@ SHIM_CHECK:
{ {
Status = gShimLock.Verify(FileBuffer, (UINT32)FileSize); Status = gShimLock.Verify(FileBuffer, (UINT32)FileSize);
if (!EFI_ERROR(Status)) if (!EFI_ERROR(Status))
{
bRevokeChkOK = VtoyCheckRevoke(FileBuffer, FileSize);
if (bRevokeChkOK)
{ {
return EFI_SUCCESS; return EFI_SUCCESS;
} }
} }
} }
}
ShowSBWarning(!bRevokeChkOK, DevicePath); ShowSBWarning(DevicePath);
return EFI_SECURITY_VIOLATION; return EFI_SECURITY_VIOLATION;
} }
@@ -559,16 +577,19 @@ STATIC VOID EFIAPI UnHookSecurityPolicy(VOID)
STATIC VOID EFIAPI VtoyByPassSB(VOID) STATIC VOID EFIAPI VtoyByPassSB(VOID)
{ {
gPolicySetFlag = TRUE;
gVtoyByPassSB = TRUE; gVtoyByPassSB = TRUE;
} }
STATIC VOID EFIAPI VtoyCheckSB(VOID) STATIC VOID EFIAPI VtoyCheckSB(VOID)
{ {
gPolicySetFlag = TRUE;
gVtoyByPassSB = FALSE; gVtoyByPassSB = FALSE;
} }
STATIC VOID EFIAPI VtoyLaunched(VOID)
{
gGrubLaunched = TRUE;
}
STATIC VOID EFIAPI UnInstallVtoyShimProtocol(VOID) STATIC VOID EFIAPI UnInstallVtoyShimProtocol(VOID)
{ {
EFI_GUID Guid = VTOY_SHIM_POLICY_GUID; EFI_GUID Guid = VTOY_SHIM_POLICY_GUID;
@@ -588,6 +609,7 @@ STATIC EFI_STATUS EFIAPI InstallVtoyShimProtocol(VOID)
gVtoyShimProtocol.ByPassSB = VtoyByPassSB; gVtoyShimProtocol.ByPassSB = VtoyByPassSB;
gVtoyShimProtocol.CheckSB = VtoyCheckSB; gVtoyShimProtocol.CheckSB = VtoyCheckSB;
gVtoyShimProtocol.Launched = VtoyLaunched;
Status = gBS->LocateProtocol(&Guid, NULL, (VOID**)&Prot); Status = gBS->LocateProtocol(&Guid, NULL, (VOID**)&Prot);
if (!EFI_ERROR(Status)) if (!EFI_ERROR(Status))

View File

@@ -101,12 +101,13 @@ do { \
#define VTOY_SHIM_POLICY_GUID {0x90a29d14, 0x3968, 0x48fe, { 0x85, 0x81, 0x6b, 0x7f, 0x7d, 0xc4, 0x70, 0x55 }}; #define VTOY_SHIM_POLICY_GUID {0x90a29d14, 0x3968, 0x48fe, { 0x85, 0x81, 0x6b, 0x7f, 0x7d, 0xc4, 0x70, 0x55 }};
typedef VOID (EFIAPI *VTOY_BYPASS_SB)(VOID); typedef VOID (EFIAPI *VTOY_BYPASS_SB)(VOID);
typedef VOID (EFIAPI *VTOY_CHECK_SB)(VOID); typedef VOID (EFIAPI *VTOY_CHECK_SB)(VOID);
typedef VOID (EFIAPI *VTOY_LAUNCHED)(VOID);
typedef struct _VTOY_SHIM{ typedef struct _VTOY_SHIM{
VTOY_BYPASS_SB ByPassSB; VTOY_BYPASS_SB ByPassSB;
VTOY_BYPASS_SB CheckSB; VTOY_BYPASS_SB CheckSB;
VTOY_LAUNCHED Launched;
} VTOY_SHIM; } VTOY_SHIM;
CONST UINT8 * ventoy_get_der_data(UINT32 *Len); CONST UINT8 * ventoy_get_der_data(UINT32 *Len);

View File

@@ -406,7 +406,8 @@ static int ventoy_secure_boot_init(void)
if (g_ventoy_plat_data == VTOY_PLAT_X86_64_UEFI) if (g_ventoy_plat_data == VTOY_PLAT_X86_64_UEFI)
{ {
g_vtoy_shim = grub_efi_locate_protocol(&ProtGuid, NULL); g_vtoy_shim = grub_efi_locate_protocol(&ProtGuid, NULL);
if (g_vtoy_shim == NULL || g_vtoy_shim->ByPassSB == NULL || g_vtoy_shim->CheckSB == NULL) if (g_vtoy_shim == NULL || g_vtoy_shim->ByPassSB == NULL ||
g_vtoy_shim->CheckSB == NULL || g_vtoy_shim->Launched == NULL)
{ {
grub_cls(); grub_cls();
grub_printf(VTOY_WARNING"\n"); grub_printf(VTOY_WARNING"\n");
@@ -418,6 +419,8 @@ static int ventoy_secure_boot_init(void)
ventoy_prompt_end(); ventoy_prompt_end();
} }
g_vtoy_shim->Launched();
} }
return 0; return 0;

View File

@@ -199,9 +199,11 @@ typedef struct cpio_newc_header
typedef void (*VTOY_BYPASS_SB)(void); typedef void (*VTOY_BYPASS_SB)(void);
typedef void (*VTOY_CHECK_SB)(void); typedef void (*VTOY_CHECK_SB)(void);
typedef void (*VTOY_LAUNCHED)(void);
typedef struct _VTOY_SHIM{ typedef struct _VTOY_SHIM{
VTOY_BYPASS_SB ByPassSB; VTOY_BYPASS_SB ByPassSB;
VTOY_CHECK_SB CheckSB; VTOY_CHECK_SB CheckSB;
VTOY_LAUNCHED Launched;
} VTOY_SHIM; } VTOY_SHIM;

View File

@@ -12,7 +12,6 @@ if [ "$VENTOY_CERT_PASS" = "YES" ]; then
fi fi
fi fi
SBAT_VER=1
sign_efi() { sign_efi() {
efi=$1 efi=$1
@@ -32,10 +31,6 @@ sign_efi() {
mv ${efi}.unxz ${efi} mv ${efi}.unxz ${efi}
fi fi
sbstr=$(printf "%08x" $SBAT_VER)
echo -en "\x8a\x06\x55\xf7\x4f\xe0\x2b\x45\x9d\x6d\x7c\x55\x96\xb3\xc0\x7d\x${sbstr:6:2}\x${sbstr:4:2}\x${sbstr:2:2}\x${sbstr:0:2}" | \
dd bs=1 count=20 of=${efi} seek=40 conv=notrunc status=none
rm -f "${efi}.signed" rm -f "${efi}.signed"
if [ "$VENTOY_CERT_PASS" = "YES" ]; then if [ "$VENTOY_CERT_PASS" = "YES" ]; then
expect -f ./sign_with_pass.exp "$KEY_PASS" "$VENTOY_CERT_KEY" "$VENTOY_CERT_PEM" "${efi}" "${efi}.signed" >/dev/null 2>&1 expect -f ./sign_with_pass.exp "$KEY_PASS" "$VENTOY_CERT_KEY" "$VENTOY_CERT_PEM" "${efi}" "${efi}.signed" >/dev/null 2>&1
@@ -52,7 +47,7 @@ sign_efi() {
mv "${efi}.signed" "$efi" mv "${efi}.signed" "$efi"
fi fi
else else
echo "### %-64s failed\n" "$efi" printf "### %-64s failed\n" "$efi"
exit 1 exit 1
fi fi
@@ -191,7 +186,6 @@ cp -a ./tool/create_ventoy_iso_part_dm.sh $tmpmnt/tool/
rm -f $tmpmnt/grub/i386-pc/*.img rm -f $tmpmnt/grub/i386-pc/*.img
sign_efi $tmpmnt/EFI/BOOT/fbx64.efi
sign_efi $tmpmnt/EFI/BOOT/fbia32.efi sign_efi $tmpmnt/EFI/BOOT/fbia32.efi
sign_efi $tmpmnt/EFI/BOOT/fbaa64.efi sign_efi $tmpmnt/EFI/BOOT/fbaa64.efi
sign_efi $tmpmnt/EFI/BOOT/grubx64_real.efi sign_efi $tmpmnt/EFI/BOOT/grubx64_real.efi
@@ -211,6 +205,23 @@ sign_efi $tmpmnt/ventoy/vtoyutil_aa64.efi
sign_efi $tmpmnt/ventoy/wimboot.i386.efi.xz sign_efi $tmpmnt/ventoy/wimboot.i386.efi.xz
sign_efi $tmpmnt/ventoy/wimboot.x86_64.xz sign_efi $tmpmnt/ventoy/wimboot.x86_64.xz
#inject Ventoy Grub sign sha256 value into VtoyShim
grub_signsha256=$(pesign -i $tmpmnt/EFI/BOOT/grubx64_real.efi -h -d sha256 | awk '{print $2}')
magic_cnt=$(hexdump -C $tmpmnt/EFI/BOOT/fbx64.efi | grep '26 26 26 26 26 26 26 26' | wc -l)
if [ $magic_cnt -ne 1 ]; then
echo "hash magic duplicate"
exit 1
fi
magic_off_hex=$(hexdump -C $tmpmnt/EFI/BOOT/fbx64.efi | grep '26 26 26 26 26 26 26 26' | awk '{print $1}')
magic_off=$(printf '%u' "0x${magic_off_hex}")
echo_cmd=$(echo $grub_signsha256 | sed 's/\(..\)/\\x\1/g')
echo Ventoy Grub sign hash $grub_signsha256
echo -en "$echo_cmd" | dd bs=1 count=32 of=$tmpmnt/EFI/BOOT/fbx64.efi seek=$magic_off conv=notrunc status=none
sign_efi $tmpmnt/EFI/BOOT/fbx64.efi
umount $tmpmnt && rm -rf $tmpmnt umount $tmpmnt && rm -rf $tmpmnt