VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common')
-rw-r--r--src/Common/Apidrvr.h13
-rw-r--r--src/Common/BootEncryption.cpp6
-rw-r--r--src/Common/BootEncryption.h10
-rw-r--r--src/Common/Common.rc2
-rw-r--r--src/Common/Crypto.c35
-rw-r--r--src/Common/Crypto.h4
-rw-r--r--src/Common/Dlgcode.c398
-rw-r--r--src/Common/Dlgcode.h27
-rw-r--r--src/Common/EncryptionThreadPool.c79
-rw-r--r--src/Common/EncryptionThreadPool.h4
-rw-r--r--src/Common/Language.c2
-rw-r--r--src/Common/Language.xml17
-rw-r--r--src/Common/Password.c3
-rw-r--r--src/Common/Tcdefs.h18
-rw-r--r--src/Common/Tests.c4
-rw-r--r--src/Common/Volumes.c151
-rw-r--r--src/Common/Xml.c21
17 files changed, 637 insertions, 157 deletions
diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h
index c56d9ff7..36946e6c 100644
--- a/src/Common/Apidrvr.h
+++ b/src/Common/Apidrvr.h
@@ -127,6 +127,8 @@
#define VC_IOCTL_IS_RAM_ENCRYPTION_ENABLED TC_IOCTL (42)
+#define VC_IOCTL_ENCRYPTION_QUEUE_PARAMS TC_IOCTL (43)
+
// Legacy IOCTLs used before version 5.0
#define TC_IOCTL_LEGACY_GET_DRIVER_VERSION 466968
#define TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES 466948
@@ -390,6 +392,13 @@ typedef struct
BOOL HwEncryptionEnabled;
} GetSystemDriveDumpConfigRequest;
+typedef struct
+{
+ int EncryptionIoRequestCount;
+ int EncryptionItemCount;
+ int EncryptionFragmentSize;
+} EncryptionQueueParameters;
+
#pragma pack (pop)
#define DRIVER_STR WIDE
@@ -407,6 +416,10 @@ typedef struct
#define TC_DRIVER_CONFIG_REG_VALUE_NAME DRIVER_STR("VeraCryptConfig")
#define TC_ENCRYPTION_FREE_CPU_COUNT_REG_VALUE_NAME DRIVER_STR("VeraCryptEncryptionFreeCpuCount")
+#define VC_ENCRYPTION_IO_REQUEST_COUNT DRIVER_STR("VeraCryptEncryptionIoRequestCount")
+#define VC_ENCRYPTION_ITEM_COUNT DRIVER_STR("VeraCryptEncryptionItemCount")
+#define VC_ENCRYPTION_FRAGMENT_SIZE DRIVER_STR("VeraCryptEncryptionFragmentSize")
+
// WARNING: Modifying the following values can introduce incompatibility with previous versions.
#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD 0x1
#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES 0x2
diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp
index c8fc90bf..c3ce07ab 100644
--- a/src/Common/BootEncryption.cpp
+++ b/src/Common/BootEncryption.cpp
@@ -2218,7 +2218,6 @@ namespace VeraCrypt
#endif // !SETUP
- NtQuerySystemInformationFn NtQuerySystemInformationPtr = NULL;
EfiBootConf::EfiBootConf() : passwordType (0),
passwordMsg ("Password: "),
@@ -2510,14 +2509,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);
diff --git a/src/Common/BootEncryption.h b/src/Common/BootEncryption.h
index decacb8b..7f5c3b16 100644
--- a/src/Common/BootEncryption.h
+++ b/src/Common/BootEncryption.h
@@ -18,16 +18,6 @@
#include "Exception.h"
#include "Platform/PlatformBase.h"
#include "Volumes.h"
-#include <Winternl.h>
-
-#define SYSPARTITIONINFORMATION 0x62
-
-typedef NTSTATUS (WINAPI *NtQuerySystemInformationFn)(
- SYSTEM_INFORMATION_CLASS SystemInformationClass,
- PVOID SystemInformation,
- ULONG SystemInformationLength,
- PULONG ReturnLength
-);
typedef ULONG (WINAPI *RtlNtStatusToDosErrorFn)(
NTSTATUS Status
diff --git a/src/Common/Common.rc b/src/Common/Common.rc
index b26a400a..6d50a1fb 100644
--- a/src/Common/Common.rc
+++ b/src/Common/Common.rc
@@ -325,7 +325,7 @@ EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW
CAPTION "VeraCrypt"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
- LTEXT "Please wait. This process may take a long time...",IDT_STATIC_MODELESS_WAIT_DLG_INFO,9,8,274,9
+ LTEXT "Please wait. This process may take a long time...",IDT_STATIC_MODELESS_WAIT_DLG_INFO,9,8,274,27
END
IDD_STATIC_MODAL_WAIT_DLG DIALOGEX 0, 0, 292, 74
diff --git a/src/Common/Crypto.c b/src/Common/Crypto.c
index 4745f981..da233090 100644
--- a/src/Common/Crypto.c
+++ b/src/Common/Crypto.c
@@ -19,6 +19,13 @@
#if !defined(_UEFI)
#include <string.h>
#ifndef TC_WINDOWS_BOOT
+#ifdef TC_WINDOWS_DRIVER
+#include <ntstrsafe.h>
+#define StringCchCatW RtlStringCchCatW
+#define StringCchCopyW RtlStringCchCopyW
+#else
+#include <strsafe.h>
+#endif
#include "EncryptionThreadPool.h"
#endif
#endif
@@ -555,33 +562,35 @@ BOOL EAInitMode (PCRYPTO_INFO ci, unsigned char* key2)
return TRUE;
}
-static void EAGetDisplayName(wchar_t *buf, int ea, int i)
+static void EAGetDisplayName(wchar_t *buf, size_t bufLen, int ea, int i)
{
- wcscpy (buf, CipherGetName (i));
+ StringCchCopyW (buf, bufLen, CipherGetName (i));
if (i = EAGetPreviousCipher(ea, i))
{
- wcscat (buf, L"(");
- EAGetDisplayName (&buf[wcslen(buf)], ea, i);
- wcscat (buf, L")");
+ size_t curLen;
+ StringCchCatW (buf, bufLen, L"(");
+ curLen = wcslen(buf);
+ EAGetDisplayName (&buf[curLen], bufLen - curLen, ea, i);
+ StringCchCatW (buf, bufLen, L")");
}
}
// Returns name of EA, cascaded cipher names are separated by hyphens
-wchar_t *EAGetName (wchar_t *buf, int ea, int guiDisplay)
+wchar_t *EAGetName (wchar_t *buf, size_t bufLen, int ea, int guiDisplay)
{
if (guiDisplay)
{
- EAGetDisplayName (buf, ea, EAGetLastCipher(ea));
+ EAGetDisplayName (buf, bufLen, ea, EAGetLastCipher(ea));
}
else
{
int i = EAGetLastCipher(ea);
- wcscpy (buf, (i != 0) ? CipherGetName (i) : L"?");
+ StringCchCopyW (buf, bufLen, (i != 0) ? CipherGetName (i) : L"?");
while (i = EAGetPreviousCipher(ea, i))
{
- wcscat (buf, L"-");
- wcscat (buf, CipherGetName (i));
+ StringCchCatW (buf, bufLen, L"-");
+ StringCchCatW (buf, bufLen, CipherGetName (i));
}
}
return buf;
@@ -595,7 +604,7 @@ int EAGetByName (wchar_t *name)
do
{
- EAGetName(n, ea, 1);
+ EAGetName(n, 128, ea, 1);
#if defined(_UEFI)
if (wcscmp(n, name) == 0)
#else
@@ -785,11 +794,11 @@ const wchar_t *HashGetName (int hashId)
return pHash? pHash -> Name : L"";
}
-void HashGetName2 (wchar_t *buf, int hashId)
+void HashGetName2 (wchar_t *buf, size_t bufLen, int hashId)
{
Hash* pHash = HashGet(hashId);
if (pHash)
- wcscpy(buf, pHash -> Name);
+ StringCchCopyW (buf, bufLen, pHash -> Name);
else
buf[0] = L'\0';
}
diff --git a/src/Common/Crypto.h b/src/Common/Crypto.h
index a31152f2..95222ba6 100644
--- a/src/Common/Crypto.h
+++ b/src/Common/Crypto.h
@@ -342,7 +342,7 @@ int EAGetFirst ();
int EAGetCount (void);
int EAGetNext (int previousEA);
#ifndef TC_WINDOWS_BOOT
-wchar_t * EAGetName (wchar_t *buf, int ea, int guiDisplay);
+wchar_t * EAGetName (wchar_t *buf, size_t bufLen, int ea, int guiDisplay);
int EAGetByName (wchar_t *name);
#endif
int EAGetKeySize (int ea);
@@ -373,7 +373,7 @@ const wchar_t *HashGetName (int hash_algo_id);
int HashGetIdByName (wchar_t *name);
#endif
Hash *HashGet (int id);
-void HashGetName2 (wchar_t *buf, int hashId);
+void HashGetName2 (wchar_t *buf, size_t bufLen, int hashId);
BOOL HashIsDeprecated (int hashId);
BOOL HashForSystemEncryption (int hashId);
int GetMaxPkcs5OutSize (void);
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index 8897a95e..c7185a84 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -82,6 +82,11 @@
#include <WinTrust.h>
#include <strsafe.h>
+#define _WIN32_DCOM
+#include <comdef.h>
+#include <Wbemidl.h>
+
+#pragma comment(lib, "wbemuuid.lib")
#pragma comment( lib, "setupapi.lib" )
#ifndef TTI_INFO_LARGE
@@ -166,6 +171,8 @@ BOOL bHistory = FALSE;
#ifndef SETUP
BOOL bLanguageSetInSetup = FALSE;
+#else
+extern BOOL bMakePackage;
#endif
// Status of detection of hidden sectors (whole-system-drive encryption).
@@ -406,22 +413,13 @@ static WTHELPERPROVDATAFROMSTATEDATA WTHelperProvDataFromStateDataFn = NULL;
static WTHELPERGETPROVSIGNERFROMCHAIN WTHelperGetProvSignerFromChainFn = NULL;
static WTHELPERGETPROVCERTFROMCHAIN WTHelperGetProvCertFromChainFn = NULL;
-static unsigned char gpbSha1CodeSignCertFingerprint[64] = {
- 0x97, 0xE3, 0x36, 0xE0, 0x45, 0x21, 0xE9, 0x8A, 0xA7, 0xEA, 0xE8, 0x68,
- 0x4A, 0x56, 0x02, 0xB2, 0xE7, 0x63, 0x59, 0x3A, 0x37, 0x03, 0x64, 0xC3,
- 0x7D, 0xBF, 0xF8, 0x19, 0xDB, 0x39, 0x57, 0x41, 0x55, 0x00, 0x9C, 0xBE,
- 0xFE, 0xA3, 0xBC, 0x0F, 0xE3, 0xD8, 0x34, 0x2D, 0x2F, 0xB4, 0x80, 0xBE,
- 0xDD, 0xEA, 0xA7, 0xDB, 0xAD, 0x53, 0x07, 0x71, 0x1A, 0x12, 0x42, 0xB4,
- 0xE9, 0x65, 0xA5, 0x61
-};
-
static unsigned char gpbSha256CodeSignCertFingerprint[64] = {
- 0x88, 0x60, 0xC4, 0x26, 0x6D, 0x42, 0x59, 0x1B, 0xDF, 0x89, 0x0F, 0x1A,
- 0x2F, 0x70, 0x8D, 0xBB, 0xC0, 0xF0, 0x03, 0x1F, 0x37, 0x11, 0xF9, 0x24,
- 0x78, 0xDF, 0xD3, 0x60, 0xFB, 0xF3, 0xDC, 0xCA, 0x0D, 0x95, 0x06, 0x6A,
- 0x5E, 0xAD, 0x5C, 0xA3, 0x3E, 0x75, 0x55, 0x96, 0x7B, 0xD1, 0x0D, 0xC1,
- 0x00, 0xFE, 0xA0, 0x95, 0x13, 0x23, 0x20, 0x63, 0x26, 0x57, 0xFA, 0x6C,
- 0xE4, 0x27, 0xF8, 0x36
+ 0x9C, 0xA0, 0x21, 0xD3, 0x7C, 0x90, 0x61, 0x88, 0xEF, 0x5F, 0x99, 0x3D,
+ 0x54, 0x9F, 0xB8, 0xCE, 0x72, 0x32, 0x4F, 0x57, 0x4F, 0x19, 0xD2, 0xA4,
+ 0xDC, 0x84, 0xFF, 0xE2, 0x84, 0x2B, 0xD4, 0x30, 0xAB, 0xA7, 0xE4, 0x63,
+ 0x18, 0xD1, 0xD8, 0x32, 0x0E, 0xA4, 0x81, 0x3C, 0x19, 0xBF, 0x13, 0x11,
+ 0xA4, 0x37, 0xD6, 0xDB, 0x26, 0xBA, 0xDC, 0x8F, 0x86, 0x96, 0x55, 0x96,
+ 0xDB, 0x6F, 0xC0, 0x62
};
@@ -1841,7 +1839,7 @@ BOOL CALLBACK AboutDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
L"Based on TrueCrypt 7.1a, freely available at http://www.truecrypt.org/ .\r\n\r\n"
L"Portions of this software:\r\n"
- L"Copyright \xA9 2013-2020 IDRIX. All rights reserved.\r\n"
+ L"Copyright \xA9 2013-2022 IDRIX. All rights reserved.\r\n"
L"Copyright \xA9 2003-2012 TrueCrypt Developers Association. All Rights Reserved.\r\n"
L"Copyright \xA9 1998-2000 Paul Le Roux. All Rights Reserved.\r\n"
L"Copyright \xA9 1998-2008 Brian Gladman. All Rights Reserved.\r\n"
@@ -1853,7 +1851,7 @@ BOOL CALLBACK AboutDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
L"Copyright \xA9 2013-2019 Stephan Mueller <smueller@chronox.de>\r\n\r\n"
L"This software as a whole:\r\n"
- L"Copyright \xA9 2013-2020 IDRIX. All rights reserved.\r\n\r\n"
+ L"Copyright \xA9 2013-2022 IDRIX. All rights reserved.\r\n\r\n"
L"An IDRIX Release");
@@ -3186,6 +3184,45 @@ void DoPostInstallTasks (HWND hwndDlg)
SavePostInstallTasksSettings (TC_POST_INSTALL_CFG_REMOVE_ALL);
}
+#ifdef SETUP_DLL
+static BOOL GetWindowVersionFromFile(DWORD* pdwMajor, DWORD* pdwMinor, DWORD* pdwBuildNumber)
+{
+ wchar_t dllPath[MAX_PATH];
+ BOOL bRet = FALSE;
+ LPBYTE versionInfo = NULL;
+ UINT size;
+ VS_FIXEDFILEINFO *vinfo;
+
+ /* Load dll explictely from System32 to avoid Dll hijacking attacks*/
+ if (!GetSystemDirectory(dllPath, MAX_PATH))
+ StringCbCopyW(dllPath, sizeof(dllPath), L"C:\\Windows\\System32");
+
+ StringCbCatW(dllPath, sizeof(dllPath), L"\\");
+ StringCbCatW(dllPath, sizeof(dllPath), L"Kernel32.dll");
+
+ size = GetFileVersionInfoSizeW(dllPath, NULL);
+ if (size)
+ {
+ versionInfo = (LPBYTE) TCalloc(size);
+ if (GetFileVersionInfo(dllPath, 0, size, versionInfo))
+ {
+
+ if (VerQueryValueW(versionInfo, L"\\", (LPVOID *)&vinfo, &size) && (size >=sizeof(VS_FIXEDFILEINFO)))
+ {
+ *pdwMajor = HIWORD(vinfo->dwProductVersionMS);
+ *pdwMinor = LOWORD(vinfo->dwProductVersionMS);
+ *pdwBuildNumber = HIWORD(vinfo->dwProductVersionLS);
+ bRet = TRUE;
+ }
+ }
+ }
+
+ if (versionInfo)
+ TCfree(versionInfo);
+ return bRet;
+}
+#endif
+
/*
* Use RtlGetVersion to get Windows version because GetVersionEx is affected by application manifestation.
*/
@@ -3194,6 +3231,9 @@ typedef NTSTATUS (WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
static BOOL GetWindowsVersion(LPOSVERSIONINFOW lpVersionInformation)
{
BOOL bRet = FALSE;
+#ifdef SETUP_DLL
+ DWORD dwMajor, dwMinor, dwBuildNumber;
+#endif
RtlGetVersionPtr RtlGetVersionFn = (RtlGetVersionPtr) GetProcAddress(GetModuleHandle (L"ntdll.dll"), "RtlGetVersion");
if (RtlGetVersionFn != NULL)
{
@@ -3204,6 +3244,17 @@ static BOOL GetWindowsVersion(LPOSVERSIONINFOW lpVersionInformation)
if (!bRet)
bRet = GetVersionExW (lpVersionInformation);
+#ifdef SETUP_DLL
+ // we get real version from Kernel32.dll version since MSI always sets current version to 6.0
+ // https://stackoverflow.com/questions/49335885/windows-10-not-detecting-on-installshield/49343826#49343826
+ if (GetWindowVersionFromFile(&dwMajor, &dwMinor, &dwBuildNumber))
+ {
+ lpVersionInformation->dwMajorVersion = dwMajor;
+ lpVersionInformation->dwMinorVersion = dwMinor;
+ lpVersionInformation->dwBuildNumber = dwBuildNumber;
+ }
+#endif
+
return bRet;
}
@@ -3517,37 +3568,40 @@ void InitApp (HINSTANCE hInstance, wchar_t *lpszCommandLine)
RemoteSession = GetSystemMetrics (SM_REMOTESESSION) != 0;
- // OS version check
- if (CurrentOSMajor < 5)
+#ifndef VC_SKIP_OS_DRIVER_REQ_CHECK
+ if (!IsSupportedOS())
{
MessageBoxW (NULL, GetString ("UNSUPPORTED_OS"), lpszTitle, MB_ICONSTOP);
exit (1);
}
+#else
+ // in TESTSIGNING mode, we support only Windows Vista, Windows 7, Windows 8/8.1
+ if ( !IsOSVersionAtLeast(WIN_VISTA, 0)
+#ifndef SETUP
+ || IsOSVersionAtLeast(WIN_10, 0)
+#else
+ || (IsOSVersionAtLeast(WIN_10, 0) && !bMakePackage)
+#endif
+ )
+ {
+ MessageBoxW (NULL, L"TESTSIGNING version of VeraCrypt targets only Windows Vista, Windows 7 and Windows 8/8.1.\n\nPlease use the standard version of VeraCrypt instead.", lpszTitle, MB_ICONSTOP);
+ exit (1);
+ }
+ else if ( !IsTestSigningModeEnabled()
+#ifdef SETUP
+ && !bMakePackage
+#endif
+ )
+ {
+ MessageBoxW (NULL, L"Test-Signing Mode, which is required to run VeraCrypt TESTSIGNING binaries, is not enabled in Windows.\n\nExecution aborted!", lpszTitle, MB_ICONSTOP);
+ exit (1);
+ }
+#endif
else
{
// Service pack check & warnings about critical MS issues
switch (nCurrentOS)
{
- case WIN_2000:
- if (CurrentOSServicePack < 3)
- Warning ("LARGE_IDE_WARNING_2K", NULL);
- else
- {
- DWORD val = 0, size = sizeof(val);
- HKEY hkey;
-
- if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Atapi\\Parameters", 0, KEY_READ, &hkey) == ERROR_SUCCESS)
- {
- if (RegQueryValueExW (hkey, L"EnableBigLba", 0, 0, (LPBYTE) &val, &size) != ERROR_SUCCESS
- || val != 1)
- {
- Warning ("LARGE_IDE_WARNING_2K_REGISTRY", NULL);
- }
- RegCloseKey (hkey);
- }
- }
- break;
-
case WIN_XP:
if (CurrentOSServicePack < 1)
{
@@ -6252,7 +6306,7 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg)
benchmarkTable[benchmarkTotalItems].decSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
benchmarkTable[benchmarkTotalItems].id = ci->ea;
benchmarkTable[benchmarkTotalItems].meanBytesPerSec = ((unsigned __int64) (benchmarkBufferSize / ((float) benchmarkTable[benchmarkTotalItems].encSpeed / benchmarkPerformanceFrequency.QuadPart)) + (unsigned __int64) (benchmarkBufferSize / ((float) benchmarkTable[benchmarkTotalItems].decSpeed / benchmarkPerformanceFrequency.QuadPart))) / 2;
- EAGetName (benchmarkTable[benchmarkTotalItems].name, ci->ea, 1);
+ EAGetName (benchmarkTable[benchmarkTotalItems].name, 100, ci->ea, 1);
benchmarkTotalItems++;
}
@@ -7175,7 +7229,7 @@ CipherTestDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
{
if (EAGetCipherCount (ea) == 1 && EAIsFormatEnabled (ea))
- AddComboPair (GetDlgItem (hwndDlg, IDC_CIPHER), EAGetName (buf, ea, 1), EAGetFirstCipher (ea));
+ AddComboPair (GetDlgItem (hwndDlg, IDC_CIPHER), EAGetName (buf, ARRAYSIZE(buf),ea, 1), EAGetFirstCipher (ea));
}
ResetCipherTest(hwndDlg, idTestCipher);
@@ -11143,6 +11197,37 @@ BOOL IsOSVersionAtLeast (OSVersionEnum reqMinOS, int reqMinServicePack)
>= (major << 16 | minor << 8 | reqMinServicePack));
}
+BOOL IsSupportedOS ()
+{
+ BOOL bRet = FALSE;
+#ifdef SETUP
+ static const wchar_t* szWin7KBs[] = {L"KB3033929", L"KB4474419"};
+ static const wchar_t* szWinVistaKBs[] = {L"KB4039648", L"KB4474419"};
+ if (IsOSAtLeast(WIN_8))
+ bRet = TRUE;
+ else if (IsOSAtLeast(WIN_7))
+ {
+ if (OneOfKBsInstalled(szWin7KBs, 2))
+ bRet = TRUE;
+ else
+ MessageBoxW (NULL, L"SHA-2 support missing from Windows.\n\nPlease Install KB3033929 or KB4474419", lpszTitle, MB_ICONWARNING);
+ }
+ else if (IsOSAtLeast(WIN_VISTA))
+ {
+ if (OneOfKBsInstalled(szWinVistaKBs, 2))
+ bRet = TRUE;
+ else
+ MessageBoxW (NULL, L"SHA-2 support missing from Windows.\n\nPlease Install KB4039648 or KB4474419", lpszTitle, MB_ICONWARNING);
+ }
+ else if (IsOSAtLeast(WIN_XP))
+ bRet = TRUE;
+#else
+ if (IsOSAtLeast(WIN_XP))
+ bRet = TRUE;
+#endif
+
+ return bRet;
+}
BOOL Is64BitOs()
{
@@ -11210,7 +11295,7 @@ BOOL IsARM()
USHORT processMachine, nativeMachine;
if (fnIsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine))
{
- if (IMAGE_FILE_MACHINE_ARM64 == nativeMachine || IMAGE_FILE_MACHINE_AMD64 == nativeMachine || IMAGE_FILE_MACHINE_IA64 == nativeMachine || IMAGE_FILE_MACHINE_ALPHA64 == nativeMachine)
+ if (IMAGE_FILE_MACHINE_ARM64 == nativeMachine || IMAGE_FILE_MACHINE_ARM == nativeMachine)
isARM = TRUE;
else
isARM = FALSE;
@@ -14357,7 +14442,7 @@ INT_PTR SecureDesktopDialogBoxParam(
#endif
-#ifdef NDEBUG
+#if defined(NDEBUG) && !defined(VC_SKIP_OS_DRIVER_REQ_CHECK)
static BOOL InitializeWintrust()
{
if (!hWinTrustLib)
@@ -14408,7 +14493,7 @@ static void FinalizeWintrust()
BOOL VerifyModuleSignature (const wchar_t* path)
{
-#ifdef NDEBUG
+#if defined(NDEBUG) && !defined (VC_SKIP_OS_DRIVER_REQ_CHECK)
BOOL bResult = FALSE;
HRESULT hResult;
GUID gActionID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
@@ -14416,6 +14501,11 @@ BOOL VerifyModuleSignature (const wchar_t* path)
WINTRUST_DATA WVTData = {0};
wchar_t filePath [TC_MAX_PATH + 1024];
+ // we check our own authenticode signature only starting from Windows 10 since this is
+ // the minimal supported OS apart from XP where we can't verify SHA256 signatures
+ if (!IsOSAtLeast (WIN_10))
+ return TRUE;
+
// Strip quotation marks (if any)
if (path [0] == L'"')
{
@@ -14460,9 +14550,7 @@ BOOL VerifyModuleSignature (const wchar_t* path)
BYTE hashVal[64];
sha512 (hashVal, pProviderCert->pCert->pbCertEncoded, pProviderCert->pCert->cbCertEncoded);
- if ( (0 == memcmp (hashVal, gpbSha1CodeSignCertFingerprint, 64))
- || (0 == memcmp (hashVal, gpbSha256CodeSignCertFingerprint, 64))
- )
+ if (0 == memcmp (hashVal, gpbSha256CodeSignCertFingerprint, 64))
{
bResult = TRUE;
}
@@ -15551,3 +15639,219 @@ BOOL GetHibernateStatus (BOOL& bHibernateEnabled, BOOL& bHiberbootEnabled)
return bResult;
}
+
+/* return TRUE if Windows is in Test Signing mode */
+/* ref: https://social.msdn.microsoft.com/Forums/Windowsapps/en-US/e6c1be93-7003-4594-b8e4-18ab4a75d273/detecting-testsigning-onoff-via-api */
+BOOL IsTestSigningModeEnabled ()
+{
+ BOOL bEnabled = FALSE;
+ NtQuerySystemInformationFn NtQuerySystemInformationPtr = (NtQuerySystemInformationFn) GetProcAddress (GetModuleHandle (L"ntdll.dll"), "NtQuerySystemInformation");
+ if(NtQuerySystemInformationPtr)
+ {
+ SYSTEM_CODEINTEGRITY_INFORMATION info = {0};
+ ULONG cbReturnedData = 0;
+ info.Length = sizeof(info);
+ if ( (NtQuerySystemInformationPtr((SYSTEM_INFORMATION_CLASS) SYSTEMCODEINTEGRITYINFORMATION, &info, sizeof(info), &cbReturnedData) >= 0)
+ && (cbReturnedData == sizeof(info))
+ )
+ {
+ if ((info.CodeIntegrityOptions & (CODEINTEGRITY_OPTION_TESTSIGN | CODEINTEGRITY_OPTION_ENABLED)) == (CODEINTEGRITY_OPTION_TESTSIGN | CODEINTEGRITY_OPTION_ENABLED))
+ {
+ bEnabled = TRUE;
+ }
+ }
+ }
+
+ return bEnabled;
+}
+
+// Adapted from https://docs.microsoft.com/en-us/windows/win32/wmisdk/example-creating-a-wmi-application
+bool GetKbList (std::vector<std::wstring>& kbList)
+{
+ HRESULT hres;
+ kbList.clear();
+
+ // Initialize COM.
+ hres = CoInitialize(NULL);
+ if (FAILED(hres))
+ {
+ return false;
+ }
+
+ // Initialize
+ hres = CoInitializeSecurity(
+ NULL,
+ -1, // COM negotiates service
+ NULL, // Authentication services
+ NULL, // Reserved
+ RPC_C_AUTHN_LEVEL_DEFAULT, // authentication
+ RPC_C_IMP_LEVEL_IMPERSONATE, // Impersonation
+ NULL, // Authentication info
+ EOAC_NONE, // Additional capabilities
+ NULL // Reserved
+ );
+
+
+ if (FAILED(hres))
+ {
+ CoUninitialize();
+ return false;
+ }
+
+ // Obtain the initial locator to Windows Management
+ // on a particular host computer.
+ IWbemLocator *pLoc = 0;
+
+ hres = CoCreateInstance(
+ CLSID_WbemLocator,
+ 0,
+ CLSCTX_INPROC_SERVER,
+ IID_IWbemLocator, (LPVOID *) &pLoc);
+
+ if (FAILED(hres))
+ {
+ CoUninitialize();
+ return false;
+ }
+
+ IWbemServices *pSvc = 0;
+
+ // Connect to the root\cimv2 namespace with the
+ // current user and obtain pointer pSvc
+ // to make IWbemServices calls.
+
+ hres = pLoc->ConnectServer(
+
+ _bstr_t(L"ROOT\\CIMV2"), // WMI namespace
+ NULL, // User name
+ NULL, // User password
+ 0, // Locale
+ NULL, // Security flags
+ 0, // Authority
+ 0, // Context object
+ &pSvc // IWbemServices proxy
+ );
+
+ if (FAILED(hres))
+ {
+ pLoc->Release();
+ CoUninitialize();
+ return false;
+ }
+
+ // Set the IWbemServices proxy so that impersonation
+ // of the user (client) occurs.
+ hres = CoSetProxyBlanket(
+
+ pSvc, // the proxy to set
+ RPC_C_AUTHN_WINNT, // authentication service
+ RPC_C_AUTHZ_NONE, // authorization service
+ NULL, // Server principal name
+ RPC_C_AUTHN_LEVEL_CALL, // authentication level
+ RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
+ NULL, // client identity
+ EOAC_NONE // proxy capabilities
+ );
+
+ if (FAILED(hres))
+ {
+ pSvc->Release();
+ pLoc->Release();
+ CoUninitialize();
+ return false;
+ }
+
+
+ // Use the IWbemServices pointer to make requests of WMI.
+ // Make requests here:
+
+ // query for all installed KBs
+ IEnumWbemClassObject* pEnumerator = NULL;
+ hres = pSvc->ExecQuery(
+ bstr_t("WQL"),
+ bstr_t("SELECT * FROM Win32_QuickFixEngineering"),
+ WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
+ NULL,
+ &pEnumerator);
+
+ if (FAILED(hres))
+ {
+ pSvc->Release();
+ pLoc->Release();
+ CoUninitialize();
+ return false;
+ }
+ else
+ {
+ IWbemClassObject *pclsObj;
+ ULONG uReturn = 0;
+
+ while (pEnumerator)
+ {
+ hres = pEnumerator->Next(WBEM_INFINITE, 1,
+ &pclsObj, &uReturn);
+
+ if(0 == uReturn)
+ {
+ break;
+ }
+
+ VARIANT vtProp;
+
+ // Get the value of the "hotfixid" property
+ hres = pclsObj->Get(L"hotfixid", 0, &vtProp, 0, 0);
+ if (SUCCEEDED(hres) && (V_VT(&vtProp) == VT_BSTR))
+ {
+ kbList.push_back(vtProp.bstrVal);
+ }
+ VariantClear(&vtProp);
+
+ pclsObj->Release();
+ pclsObj = NULL;
+ }
+
+ }
+
+ // Cleanup
+ // ========
+
+ pSvc->Release();
+ pLoc->Release();
+ pEnumerator->Release();
+
+ CoUninitialize();
+
+ return true;
+}
+
+bool OneOfKBsInstalled (const wchar_t* szKBs[], int count)
+{
+ std::vector<std::wstring> kbList;
+ bool bRet = GetKbList(kbList);
+ if (bRet)
+ {
+ // at least one of the given KBs must be present
+ bool bFound = false;
+
+ for (size_t j = 0; j < kbList.size(); j++)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ if (_wcsicmp(szKBs[i], kbList[j].c_str()) == 0)
+ {
+ bFound = true;
+ break;
+ }
+ }
+
+ if (bFound)
+ {
+ break;
+ }
+ }
+
+ bRet = bFound;
+ }
+
+ return bRet;
+}
diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h
index 86e655a7..6e84c94f 100644
--- a/src/Common/Dlgcode.h
+++ b/src/Common/Dlgcode.h
@@ -18,6 +18,7 @@
#include "Apidrvr.h"
#include "Keyfiles.h"
#include "Wipe.h"
+#include <Winternl.h>
#ifdef __cplusplus
extern "C" {
@@ -250,6 +251,28 @@ typedef enum BitLockerEncryptionStatus
BL_Status_Protected
} BitLockerEncryptionStatus;
+#ifndef CODEINTEGRITY_OPTION_ENABLED
+
+#define CODEINTEGRITY_OPTION_ENABLED 0x01
+#define CODEINTEGRITY_OPTION_TESTSIGN 0x02
+
+typedef struct _SYSTEM_CODEINTEGRITY_INFORMATION {
+ ULONG Length;
+ ULONG CodeIntegrityOptions;
+} SYSTEM_CODEINTEGRITY_INFORMATION, *PSYSTEM_CODEINTEGRITY_INFORMATION;
+
+#endif
+
+#define SYSPARTITIONINFORMATION 0x62
+#define SYSTEMCODEINTEGRITYINFORMATION 0x67
+
+typedef NTSTATUS (WINAPI *NtQuerySystemInformationFn)(
+ SYSTEM_INFORMATION_CLASS SystemInformationClass,
+ PVOID SystemInformation,
+ ULONG SystemInformationLength,
+ PULONG ReturnLength
+);
+
#define DEFAULT_VOL_CREATION_WIZARD_MODE WIZARD_MODE_FILE_CONTAINER
@@ -479,6 +502,7 @@ void Debug (char *format, ...);
void DebugMsgBox (char *format, ...);
BOOL IsOSAtLeast (OSVersionEnum reqMinOS);
BOOL IsOSVersionAtLeast (OSVersionEnum reqMinOS, int reqMinServicePack);
+BOOL IsSupportedOS ();
BOOL Is64BitOs ();
BOOL IsARM();
BOOL IsServerOS ();
@@ -567,6 +591,7 @@ BOOL BufferHasPattern (const unsigned char* buffer, size_t bufferLen, const void
BOOL EnableProcessProtection();
void SafeOpenURL (LPCWSTR szUrl);
BitLockerEncryptionStatus GetBitLockerEncryptionStatus(WCHAR driveLetter);
+BOOL IsTestSigningModeEnabled ();
#ifdef _WIN64
void GetAppRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed);
#endif
@@ -757,6 +782,8 @@ public:
};
BOOL GetHibernateStatus (BOOL& bHibernateEnabled, BOOL& bHiberbootEnabled);
+bool GetKbList (std::vector<std::wstring>& kbList);
+bool OneOfKBsInstalled (const wchar_t* szKBs[], int count);
#endif // __cplusplus
diff --git a/src/Common/EncryptionThreadPool.c b/src/Common/EncryptionThreadPool.c
index 10052796..1401e8a0 100644
--- a/src/Common/EncryptionThreadPool.c
+++ b/src/Common/EncryptionThreadPool.c
@@ -108,6 +108,18 @@ typedef struct EncryptionThreadPoolWorkItemStruct
char *Salt;
} KeyDerivation;
+
+ struct
+ {
+ TC_EVENT *KeyDerivationCompletedEvent;
+ TC_EVENT *NoOutstandingWorkItemEvent;
+ LONG *outstandingWorkItemCount;
+ void* keyInfoBuffer;
+ int keyInfoBufferSize;
+ void* keyDerivationWorkItems;
+ int keyDerivationWorkItemsSize;
+
+ } ReadVolumeHeaderFinalization;
};
} EncryptionThreadPoolWorkItem;
@@ -275,6 +287,37 @@ static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
TC_SET_EVENT (WorkItemCompletedEvent);
continue;
+ case ReadVolumeHeaderFinalizationWork:
+ TC_WAIT_EVENT (*(workItem->ReadVolumeHeaderFinalization.NoOutstandingWorkItemEvent));
+
+ if (workItem->ReadVolumeHeaderFinalization.keyDerivationWorkItems)
+ {
+ burn (workItem->ReadVolumeHeaderFinalization.keyDerivationWorkItems, workItem->ReadVolumeHeaderFinalization.keyDerivationWorkItemsSize);
+#if !defined(DEVICE_DRIVER)
+ VirtualUnlock (workItem->ReadVolumeHeaderFinalization.keyDerivationWorkItems, workItem->ReadVolumeHeaderFinalization.keyDerivationWorkItemsSize);
+#endif
+ TCfree (workItem->ReadVolumeHeaderFinalization.keyDerivationWorkItems);
+ }
+
+ if (workItem->ReadVolumeHeaderFinalization.keyInfoBuffer)
+ {
+ burn (workItem->ReadVolumeHeaderFinalization.keyInfoBuffer, workItem->ReadVolumeHeaderFinalization.keyInfoBufferSize);
+#if !defined(DEVICE_DRIVER)
+ VirtualUnlock (workItem->ReadVolumeHeaderFinalization.keyInfoBuffer, workItem->ReadVolumeHeaderFinalization.keyInfoBufferSize);
+#endif
+ TCfree (workItem->ReadVolumeHeaderFinalization.keyInfoBuffer);
+ }
+
+#if !defined(DEVICE_DRIVER)
+ CloseHandle (*(workItem->ReadVolumeHeaderFinalization.KeyDerivationCompletedEvent));
+ CloseHandle (*(workItem->ReadVolumeHeaderFinalization.NoOutstandingWorkItemEvent));
+#endif
+ TCfree (workItem->ReadVolumeHeaderFinalization.KeyDerivationCompletedEvent);
+ TCfree (workItem->ReadVolumeHeaderFinalization.NoOutstandingWorkItemEvent);
+ TCfree (workItem->ReadVolumeHeaderFinalization.outstandingWorkItemCount);
+ SetWorkItemState (workItem, WorkItemFree);
+ TC_SET_EVENT (WorkItemCompletedEvent);
+ continue;
default:
TC_THROW_FATAL_EXCEPTION;
}
@@ -528,6 +571,40 @@ void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT
TC_RELEASE_MUTEX (&EnqueueMutex);
}
+void EncryptionThreadPoolBeginReadVolumeHeaderFinalization (TC_EVENT *keyDerivationCompletedEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG* outstandingWorkItemCount,
+ void* keyInfoBuffer, int keyInfoBufferSize,
+ void* keyDerivationWorkItems, int keyDerivationWorkItemsSize)
+{
+ EncryptionThreadPoolWorkItem *workItem;
+
+ if (!ThreadPoolRunning)
+ TC_THROW_FATAL_EXCEPTION;
+
+ TC_ACQUIRE_MUTEX (&EnqueueMutex);
+
+ workItem = &WorkItemQueue[EnqueuePosition++];
+ if (EnqueuePosition >= ThreadQueueSize)
+ EnqueuePosition = 0;
+
+ while (GetWorkItemState (workItem) != WorkItemFree)
+ {
+ TC_WAIT_EVENT (WorkItemCompletedEvent);
+ }
+
+ workItem->Type = ReadVolumeHeaderFinalizationWork;
+ workItem->ReadVolumeHeaderFinalization.NoOutstandingWorkItemEvent = noOutstandingWorkItemEvent;
+ workItem->ReadVolumeHeaderFinalization.KeyDerivationCompletedEvent = keyDerivationCompletedEvent;
+ workItem->ReadVolumeHeaderFinalization.keyInfoBuffer = keyInfoBuffer;
+ workItem->ReadVolumeHeaderFinalization.keyInfoBufferSize = keyInfoBufferSize;
+ workItem->ReadVolumeHeaderFinalization.keyDerivationWorkItems = keyDerivationWorkItems;
+ workItem->ReadVolumeHeaderFinalization.keyDerivationWorkItemsSize = keyDerivationWorkItemsSize;
+ workItem->ReadVolumeHeaderFinalization.outstandingWorkItemCount = outstandingWorkItemCount;
+
+ SetWorkItemState (workItem, WorkItemReady);
+ TC_SET_EVENT (WorkItemReadyEvent);
+ TC_RELEASE_MUTEX (&EnqueueMutex);
+}
+
void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, byte *data, const UINT64_STRUCT *startUnitNo, uint32 unitCount, PCRYPTO_INFO cryptoInfo)
{
@@ -615,7 +692,7 @@ void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, byte *data,
workItem->Encryption.UnitCount = unitsPerFragment;
workItem->Encryption.StartUnitNo.Value = fragmentStartUnitNo;
- fragmentData += unitsPerFragment * ENCRYPTION_DATA_UNIT_SIZE;
+ fragmentData += ((uint64)unitsPerFragment) * ENCRYPTION_DATA_UNIT_SIZE;
fragmentStartUnitNo += unitsPerFragment;
if (remainder > 0 && --remainder == 0)
diff --git a/src/Common/EncryptionThreadPool.h b/src/Common/EncryptionThreadPool.h
index 161fb7ce..053d4107 100644
--- a/src/Common/EncryptionThreadPool.h
+++ b/src/Common/EncryptionThreadPool.h
@@ -24,7 +24,8 @@ typedef enum
{
EncryptDataUnitsWork,
DecryptDataUnitsWork,
- DeriveKeyWork
+ DeriveKeyWork,
+ ReadVolumeHeaderFinalizationWork
} EncryptionThreadPoolWorkType;
#ifndef DEVICE_DRIVER
@@ -32,6 +33,7 @@ size_t GetCpuCount (WORD* pGroupCount);
#endif
void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, char *derivedKey);
+void EncryptionThreadPoolBeginReadVolumeHeaderFinalization (TC_EVENT *keyDerivationCompletedEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG* outstandingWorkItemCount, void* keyInfoBuffer, int keyInfoBufferSize, void* keyDerivationWorkItems, int keyDerivationWorkItemsSize);
void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, byte *data, const UINT64_STRUCT *startUnitNo, uint32 unitCount, PCRYPTO_INFO cryptoInfo);
BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount);
void EncryptionThreadPoolStop ();
diff --git a/src/Common/Language.c b/src/Common/Language.c
index ffccd44e..844f4dad 100644
--- a/src/Common/Language.c
+++ b/src/Common/Language.c
@@ -226,7 +226,7 @@ static BOOL LoadLanguageData (int resourceid, BOOL bForceSetPreferredLanguage, B
XmlGetAttributeText (xml, "prog-version", attr, sizeof (attr));
// Check version of external language file
- if (defaultLangParsed && strcmp (attr, VERSION_STRING VERSION_STRING_SUFFIX) && strcmp (attr, "DEBUG"))
+ if (defaultLangParsed && strcmp (attr, VERSION_STRING) && strcmp (attr, "DEBUG"))
{
wchar_t m[2048];
StringCbPrintfW (m, sizeof(m), L"The installed language pack is incompatible with this version of VeraCrypt (the language pack is for VeraCrypt %hs). A newer version may be available at www.idrix.fr.\n\nTo prevent this message from being displayed, do any of the following:\n\n- Select 'Settings' > 'Language'; then select 'English' and click 'OK'.\n\n- Remove or replace the language pack with a compatible version (the language pack may reside e.g. in 'C:\\Program Files\\VeraCrypt' or '%%LOCALAPPDATA%%\\VirtualStore\\Program Files\\VeraCrypt', etc.)", attr);
diff --git a/src/Common/Language.xml b/src/Common/Language.xml
index fc946fce..441909bf 100644
--- a/src/Common/Language.xml
+++ b/src/Common/Language.xml
@@ -32,6 +32,7 @@
<entry lang="en" key="IDC_DEVICE_TRANSFORM_MODE_INPLACE">Encrypt partition in place</entry>
<entry lang="en" key="IDC_DISPLAY_KEYS">Display generated keys (their portions)</entry>
<entry lang="en" key="IDC_DISPLAY_POOL_CONTENTS">Display pool content</entry>
+ <entry lang="en" key="IDC_DOWNLOAD_CD_BURN_SOFTWARE">Download CD/DVD recording software</entry>
<entry lang="en" key="IDC_FILE_CONTAINER">Create an encrypted file container</entry>
<entry lang="en" key="IDC_GB">&amp;GiB</entry>
<entry lang="en" key="IDC_TB">&amp;TiB</entry>
@@ -602,6 +603,7 @@
<entry lang="en" key="OVERWRITEPROMPT_DEVICE_HIDDEN_OS_PARTITION">CAUTION: ANY FILES CURRENTLY STORED ON THE PARTITION '%s'%s (I.E. ON THE FIRST PARTITION BEHIND THE SYSTEM PARTITION) WILL BE ERASED AND LOST (THEY WILL NOT BE ENCRYPTED)!\n\nAre you sure you want to proceed with format?</entry>
<entry lang="en" key="OVERWRITEPROMPT_DEVICE_SECOND_WARNING_LOTS_OF_DATA">WARNING: THE SELECTED PARTITION CONTAINS A LARGE AMOUNT OF DATA! Any files stored on the partition will be erased and lost (they will NOT be encrypted)!</entry>
<entry lang="en" key="ERASE_FILES_BY_CREATING_VOLUME">Erase any files stored on the partition by creating a VeraCrypt volume within it</entry>
+ <entry lang="en" key="PASSWORD">Password</entry>
<entry lang="en" key="PIM">PIM</entry>
<entry lang="en" key="IDD_PCDM_CHANGE_PKCS5_PRF">Set Header Key Derivation Algorithm</entry>
<entry lang="en" key="IDD_PCDM_ADD_REMOVE_VOL_KEYFILES">Add/Remove Keyfiles to/from Volume</entry>
@@ -956,7 +958,7 @@
<entry lang="en" key="HEADER_RESTORE_INTERNAL">Restore the volume header from the backup embedded in the volume</entry>
<entry lang="en" key="HEADER_RESTORE_EXTERNAL">Restore the volume header from an external backup file</entry>
<entry lang="en" key="HEADER_BACKUP_SIZE_INCORRECT">The size of the volume header backup file is incorrect.</entry>
- <entry 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).</entry>
+ <entry lang="en" key="VOLUME_HAS_NO_BACKUP_HEADER">There is no backup header embedded in this volume (note that only volumes created by TrueCrypt 6.0 or later contain embedded backup headers).</entry>
<entry 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?</entry>
<entry 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?</entry>
<entry 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.</entry>
@@ -1105,7 +1107,6 @@
<entry lang="en" key="PIM_REQUIRE_LONG_PASSWORD">Password must contain 20 or more characters in order to use the specified PIM.\nShorter passwords can only be used if the PIM is 485 or greater.</entry>
<entry lang="en" key="BOOT_PIM_REQUIRE_LONG_PASSWORD">Pre-boot authentication Password must contain 20 or more characters in order to use the specified PIM.\nShorter passwords can only be used if the PIM is 98 or greater.</entry>
<entry lang="en" key="KEYFILES_NOT_SUPPORTED_FOR_SYS_ENCRYPTION">Keyfiles are currently not supported for system encryption.</entry>
- <entry lang="en" key="RESCUE_DISK_BACK_BUTTON">The Rescue Disk was already created depending on the selected options. In order to prevent incompatibility, you have to click 'cancel' and restart the system encryption process, if you want to modify any configuration.</entry>
<entry lang="en" key="CANNOT_RESTORE_KEYBOARD_LAYOUT">Warning: VeraCrypt could not restore the original keyboard layout. This may cause you to enter a password incorrectly.</entry>
<entry lang="en" key="CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION">Error: Cannot set the keyboard layout for VeraCrypt to the standard US keyboard layout.\n\nNote that the password needs to be typed in the pre-boot environment (before Windows starts) where non-US Windows keyboard layouts are not available. Therefore, the password must always be typed using the standard US keyboard layout.</entry>
<entry lang="en" key="ALT_KEY_CHARS_NOT_FOR_SYS_ENCRYPTION">It is not possible to type characters by pressing keys while the right Alt key is held down. However, you can type most of such characters by pressing appropriate keys while the Shift key is held down.</entry>
@@ -1174,14 +1175,13 @@
<entry lang="en" key="CD_BURNER_NOT_PRESENT_CONNECTED_NOW">A CD/DVD burner is connected to my computer now. Continue and write the Rescue Disk.</entry>
<entry lang="en" key="CD_BURNER_NOT_PRESENT_WILL_STORE_ISO_INFO">Please follow these steps:\n\n1) Connect a removable drive, such as a USB flash drive, to your computer now.\n\n2) Copy the VeraCrypt Rescue Disk image file (%s) to the removable drive.\n\nIn case you need to use the VeraCrypt Rescue Disk in the future, you will be able to connect your removable drive (containing the VeraCrypt Rescue Disk image) to a computer with a CD/DVD burner and create a bootable VeraCrypt Rescue Disk by burning the image to a CD or DVD. IMPORTANT: Note that the VeraCrypt Rescue Disk image file must be written to the CD/DVD as an ISO disk image (not as an individual file).</entry>
<entry lang="en" key="RESCUE_DISK_RECORDING_TITLE">Rescue Disk Recording</entry>
- <entry lang="en" key="AES_BOX_HELP">AES is secure according to NIST</entry>
- <entry lang="en" key="BACKUP_RESCUE_DISK_TITLE">Backup Rescue Disk</entry>
<entry lang="en" key="RESCUE_DISK_CREATED_TITLE">Rescue Disk Created</entry>
<entry lang="en" key="SYS_ENCRYPTION_PRETEST_TITLE">System Encryption Test</entry>
<entry lang="en" key="RESCUE_DISK_DISK_VERIFIED_TITLE">Rescue Disk Verified</entry>
<entry lang="en" key="RESCUE_DISK_VERIFIED_INFO">\nThe VeraCrypt Rescue Disk has been successfully verified. Please remove it from the drive now and store it in a safe place.\n\nClick Next to continue.</entry>
<entry lang="en" key="REMOVE_RESCUE_DISK_FROM_DRIVE">WARNING: During the next steps, the VeraCrypt Rescue Disk must not be in the drive. Otherwise, it will not be possible to complete the steps correctly.\n\nPlease remove it from the drive now and store it in a safe place. Then click OK.</entry>
<entry lang="en" key="PREBOOT_NOT_LOCALIZED">Warning: Due to technical limitations of the pre-boot environment, texts displayed by VeraCrypt in the pre-boot environment (i.e. before Windows starts) cannot be localized. The VeraCrypt Boot Loader user interface is completely in English.\n\nContinue?</entry>
+ <entry lang="en" key="SYS_ENCRYPTION_PRETEST_INFO">Before encrypting your system partition or drive, VeraCrypt needs to verify that everything works correctly.\n\nAfter you click Test, all the necessary components (for example, the pre-boot authentication component, i.e. the VeraCrypt Boot Loader) will be installed and your computer will be restarted. Then you will have to enter your password in the VeraCrypt Boot Loader screen that will appear before Windows starts. After Windows starts, you will be automatically informed about the result of this pretest.\n\nThe following device will be modified: Drive #%d\n\n\nIf you click Cancel now, nothing will be installed and the pretest will not be performed.</entry>
<entry lang="en" key="SYS_ENCRYPTION_PRETEST_INFO2_PORTION_1">IMPORTANT NOTES -- PLEASE READ OR PRINT (click 'Print'):\n\nNote that none of your files will be encrypted before you successfully restart your computer and start Windows. Thus, if anything fails, your data will NOT be lost. However, if something does go wrong, you might encounter difficulties in starting Windows. Therefore, please read (and, if possible, print) the following guidelines on what to do if Windows cannot start after you restart the computer.\n\n</entry>
<entry lang="en" key="SYS_ENCRYPTION_PRETEST_INFO2_PORTION_2">What to Do If Windows Cannot Start\n------------------------------------------------\n\nNote: These instructions are valid only if you have not started encrypting.\n\n- If Windows does not start after you enter the correct password (or if you repeatedly enter the correct password but VeraCrypt says that the password is incorrect), do not panic. Restart (power off and on) the computer, and in the VeraCrypt Boot Loader screen, press the Esc key on your keyboard (and if you have multiple systems, choose which to start). Then Windows should start (provided that it is not encrypted) and VeraCrypt will automatically ask whether you want to uninstall the pre-boot authentication component. Note that the previous steps do NOT work if the system partition/drive is encrypted (nobody can start Windows or access encrypted data on the drive without the correct password even if he or she follows the previous steps).\n\n</entry>
<entry lang="en" key="SYS_ENCRYPTION_PRETEST_INFO2_PORTION_3">- If the previous steps do not help or if the VeraCrypt Boot Loader screen does not appear (before Windows starts), insert the VeraCrypt Rescue Disk into your CD/DVD drive and restart your computer. If the VeraCrypt Rescue Disk screen does not appear (or if you do not see the 'Repair Options' item in the 'Keyboard Controls' section of the VeraCrypt Rescue Disk screen), it is possible that your BIOS is configured to attempt to boot from hard drives before CD/DVD drives. If that is the case, restart your computer, press F2 or Delete (as soon as you see a BIOS start-up screen), and wait until a BIOS configuration screen appears. If no BIOS configuration screen appears, restart (reset) the computer again and start pressing F2 or Delete repeatedly as soon as you restart (reset) the computer. When a BIOS configuration screen appears, configure your BIOS to boot from the CD/DVD drive first (for information on how to do so, please refer to the documentation for your BIOS/motherboard or contact your computer vendor's technical support team for assistance). Then restart your computer. The VeraCrypt Rescue Disk screen should appear now. In the VeraCrypt Rescue Disk screen, select 'Repair Options' by pressing F8 on your keyboard. From the 'Repair Options' menu, select 'Restore original system loader'. Then remove the Rescue Disk from your CD/DVD drive and restart your computer. Windows should start normally (provided that it is not encrypted).\n\n</entry>
@@ -1189,7 +1189,6 @@
<entry lang="en" key="SYS_ENCRYPTION_PRETEST_RESULT_TITLE">Pretest Successfully Completed</entry>
<entry lang="en" key="SYS_ENCRYPTION_PRETEST_RESULT_INFO">If the encryption is interrupted you can resume it restarting VeraCrypt and selecting 'System' > 'Resume Interrupted Process'\n\nPlease make sure, that your device does not run out of power during the encryption process.</entry>
<entry lang="en" key="SYSENC_ENCRYPTION_PAGE_INFO">Make sure that your device does not run out of power.\nIf the encryption is interrupted you can resume it restarting VeraCrypt and selecting 'System' > 'Resume Interrupted Process'.</entry>
- <entry lang="en" key="SYSENC_DECRYPTION_PAGE_INFO">Make sure that your device does not run out of power.\nIf the decryption is interrupted you can resume it restarting VeraCrypt and selecting 'System' > 'Resume Interrupted Process'.</entry>
<entry lang="en" key="NONSYS_INPLACE_ENC_ENCRYPTION_PAGE_INFO">\n\nYou can click Pause or Defer anytime to interrupt the process of encryption, exit this wizard, restart or shut down your computer, and then resume the process, which will continue from the point it was stopped. Note that the volume cannot be mounted until it has been fully encrypted.</entry>
<entry lang="en" key="NONSYS_INPLACE_DEC_DECRYPTION_PAGE_INFO">\n\nYou can click Pause or Defer anytime to interrupt the process of decryption, exit this wizard, restart or shut down the computer, and then resume the process, which will continue from the point where it was stopped. Note that the volume cannot be mounted until it has been fully decrypted.</entry>
<entry lang="en" key="SYSENC_HIDDEN_OS_INITIAL_INFO_TITLE">Hidden System Started</entry>
@@ -1476,7 +1475,6 @@
<entry lang="en" key="LINUX_CROSS_SUPPORT_OTHER_HELP">Choose this option if you need to use the volume on other platforms.</entry>
<entry lang="en" key="LINUX_CROSS_SUPPORT_ONLY">I will mount the volume only on {0}</entry>
<entry lang="en" key="LINUX_CROSS_SUPPORT_ONLY_HELP">Choose this option if you do not need to use the volume on other platforms.</entry>
- <entry lang="en" key="LINUX_CROSS_SUPPORT_ONLY_HELP">Choose this option if you do not need to use the volume on other platforms.</entry>
<entry lang="en" key="LINUX_DESELECT">Deselect</entry>
<entry lang="en" key="LINUX_ADMIN_PW_QUERY">Enter your user password or administrator password:</entry>
<entry lang="en" key="LINUX_ADMIN_PW_QUERY_TITLE">Administrator privileges required</entry>
@@ -1560,7 +1558,7 @@
<entry lang="en" key="ENTER_PASSWORD">Enter password</entry>
<entry lang="en" key="ENTER_TC_VOL_PASSWORD">Enter VeraCrypt Volume Password</entry>
<entry lang="en" key="MOUNT">Mount</entry>
- <entry lang="en" key="MOUNT_POINT">Mount Directory"</entry>
+ <entry lang="en" key="MOUNT_POINT">Mount Directory</entry>
<entry lang="en" key="NO_VOLUMES_MOUNTED">No volumes mounted.</entry>
<entry lang="en" key="OPEN_NEW_VOLUME">Specify a New VeraCrypt Volume</entry>
<entry lang="en" key="PARAMETER_INCORRECT">Parameter incorrect</entry>
@@ -1570,6 +1568,11 @@
<entry lang="en" key="UNKNOWN_OPTION">Unknown option</entry>
<entry lang="en" key="VOLUME_LOCATION">Volume Location</entry>
<entry lang="en" key="VOLUME_HOST_IN_USE">WARNING: The host file/device {0} is already in use!\n\nIgnoring this can cause undesired results including system instability. All applications that might be using the host file/device should be closed before mounting the volume.\n\nContinue mounting?</entry>
+ <entry lang="en" key="CANT_INSTALL_WITH_EXE_OVER_MSI">VeraCrypt was previously installed using an MSI package and so it can't be updated using the standard installer.\n\nPlease use the MSI package to update your VeraCrypt installation.</entry>
+ <entry lang="en" key="IDC_USE_ALL_FREE_SPACE">Use all available free space</entry>
+ <entry lang="en" key="RESCUE_DISK_BACK_BUTTON">The Rescue Disk was already created depending on the selected options. In order to prevent incompatibility, you have to click 'cancel' and restart the system encryption process, if you want to modify any configuration.</entry>
+ <entry lang="en" key="AES_BOX_HELP">AES is secure according to NIST</entry>
+ <entry lang="en" key="BACKUP_RESCUE_DISK_TITLE">Backup Rescue Disk</entry>
<entry lang="en" key="RESCUE_DISK_CHECKLIST_A">Store your password in a safe location. You can not recover your data without your password.\nThat is why VeraCrypt is considered to be secure.</entry>
<entry lang="en" key="RESCUE_DISK_CHECKLIST_B">Make sure that the rescue file is stored on an external medium. This could be a flash drive, an external hard drive or even a cloud storage.\nYour rescue file is located here:</entry>
<entry lang="en" key="RESCUE_DISK_CHECKLIST_C">Before you start encrypting your system, it is always a good idea to backup your personal data on an external drive for the unlikely case that the encryption process fails.</entry>
diff --git a/src/Common/Password.c b/src/Common/Password.c
index 8c94fc06..3c9faa82 100644
--- a/src/Common/Password.c
+++ b/src/Common/Password.c
@@ -23,6 +23,7 @@
#include "Random.h"
#include <io.h>
+#include <strsafe.h>
#ifndef SRC_POS
#define SRC_POS (__FUNCTION__ ":" TC_TO_STRING(__LINE__))
@@ -211,7 +212,7 @@ int ChangePwd (const wchar_t *lpszVolume, Password *oldPassword, int old_pkcs5,
if (bDevice == FALSE)
{
- wcscpy (szCFDevice, szDiskFile);
+ StringCchCopyW (szCFDevice, ARRAYSIZE(szCFDevice), szDiskFile);
}
else
{
diff --git a/src/Common/Tcdefs.h b/src/Common/Tcdefs.h
index d01ea63b..f8ec9960 100644
--- a/src/Common/Tcdefs.h
+++ b/src/Common/Tcdefs.h
@@ -55,21 +55,23 @@ extern unsigned short _rotl16(unsigned short value, unsigned char shift);
#define TC_APP_NAME "VeraCrypt"
// Version displayed to user
-#define VERSION_STRING "1.24-Update9"
+#define VERSION_STRING "1.25.7"
#ifdef VC_EFI_CUSTOM_MODE
#define VERSION_STRING_SUFFIX "-CustomEFI"
+#elif defined(VC_SKIP_OS_DRIVER_REQ_CHECK)
+#define VERSION_STRING_SUFFIX "-TESTSIGNING"
#else
#define VERSION_STRING_SUFFIX ""
#endif
// Version number to compare against driver
-#define VERSION_NUM 0x0124
+#define VERSION_NUM 0x0125
// Release date
-#define TC_STR_RELEASE_DATE L"January 1, 2021"
-#define TC_RELEASE_DATE_YEAR 2021
-#define TC_RELEASE_DATE_MONTH 1
+#define TC_STR_RELEASE_DATE L"January 7, 2022"
+#define TC_RELEASE_DATE_YEAR 2022
+#define TC_RELEASE_DATE_MONTH 01
#define BYTES_PER_KB 1024LL
#define BYTES_PER_MB 1048576LL
@@ -180,10 +182,10 @@ typedef uint64 uint_64t;
typedef CHAR16 wchar_t;
typedef int LONG;
-#define wcscpy StrCpy
+#define StringCchCopyW StrCpyS
#define wcslen StrLen
#define wcscmp StrCmp
-#define wcscat StrCat
+#define StringCchCatW StrCatS
#define memcpy(dest,source,count) CopyMem(dest,source,(UINTN)(count))
#define memset(dest,ch,count) SetMem(dest,(UINTN)(count),(UINT8)(ch))
@@ -195,7 +197,7 @@ typedef int LONG;
#define strchr(str,ch) ScanMem8((VOID *)(str),AsciiStrSize(str),(UINT8)ch)
#define strcmp AsciiStrCmp
#define strncmp(string1,string2,count) (int)(AsciiStrnCmp(string1,string2,(UINTN)(count)))
-#define strcpy(strDest,strSource) AsciiStrCpyS(strDest,MAX_STRING_SIZE,strSource)
+#define StringCchCopyA(strDest,strMaxSize,strSource) AsciiStrCpyS(strDest,strMaxSize,strSource)
#define strncpy(strDest,strSource,count) AsciiStrnCpyS(strDest,MAX_STRING_SIZE,strSource,(UINTN)count)
#define strlen(str) (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE))
#define strstr AsciiStrStr
diff --git a/src/Common/Tests.c b/src/Common/Tests.c
index 0af4313e..a66c7b54 100644
--- a/src/Common/Tests.c
+++ b/src/Common/Tests.c
@@ -707,7 +707,7 @@ BOOL TestSectorBufEncryption (PCRYPTO_INFO ci)
if (!EAIsModeSupported (ci->ea, ci->mode))
continue;
- EAGetName (name, ci->ea, 0);
+ EAGetName (name, ARRAYSIZE(name), ci->ea, 0);
if (EAInit (ci->ea, key1, ci->ks) != ERR_SUCCESS)
return FALSE;
@@ -1188,7 +1188,7 @@ BOOL TestSectorBufEncryption (PCRYPTO_INFO ci)
if (!EAIsModeSupported (ci->ea, ci->mode))
continue;
- EAGetName (name, ci->ea, 0);
+ EAGetName (name, ARRAYSIZE(name), ci->ea, 0);
if (EAInit (ci->ea, key1, ci->ks) != ERR_SUCCESS)
return FALSE;
diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c
index d3001a94..7bfb8ec2 100644
--- a/src/Common/Volumes.c
+++ b/src/Common/Volumes.c
@@ -170,7 +170,10 @@ BOOL ReadVolumeHeaderRecoveryMode = FALSE;
int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int selected_pkcs5_prf, int pim, BOOL truecryptMode, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
{
char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
- CRYPTOPP_ALIGN_DATA(16) KEY_INFO keyInfo;
+ unsigned char* keyInfoBuffer = NULL;
+ int keyInfoBufferSize = sizeof (KEY_INFO) + 16;
+ size_t keyInfoBufferOffset;
+ PKEY_INFO keyInfo;
PCRYPTO_INFO cryptoInfo;
CRYPTOPP_ALIGN_DATA(16) char dk[MASTER_KEYDATA_SIZE];
int enqPkcs5Prf, pkcs5_prf;
@@ -179,16 +182,28 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int
int primaryKeyOffset;
int pkcs5PrfCount = LAST_PRF_ID - FIRST_PRF_ID + 1;
#if !defined(_UEFI)
- TC_EVENT keyDerivationCompletedEvent;
- TC_EVENT noOutstandingWorkItemEvent;
+ TC_EVENT *keyDerivationCompletedEvent = NULL;
+ TC_EVENT *noOutstandingWorkItemEvent = NULL;
KeyDerivationWorkItem *keyDerivationWorkItems = NULL;
+ int keyDerivationWorkItemsSize = 0;
KeyDerivationWorkItem *item;
size_t encryptionThreadCount = GetEncryptionThreadCount();
- LONG outstandingWorkItemCount = 0;
+ LONG *outstandingWorkItemCount = NULL;
int i;
#endif
size_t queuedWorkItems = 0;
+ // allocate 16-bytes aligned buffer to hold KEY_INFO in a portable way
+ keyInfoBuffer = TCalloc(keyInfoBufferSize);
+ if (!keyInfoBuffer)
+ return ERR_OUTOFMEMORY;
+ keyInfoBufferOffset = 16 - (((uint64) keyInfoBuffer) % 16);
+ keyInfo = (PKEY_INFO) (keyInfoBuffer + keyInfoBufferOffset);
+
+#if !defined(DEVICE_DRIVER) && !defined(_UEFI)
+ VirtualLock (keyInfoBuffer, keyInfoBufferSize);
+#endif
+
// if no PIM specified, use default value
if (pim < 0)
pim = 0;
@@ -218,45 +233,78 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int
/* use thread pool only if no PRF was specified */
if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1))
{
- keyDerivationWorkItems = TCalloc (sizeof (KeyDerivationWorkItem) * pkcs5PrfCount);
+ keyDerivationCompletedEvent = TCalloc (sizeof (TC_EVENT));
+ if (!keyDerivationCompletedEvent)
+ return ERR_OUTOFMEMORY;
+
+ noOutstandingWorkItemEvent = TCalloc (sizeof (TC_EVENT));
+ if (!noOutstandingWorkItemEvent)
+ {
+ TCfree(keyDerivationCompletedEvent);
+ return ERR_OUTOFMEMORY;
+ }
+
+ outstandingWorkItemCount = TCalloc (sizeof (LONG));
+ if (!outstandingWorkItemCount)
+ {
+ TCfree(keyDerivationCompletedEvent);
+ TCfree(noOutstandingWorkItemEvent);
+ return ERR_OUTOFMEMORY;
+ }
+
+ keyDerivationWorkItemsSize = sizeof (KeyDerivationWorkItem) * pkcs5PrfCount;
+ keyDerivationWorkItems = TCalloc (keyDerivationWorkItemsSize);
if (!keyDerivationWorkItems)
+ {
+ TCfree(keyDerivationCompletedEvent);
+ TCfree(noOutstandingWorkItemEvent);
+ TCfree(outstandingWorkItemCount);
return ERR_OUTOFMEMORY;
+ }
for (i = 0; i < pkcs5PrfCount; ++i)
keyDerivationWorkItems[i].Free = TRUE;
+ *outstandingWorkItemCount = 0;
#ifdef DEVICE_DRIVER
- KeInitializeEvent (&keyDerivationCompletedEvent, SynchronizationEvent, FALSE);
- KeInitializeEvent (&noOutstandingWorkItemEvent, SynchronizationEvent, TRUE);
+ KeInitializeEvent (keyDerivationCompletedEvent, SynchronizationEvent, FALSE);
+ KeInitializeEvent (noOutstandingWorkItemEvent, SynchronizationEvent, TRUE);
#else
- keyDerivationCompletedEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
- if (!keyDerivationCompletedEvent)
+ *keyDerivationCompletedEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+ if (!*keyDerivationCompletedEvent)
{
TCfree (keyDerivationWorkItems);
+ TCfree(keyDerivationCompletedEvent);
+ TCfree(noOutstandingWorkItemEvent);
+ TCfree(outstandingWorkItemCount);
return ERR_OUTOFMEMORY;
}
- noOutstandingWorkItemEvent = CreateEvent (NULL, FALSE, TRUE, NULL);
- if (!noOutstandingWorkItemEvent)
+ *noOutstandingWorkItemEvent = CreateEvent (NULL, FALSE, TRUE, NULL);
+ if (!*noOutstandingWorkItemEvent)
{
CloseHandle (keyDerivationCompletedEvent);
TCfree (keyDerivationWorkItems);
+ TCfree(keyDerivationCompletedEvent);
+ TCfree(noOutstandingWorkItemEvent);
+ TCfree(outstandingWorkItemCount);
return ERR_OUTOFMEMORY;
}
+
+ VirtualLock (keyDerivationWorkItems, keyDerivationWorkItemsSize);
#endif
}
#if !defined(DEVICE_DRIVER)
- VirtualLock (&keyInfo, sizeof (keyInfo));
VirtualLock (&dk, sizeof (dk));
VirtualLock (&header, sizeof (header));
#endif
#endif // !defined(_UEFI)
- crypto_loadkey (&keyInfo, password->Text, (int) password->Length);
+ crypto_loadkey (keyInfo, password->Text, (int) password->Length);
// PKCS5 is used to derive the primary header key(s) and secondary header key(s) (XTS mode) from the password
- memcpy (keyInfo.salt, encryptedHeader + HEADER_SALT_OFFSET, PKCS5_SALT_SIZE);
+ memcpy (keyInfo->salt, encryptedHeader + HEADER_SALT_OFFSET, PKCS5_SALT_SIZE);
// Test all available PKCS5 PRFs
for (enqPkcs5Prf = FIRST_PRF_ID; enqPkcs5Prf <= LAST_PRF_ID || queuedWorkItems > 0; ++enqPkcs5Prf)
@@ -283,9 +331,9 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int
item->KeyReady = FALSE;
item->Pkcs5Prf = enqPkcs5Prf;
- EncryptionThreadPoolBeginKeyDerivation (&keyDerivationCompletedEvent, &noOutstandingWorkItemEvent,
- &item->KeyReady, &outstandingWorkItemCount, enqPkcs5Prf, keyInfo.userKey,
- keyInfo.keyLength, keyInfo.salt, get_pkcs5_iteration_count (enqPkcs5Prf, pim, truecryptMode, bBoot), item->DerivedKey);
+ EncryptionThreadPoolBeginKeyDerivation (keyDerivationCompletedEvent, noOutstandingWorkItemEvent,
+ &item->KeyReady, outstandingWorkItemCount, enqPkcs5Prf, keyInfo->userKey,
+ keyInfo->keyLength, keyInfo->salt, get_pkcs5_iteration_count (enqPkcs5Prf, pim, truecryptMode, bBoot), item->DerivedKey);
++queuedWorkItems;
break;
@@ -307,7 +355,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int
if (!item->Free && InterlockedExchangeAdd (&item->KeyReady, 0) == TRUE)
{
pkcs5_prf = item->Pkcs5Prf;
- keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, truecryptMode, bBoot);
+ keyInfo->noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, truecryptMode, bBoot);
memcpy (dk, item->DerivedKey, sizeof (dk));
item->Free = TRUE;
@@ -317,7 +365,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int
}
if (queuedWorkItems > 0)
- TC_WAIT_EVENT (keyDerivationCompletedEvent);
+ TC_WAIT_EVENT (*keyDerivationCompletedEvent);
}
continue;
KeyReady: ;
@@ -326,33 +374,33 @@ KeyReady: ;
#endif // !defined(_UEFI)
{
pkcs5_prf = enqPkcs5Prf;
- keyInfo.noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, pim, truecryptMode, bBoot);
+ keyInfo->noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, pim, truecryptMode, bBoot);
switch (pkcs5_prf)
{
case RIPEMD160:
- derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
- PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
+ derive_key_ripemd160 (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
+ PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize());
break;
case SHA512:
- derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
- PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
+ derive_key_sha512 (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
+ PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize());
break;
case WHIRLPOOL:
- derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
- PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
+ derive_key_whirlpool (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
+ PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize());
break;
case SHA256:
- derive_key_sha256 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
- PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
+ derive_key_sha256 (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
+ PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize());
break;
case STREEBOG:
- derive_key_streebog(keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
- PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
+ derive_key_streebog(keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
+ PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize());
break;
default:
// Unknown/wrong ID
@@ -509,7 +557,7 @@ KeyReady: ;
if (retInfo == NULL)
{
cryptoInfo->pkcs5 = pkcs5_prf;
- cryptoInfo->noIterations = keyInfo.noIterations;
+ cryptoInfo->noIterations = keyInfo->noIterations;
cryptoInfo->bTrueCryptMode = truecryptMode;
cryptoInfo->volumePim = pim;
goto ret;
@@ -526,34 +574,34 @@ KeyReady: ;
}
// Master key data
- memcpy (keyInfo.master_keydata, header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE);
+ memcpy (keyInfo->master_keydata, header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE);
#ifdef TC_WINDOWS_DRIVER
{
RMD160_CTX ctx;
RMD160Init (&ctx);
- RMD160Update (&ctx, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
+ RMD160Update (&ctx, keyInfo->master_keydata, MASTER_KEYDATA_SIZE);
RMD160Update (&ctx, header, sizeof(header));
RMD160Final (cryptoInfo->master_keydata_hash, &ctx);
burn(&ctx, sizeof (ctx));
}
#else
- memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
+ memcpy (cryptoInfo->master_keydata, keyInfo->master_keydata, MASTER_KEYDATA_SIZE);
#endif
// PKCS #5
cryptoInfo->pkcs5 = pkcs5_prf;
- cryptoInfo->noIterations = keyInfo.noIterations;
+ cryptoInfo->noIterations = keyInfo->noIterations;
cryptoInfo->bTrueCryptMode = truecryptMode;
cryptoInfo->volumePim = pim;
// Init the cipher with the decrypted master key
- status = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
+ status = EAInit (cryptoInfo->ea, keyInfo->master_keydata + primaryKeyOffset, cryptoInfo->ks);
if (status == ERR_CIPHER_INIT_FAILURE)
goto err;
#ifndef TC_WINDOWS_DRIVER
// The secondary master key (if cascade, multiple concatenated)
- memcpy (cryptoInfo->k2, keyInfo.master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
+ memcpy (cryptoInfo->k2, keyInfo->master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
#endif
- if (!EAInitMode (cryptoInfo, keyInfo.master_keydata + EAGetKeySize (cryptoInfo->ea)))
+ if (!EAInitMode (cryptoInfo, keyInfo->master_keydata + EAGetKeySize (cryptoInfo->ea)))
{
status = ERR_MODE_INIT_FAILED;
goto err;
@@ -573,13 +621,11 @@ err:
*retInfo = NULL;
}
-ret:
- burn (&keyInfo, sizeof (keyInfo));
+ret:
burn (dk, sizeof(dk));
burn (header, sizeof(header));
#if !defined(DEVICE_DRIVER) && !defined(_UEFI)
- VirtualUnlock (&keyInfo, sizeof (keyInfo));
VirtualUnlock (&dk, sizeof (dk));
VirtualUnlock (&header, sizeof (header));
#endif
@@ -587,20 +633,19 @@ ret:
#if !defined(_UEFI)
if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1))
{
- TC_WAIT_EVENT (noOutstandingWorkItemEvent);
-
- if (keyDerivationWorkItems)
- {
- burn (keyDerivationWorkItems, sizeof (KeyDerivationWorkItem) * pkcs5PrfCount);
- TCfree (keyDerivationWorkItems);
- }
-
-#if !defined(DEVICE_DRIVER)
- CloseHandle (keyDerivationCompletedEvent);
- CloseHandle (noOutstandingWorkItemEvent);
-#endif
+ EncryptionThreadPoolBeginReadVolumeHeaderFinalization (keyDerivationCompletedEvent, noOutstandingWorkItemEvent, outstandingWorkItemCount,
+ keyInfoBuffer, keyInfoBufferSize,
+ keyDerivationWorkItems, keyDerivationWorkItemsSize);
}
+ else
#endif
+ {
+ burn (keyInfo, sizeof (KEY_INFO));
+#if !defined(DEVICE_DRIVER) && !defined(_UEFI)
+ VirtualUnlock (keyInfoBuffer, keyInfoBufferSize);
+#endif
+ TCfree(keyInfoBuffer);
+ }
return status;
}
diff --git a/src/Common/Xml.c b/src/Common/Xml.c
index 37b73498..9f77b3ba 100644
--- a/src/Common/Xml.c
+++ b/src/Common/Xml.c
@@ -12,6 +12,7 @@
#if !defined(_UEFI)
#include <windows.h>
#include <stdio.h>
+#include <strsafe.h>
#else
#include "Tcdefs.h"
#pragma warning( disable : 4706 ) // assignment within conditional expression
@@ -185,26 +186,30 @@ char *XmlQuoteText (const char *textSrc, char *textDst, int textDstMaxSize)
case '&':
if (textDst + 6 > textDstLast)
return NULL;
- strcpy (textDst, "&amp;");
+ StringCchCopyA (textDst, textDstMaxSize, "&amp;");
textDst += 5;
+ textDstMaxSize -= 5;
continue;
case '>':
if (textDst + 5 > textDstLast)
return NULL;
- strcpy (textDst, "&gt;");
+ StringCchCopyA (textDst, textDstMaxSize, "&gt;");
textDst += 4;
+ textDstMaxSize -= 4;
continue;
case '<':
if (textDst + 5 > textDstLast)
return NULL;
- strcpy (textDst, "&lt;");
+ StringCchCopyA (textDst, textDstMaxSize, "&lt;");
textDst += 4;
+ textDstMaxSize -= 4;
continue;
default:
*textDst++ = c;
+ textDstMaxSize--;
}
}
@@ -230,26 +235,30 @@ wchar_t *XmlQuoteTextW (const wchar_t *textSrc, wchar_t *textDst, int textDstMax
case L'&':
if (textDst + 6 > textDstLast)
return NULL;
- wcscpy (textDst, L"&amp;");
+ StringCchCopyW (textDst, textDstMaxSize, L"&amp;");
textDst += 5;
+ textDstMaxSize -= 5;
continue;
case L'>':
if (textDst + 5 > textDstLast)
return NULL;
- wcscpy (textDst, L"&gt;");
+ StringCchCopyW (textDst, textDstMaxSize, L"&gt;");
textDst += 4;
+ textDstMaxSize -= 4;
continue;
case L'<':
if (textDst + 5 > textDstLast)
return NULL;
- wcscpy (textDst, L"&lt;");
+ StringCchCopyW (textDst, textDstMaxSize, L"&lt;");
textDst += 4;
+ textDstMaxSize -= 4;
continue;
default:
*textDst++ = c;
+ textDstMaxSize--;
}
}