VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common')
-rw-r--r--src/Common/Apidrvr.h3
-rw-r--r--src/Common/BootEncryption.cpp41
-rw-r--r--src/Common/Common.rc4
-rw-r--r--src/Common/Crypto.h2
-rw-r--r--src/Common/Dlgcode.c124
-rw-r--r--src/Common/Language.c44
-rw-r--r--src/Common/Language.xml19
-rw-r--r--src/Common/Lzma_vs2019.vcxproj22
-rw-r--r--src/Common/Password.c4
-rw-r--r--src/Common/Tcdefs.h26
-rw-r--r--src/Common/Volumes.c8
-rw-r--r--src/Common/Zip_vs2019.vcxproj21
12 files changed, 261 insertions, 57 deletions
diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h
index 4074503d..04d69c05 100644
--- a/src/Common/Apidrvr.h
+++ b/src/Common/Apidrvr.h
@@ -177,6 +177,7 @@ typedef struct
ULONG MaximumTransferLength;
ULONG MaximumPhysicalPages;
ULONG AlignmentMask;
+ BOOL VolumeMasterKeyVulnerable;
} MOUNT_STRUCT;
typedef struct
@@ -316,6 +317,8 @@ typedef struct
// is read-only (or mounted an outer/normal TrueCrypt volume as read only)
uint32 HiddenSysLeakProtectionCount;
+ BOOL MasterKeyVulnerable;
+
} BootEncryptionStatus;
diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp
index 2080a44b..f79e7339 100644
--- a/src/Common/BootEncryption.cpp
+++ b/src/Common/BootEncryption.cpp
@@ -1462,6 +1462,7 @@ namespace VeraCrypt
/* IMPORTANT: Do NOT add any potentially time-consuming operations to this function. */
BootEncryptionStatus status;
+ memset (&status, 0, sizeof(status));
CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS, NULL, 0, &status, sizeof (status));
return status;
}
@@ -2635,14 +2636,24 @@ namespace VeraCrypt
bool EfiBoot::IsEfiBoot() {
DWORD BootOrderLen;
BootOrderLen = GetFirmwareEnvironmentVariable(L"BootOrder", EfiVarGuid, tempBuf, sizeof(tempBuf));
- return BootOrderLen != 0;
+ return (BootOrderLen != 0) || (GetLastError() != ERROR_INVALID_FUNCTION);
}
void EfiBoot::DeleteStartExec(uint16 statrtOrderNum, wchar_t* type) {
- SetPrivilege(SE_SYSTEM_ENVIRONMENT_NAME, TRUE);
+ DWORD dwLastError;
+ BOOL bPrivilegesSet = IsPrivilegeEnabled (SE_SYSTEM_ENVIRONMENT_NAME);
+ if (!bPrivilegesSet && !SetPrivilege(SE_SYSTEM_ENVIRONMENT_NAME, TRUE))
+ {
+ dwLastError = GetLastError();
+ wchar_t szMsg[128];
+ StringCchPrintfW(szMsg, ARRAYSIZE(szMsg), L"Failed to set SE_SYSTEM_ENVIRONMENT_NAME privilege (error code 0x%.8X)", dwLastError);
+ throw ErrorException(szMsg, SRC_POS);
+ }
// Check EFI
if (!IsEfiBoot()) {
- throw ErrorException(L"can not detect EFI environment", SRC_POS);
+ if (!bPrivilegesSet)
+ SetPrivilege(SE_SYSTEM_ENVIRONMENT_NAME, FALSE);
+ throw ErrorException(L"Failed to detect EFI environment (error ERROR_INVALID_FUNCTION)", SRC_POS);
}
wchar_t varName[256];
StringCchPrintfW(varName, ARRAYSIZE (varName), L"%s%04X", type == NULL ? L"Boot" : type, statrtOrderNum);
@@ -2685,13 +2696,26 @@ namespace VeraCrypt
SetFirmwareEnvironmentVariable(next.c_str(), EfiVarGuid, startOrder, 0);
}
}
+
+ if (!bPrivilegesSet)
+ SetPrivilege(SE_SYSTEM_ENVIRONMENT_NAME, FALSE);
}
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);
+ DWORD dwLastError;
+ BOOL bPrivilegesSet = IsPrivilegeEnabled (SE_SYSTEM_ENVIRONMENT_NAME);
+ if (!bPrivilegesSet && !SetPrivilege(SE_SYSTEM_ENVIRONMENT_NAME, TRUE))
+ {
+ dwLastError = GetLastError();
+ wchar_t szMsg[128];
+ StringCchPrintfW(szMsg, ARRAYSIZE(szMsg), L"Failed to set SE_SYSTEM_ENVIRONMENT_NAME privilege (error code 0x%.8X)", dwLastError);
+ throw ErrorException(szMsg, SRC_POS);
+ }
// Check EFI
if (!IsEfiBoot()) {
- throw ErrorException(L"can not detect EFI environment", SRC_POS);
+ if (!bPrivilegesSet)
+ SetPrivilege(SE_SYSTEM_ENVIRONMENT_NAME, FALSE);
+ throw ErrorException(L"Failed to detect EFI environment (error ERROR_INVALID_FUNCTION)", SRC_POS);
}
if (bDeviceInfoValid)
@@ -2865,6 +2889,9 @@ namespace VeraCrypt
SetFirmwareEnvironmentVariable(next.c_str(), EfiVarGuid, &statrtOrderNum, 2);
}
+
+ if (!bPrivilegesSet)
+ SetPrivilege(SE_SYSTEM_ENVIRONMENT_NAME, FALSE);
}
bool EfiBoot::CompareFiles (const wchar_t* fileName1, const wchar_t* fileName2)
@@ -5401,6 +5428,10 @@ namespace VeraCrypt
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 the XTS master key is vulnerable, return error and do not allow the user to change the password since the master key will not be changed
+ if ((status == 0) && cryptoInfo->bVulnerableMasterKey)
+ status = ERR_SYSENC_XTS_MASTERKEY_VULNERABLE;
+
if (status != 0)
{
handleError (hwndDlg, status, SRC_POS);
diff --git a/src/Common/Common.rc b/src/Common/Common.rc
index cbd401d8..41778dfc 100644
--- a/src/Common/Common.rc
+++ b/src/Common/Common.rc
@@ -344,9 +344,9 @@ IDD_TEXT_EDIT_DLG DIALOGEX 0, 0, 372, 220
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
- PUSHBUTTON "OK",IDOK,306,201,58,14
+ PUSHBUTTON "OK",IDOK,244,201,58,14
CONTROL "",IDC_INFO_BOX_TEXT,"RichEdit20W",ES_MULTILINE | ES_WANTRETURN | ES_NUMBER | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,5,6,361,188
- DEFPUSHBUTTON "Cancel",IDCANCEL,240,201,58,14
+ DEFPUSHBUTTON "Cancel",IDCANCEL,308,201,58,14
END
diff --git a/src/Common/Crypto.h b/src/Common/Crypto.h
index 178e08e1..89d22f0e 100644
--- a/src/Common/Crypto.h
+++ b/src/Common/Crypto.h
@@ -277,6 +277,8 @@ typedef struct CRYPTO_INFO_t
uint32 SectorSize;
+ BOOL bVulnerableMasterKey; // TRUE if XTS primary key is identical to secondary key (i.e. the volume is vulnerable to attack on XTS mode)
+
#endif // !TC_WINDOWS_BOOT
UINT64_STRUCT VolumeSize;
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index 4ee08bb7..b91167d4 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -4165,6 +4165,7 @@ BOOL CALLBACK TextEditDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
case WM_INITDIALOG:
{
prm = (TEXT_INFO_DIALOG_PARAM_PTR)lParam;
+ LocalizeDialog (hwndDlg, NULL);
// increase size limit of rich edit control
SendMessage(GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), EM_EXLIMITTEXT, 0, -1);
@@ -4175,9 +4176,43 @@ BOOL CALLBACK TextEditDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
if (prm->ReadOnly)
{
// switch rich edit control to ReadOnly
- SendMessage(GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), ES_READONLY, TRUE, 0);
+ SendMessage(GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), EM_SETREADONLY , TRUE, 0);
// hide cancel button
- ShowWindow(GetDlgItem(hwndDlg, IDCANCEL), SW_HIDE);
+ HWND hwndCancel = GetDlgItem(hwndDlg, IDCANCEL);
+ ShowWindow(hwndCancel, SW_HIDE);
+
+ // Reposition OK button to Cancel button's position
+ HWND hwndOK = GetDlgItem(hwndDlg, IDOK);
+ if (hwndOK && hwndCancel)
+ {
+ // Get Cancel button's position in screen coordinates
+ RECT rectCancel;
+ if (GetWindowRect(hwndCancel, &rectCancel))
+ {
+ // Convert Cancel button's position to dialog's client coordinates
+ POINT ptCancel = { rectCancel.left, rectCancel.top };
+ ScreenToClient(hwndDlg, &ptCancel);
+
+ // Get OK button's current size
+ RECT rectOK;
+ if (GetWindowRect(hwndOK, &rectOK))
+ {
+ int width = rectOK.right - rectOK.left;
+ int height = rectOK.bottom - rectOK.top;
+
+ // Move OK button to Cancel button's position
+ SetWindowPos(
+ hwndOK,
+ NULL,
+ ptCancel.x,
+ ptCancel.y,
+ width,
+ height,
+ SWP_NOZORDER | SWP_NOACTIVATE
+ );
+ }
+ }
+ }
}
SendMessage (hwndDlg, TC_APPMSG_LOAD_TEXT_BOX_CONTENT, 0, 0);
@@ -4189,8 +4224,12 @@ BOOL CALLBACK TextEditDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
{
if (!prm->ReadOnly)
{
- prm->Text.resize(GetWindowTextLengthA (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT)) + 1);
- GetWindowTextA (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), &(prm->Text)[0], (int) prm->Text.size());
+ // read content of the text box as UTF16 and then convert it to UTF8
+ HWND hEdit = GetDlgItem(hwndDlg, IDC_INFO_BOX_TEXT);
+ int size = GetWindowTextLengthW(hEdit);
+ std::vector<WCHAR> buffer(size + 1);
+ GetWindowTextW(hEdit, buffer.data(), size + 1);
+ prm->Text = WideToUtf8String(buffer.data());
}
NormalCursor ();
EndDialog (hwndDlg, IDOK);
@@ -4207,7 +4246,8 @@ BOOL CALLBACK TextEditDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
case TC_APPMSG_LOAD_TEXT_BOX_CONTENT:
{
- SetWindowTextA (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), prm->Text.c_str());
+ // convert prm->Text to UTF16 using Utf8StringToWide
+ SetWindowTextW(GetDlgItem(hwndDlg, IDC_INFO_BOX_TEXT), Utf8StringToWide(prm->Text).c_str());
}
return 0;
@@ -5577,6 +5617,14 @@ void handleError (HWND hwndDlg, int code, const char* srcPos)
break;
#endif
+ case ERR_XTS_MASTERKEY_VULNERABLE:
+ MessageBoxW (hwndDlg, AppendSrcPos (GetString ("ERR_XTS_MASTERKEY_VULNERABLE"), srcPos).c_str(), lpszTitle, ICON_HAND);
+ break;
+
+ case ERR_SYSENC_XTS_MASTERKEY_VULNERABLE:
+ MessageBoxW (hwndDlg, AppendSrcPos (GetString ("ERR_SYSENC_XTS_MASTERKEY_VULNERABLE"), srcPos).c_str(), lpszTitle, ICON_HAND);
+ break;
+
default:
StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("ERR_UNKNOWN"), code);
MessageBoxW (hwndDlg, AppendSrcPos (szTmp, srcPos).c_str(), lpszTitle, ICON_HAND);
@@ -8953,6 +9001,12 @@ retry:
LastMountedVolumeDirty = mount.FilesystemDirty;
+ if (mount.VolumeMasterKeyVulnerable
+ && !Silent)
+ {
+ Warning ("ERR_XTS_MASTERKEY_VULNERABLE", hwndDlg);
+ }
+
if (mount.FilesystemDirty)
{
wchar_t msg[1024];
@@ -13692,11 +13746,11 @@ BOOL SetPrivilege(LPTSTR szPrivilegeName, BOOL bEnable)
&tkp.Privileges[0].Luid))
{
tkp.PrivilegeCount = 1;
- tkp.Privileges[0].Attributes = bEnable? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED;
+ tkp.Privileges[0].Attributes = bEnable? SE_PRIVILEGE_ENABLED : 0;
bRet = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, NULL);
dwLastError = GetLastError ();
- if ( ERROR_SUCCESS != dwLastError)
+ if (bRet && (ERROR_NOT_ALL_ASSIGNED == dwLastError))
{
bRet = FALSE;
}
@@ -13907,20 +13961,33 @@ static unsigned int __stdcall SecureDesktopThread( LPVOID lpThreadParameter )
StringCbCopy(SecureDesktopName, sizeof (SecureDesktopName), pParam->szDesktopName);
pParam->hDesk = hSecureDesk;
- // wait for SwitchDesktop to succeed before using it for current thread
- while (true)
+ bNewDesktopSet = SetThreadDesktop (hSecureDesk);
+
+ if (bNewDesktopSet)
{
- if (SwitchDesktop (hSecureDesk))
+ // call ImmDisableIME from imm32.dll to disable IME since it can create issue with secure desktop
+ // cf: https://keepass.info/help/kb/sec_desk.html#ime
+ HMODULE hImmDll = LoadLibraryEx (L"imm32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ if (hImmDll)
{
- break;
+ typedef BOOL (WINAPI *ImmDisableIME_t)(DWORD);
+ ImmDisableIME_t ImmDisableIME = (ImmDisableIME_t) GetProcAddress (hImmDll, "ImmDisableIME");
+ if (ImmDisableIME)
+ {
+ ImmDisableIME (0);
+ }
}
- Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
- }
- bNewDesktopSet = SetThreadDesktop (hSecureDesk);
+ // wait for SwitchDesktop to succeed before using it for current thread
+ while (true)
+ {
+ if (SwitchDesktop (hSecureDesk))
+ {
+ break;
+ }
+ Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
+ }
- if (bNewDesktopSet)
- {
// create the thread that will ensure that VeraCrypt secure desktop has always user input
// this is done only if the stop event is created successfully
HANDLE hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
@@ -13950,6 +14017,12 @@ static unsigned int __stdcall SecureDesktopThread( LPVOID lpThreadParameter )
}
pParam->bDlgDisplayed = TRUE;
+
+ // free imm32.dll handle
+ if (hImmDll)
+ {
+ FreeLibrary (hImmDll);
+ }
}
else
{
@@ -14070,19 +14143,20 @@ INT_PTR SecureDesktopDialogBoxParam(
// dialog box was indeed displayed in Secure Desktop
retValue = param.retValue;
bSuccess = TRUE;
+
+ // switch back to the original desktop
+ while (!SwitchDesktop (hOriginalDesk))
+ {
+ Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
+ }
+
+ SetThreadDesktop (hOriginalDesk);
}
- }
- if (param.hDesk)
- {
- while (!SwitchDesktop (hOriginalDesk))
+ if (param.hDesk)
{
- Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
+ CloseDesktop (param.hDesk);
}
-
- SetThreadDesktop (hOriginalDesk);
-
- CloseDesktop (param.hDesk);
}
// get the new list of ctfmon.exe processes in order to find the ID of the
diff --git a/src/Common/Language.c b/src/Common/Language.c
index 278b7dd1..a6bc9891 100644
--- a/src/Common/Language.c
+++ b/src/Common/Language.c
@@ -83,6 +83,31 @@ static char *MapFirstLanguageFile ()
return LanguageFileBuffer;
}
+static int IsValidLanguageFileName(const wchar_t* filename) {
+ size_t len = wcslen(filename);
+
+ // Check the base format and length directly
+ if (_wcsnicmp(filename, L"Language.", 9) != 0 || (len != 15 && len != 18))
+ return 0; // Does not start with "Language." or has incorrect length
+
+ // Check for the ".xml" suffix
+ if (_wcsicmp(filename + len - 4, L".xml") != 0)
+ return 0; // Does not end with ".xml"
+
+ // Detailed checks based on the specific length
+ if (len == 15) {
+ // Format should be Language.xx.xml
+ if (iswalpha(filename[9]) && iswalpha(filename[10]))
+ return 1; // Valid format for short code
+ } else if (len == 18) {
+ // Format should be Language.xx-yy.xml
+ if (iswalpha(filename[9]) && iswalpha(filename[10]) && filename[11] == L'-' &&
+ iswalpha(filename[12]) && iswalpha(filename[13]))
+ return 1; // Valid format for long code
+ }
+
+ return 0; // If none of the conditions are met, the filename is invalid
+}
static char *MapNextLanguageFile (int resourceid)
{
@@ -91,6 +116,7 @@ static char *MapNextLanguageFile (int resourceid)
HANDLE file;
DWORD read;
BOOL bStatus;
+ BOOL validFileFound = FALSE;
/* free memory here to avoid leaks */
if (LanguageFileBuffer != NULL)
@@ -122,6 +148,24 @@ static char *MapNextLanguageFile (int resourceid)
if (LanguageFileFindHandle == INVALID_HANDLE_VALUE) return NULL;
if (find.nFileSizeHigh != 0) return NULL;
+ // Validate the file name format
+ while (!validFileFound)
+ {
+ if (!IsValidLanguageFileName(find.cFileName))
+ {
+ if (!FindNextFileW(LanguageFileFindHandle, &find))
+ {
+ FindClose(LanguageFileFindHandle);
+ LanguageFileFindHandle = INVALID_HANDLE_VALUE;
+ return NULL;
+ }
+ }
+ else
+ {
+ validFileFound = TRUE;
+ }
+ }
+
LanguageFileBuffer = malloc(find.nFileSizeLow + 1);
if (LanguageFileBuffer == NULL) return NULL;
diff --git a/src/Common/Language.xml b/src/Common/Language.xml
index e3e96a1f..9821bbe9 100644
--- a/src/Common/Language.xml
+++ b/src/Common/Language.xml
@@ -632,12 +632,12 @@
<entry lang="en" key="PASSWORD_HIDDEN_OS_TITLE">Password for Hidden Operating System</entry>
<entry lang="en" key="PASSWORD_LENGTH_WARNING">WARNING: Short passwords are easy to crack using brute force techniques!\n\nWe recommend choosing a password consisting of 20 or more characters. Are you sure you want to use a short password?</entry>
<entry lang="en" key="PASSWORD_TITLE">Volume Password</entry>
- <entry lang="en" key="PASSWORD_WRONG">Operation failed due to one or more of the following:\n - Incorrect password.\n - Incorrect Volume PIM number.\n - Incorrect PRF (hash).\n - Not a valid volume.</entry>
- <entry lang="en" key="PASSWORD_OR_KEYFILE_WRONG">Operation failed due to one or more of the following:\n - Incorrect keyfile(s).\n - Incorrect password.\n - Incorrect Volume PIM number.\n - Incorrect PRF (hash).\n - Not a valid volume.</entry>
- <entry lang="en" key="PASSWORD_OR_MODE_WRONG">Operation failed due to one or more of the following:\n - Wrong mount mode.\n - Incorrect password.\n - Incorrect Volume PIM number.\n - Incorrect PRF (hash).\n - Not a valid volume.</entry>
- <entry lang="en" key="PASSWORD_OR_KEYFILE_OR_MODE_WRONG">Operation failed due to one or more of the following:\n - Wrong mount mode.\n - Incorrect keyfile(s).\n - Incorrect password.\n - Incorrect Volume PIM number.\n - Incorrect PRF (hash).\n - Not a valid volume.</entry>
- <entry lang="en" key="PASSWORD_WRONG_AUTOMOUNT">Auto-mount failed due to one or more of the following:\n - Incorrect password.\n - Incorrect Volume PIM number.\n - Incorrect PRF (hash).\n - No valid volume found.</entry>
- <entry lang="en" key="PASSWORD_OR_KEYFILE_WRONG_AUTOMOUNT">Auto-mount failed due to one or more of the following:\n - Incorrect keyfile(s).\n - Incorrect password.\n - Incorrect Volume PIM number.\n - Incorrect PRF (hash).\n - No valid volume found.</entry>
+ <entry lang="en" key="PASSWORD_WRONG">Operation failed due to one or more of the following:\n - Incorrect password.\n - Incorrect Volume PIM number.\n - Incorrect PRF (hash).\n - Not a valid volume.\n - Volume uses an old algorithm that has been removed.\n - TrueCrypt format volumes are no longer supported.</entry>
+ <entry lang="en" key="PASSWORD_OR_KEYFILE_WRONG">Operation failed due to one or more of the following:\n - Incorrect keyfile(s).\n - Incorrect password.\n - Incorrect Volume PIM number.\n - Incorrect PRF (hash).\n - Not a valid volume.\n - Volume uses an old algorithm that has been removed.\n - TrueCrypt format volumes are no longer supported.</entry>
+ <entry lang="en" key="PASSWORD_OR_MODE_WRONG">Operation failed due to one or more of the following:\n - Wrong mount mode.\n - Incorrect password.\n - Incorrect Volume PIM number.\n - Incorrect PRF (hash).\n - Not a valid volume.\n - Volume uses an old algorithm that has been removed.\n - TrueCrypt format volumes are no longer supported.</entry>
+ <entry lang="en" key="PASSWORD_OR_KEYFILE_OR_MODE_WRONG">Operation failed due to one or more of the following:\n - Wrong mount mode.\n - Incorrect keyfile(s).\n - Incorrect password.\n - Incorrect Volume PIM number.\n - Incorrect PRF (hash).\n - Not a valid volume.\n - Volume uses an old algorithm that has been removed.\n - TrueCrypt format volumes are no longer supported.</entry>
+ <entry lang="en" key="PASSWORD_WRONG_AUTOMOUNT">Auto-mount failed due to one or more of the following:\n - Incorrect password.\n - Incorrect Volume PIM number.\n - Incorrect PRF (hash).\n - No valid volume found.\n - Volume uses an old algorithm that has been removed.\n - TrueCrypt format volumes are no longer supported.</entry>
+ <entry lang="en" key="PASSWORD_OR_KEYFILE_WRONG_AUTOMOUNT">Auto-mount failed due to one or more of the following:\n - Incorrect keyfile(s).\n - Incorrect password.\n - Incorrect Volume PIM number.\n - Incorrect PRF (hash).\n - No valid volume found.\n - Volume uses an old algorithm that has been removed.\n - TrueCrypt format volumes are no longer supported.</entry>
<entry lang="en" key="PASSWORD_WRONG_CAPSLOCK_ON">\n\nWarning: Caps Lock is on. This may cause you to enter your password incorrectly.</entry>
<entry lang="en" key="PIM_CHANGE_WARNING">Remember Number to Mount Volume</entry>
<entry lang="en" key="PIM_HIDVOL_HOST_TITLE">Outer Volume PIM</entry>
@@ -1617,10 +1617,10 @@
<entry lang="en" key="EMV_SELECT_AID_FAILED">The AID of the card in the reader could not be selected.</entry>
<entry lang="en" key="EMV_ICC_CERT_NOTFOUND">ICC Public Key Certificate was not found in the card.</entry>
<entry lang="en" key="EMV_ISSUER_CERT_NOTFOUND">Issuer Public Key Certificate was not found in the card.</entry>
- <entry lang="en" key="EMV_CPLC_NOTFOUND">CLPC was not found in the EMV card.</entry>
+ <entry lang="en" key="EMV_CPLC_NOTFOUND">CPLC was not found in the EMV card.</entry>
<entry lang="en" key="EMV_PAN_NOTFOUND">No Primary Account Number (PAN) found in the EMV card.</entry>
<entry lang="en" key="INVALID_EMV_PATH">EMV path is invalid.</entry>
- <entry lang="en" key="EMV_KEYFILE_DATA_NOTFOUND">Unable to build a keyfile from the EMV card's data.\n\nOne of the following is missing:\n- ICC Public Key Certificate.\n- Issuer Public Key Certificate.\n- CPCL data.</entry>
+ <entry lang="en" key="EMV_KEYFILE_DATA_NOTFOUND">Unable to build a keyfile from the EMV card's data.\n\nOne of the following is missing:\n- ICC Public Key Certificate.\n- Issuer Public Key Certificate.\n- CPLC data.</entry>
<entry lang="en" key="SCARD_W_REMOVED_CARD">No card in the reader.\n\nPlease make sure the card is correctly slotted.</entry>
<entry lang="en" key="FORMAT_EXTERNAL_FAILED">Windows format.com command failed to format the volume as NTFS/exFAT/ReFS: Error 0x%.8X.\n\nFalling back to using Windows FormatEx API.</entry>
<entry lang="en" key="FORMATEX_API_FAILED">Windows FormatEx API failed to format the volume as NTFS/exFAT/ReFS.\n\nFailure status = %s.</entry>
@@ -1638,6 +1638,9 @@
<entry lang="en" key="LINUX_LANGUAGE">Language</entry>
<entry lang="en" key="LINUX_SELECT_SYS_DEFAULT_LANG">Select system's default language</entry>
<entry lang="en" key="LINUX_RESTART_FOR_LANGUAGE_CHANGE">For the language change to come into effect, VeraCrypt needs to be restarted.</entry>
+ <entry lang="en" key="ERR_XTS_MASTERKEY_VULNERABLE">WARNING: The volume's master key is vulnerable to an attack that compromises data security.\n\nPlease create a new volume and transfer the data to it.</entry>
+ <entry lang="en" key="ERR_SYSENC_XTS_MASTERKEY_VULNERABLE">WARNING: The encrypted system's master key is vulnerable to an attack that compromises data security.\nPlease decrypt the system partition/drive and then re-encrypt it.</entry>
+ <entry lang="en" key="ERR_XTS_MASTERKEY_VULNERABLE_SHORT">WARNING: The volume's master key has a security vulnerability.</entry>
</localization>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="VeraCrypt">
diff --git a/src/Common/Lzma_vs2019.vcxproj b/src/Common/Lzma_vs2019.vcxproj
index 81a57daa..9f640dc5 100644
--- a/src/Common/Lzma_vs2019.vcxproj
+++ b/src/Common/Lzma_vs2019.vcxproj
@@ -61,6 +61,7 @@
<Keyword>Win32Proj</Keyword>
<RootNamespace>Lzma</RootNamespace>
<ProjectName>Lzma</ProjectName>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@@ -128,22 +129,28 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <OutDir>$(Configuration)\</OutDir>
+ <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <OutDir>$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
- <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <OutDir>$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <OutDir>$(Configuration)\</OutDir>
+ <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <OutDir>$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
- <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <OutDir>$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@@ -197,6 +204,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <ControlFlowGuard>Guard</ControlFlowGuard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -215,6 +223,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <ControlFlowGuard>Guard</ControlFlowGuard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -233,6 +242,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <ControlFlowGuard>Guard</ControlFlowGuard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
diff --git a/src/Common/Password.c b/src/Common/Password.c
index ae6b8035..c0247207 100644
--- a/src/Common/Password.c
+++ b/src/Common/Password.c
@@ -371,6 +371,10 @@ int ChangePwd (const wchar_t *lpszVolume, Password *oldPassword, int old_pkcs5,
if (nStatus == ERR_CIPHER_INIT_WEAK_KEY)
nStatus = 0; // We can ignore this error here
+ // if the XTS master key is vulnerable, return error and do not allow the user to change the password since the master key will not be changed
+ if ((nStatus == 0) && cryptoInfo->bVulnerableMasterKey)
+ nStatus = ERR_XTS_MASTERKEY_VULNERABLE;
+
if (nStatus == ERR_PASSWORD_WRONG)
{
continue; // Try next volume type
diff --git a/src/Common/Tcdefs.h b/src/Common/Tcdefs.h
index 6f903e07..3fd18358 100644
--- a/src/Common/Tcdefs.h
+++ b/src/Common/Tcdefs.h
@@ -59,7 +59,7 @@ extern unsigned short _rotl16(unsigned short value, unsigned char shift);
#define TC_APP_NAME "VeraCrypt"
// Version displayed to user
-#define VERSION_STRING "1.26.12"
+#define VERSION_STRING "1.26.15"
#ifdef VC_EFI_CUSTOM_MODE
#define VERSION_STRING_SUFFIX "-CustomEFI"
@@ -73,9 +73,9 @@ extern unsigned short _rotl16(unsigned short value, unsigned char shift);
#define VERSION_NUM 0x0126
// Release date
-#define TC_STR_RELEASE_DATE L"July 12, 2024"
+#define TC_STR_RELEASE_DATE L"September 2, 2024"
#define TC_RELEASE_DATE_YEAR 2024
-#define TC_RELEASE_DATE_MONTH 7
+#define TC_RELEASE_DATE_MONTH 9
#define BYTES_PER_KB 1024LL
#define BYTES_PER_MB 1048576LL
@@ -108,6 +108,12 @@ typedef unsigned __int64 uint64;
#define LL(x) x##ui64
#endif
+#if _MSC_VER > 1900
+#define VC_CDECL __cdecl // this is needed because Windows driver on VS2019 uses stdcall for build
+#else
+#define VC_CDECL
+#endif
+
#pragma warning( disable : 4201 ) // disable: 4201 nonstandard extension used : nameless struct/union
#pragma warning( disable : 4324 ) // disable: 4324 structure was padded due to __declspec(align())
@@ -151,6 +157,8 @@ typedef uint64 TC_LARGEST_COMPILER_UINT;
#define TRUE 1
#endif
+#define VC_CDECL
+
#endif // !_MSC_VER
#define TC_INT_TYPES_DEFINED
@@ -349,7 +357,13 @@ extern BOOLEAN VC_KeAreAllApcsDisabled (VOID);
#ifdef _M_ARM64
# define _WIN32_WINNT 0x0A00
#else
-# define _WIN32_WINNT 0x0601 /* Does not apply to the driver */
+// for Visual Studio 2015 and later, set minimum Windows version to Windows 8
+// for old versions of Visual Studio, set minimum Windows version to Windows 7
+#if _MSC_VER >= 1900
+# define _WIN32_WINNT 0x0602
+#else
+# define _WIN32_WINNT 0x0601
+#endif
#endif
#endif
@@ -494,7 +508,9 @@ enum
ERR_NONSYS_INPLACE_ENC_INCOMPLETE = 32,
ERR_USER_ABORT = 33,
ERR_RAND_INIT_FAILED = 34,
- ERR_CAPI_INIT_FAILED = 35
+ ERR_CAPI_INIT_FAILED = 35,
+ ERR_XTS_MASTERKEY_VULNERABLE = 36,
+ ERR_SYSENC_XTS_MASTERKEY_VULNERABLE = 37
};
#endif // #ifndef TCDEFS_H
diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c
index df1cd1e3..7ee519f6 100644
--- a/src/Common/Volumes.c
+++ b/src/Common/Volumes.c
@@ -597,6 +597,14 @@ KeyReady: ;
goto err;
}
+ // check that first half of keyInfo.master_keydata is different from the second half. If they are the same return error
+ if (memcmp (keyInfo->master_keydata, keyInfo->master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea)) == 0)
+ {
+ cryptoInfo->bVulnerableMasterKey = TRUE;
+ if (retHeaderCryptoInfo)
+ retHeaderCryptoInfo->bVulnerableMasterKey = TRUE;
+ }
+
status = ERR_SUCCESS;
goto ret;
}
diff --git a/src/Common/Zip_vs2019.vcxproj b/src/Common/Zip_vs2019.vcxproj
index 26ab3310..b68dcab8 100644
--- a/src/Common/Zip_vs2019.vcxproj
+++ b/src/Common/Zip_vs2019.vcxproj
@@ -252,22 +252,28 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <OutDir>$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <OutDir>$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <OutDir>$(Configuration)\</OutDir>
+ <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
- <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <OutDir>$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <OutDir>$(Configuration)\</OutDir>
+ <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
- <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <OutDir>$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@@ -337,6 +343,7 @@
<PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_LIB;WIN32;HAVE_CONFIG_H;ZIP_STATIC;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>zlib;libzip</AdditionalIncludeDirectories>
+ <ControlFlowGuard>Guard</ControlFlowGuard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -360,6 +367,7 @@
<PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_LIB;WIN32;HAVE_CONFIG_H;ZIP_STATIC;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>zlib;libzip</AdditionalIncludeDirectories>
+ <ControlFlowGuard>Guard</ControlFlowGuard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -383,6 +391,7 @@
<PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_LIB;WIN32;HAVE_CONFIG_H;ZIP_STATIC;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>zlib;libzip</AdditionalIncludeDirectories>
+ <ControlFlowGuard>Guard</ControlFlowGuard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>