From 2d72e42c6c0abd96e01fdcfb2737977dbda8edbe Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sun, 14 Aug 2016 23:01:26 +0200 Subject: Windows: Implement Rescue Disk support for EFI system encryption --- src/Common/BootEncryption.cpp | 617 ++++++++++++++++++++++++++++++++---------- 1 file changed, 475 insertions(+), 142 deletions(-) (limited to 'src/Common/BootEncryption.cpp') diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp index dd0b9d13..0146c7a5 100644 --- a/src/Common/BootEncryption.cpp +++ b/src/Common/BootEncryption.cpp @@ -29,6 +29,8 @@ #include "Registry.h" #include "Volumes.h" #include "Xml.h" +#include "XZip.h" +#include "XUnzip.h" #ifdef VOLFORMAT #include "Format/FormatCom.h" @@ -575,10 +577,17 @@ namespace VeraCrypt LARGE_INTEGER lSize; lSize.QuadPart = 0; throw_sys_if (!GetFileSizeEx (Handle, &lSize)); - size = (size_t) lSize.QuadPart; + size = (unsigned __int64) lSize.QuadPart; } } + void File::GetFileSize (DWORD& dwSize) + { + unsigned __int64 size64; + GetFileSize (size64); + dwSize = (DWORD) size64; + } + void File::Write (byte *buffer, DWORD size) { DWORD bytesWritten; @@ -682,6 +691,8 @@ namespace VeraCrypt ParentWindow (parent), RealSystemDriveSizeValid (false), RescueIsoImage (nullptr), + RescueZipData (nullptr), + RescueZipSize (0), RescueVolumeHeaderValid (false), SelectedEncryptionAlgorithmId (0), SelectedPrfAlgorithmId (0), @@ -701,7 +712,15 @@ namespace VeraCrypt BootEncryption::~BootEncryption () { if (RescueIsoImage) + { + burn (RescueIsoImage, RescueIsoImageSize); delete[] RescueIsoImage; + } + if (RescueZipData) + { + burn (RescueZipData, RescueZipSize); + delete [] RescueZipData; + } Elevator::Release(); } @@ -2515,6 +2534,10 @@ namespace VeraCrypt byte *LegacySpeakerImg = MapResource(L"BIN", IDR_EFI_LEGACYSPEAKER, &sizeLegacySpeaker); if (!LegacySpeakerImg) throw ErrorException(L"Out of resource LegacySpeaker", SRC_POS); + DWORD sizeBootMenuLocker; + byte *BootMenuLockerImg = MapResource(L"BIN", IDR_EFI_DCSBML, &sizeBootMenuLocker); + if (!BootMenuLockerImg) + throw ErrorException(L"Out of resource DcsBml", SRC_POS); finally_do ({ EfiBootInst.DismountBootPartition(); }); EfiBootInst.MountBootPartition(0); @@ -2530,6 +2553,7 @@ namespace VeraCrypt EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsInt.dcs", dcsIntImg, sizeDcsInt); EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsCfg.dcs", dcsCfgImg, sizeDcsCfg); EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\LegacySpeaker.dcs", LegacySpeakerImg, sizeLegacySpeaker); + EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsBml.dcs", BootMenuLockerImg, sizeBootMenuLocker); EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi"); // move configuration file from old location (if it exists) to new location @@ -2683,126 +2707,255 @@ namespace VeraCrypt BootEncryptionStatus encStatus = GetStatus(); if (encStatus.SetupInProgress) throw ParameterIncorrect (SRC_POS); + BOOL bIsGPT = GetSystemDriveConfiguration().SystemPartition.IsGPT; + if (bIsGPT) + { + // create EFI disk structure + DWORD sizeDcsBoot; + byte *dcsBootImg = MapResource(L"BIN", IDR_EFI_DCSBOOT, &sizeDcsBoot); + if (!dcsBootImg) + throw ParameterIncorrect (SRC_POS); + DWORD sizeDcsInt; + byte *dcsIntImg = MapResource(L"BIN", IDR_EFI_DCSINT, &sizeDcsInt); + if (!dcsIntImg) + throw ParameterIncorrect (SRC_POS); + DWORD sizeDcsCfg; + byte *dcsCfgImg = MapResource(L"BIN", IDR_EFI_DCSCFG, &sizeDcsCfg); + if (!dcsCfgImg) + throw ParameterIncorrect (SRC_POS); + DWORD sizeLegacySpeaker; + byte *LegacySpeakerImg = MapResource(L"BIN", IDR_EFI_LEGACYSPEAKER, &sizeLegacySpeaker); + if (!LegacySpeakerImg) + throw ParameterIncorrect (SRC_POS); + DWORD sizeBootMenuLocker; + byte *BootMenuLockerImg = MapResource(L"BIN", IDR_EFI_DCSBML, &sizeBootMenuLocker); + if (!BootMenuLockerImg) + throw ParameterIncorrect (SRC_POS); + DWORD sizeDcsRescue; + byte *DcsRescueImg = MapResource(L"BIN", IDR_EFI_DCSRE, &sizeDcsRescue); + if (!DcsRescueImg) + throw ParameterIncorrect (SRC_POS); - Buffer imageBuf (RescueIsoImageSize); - - byte *image = imageBuf.Ptr(); - memset (image, 0, RescueIsoImageSize); - - // Primary volume descriptor - const char* szPrimVolDesc = "\001CD001\001"; - const char* szPrimVolLabel = "VeraCrypt Rescue Disk "; - memcpy (image + 0x8000, szPrimVolDesc, strlen(szPrimVolDesc) + 1); - memcpy (image + 0x7fff + 41, szPrimVolLabel, strlen(szPrimVolLabel) + 1); - *(uint32 *) (image + 0x7fff + 81) = RescueIsoImageSize / 2048; - *(uint32 *) (image + 0x7fff + 85) = BE32 (RescueIsoImageSize / 2048); - image[0x7fff + 121] = 1; - image[0x7fff + 124] = 1; - image[0x7fff + 125] = 1; - image[0x7fff + 128] = 1; - image[0x7fff + 130] = 8; - image[0x7fff + 131] = 8; - - image[0x7fff + 133] = 10; - image[0x7fff + 140] = 10; - image[0x7fff + 141] = 0x14; - image[0x7fff + 157] = 0x22; - image[0x7fff + 159] = 0x18; - - // Boot record volume descriptor - const char* szBootRecDesc = "CD001\001EL TORITO SPECIFICATION"; - memcpy (image + 0x8801, szBootRecDesc, strlen(szBootRecDesc) + 1); - image[0x8800 + 0x47] = 0x19; - - // Volume descriptor set terminator - const char* szVolDescTerm = "\377CD001\001"; - memcpy (image + 0x9000, szVolDescTerm, strlen(szVolDescTerm) + 1); - - // Path table - image[0xA000 + 0] = 1; - image[0xA000 + 2] = 0x18; - image[0xA000 + 6] = 1; - - // Root directory - image[0xc000 + 0] = 0x22; - image[0xc000 + 2] = 0x18; - image[0xc000 + 9] = 0x18; - image[0xc000 + 11] = 0x08; - image[0xc000 + 16] = 0x08; - image[0xc000 + 25] = 0x02; - image[0xc000 + 28] = 0x01; - image[0xc000 + 31] = 0x01; - image[0xc000 + 32] = 0x01; - image[0xc000 + 34] = 0x22; - image[0xc000 + 36] = 0x18; - image[0xc000 + 43] = 0x18; - image[0xc000 + 45] = 0x08; - image[0xc000 + 50] = 0x08; - image[0xc000 + 59] = 0x02; - image[0xc000 + 62] = 0x01; - *(uint32 *) (image + 0xc000 + 65) = 0x010101; - - // Validation entry - image[0xc800] = 1; - int offset = 0xc800 + 0x1c; - image[offset++] = 0xaa; - image[offset++] = 0x55; - image[offset++] = 0x55; - image[offset] = 0xaa; - - // Initial entry - offset = 0xc820; - image[offset++] = 0x88; - image[offset++] = 2; - image[0xc820 + 6] = 1; - image[0xc820 + 8] = TC_CD_BOOT_LOADER_SECTOR; - - // TrueCrypt Boot Loader - CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, true); - - // Volume header - if (initialSetup) - { - if (!RescueVolumeHeaderValid) + unsigned int maxRescueZipSize = 4 * 1024 * 1024; + ZRESULT res; + HZIP hz = CreateZip (0, maxRescueZipSize, ZIP_MEMORY); + if (!hz) + throw ParameterIncorrect (SRC_POS); + + finally_do_arg (HZIP, hz, { CloseZip (finally_arg); }); + + if (ZR_OK != ZipAdd (hz, L"EFI/Boot/bootx64.efi", DcsRescueImg, sizeDcsRescue, ZIP_MEMORY)) + throw ParameterIncorrect (SRC_POS); + if (ZR_OK !=ZipAdd (hz, L"EFI/VeraCrypt/DcsBml.dcs", BootMenuLockerImg, sizeBootMenuLocker, ZIP_MEMORY)) + throw ParameterIncorrect (SRC_POS); + if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/DcsBoot.efi", dcsBootImg, sizeDcsBoot, ZIP_MEMORY)) + throw ParameterIncorrect (SRC_POS); + if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/DcsCfg.dcs", dcsCfgImg, sizeDcsCfg, ZIP_MEMORY)) + throw ParameterIncorrect (SRC_POS); + if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/DcsInt.dcs", dcsIntImg, sizeDcsInt, ZIP_MEMORY)) + throw ParameterIncorrect (SRC_POS); + if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/LegacySpeaker.dcs", LegacySpeakerImg, sizeLegacySpeaker, ZIP_MEMORY)) + throw ParameterIncorrect (SRC_POS); + + Buffer volHeader(TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); + + // Volume header + if (initialSetup) + { + if (!RescueVolumeHeaderValid) + throw ParameterIncorrect (SRC_POS); + + memcpy (volHeader.Ptr (), RescueVolumeHeader, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); + } + else + { + Device bootDevice (GetSystemDriveConfiguration().DevicePath, true); + bootDevice.CheckOpened (SRC_POS); + bootDevice.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); + bootDevice.Read (volHeader.Ptr (), TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); + } + + if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/svh_bak", volHeader.Ptr (), TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE, ZIP_MEMORY)) + throw ParameterIncorrect (SRC_POS); + + // Original system loader + res = ZR_WRITE; + try + { + DWORD fileSize = 0; + File sysBakFile (GetSystemLoaderBackupPath(), true); + sysBakFile.CheckOpened (SRC_POS); + sysBakFile.GetFileSize(fileSize); + Buffer fileBuf ((DWORD) fileSize); + DWORD sizeLoader = sysBakFile.Read (fileBuf.Ptr (), fileSize); + res = ZipAdd (hz, L"EFI/Boot/original_bootx64.vc_backup", fileBuf.Ptr (), sizeLoader, ZIP_MEMORY); + } + catch (Exception &e) + { + e.Show (ParentWindow); + Warning ("SYS_LOADER_UNAVAILABLE_FOR_RESCUE_DISK", ParentWindow); + } + + if (res != ZR_OK) + throw ParameterIncorrect (SRC_POS); + + EfiBootConf conf; + wstring dcsPropFileName = GetTempPathString() + L"_dcsproprescue"; + finally_do_arg (wstring, dcsPropFileName, { DeleteFileW (finally_arg.c_str()); }); + if (conf.Save(dcsPropFileName.c_str(), ParentWindow)) + { + DWORD fileSize = 0; + File propFile (dcsPropFileName, true, false); + propFile.CheckOpened (SRC_POS); + propFile.GetFileSize(fileSize); + Buffer propBuf (fileSize); + DWORD sizeDcsProp = propFile.Read (propBuf.Ptr (), fileSize); + + if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/DcsProp", propBuf.Ptr (), sizeDcsProp, ZIP_MEMORY)) + throw ParameterIncorrect (SRC_POS); + } + else throw ParameterIncorrect (SRC_POS); - memcpy (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, RescueVolumeHeader, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); + void* pZipContent = NULL; + unsigned long ulZipSize = 0; + if (ZR_OK != ZipGetMemory (hz, &pZipContent, &ulZipSize)) + throw ParameterIncorrect (SRC_POS); + + RescueZipData = new byte[ulZipSize]; + if (!RescueZipData) + throw bad_alloc(); + memcpy (RescueZipData, pZipContent, ulZipSize); + RescueZipSize = ulZipSize; + + if (!isoImagePath.empty()) + { + File isoFile (isoImagePath, false, true); + isoFile.Write (RescueZipData, RescueZipSize); + } } else { - Device bootDevice (GetSystemDriveConfiguration().DevicePath, true); - bootDevice.CheckOpened (SRC_POS); - bootDevice.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); - bootDevice.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); - } + Buffer imageBuf (RescueIsoImageSize); + + byte *image = imageBuf.Ptr(); + memset (image, 0, RescueIsoImageSize); + + // Primary volume descriptor + const char* szPrimVolDesc = "\001CD001\001"; + const char* szPrimVolLabel = "VeraCrypt Rescue Disk "; + memcpy (image + 0x8000, szPrimVolDesc, strlen(szPrimVolDesc) + 1); + memcpy (image + 0x7fff + 41, szPrimVolLabel, strlen(szPrimVolLabel) + 1); + *(uint32 *) (image + 0x7fff + 81) = RescueIsoImageSize / 2048; + *(uint32 *) (image + 0x7fff + 85) = BE32 (RescueIsoImageSize / 2048); + image[0x7fff + 121] = 1; + image[0x7fff + 124] = 1; + image[0x7fff + 125] = 1; + image[0x7fff + 128] = 1; + image[0x7fff + 130] = 8; + image[0x7fff + 131] = 8; + + image[0x7fff + 133] = 10; + image[0x7fff + 140] = 10; + image[0x7fff + 141] = 0x14; + image[0x7fff + 157] = 0x22; + image[0x7fff + 159] = 0x18; + + // Boot record volume descriptor + const char* szBootRecDesc = "CD001\001EL TORITO SPECIFICATION"; + memcpy (image + 0x8801, szBootRecDesc, strlen(szBootRecDesc) + 1); + image[0x8800 + 0x47] = 0x19; + + // Volume descriptor set terminator + const char* szVolDescTerm = "\377CD001\001"; + memcpy (image + 0x9000, szVolDescTerm, strlen(szVolDescTerm) + 1); + + // Path table + image[0xA000 + 0] = 1; + image[0xA000 + 2] = 0x18; + image[0xA000 + 6] = 1; + + // Root directory + image[0xc000 + 0] = 0x22; + image[0xc000 + 2] = 0x18; + image[0xc000 + 9] = 0x18; + image[0xc000 + 11] = 0x08; + image[0xc000 + 16] = 0x08; + image[0xc000 + 25] = 0x02; + image[0xc000 + 28] = 0x01; + image[0xc000 + 31] = 0x01; + image[0xc000 + 32] = 0x01; + image[0xc000 + 34] = 0x22; + image[0xc000 + 36] = 0x18; + image[0xc000 + 43] = 0x18; + image[0xc000 + 45] = 0x08; + image[0xc000 + 50] = 0x08; + image[0xc000 + 59] = 0x02; + image[0xc000 + 62] = 0x01; + *(uint32 *) (image + 0xc000 + 65) = 0x010101; + + // Validation entry + image[0xc800] = 1; + int offset = 0xc800 + 0x1c; + image[offset++] = 0xaa; + image[offset++] = 0x55; + image[offset++] = 0x55; + image[offset] = 0xaa; + + // Initial entry + offset = 0xc820; + image[offset++] = 0x88; + image[offset++] = 2; + image[0xc820 + 6] = 1; + image[0xc820 + 8] = TC_CD_BOOT_LOADER_SECTOR; + + // TrueCrypt Boot Loader + CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, true); + + // Volume header + if (initialSetup) + { + if (!RescueVolumeHeaderValid) + throw ParameterIncorrect (SRC_POS); - // Original system loader - try - { - File sysBakFile (GetSystemLoaderBackupPath(), true); - sysBakFile.CheckOpened (SRC_POS); - sysBakFile.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE); + memcpy (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, RescueVolumeHeader, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); + } + else + { + Device bootDevice (GetSystemDriveConfiguration().DevicePath, true); + bootDevice.CheckOpened (SRC_POS); + bootDevice.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); + bootDevice.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); + } + + // Original system loader + try + { + File sysBakFile (GetSystemLoaderBackupPath(), true); + sysBakFile.CheckOpened (SRC_POS); + sysBakFile.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE); - image[TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER; - } - catch (Exception &e) - { - e.Show (ParentWindow); - Warning ("SYS_LOADER_UNAVAILABLE_FOR_RESCUE_DISK", ParentWindow); - } + image[TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER; + } + catch (Exception &e) + { + e.Show (ParentWindow); + Warning ("SYS_LOADER_UNAVAILABLE_FOR_RESCUE_DISK", ParentWindow); + } - // Boot loader backup - CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, false); + // Boot loader backup + CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, false); - RescueIsoImage = new byte[RescueIsoImageSize]; - if (!RescueIsoImage) - throw bad_alloc(); - memcpy (RescueIsoImage, image, RescueIsoImageSize); + RescueIsoImage = new byte[RescueIsoImageSize]; + if (!RescueIsoImage) + throw bad_alloc(); + memcpy (RescueIsoImage, image, RescueIsoImageSize); - if (!isoImagePath.empty()) - { - File isoFile (isoImagePath, false, true); - isoFile.Write (image, RescueIsoImageSize); + if (!isoImagePath.empty()) + { + File isoFile (isoImagePath, false, true); + isoFile.Write (image, RescueIsoImageSize); + } } } #endif @@ -2827,61 +2980,240 @@ namespace VeraCrypt bool BootEncryption::VerifyRescueDisk () { - if (!RescueIsoImage) + BOOL bIsGPT = GetSystemDriveConfiguration().SystemPartition.IsGPT; + if ((bIsGPT && !RescueZipData) || (!bIsGPT && !RescueIsoImage)) throw ParameterIncorrect (SRC_POS); - for (WCHAR drive = L'Z'; drive >= L'C'; --drive) + if (bIsGPT) + { + const wchar_t* efiFiles[] = { + L"EFI/Boot/bootx64.efi", + L"EFI/VeraCrypt/DcsBml.dcs", + L"EFI/VeraCrypt/DcsBoot.efi", + L"EFI/VeraCrypt/DcsCfg.dcs", + L"EFI/VeraCrypt/DcsInt.dcs", + L"EFI/VeraCrypt/LegacySpeaker.dcs", + L"EFI/VeraCrypt/svh_bak", + L"EFI/Boot/original_bootx64.vc_backup" + }; + + ZRESULT res; + HZIP hz = OpenZip(RescueZipData, RescueZipSize, ZIP_MEMORY); + if (!hz) + throw ParameterIncorrect (SRC_POS); + finally_do_arg (HZIP, hz, { CloseZip (finally_arg); }); + + for (WCHAR drive = L'Z'; drive >= L'C'; --drive) + { + try + { + WCHAR rootPath[4] = { drive, L':', L'\\', 0}; + UINT driveType = GetDriveType (rootPath); + if (DRIVE_REMOVABLE == driveType) + { + // check if it is FAT/FAT32 + WCHAR szNameBuffer[TC_MAX_PATH]; + if (GetVolumeInformationW (rootPath, NULL, 0, NULL, NULL, NULL, szNameBuffer, ARRAYSIZE(szNameBuffer)) + && !wcsncmp (szNameBuffer, L"FAT", 3)) + { + int index, i; + ZIPENTRYW ze; + for (i = 0; i < ARRAYSIZE(efiFiles); i++) + { + bool bMatch = false; + res = FindZipItemW (hz, efiFiles[i], true, &index, &ze); + if ((res == ZR_OK) && (index >= 0)) + { + // check that the file exists on the disk and that it has the same content + StringCbCopyW (szNameBuffer, sizeof (szNameBuffer), rootPath); + StringCbCatW (szNameBuffer, sizeof (szNameBuffer), efiFiles[i]); + + try + { + DWORD dwSize = 0; + File diskFile (szNameBuffer, true); + diskFile.CheckOpened (SRC_POS); + diskFile.GetFileSize (dwSize); + if (dwSize == (DWORD) ze.unc_size) + { + Buffer fileBuf (dwSize); + if (dwSize == diskFile.Read (fileBuf.Ptr (), dwSize)) + { + Buffer efiBuf (dwSize); + res = UnzipItem (hz, ze.index, efiBuf.Ptr (), dwSize, ZIP_MEMORY); + if (res == ZR_OK) + { + bMatch = (memcmp (efiBuf.Ptr(), fileBuf.Ptr(), dwSize) == 0); + } + } + } + } + catch (...) + { + } + + } + else + { + // entry not found in our Rescue ZIP image. Skip it. + bMatch = true; + } + + if (!bMatch) + break; + } + + if (i == ARRAYSIZE(efiFiles)) + { + // All entries processed + return true; + } + } + } + } + catch (...) { } + } + } + else { - try + size_t verifiedSectorCount = (TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET + TC_BOOT_LOADER_AREA_SIZE) / 2048; + Buffer buffer ((verifiedSectorCount + 1) * 2048); + for (WCHAR drive = L'Z'; drive >= L'C'; --drive) { - WCHAR rootPath[4] = { drive, L':', L'\\', 0}; - UINT driveType = GetDriveType (rootPath); - // check that it is a CD/DVD drive or a removable media in case a bootable - // USB key was created from the rescue disk ISO file - if ((DRIVE_CDROM == driveType) || (DRIVE_REMOVABLE == driveType)) + try { - rootPath[2] = 0; // remove trailing backslash + WCHAR rootPath[4] = { drive, L':', L'\\', 0}; + UINT driveType = GetDriveType (rootPath); + // check that it is a CD/DVD drive or a removable media in case a bootable + // USB key was created from the rescue disk ISO file + if ((DRIVE_CDROM == driveType) || (DRIVE_REMOVABLE == driveType)) + { + rootPath[2] = 0; // remove trailing backslash - Device driveDevice (rootPath, true); - driveDevice.CheckOpened (SRC_POS); - size_t verifiedSectorCount = (TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET + TC_BOOT_LOADER_AREA_SIZE) / 2048; - Buffer buffer ((verifiedSectorCount + 1) * 2048); + Device driveDevice (rootPath, true); + driveDevice.CheckOpened (SRC_POS); - DWORD bytesRead = driveDevice.Read (buffer.Ptr(), (DWORD) buffer.Size()); - if (bytesRead != buffer.Size()) - continue; + DWORD bytesRead = driveDevice.Read (buffer.Ptr(), (DWORD) buffer.Size()); + if (bytesRead != buffer.Size()) + continue; - if (memcmp (buffer.Ptr(), RescueIsoImage, buffer.Size()) == 0) - return true; + if (memcmp (buffer.Ptr(), RescueIsoImage, buffer.Size()) == 0) + return true; + } } + catch (...) { } } - catch (...) { } } return false; } - bool BootEncryption::VerifyRescueDiskIsoImage (const wchar_t* imageFile) + bool BootEncryption::VerifyRescueDiskImage (const wchar_t* imageFile) { - if (!RescueIsoImage) + BOOL bIsGPT = GetSystemDriveConfiguration().SystemPartition.IsGPT; + if ((bIsGPT && !RescueZipData) || (!bIsGPT && !RescueIsoImage)) throw ParameterIncorrect (SRC_POS); - try + if (bIsGPT) { - File isoFile (imageFile, true); - isoFile.CheckOpened (SRC_POS); - size_t verifiedSectorCount = (TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET + TC_BOOT_LOADER_AREA_SIZE) / 2048; - Buffer buffer ((verifiedSectorCount + 1) * 2048); + try + { + DWORD dwSize = 0; + File rescueFile (imageFile, true); + rescueFile.CheckOpened (SRC_POS); + rescueFile.GetFileSize (dwSize); + Buffer rescueData (dwSize); - DWORD bytesRead = isoFile.Read (buffer.Ptr(), (DWORD) buffer.Size()); - if ( (bytesRead == buffer.Size()) - && (memcmp (buffer.Ptr(), RescueIsoImage, buffer.Size()) == 0) - ) + if (dwSize == rescueFile.Read (rescueData.Ptr (), dwSize)) + { + ZRESULT res; + HZIP hzFile = OpenZip(rescueData.Ptr (), dwSize, ZIP_MEMORY); + if (hzFile) + { + finally_do_arg (HZIP, hzFile, { CloseZip (finally_arg); }); + HZIP hzMem = OpenZip(RescueZipData, RescueZipSize, ZIP_MEMORY); + if (hzMem) + { + finally_do_arg (HZIP, hzMem, { CloseZip (finally_arg); }); + const wchar_t* efiFiles[] = { + L"EFI/Boot/bootx64.efi", + L"EFI/VeraCrypt/DcsBml.dcs", + L"EFI/VeraCrypt/DcsBoot.efi", + L"EFI/VeraCrypt/DcsCfg.dcs", + L"EFI/VeraCrypt/DcsInt.dcs", + L"EFI/VeraCrypt/LegacySpeaker.dcs", + L"EFI/VeraCrypt/svh_bak", + L"EFI/Boot/original_bootx64.vc_backup" + }; + + int index, i; + ZIPENTRYW zeFile, zeMem; + for (i = 0; i < ARRAYSIZE(efiFiles); i++) + { + bool bMatch = false; + res = FindZipItemW (hzMem, efiFiles[i], true, &index, &zeMem); + if ((res == ZR_OK) && (index >= 0)) + { + res = FindZipItemW (hzFile, efiFiles[i], true, &index, &zeFile); + if ((res == ZR_OK) && (index >= 0) && (zeMem.unc_size == zeFile.unc_size)) + { + Buffer fileBuf (zeFile.unc_size); + Buffer memBuf (zeFile.unc_size); + + res = UnzipItem (hzMem, zeMem.index, memBuf.Ptr (), zeMem.unc_size, ZIP_MEMORY); + if (res == ZR_OK) + { + res = UnzipItem (hzFile, zeFile.index, fileBuf.Ptr (), zeFile.unc_size, ZIP_MEMORY); + if (res == ZR_OK) + { + bMatch = (memcmp (memBuf.Ptr (), fileBuf.Ptr (), zeMem.unc_size) == 0); + } + } + } + + } + else + { + // entry not found in our internal Rescue ZIP image. Skip it. + bMatch = true; + } + + if (!bMatch) + break; + } + + if (i == ARRAYSIZE(efiFiles)) + { + // All entries processed + return true; + } + + + } + } + } + } + catch (...) { } + } + else + { + try { - return true; + File rescueFile (imageFile, true); + rescueFile.CheckOpened (SRC_POS); + size_t verifiedSectorCount = (TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET + TC_BOOT_LOADER_AREA_SIZE) / 2048; + Buffer buffer ((verifiedSectorCount + 1) * 2048); + + DWORD bytesRead = rescueFile.Read (buffer.Ptr(), (DWORD) buffer.Size()); + if ( (bytesRead == buffer.Size()) + && (memcmp (buffer.Ptr(), RescueIsoImage, buffer.Size()) == 0) + ) + { + return true; + } } + catch (...) { } } - catch (...) { } return false; } @@ -3063,6 +3395,7 @@ namespace VeraCrypt EfiBootInst.DelFile(L"\\EFI\\VeraCrypt\\DcsInt.dcs"); EfiBootInst.DelFile(L"\\EFI\\VeraCrypt\\DcsCfg.dcs"); EfiBootInst.DelFile(L"\\EFI\\VeraCrypt\\LegacySpeaker.dcs"); + EfiBootInst.DelFile(L"\\EFI\\VeraCrypt\\DcsBml.dcs"); EfiBootInst.DelFile(L"\\EFI\\VeraCrypt\\DcsBoot"); EfiBootInst.DelFile(L"\\EFI\\VeraCrypt\\DcsProp"); } -- cgit v1.2.3