VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/BootEncryption.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/BootEncryption.cpp')
-rw-r--r--src/Common/BootEncryption.cpp259
1 files changed, 176 insertions, 83 deletions
diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp
index 583a8cb2..af6063e4 100644
--- a/src/Common/BootEncryption.cpp
+++ b/src/Common/BootEncryption.cpp
@@ -275,6 +275,27 @@ bool ZipAdd (zip_t *z, const char* name, const unsigned char* pbData, DWORD cbDa
return true;
}
+static BOOL IsWindowsMBR (const byte *buffer, size_t bufferSize)
+{
+ BOOL bRet = FALSE;
+ byte g_pbMsSignature[4] = {0x33, 0xc0, 0x8e, 0xd0};
+ const char* g_szStr1 = "Invalid partition table";
+ const char* g_szStr2 = "Error loading operating system";
+ const char* g_szStr3 = "Missing operating system";
+
+ if ((0 == memcmp (buffer, g_pbMsSignature, 4)) &&
+ (BufferContainsString (buffer, bufferSize, g_szStr1)
+ || BufferContainsString (buffer, bufferSize, g_szStr2)
+ || BufferContainsString (buffer, bufferSize, g_szStr3)
+ )
+ )
+ {
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
namespace VeraCrypt
{
#if !defined (SETUP)
@@ -646,6 +667,18 @@ namespace VeraCrypt
}
}
+ static void NotifyService (DWORD dwNotifyCmd)
+ {
+ Elevate();
+
+ DWORD result = ElevatedComInstance->NotifyService (dwNotifyCmd);
+ if (result != ERROR_SUCCESS)
+ {
+ SetLastError (result);
+ throw SystemException(SRC_POS);
+ }
+ }
+
static void Release ()
{
if (--ReferenceCount == 0 && ElevatedComInstance)
@@ -679,7 +712,7 @@ namespace VeraCrypt
if (!ElevatedComInstance || ElevatedComInstanceThreadId != GetCurrentThreadId())
{
- CoInitialize (NULL);
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
ElevatedComInstance = GetElevatedInstance (GetActiveWindow() ? GetActiveWindow() : MainDlg);
ElevatedComInstanceThreadId = GetCurrentThreadId();
}
@@ -775,8 +808,6 @@ namespace VeraCrypt
if (Elevated)
{
- DWORD bytesRead;
-
Elevator::ReadWriteFile (false, IsDevice, Path, buffer, FilePointerPosition, size, &bytesRead);
FilePointerPosition += bytesRead;
return bytesRead;
@@ -1030,7 +1061,7 @@ namespace VeraCrypt
static EfiBoot EfiBootInst;
- BootEncryption::BootEncryption (HWND parent, bool postOOBE, bool setBootNext)
+ BootEncryption::BootEncryption (HWND parent, bool postOOBE, bool setBootEntry, bool forceFirstBootEntry, bool setBootNext)
: DriveConfigValid (false),
ParentWindow (parent),
RealSystemDriveSizeValid (false),
@@ -1042,7 +1073,9 @@ namespace VeraCrypt
SelectedPrfAlgorithmId (0),
VolumeHeaderValid (false),
PostOOBEMode (postOOBE),
- SetBootNext (setBootNext)
+ SetBootNext (setBootNext),
+ SetBootEntry (setBootEntry),
+ ForceFirstBootEntry (forceFirstBootEntry)
{
HiddenOSCandidatePartition.IsGPT = FALSE;
HiddenOSCandidatePartition.Number = (size_t) -1;
@@ -1115,7 +1148,7 @@ namespace VeraCrypt
if (partition.Info.PartitionNumber != config.SystemPartition.Number)
{
// If there is an extra boot partition, the system partition must be located right behind it
- if (IsOSAtLeast (WIN_7) && config.ExtraBootPartitionPresent)
+ if (config.ExtraBootPartitionPresent)
{
int64 minOffsetFound = config.DrivePartition.Info.PartitionLength.QuadPart;
Partition bootPartition = partition;
@@ -1243,32 +1276,9 @@ namespace VeraCrypt
finally_do_arg (SC_HANDLE, service, { CloseServiceHandle (finally_arg); });
- // Windows versions preceding Vista can be installed on FAT filesystem which does not
- // support long filenames during boot. Convert the driver path to short form if required.
- wstring driverPath;
- if (startOnBoot && !IsOSAtLeast (WIN_VISTA))
- {
- wchar_t pathBuf[MAX_PATH];
- wchar_t filesystem[128];
-
- wstring path (GetWindowsDirectory());
- path += L"\\drivers\\veracrypt.sys";
-
- if (GetVolumePathName (path.c_str(), pathBuf, ARRAYSIZE (pathBuf))
- && GetVolumeInformation (pathBuf, NULL, 0, NULL, NULL, NULL, filesystem, ARRAYSIZE(filesystem))
- && wmemcmp (filesystem, L"FAT", 3) == 0)
- {
- throw_sys_if (GetShortPathName (path.c_str(), pathBuf, ARRAYSIZE (pathBuf)) == 0);
-
- // Convert absolute path to relative to the Windows directory
- driverPath = pathBuf;
- driverPath = driverPath.substr (driverPath.rfind (L"\\", driverPath.rfind (L"\\", driverPath.rfind (L"\\") - 1) - 1) + 1);
- }
- }
-
throw_sys_if (!ChangeServiceConfig (service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE,
startOnBoot ? SERVICE_ERROR_SEVERE : SERVICE_ERROR_NORMAL,
- driverPath.empty() ? NULL : driverPath.c_str(),
+ NULL,
startOnBoot ? L"Filter" : NULL,
NULL, NULL, NULL, NULL, NULL));
@@ -1628,8 +1638,7 @@ namespace VeraCrypt
{
SystemDriveConfiguration config = GetSystemDriveConfiguration();
- if (IsOSAtLeast (WIN_7)
- && config.Partitions.size() == 2
+ if (config.Partitions.size() == 2
&& config.ExtraBootPartitionPresent
&& config.DrivePartition.Info.PartitionLength.QuadPart - config.SystemPartition.Info.PartitionLength.QuadPart < 164 * BYTES_PER_MB)
{
@@ -1678,29 +1687,28 @@ namespace VeraCrypt
if (_stricmp (request.BootEncryptionAlgorithmName, "AES") == 0)
ea = AES;
- else if (_stricmp (request.BootEncryptionAlgorithmName, "Serpent") == 0)
+ #ifndef WOLFCRYPT_BACKEND
+ else if (_stricmp (request.BootEncryptionAlgorithmName, "Camellia") == 0)
+ ea = CAMELLIA;
+ else if (_stricmp (request.BootEncryptionAlgorithmName, "Serpent") == 0)
ea = SERPENT;
else if (_stricmp (request.BootEncryptionAlgorithmName, "Twofish") == 0)
ea = TWOFISH;
- else if (_stricmp (request.BootEncryptionAlgorithmName, "Camellia") == 0)
- ea = CAMELLIA;
-#if defined(CIPHER_GOST89)
- else if (_stricmp (request.BootEncryptionAlgorithmName, "GOST89") == 0)
- ea = GOST89;
-#endif
-
+ #endif
if (_stricmp(request.BootPrfAlgorithmName, "SHA-256") == 0)
pkcs5_prf = SHA256;
- else if (_stricmp(request.BootPrfAlgorithmName, "RIPEMD-160") == 0)
- pkcs5_prf = RIPEMD160;
- else if (_stricmp(request.BootPrfAlgorithmName, "SHA-512") == 0)
+ else if (_stricmp(request.BootPrfAlgorithmName, "SHA-512") == 0)
pkcs5_prf = SHA512;
+ #ifndef WOLFCRYPT_BACKEND
+ else if (_stricmp(request.BootPrfAlgorithmName, "BLAKE2s-256") == 0)
+ pkcs5_prf = BLAKE2S;
else if (_stricmp(request.BootPrfAlgorithmName, "Whirlpool") == 0)
pkcs5_prf = WHIRLPOOL;
else if (_stricmp(request.BootPrfAlgorithmName, "Streebog") == 0)
pkcs5_prf = STREEBOG;
+ #endif
else if (strlen(request.BootPrfAlgorithmName) == 0) // case of version < 1.0f
- pkcs5_prf = RIPEMD160;
+ pkcs5_prf = BLAKE2S;
}
catch (...)
{
@@ -1726,8 +1734,8 @@ namespace VeraCrypt
pkcs5_prf = SelectedPrfAlgorithmId;
}
- // Only RIPEMD160 and SHA-256 are supported for MBR boot loader
- if (!bIsGPT && pkcs5_prf != RIPEMD160 && pkcs5_prf != SHA256)
+ // Only BLAKE2s and SHA-256 are supported for MBR boot loader
+ if (!bIsGPT && pkcs5_prf != BLAKE2S && pkcs5_prf != SHA256)
throw ParameterIncorrect (SRC_POS);
int bootSectorId = 0;
@@ -1809,8 +1817,7 @@ namespace VeraCrypt
*(uint16 *) (buffer + TC_BOOT_SECTOR_VERSION_OFFSET) = BE16 (VERSION_NUM);
- if (IsOSAtLeast (WIN_VISTA))
- buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER;
+ buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER;
if (rescueDisk && (ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION))
buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION;
@@ -2197,12 +2204,11 @@ namespace VeraCrypt
#endif // !SETUP
- NtQuerySystemInformationFn NtQuerySystemInformationPtr = NULL;
EfiBootConf::EfiBootConf() : passwordType (0),
passwordMsg ("Password: "),
passwordPicture ("login.bmp"),
- hashMsg ("(0) TEST ALL (1) SHA512 (2) WHIRLPOOL (3) SHA256 (4) RIPEMD160 (5) STREEBOG\nHash: "),
+ hashMsg ("(0) TEST ALL (1) SHA512 (2) WHIRLPOOL (3) SHA256 (4) BLAKE2S (5) STREEBOG\nHash: "),
hashAlgo (0),
requestHash (0),
pimMsg ("PIM (Leave empty for default): "),
@@ -2319,7 +2325,7 @@ namespace VeraCrypt
passwordType = ReadConfigInteger (configContent, "PasswordType", 0);
passwordMsg = ReadConfigString (configContent, "PasswordMsg", "Password: ", buffer, sizeof (buffer));
passwordPicture = ReadConfigString (configContent, "PasswordPicture", "\\EFI\\VeraCrypt\\login.bmp", buffer, sizeof (buffer));
- //hashMsg = ReadConfigString (configContent, "HashMsg", "(0) TEST ALL (1) SHA512 (2) WHIRLPOOL (3) SHA256 (4) RIPEMD160 (5) STREEBOG\nHash: ", buffer, sizeof (buffer));
+ //hashMsg = ReadConfigString (configContent, "HashMsg", "(0) TEST ALL (1) SHA512 (2) WHIRLPOOL (3) SHA256 (4) BLAKE2S (5) STREEBOG\nHash: ", buffer, sizeof (buffer));
hashAlgo = ReadConfigInteger (configContent, "Hash", 0);
requestHash = ReadConfigInteger (configContent, "HashRqt", 1);
pimMsg = ReadConfigString (configContent, "PimMsg", "PIM: ", buffer, sizeof (buffer));
@@ -2489,14 +2495,13 @@ namespace VeraCrypt
ULONG len;
NTSTATUS res;
WCHAR tempBuf[1024];
+ NtQuerySystemInformationFn NtQuerySystemInformationPtr = (NtQuerySystemInformationFn) GetProcAddress (GetModuleHandle (L"ntdll.dll"), "NtQuerySystemInformation");
memset(tempBuf, 0, sizeof(tempBuf));
// Load NtQuerySystemInformation function point
if (!NtQuerySystemInformationPtr)
{
- NtQuerySystemInformationPtr = (NtQuerySystemInformationFn) GetProcAddress (GetModuleHandle (L"ntdll.dll"), "NtQuerySystemInformation");
- if (!NtQuerySystemInformationPtr)
- throw SystemException (SRC_POS);
+ throw SystemException (SRC_POS);
}
res = NtQuerySystemInformationPtr((SYSTEM_INFORMATION_CLASS)SYSPARTITIONINFORMATION, tempBuf, sizeof(tempBuf), &len);
@@ -2682,7 +2687,7 @@ namespace VeraCrypt
}
}
- void EfiBoot::SetStartExec(wstring description, wstring execPath, bool setBootNext, uint16 statrtOrderNum , wchar_t* type, uint32 attr) {
+ void EfiBoot::SetStartExec(wstring description, wstring execPath, bool setBootEntry, bool forceFirstBootEntry, bool setBootNext, uint16 statrtOrderNum , wchar_t* type, uint32 attr) {
SetPrivilege(SE_SYSTEM_ENVIRONMENT_NAME, TRUE);
// Check EFI
if (!IsEfiBoot()) {
@@ -2799,27 +2804,56 @@ namespace VeraCrypt
}
}
- // Create new entry if absent
- if (startOrderNumPos == UINT_MAX) {
- if (bDeviceInfoValid)
+ if (setBootEntry)
+ {
+ // check if first entry in BootOrder is Windows one
+ bool bFirstEntryIsWindows = false;
+ if (startOrderNumPos != 0)
{
- for (uint32 i = startOrderLen / 2; i > 0; --i) {
+ wchar_t varName[256];
+ StringCchPrintfW(varName, ARRAYSIZE (varName), L"%s%04X", type == NULL ? L"Boot" : type, startOrder[0]);
+
+ byte* existingVar = new byte[512];
+ DWORD existingVarLen = GetFirmwareEnvironmentVariableW (varName, EfiVarGuid, existingVar, 512);
+ if (existingVarLen > 0)
+ {
+ if (BufferContainsWideString (existingVar, existingVarLen, L"EFI\\Microsoft\\Boot\\bootmgfw.efi"))
+ bFirstEntryIsWindows = true;
+ }
+
+ delete [] existingVar;
+ }
+
+
+ // Create new entry if absent
+ if (startOrderNumPos == UINT_MAX) {
+ if (bDeviceInfoValid)
+ {
+ if (forceFirstBootEntry && bFirstEntryIsWindows)
+ {
+ for (uint32 i = startOrderLen / 2; i > 0; --i) {
+ startOrder[i] = startOrder[i - 1];
+ }
+ startOrder[0] = statrtOrderNum;
+ }
+ else
+ {
+ startOrder[startOrderLen/2] = statrtOrderNum;
+ }
+ startOrderLen += 2;
+ startOrderUpdate = true;
+ }
+ } else if ((startOrderNumPos > 0) && forceFirstBootEntry && bFirstEntryIsWindows) {
+ for (uint32 i = startOrderNumPos; i > 0; --i) {
startOrder[i] = startOrder[i - 1];
}
startOrder[0] = statrtOrderNum;
- startOrderLen += 2;
startOrderUpdate = true;
}
- } else if (startOrderNumPos > 0) {
- for (uint32 i = startOrderNumPos; i > 0; --i) {
- startOrder[i] = startOrder[i - 1];
- }
- startOrder[0] = statrtOrderNum;
- startOrderUpdate = true;
- }
- if (startOrderUpdate) {
- SetFirmwareEnvironmentVariable(order.c_str(), EfiVarGuid, startOrder, startOrderLen);
+ if (startOrderUpdate) {
+ SetFirmwareEnvironmentVariable(order.c_str(), EfiVarGuid, startOrder, startOrderLen);
+ }
}
if (setBootNext)
@@ -3333,7 +3367,7 @@ namespace VeraCrypt
// restore boot menu entry in case of PostOOBE
if (PostOOBEMode)
- EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi", SetBootNext);
+ EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi", SetBootEntry, ForceFirstBootEntry, SetBootNext);
if (EfiBootInst.FileExists (L"\\EFI\\Microsoft\\Boot\\bootmgfw_ms.vc"))
{
@@ -3446,7 +3480,7 @@ namespace VeraCrypt
EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsInfo.dcs", DcsInfoImg, sizeDcsInfo);
if (!preserveUserConfig)
EfiBootInst.DelFile(L"\\EFI\\VeraCrypt\\PlatformInfo");
- EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi");
+ EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi", SetBootEntry, ForceFirstBootEntry, SetBootNext);
if (EfiBootInst.FileExists (szStdEfiBootloader))
{
@@ -3534,8 +3568,10 @@ namespace VeraCrypt
}
}
- // perform actual write only if content is different
- if (memcmp (mbr, bootLoaderBuf, TC_MAX_MBR_BOOT_CODE_SIZE))
+ // perform actual write only if content is different and either we are not in PostOOBE mode or the MBR contains VeraCrypt/Windows signature.
+ // this last check is done to avoid interfering with multi-boot configuration where MBR belongs to a boot manager like Grub
+ if (memcmp (mbr, bootLoaderBuf, TC_MAX_MBR_BOOT_CODE_SIZE)
+ && (!PostOOBEMode || BufferContainsString (mbr, sizeof (mbr), TC_APP_NAME) || IsWindowsMBR (mbr, sizeof (mbr))))
{
memcpy (mbr, bootLoaderBuf, TC_MAX_MBR_BOOT_CODE_SIZE);
@@ -4326,7 +4362,7 @@ namespace VeraCrypt
// Initial rescue disk assumes encryption of the drive has been completed (EncryptedAreaLength == volumeSize)
memcpy (RescueVolumeHeader, VolumeHeader, sizeof (RescueVolumeHeader));
- if (0 != ReadVolumeHeader (TRUE, (char *) RescueVolumeHeader, password, pkcs5, pim, FALSE, NULL, cryptoInfo))
+ if (0 != ReadVolumeHeader (TRUE, (char *) RescueVolumeHeader, password, pkcs5, pim, NULL, cryptoInfo))
throw ParameterIncorrect (SRC_POS);
DecryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
@@ -4687,9 +4723,6 @@ namespace VeraCrypt
break;
case DumpFilter:
- if (!IsOSAtLeast (WIN_VISTA))
- return;
-
filter = "veracrypt.sys";
filterReg = "DumpFilters";
SetLastError (RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\CrashControl", 0, KEY_READ | KEY_WRITE, &regKey));
@@ -5023,7 +5056,7 @@ namespace VeraCrypt
void BootEncryption::SetServiceConfigurationFlag (uint32 flag, bool state)
{
- DWORD configMap = ReadDriverConfigurationFlags();
+ DWORD configMap = ReadServiceConfigurationFlags();
if (state)
configMap |= flag;
@@ -5115,16 +5148,22 @@ namespace VeraCrypt
#endif
#ifndef SETUP
void BootEncryption::CheckRequirements ()
- {
- if (nCurrentOS == WIN_2000)
- throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_CURRENT_OS", SRC_POS);
-
+ {
if (CurrentOSMajor == 6 && CurrentOSMinor == 0 && CurrentOSServicePack < 1)
throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_VISTA_SP0", SRC_POS);
+ if (IsARM())
+ throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_CURRENT_OS", SRC_POS);
+
if (IsNonInstallMode())
throw ErrorException ("FEATURE_REQUIRES_INSTALLATION", SRC_POS);
+ /* check if the system drive is already encrypted by BitLocker */
+ wchar_t windowsDrive = (wchar_t) towupper (GetWindowsDirectory()[0]);
+ BitLockerEncryptionStatus bitLockerStatus = GetBitLockerEncryptionStatus (windowsDrive);
+ if (bitLockerStatus == BL_Status_Protected)
+ throw ErrorException ("SYSENC_BITLOCKER_CONFLICT", SRC_POS);
+
SystemDriveConfiguration config = GetSystemDriveConfiguration ();
if (SystemDriveIsDynamic())
@@ -5359,7 +5398,7 @@ namespace VeraCrypt
PCRYPTO_INFO cryptoInfo = NULL;
- int status = ReadVolumeHeader (!encStatus.HiddenSystem, header, oldPassword, old_pkcs5, old_pim, FALSE, &cryptoInfo, NULL);
+ int status = ReadVolumeHeader (!encStatus.HiddenSystem, header, oldPassword, old_pkcs5, old_pim, &cryptoInfo, NULL);
finally_do_arg (PCRYPTO_INFO, cryptoInfo, { if (finally_arg) crypto_close (finally_arg); });
if (status != 0)
@@ -5616,6 +5655,16 @@ namespace VeraCrypt
if (!rescueIsoImagePath.empty())
CreateRescueIsoImage (true, rescueIsoImagePath);
+
+ // check if Fast Startup is enabled and if yes then offer to disable it
+ BOOL bHibernateEnabled = FALSE, bHiberbootEnabled = FALSE;
+ if (GetHibernateStatus (bHibernateEnabled, bHiberbootEnabled) && bHiberbootEnabled)
+ {
+ if (AskWarnYesNo ("CONFIRM_DISABLE_FAST_STARTUP", ParentWindow) == IDYES)
+ {
+ WriteLocalMachineRegistryDwordValue (L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Power", L"HiberbootEnabled", 0);
+ }
+ }
}
bool BootEncryption::IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
@@ -5646,6 +5695,22 @@ namespace VeraCrypt
throw_sys_if (!WriteLocalMachineRegistryDword (keyPath, valueName, value));
}
+ void BootEncryption::NotifyService (DWORD dwNotifyCmd)
+ {
+ if (!IsAdmin() && IsUacSupported())
+ {
+ Elevator::NotifyService (dwNotifyCmd);
+ return;
+ }
+
+ DWORD dwRet = SendServiceNotification(dwNotifyCmd);
+ if (dwRet != ERROR_SUCCESS)
+ {
+ SetLastError(dwRet);
+ throw SystemException (SRC_POS);
+ }
+ }
+
void BootEncryption::StartDecryption (BOOL discardUnreadableEncryptedSectors)
{
BootEncryptionStatus encStatus = GetStatus();
@@ -5770,4 +5835,32 @@ namespace VeraCrypt
{
return (::RestartComputer(bShutdown) != FALSE);
}
+
+ bool BootEncryption::IsUsingUnsupportedAlgorithm(LONG driverVersion)
+ {
+ bool bRet = false;
+
+ try
+ {
+ if (driverVersion <= 0x125)
+ {
+ // version 1.25 is last version to support RIPEMD160 and GOST89
+ static int GOST89_EA = 5;
+ static int RIPEMD160_PRF = 4;
+
+ VOLUME_PROPERTIES_STRUCT props = {0};
+ GetVolumeProperties(&props);
+
+ //
+ if (props.ea == GOST89_EA || props.pkcs5 == RIPEMD160_PRF)
+ bRet = true;
+ }
+ }
+ catch(...)
+ {
+
+ }
+
+ return bRet;
+ }
}