diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2016-08-14 23:01:26 +0200 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2016-08-15 01:09:17 +0200 |
commit | 2d72e42c6c0abd96e01fdcfb2737977dbda8edbe (patch) | |
tree | 228251478ed0910a35534dadc478a10643f8ecab /src/Common | |
parent | 71a38563ae44daea05ec919c21cb3e622d08720f (diff) | |
download | VeraCrypt-2d72e42c6c0abd96e01fdcfb2737977dbda8edbe.tar.gz VeraCrypt-2d72e42c6c0abd96e01fdcfb2737977dbda8edbe.zip |
Windows: Implement Rescue Disk support for EFI system encryption
Diffstat (limited to 'src/Common')
-rw-r--r-- | src/Common/BootEncryption.cpp | 617 | ||||
-rw-r--r-- | src/Common/BootEncryption.h | 5 | ||||
-rw-r--r-- | src/Common/Common.rc | 2 | ||||
-rw-r--r-- | src/Common/Language.xml | 17 | ||||
-rw-r--r-- | src/Common/Resource.h | 4 |
5 files changed, 496 insertions, 149 deletions
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"); } diff --git a/src/Common/BootEncryption.h b/src/Common/BootEncryption.h index dd8346d7..c8c9e29f 100644 --- a/src/Common/BootEncryption.h +++ b/src/Common/BootEncryption.h @@ -46,6 +46,7 @@ namespace VeraCrypt void Write (byte *buffer, DWORD size); void SeekAt (int64 position); void GetFileSize (unsigned __int64& size); + void GetFileSize (DWORD& dwSize); bool IoCtl(DWORD code, void* inBuf, DWORD inBufSize, void* outBuf, DWORD outBufSize); protected: @@ -277,7 +278,7 @@ namespace VeraCrypt bool SystemPartitionCoversWholeDrive (); bool SystemDriveIsDynamic (); bool VerifyRescueDisk (); - bool VerifyRescueDiskIsoImage (const wchar_t* imageFile); + bool VerifyRescueDiskImage (const wchar_t* imageFile); void WipeHiddenOSCreationConfig (); void WriteBootDriveSector (uint64 offset, byte *data); void WriteBootSectorConfig (const byte newConfig[]); @@ -308,6 +309,8 @@ namespace VeraCrypt int SelectedPrfAlgorithmId; Partition HiddenOSCandidatePartition; byte *RescueIsoImage; + byte *RescueZipData; + unsigned long RescueZipSize; byte RescueVolumeHeader[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE]; byte VolumeHeader[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE]; bool DriveConfigValid; diff --git a/src/Common/Common.rc b/src/Common/Common.rc index d082dc3e..c3dd808e 100644 --- a/src/Common/Common.rc +++ b/src/Common/Common.rc @@ -536,6 +536,8 @@ IDR_EFI_DCSBOOT BIN "..\\Boot\\EFI\\DcsBoot.efi" IDR_EFI_DCSINT BIN "..\\Boot\\EFI\\DcsInt.efi" IDR_EFI_DCSCFG BIN "..\\Boot\\EFI\\DcsCfg.efi" IDR_EFI_LEGACYSPEAKER BIN "..\\Boot\\EFI\\LegacySpeaker.efi" +IDR_EFI_DCSBML BIN "..\\Boot\\EFI\\DcsBml.efi" +IDR_EFI_DCSRE BIN "..\\Boot\\EFI\\DcsRe.efi" ///////////////////////////////////////////////////////////////////////////// // diff --git a/src/Common/Language.xml b/src/Common/Language.xml index 5350ece1..38f2cc49 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -261,7 +261,7 @@ <control lang="en" key="IDM_UNMOUNTALL">Dismount All Mounted Volumes</control> <control lang="en" key="IDM_UNMOUNT_VOLUME">Dismount Volume</control> <control lang="en" key="IDM_VERIFY_RESCUE_DISK">Verify Rescue Disk</control> - <control lang="en" key="IDM_VERIFY_RESCUE_DISK_ISO">Verify Rescue Disk ISO Image</control> + <control lang="en" key="IDM_VERIFY_RESCUE_DISK_ISO">Verify Rescue Disk Image</control> <control lang="en" key="IDM_VERSION_HISTORY">Version History</control> <control lang="en" key="IDM_VOLUME_EXPANDER">Volume Expander</control> <control lang="en" key="IDM_VOLUME_PROPERTIES">Volume Properties</control> @@ -962,14 +962,14 @@ <string lang="en" key="VOLUME_HAS_NO_BACKUP_HEADER">There is no backup header embedded in this volume (note that only volumes created by VeraCrypt 6.0 or later contain embedded backup headers).</string> <string lang="en" key="BACKUP_HEADER_NOT_FOR_SYS_DEVICE">You are attempting to back up the header of the system partition/drive. This is not allowed. Backup/restore operations pertaining to the system partition/drive can be performed only using the VeraCrypt Rescue Disk.\n\nDo you want to create a VeraCrypt Rescue Disk?</string> <string lang="en" key="RESTORE_HEADER_NOT_FOR_SYS_DEVICE">You are attempting to restore the header of a virtual VeraCrypt volume but you selected the system partition/drive. This is not allowed. Backup/restore operations pertaining to the system partition/drive can be performed only using the VeraCrypt Rescue Disk.\n\nDo you want to create a VeraCrypt Rescue Disk?</string> - <string lang="en" key="RESCUE_DISK_NON_WIZARD_CREATION_SELECT_PATH">After you click OK, you will select a filename for the new VeraCrypt Rescue Disk ISO image and the location where you wish to place it.</string> + <string lang="en" key="RESCUE_DISK_NON_WIZARD_CREATION_SELECT_PATH">After you click OK, you will select a filename for the new VeraCrypt Rescue Disk image and the location where you wish to place it.</string> <string lang="en" key="RESCUE_DISK_NON_WIZARD_CREATION_BURN">The Rescue Disk image has been created and stored in this file:\n%s\n\nNow you need to burn the Rescue Disk image to a CD or DVD.\n\nIMPORTANT: Note that the file must be written to the CD/DVD as an ISO disk image (not as an individual file). For information on how to do so, please refer to the documentation of your CD/DVD recording software.\n\nAfter you burn the Rescue Disk, select 'System' > 'Verify Rescue Disk' to verify that it has been correctly burned.</string> <string lang="en" key="RESCUE_DISK_NON_WIZARD_CREATION_WIN_ISOBURN">The Rescue Disk image has been created and stored in this file:\n%s\n\nNow you need to burn the Rescue Disk image to a CD or DVD.\n\nDo you want to launch the Microsoft Windows Disc Image Burner now?\n\nNote: After you burn the Rescue Disk, select 'System' > 'Verify Rescue Disk' to verify that it has been correctly burned.</string> - <string lang="en" key="RESCUE_DISK_NON_WIZARD_CHECK_INSERT">Please insert your VeraCrypt Rescue Disk into your CD/DVD drive and click OK to verify it.</string> + <string lang="en" key="RESCUE_DISK_NON_WIZARD_CHECK_INSERT">Please insert your VeraCrypt Rescue Disk and click OK to verify it.</string> <string lang="en" key="RESCUE_DISK_NON_WIZARD_CHECK_PASSED">The VeraCrypt Rescue Disk has been successfully verified.</string> <string lang="en" key="RESCUE_DISK_NON_WIZARD_CHECK_FAILED">Cannot verify that the Rescue Disk has been correctly burned.\n\nIf you have burned the Rescue Disk, please eject and reinsert the CD/DVD; then try again. If this does not help, please try other CD/DVD recording software and/or medium.\n\nIf you attempted to verify a VeraCrypt Rescue Disk created for a different master key, password, salt, etc., please note that such Rescue Disk will always fail this verification. To create a new Rescue Disk fully compatible with your current configuration, select 'System' > 'Create Rescue Disk'.</string> - <string lang="en" key="RESCUE_DISK_ISO_IMAGE_CHECK_PASSED">The VeraCrypt Rescue Disk ISO image has been successfully verified.</string> - <string lang="en" key="RESCUE_DISK_ISO_IMAGE_CHECK_FAILED">The Rescue Disk ISO image verification failed.\n\nIf you attempted to verify a VeraCrypt Rescue Disk ISO image created for a different master key, password, salt, etc., please note that such Rescue Disk ISO image will always fail this verification. To create a new Rescue Disk ISO image fully compatible with your current configuration, select 'System' > 'Create Rescue Disk'.</string> + <string lang="en" key="RESCUE_DISK_ISO_IMAGE_CHECK_PASSED">The VeraCrypt Rescue Disk image has been successfully verified.</string> + <string lang="en" key="RESCUE_DISK_ISO_IMAGE_CHECK_FAILED">The Rescue Disk image verification failed.\n\nIf you attempted to verify a VeraCrypt Rescue Disk image created for a different master key, password, salt, etc., please note that such Rescue Disk image will always fail this verification. To create a new Rescue Disk image fully compatible with your current configuration, select 'System' > 'Create Rescue Disk'.</string> <string lang="en" key="ERROR_CREATING_RESCUE_DISK">Error creating VeraCrypt Rescue Disk.</string> <string lang="en" key="CANNOT_CREATE_RESCUE_DISK_ON_HIDDEN_OS">VeraCrypt Rescue Disk cannot be created when a hidden operating system is running.\n\nTo create a VeraCrypt Rescue Disk, boot the decoy operating system and then select 'System' > 'Create Rescue Disk'.</string> <string lang="en" key="RESCUE_DISK_CHECK_FAILED">Cannot verify that the Rescue Disk has been correctly burned.\n\nIf you have burned the Rescue Disk, please eject and reinsert the CD/DVD; then click Next to try again. If this does not help, please try another medium%s.\n\nIf you have not burned the Rescue Disk yet, please do so, and then click Next.\n\nIf you attempted to verify a VeraCrypt Rescue Disk created before you started this wizard, please note that such Rescue Disk cannot be used, because it was created for a different master key. You need to burn the newly generated Rescue Disk.</string> @@ -1406,6 +1406,13 @@ <string lang="en" key="TIME">Time</string> <string lang="en" key="ITERATIONS">Iterations</string> <string lang="en" key="PRE-BOOT">Pre-Boot</string> + <string lang="en" key="RESCUE_DISK_EFI_INFO">Before you can encrypt the partition, you must create a VeraCrypt Rescue Disk (VRD), which serves the following purposes:\n\n- If the VeraCrypt Boot Loader, master key, or other critical data gets damaged, the VRD allows you to restore it (note, however, that you will still have to enter the correct password then).\n\n- If Windows gets damaged and cannot start, the VRD allows you to permanently decrypt the partition before Windows starts.\n\n- The VRD will contain a backup of the present EFI boot loader and will allow you to restore it if necessary.\n\nThe VeraCrypt Rescue Disk ZIP image will be created in the location specified below.</string> + <string lang="en" key="RESCUE_DISK_EFI_EXTRACT_INFO">The Rescue Disk ZIP image has been created and stored in this file:\n%s\n\nNow you need to extract it to a USB stick that is formatted as FAT/FAT32.\n\n%lsAfter you create the Rescue Disk, click Next to verify that it has been correctly created.</string> + <string lang="en" key="RESCUE_DISK_EFI_EXTRACT_INFO_NO_CHECK">The Rescue Disk ZIP image has been created and stored in this file:\n%s\n\nNow you should either extract the image to a USB stick that is formatted as FAT/FAT32 or move it to a safe location for later use.\n\n%lsClick Next to continue.</string> + <string lang="en" key="RESCUE_DISK_EFI_EXTRACT_INFO_NOTE">IMPORTANT: Note that the zip file must be extracted directly to the root of the USB stick. For example, if the drive letter of the USB stick is E: then extracting the zip file should create a folder E:\\EFI on the USB stick.\n\n</string> + <string lang="en" key="RESCUE_DISK_EFI_CHECK_FAILED">Cannot verify that the Rescue Disk has been correctly extracted.\n\nIf you have extracted the Rescue Disk, please eject and reinsert the USB stick; then click Next to try again. If this does not help, please try another USB stick and/or another ZIP software.\n\nIf you have not extracted the Rescue Disk yet, please do so, and then click Next.\n\nIf you attempted to verify a VeraCrypt Rescue Disk created before you started this wizard, please note that such Rescue Disk cannot be used, because it was created for a different master key. You need to extract the newly generated Rescue Disk ZIP image.</string> + <string lang="en" key="RESCUE_DISK_EFI_NON_WIZARD_CHECK_FAILED">Cannot verify that the Rescue Disk has been correctly extracted.\n\nIf you have extracted the Rescue Disk image to a USB stick, please eject it and reinsert it; then try again. If this does not help, please try other ZIP software and/or medium.\n\nIf you attempted to verify a VeraCrypt Rescue Disk created for a different master key, password, salt, etc., please note that such Rescue Disk will always fail this verification. To create a new Rescue Disk fully compatible with your current configuration, select 'System' > 'Create Rescue Disk'.</string> + <string lang="en" key="RESCUE_DISK_EFI_NON_WIZARD_CREATION">The Rescue Disk image has been created and stored in this file:\n%s\n\nNow you need to extract the Rescue Disk image to a USB stick that is formatted as FAT/FAT32.\n\nIMPORTANT: Note that the zip file must be extracted directly to the root of the USB stick. For example, if the drive letter of the USB stick is E: then extracting the zip file should create a folder E:\\EFI on the USB stick.\n\nAfter you create the Rescue Disk, select 'System' > 'Verify Rescue Disk' to verify that it has been correctly created.</string> </localization> <!-- XML Schema --> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> diff --git a/src/Common/Resource.h b/src/Common/Resource.h index 739732c9..12907c12 100644 --- a/src/Common/Resource.h +++ b/src/Common/Resource.h @@ -71,6 +71,8 @@ #define IDR_EFI_DCSINT 567 #define IDR_EFI_DCSCFG 568 #define IDR_EFI_LEGACYSPEAKER 569 +#define IDR_EFI_DCSBML 570 +#define IDR_EFI_DCSRE 571 #define IDC_HW_AES_LABEL_LINK 5000 #define IDC_HW_AES 5001 #define IDC_PARALLELIZATION_LABEL_LINK 5002 @@ -218,7 +220,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 570 +#define _APS_NEXT_RESOURCE_VALUE 572 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 5141 #define _APS_NEXT_SYMED_VALUE 101 |