diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.c index 0ce85a10..216b5a3c 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.c +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.c @@ -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 diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.h index f15755a3..6f2d62ed 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.h +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.h @@ -110,7 +110,7 @@ typedef struct _VTOY_SHIM{ VTOY_LAUNCHED Launched; } VTOY_SHIM; -CONST UINT8 * ventoy_get_der_data(UINT32 *Len); +void calc_sha256(const void *data, UINT64 len, void *output); #endif diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.inf b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.inf index 5ed232bb..6cce933d 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.inf +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.inf @@ -31,6 +31,7 @@ [Sources] VtoyShim.h VtoyShim.c + sha256.c [Packages] MdePkg/MdePkg.dec diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/sha256.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/sha256.c new file mode 100644 index 00000000..eb2e2a24 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/sha256.c @@ -0,0 +1,170 @@ +/****************************************************************************** + * VtoyShim.c + * + * Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: BSD-2-Clause-Patent + * + */ + +#include +#include +#include +#include +#include + + +static const UINT32 sha256_initial_h[8] + = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; + +static const UINT32 sha256_round_k[64] + = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; + +static void sha256_endian_reverse64(UINT64 input, UINT8 *output) { + output[7] = (input >> 0) & 0xff; + output[6] = (input >> 8) & 0xff; + output[5] = (input >> 16) & 0xff; + output[4] = (input >> 24) & 0xff; + output[3] = (input >> 32) & 0xff; + output[2] = (input >> 40) & 0xff; + output[1] = (input >> 48) & 0xff; + output[0] = (input >> 56) & 0xff; +} + +static UINT32 sha256_endian_read32(UINT8 *input) { + UINT32 output = 0; + output |= (input[0] << 24); + output |= (input[1] << 16); + output |= (input[2] << 8); + output |= (input[3] << 0); + + return output; +} + +static void sha256_endian_reverse32(UINT32 input, UINT8 *output) { + output[3] = (input >> 0) & 0xff; + output[2] = (input >> 8) & 0xff; + output[1] = (input >> 16) & 0xff; + output[0] = (input >> 24) & 0xff; +} + +static UINT32 sha256_ror(UINT32 input, UINT32 by) { + return (input >> by) | (((input & ((1 << by) - 1))) << (32 - by)); +} + +void calc_sha256(const void *data, UINT64 len, void *output) +{ + int i = 0; + int j = 0; + UINT8 padding[80]; + UINT64 current = (len + 1) % 64; + // want to be == 56 % 64. + UINT64 needed = (64 + 56 - current) % 64; + UINT64 extra = needed + 9; + UINT64 total = len + extra; + UINT32 v[8]; + UINT64 cursor = 0; + + for(i = 1; i < 80; i++) + { + padding[i] = 0; + } + padding[0] = 0x80; + + sha256_endian_reverse64(len * 8, padding + total - len - 8); + + for(i = 0; i < 8; i++) + { + v[i] = sha256_initial_h[i]; + } + + for(cursor = 0; cursor * 64 < total; cursor++) + { + UINT32 t[8]; + UINT32 w[64]; + + for(i = 0; i < 8; i++) + { + t[i] = v[i]; + } + + + if(cursor * 64 + 64 <= len) + { + for(j = 0; j < 16; j++) + { + w[j] = sha256_endian_read32((UINT8 *)data + cursor * 64 + j * 4); + } + } + else + { + if(cursor * 64 < len) + { + UINT64 size = len - cursor * 64; + if(size > 0) + { + CopyMem(w, (UINT8 *)data + cursor * 64, size); + } + CopyMem((UINT8 *)w + size, padding, 64 - size); + } + else + { + UINT64 off = (cursor * 64 - len) % 64; + CopyMem((UINT8 *)w, padding + off, 64); + } + + for(j = 0; j < 16; j++) + { + w[j] = sha256_endian_read32((UINT8 *)&w[j]); + } + } + + for(j = 16; j < 64; j++) + { + UINT32 s1 = sha256_ror(w[j - 2], 17) ^ sha256_ror(w[j - 2], 19) ^ (w[j - 2] >> 10); + UINT32 s0 = sha256_ror(w[j - 15], 7) ^ sha256_ror(w[j - 15], 18) ^ (w[j - 15] >> 3); + w[j] = s1 + w[j - 7] + s0 + w[j - 16]; + } + + for(j = 0; j < 64; j++) + { + UINT32 ch = (t[4] & t[5]) ^ (~t[4] & t[6]); + UINT32 maj = (t[0] & t[1]) ^ (t[0] & t[2]) ^ (t[1] & t[2]); + UINT32 S0 = sha256_ror(t[0], 2) ^ sha256_ror(t[0], 13) ^ sha256_ror(t[0], 22); + UINT32 S1 = sha256_ror(t[4], 6) ^ sha256_ror(t[4], 11) ^ sha256_ror(t[4], 25); + UINT32 t1 = t[7] + S1 + ch + sha256_round_k[j] + w[j]; + UINT32 t2 = S0 + maj; + + t[7] = t[6]; + t[6] = t[5]; + t[5] = t[4]; + t[4] = t[3] + t1; + t[3] = t[2]; + t[2] = t[1]; + t[1] = t[0]; + t[0] = t1 + t2; + } + + for(i = 0; i < 8; i++) + { + v[i] += t[i]; + } + } + + for(i = 0; i < 8; i++) + { + sha256_endian_reverse32(v[i], (UINT8 *)output + i * 4); + } +} + + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c index 1911d916..09c5fd86 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c @@ -6463,7 +6463,12 @@ static grub_err_t ventoy_cmd_sb_info(grub_extcmd_context_t ctxt, int argc, char (void)args; #ifdef GRUB_MACHINE_EFI + const char *env = NULL; const char *policy = NULL; + grub_efi_guid_t security = + { 0xA46423E3, 0x4617, 0x49f1, {0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39 } }; + grub_efi_guid_t security2 = + { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } }; if (g_sb_policy == VTOY_SB_POLICY_BYPASS) { @@ -6478,8 +6483,14 @@ static grub_err_t ventoy_cmd_sb_info(grub_extcmd_context_t ctxt, int argc, char policy = "XXX"; } - grub_printf("UEFI Firmware Secure Boot: %s\n", g_sys_sb ? "Enable" : "Disable"); - grub_printf("Ventoy Secure Boot Policy: %s\n", policy); + env = grub_env_get("grub_uefi_version"); + grub_printf("UEFI Firmware Version : %s\n", env ? env : "NA"); + grub_printf("UEFI Firmware Secure Boot : %s\n", g_sys_sb ? "Enable" : "Disable"); + grub_printf("Ventoy Secure Boot Policy : %s\n", policy); + + grub_printf("UEFI Security Protocol : %s\n", grub_efi_locate_protocol(&security, NULL) ? "Yes" : "No"); + grub_printf("UEFI Security2 Protocol : %s\n", grub_efi_locate_protocol(&security2, NULL) ? "Yes" : "No"); + #else grub_printf("Non EFI mode!\n"); #endif diff --git a/INSTALL/ventoy_pack.sh b/INSTALL/ventoy_pack.sh index 42bc72e2..850d8f4a 100644 --- a/INSTALL/ventoy_pack.sh +++ b/INSTALL/ventoy_pack.sh @@ -206,7 +206,7 @@ sign_efi $tmpmnt/ventoy/wimboot.i386.efi.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}') +grub_sha256=$(sha256sum $tmpmnt/EFI/BOOT/grubx64_real.efi | awk '{print $1}') 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" @@ -215,9 +215,9 @@ 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_cmd=$(echo $grub_sha256 | sed 's/\(..\)/\\x\1/g') -echo Ventoy Grub sign hash $grub_signsha256 +echo Ventoy Grub hash $grub_sha256 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