From ed1263bf8c6c678420eb1b9ad3f37d3a6d33af7c Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Fri, 2 Aug 2024 00:20:53 +0200 Subject: Implement detection of volumes with vulnerable XTS master key. If vulnerability detected, a warning message is displayed during mount or backup/restore header, and changing the password is disallowed since it will not change the master key. --- src/Main/Forms/ChangePasswordDialog.cpp | 5 +++++ src/Main/GraphicUserInterface.cpp | 22 ++++++++++++++++++++++ src/Main/TextUserInterface.cpp | 27 +++++++++++++++++++++++++++ src/Main/UserInterface.cpp | 17 +++++++++++++++++ 4 files changed, 71 insertions(+) (limited to 'src/Main') diff --git a/src/Main/Forms/ChangePasswordDialog.cpp b/src/Main/Forms/ChangePasswordDialog.cpp index 397ee693..39da8e60 100644 --- a/src/Main/Forms/ChangePasswordDialog.cpp +++ b/src/Main/Forms/ChangePasswordDialog.cpp @@ -171,6 +171,7 @@ namespace VeraCrypt RandomNumberGenerator::SetEnrichedByUserStatus (false); Gui->UserEnrichRandomPool (this, NewPasswordPanel->GetPkcs5Kdf() ? NewPasswordPanel->GetPkcs5Kdf()->GetHash() : shared_ptr ()); + bool masterKeyVulnerable = false; { #ifdef TC_UNIX // Temporarily take ownership of a device if the user is not an administrator @@ -193,6 +194,7 @@ namespace VeraCrypt CurrentPasswordPanel->GetPassword(), CurrentPasswordPanel->GetVolumePim(), CurrentPasswordPanel->GetPkcs5Kdf(), CurrentPasswordPanel->GetKeyfiles(), newPassword, newPim, newKeyfiles, NewPasswordPanel->GetPkcs5Kdf(), NewPasswordPanel->GetHeaderWipeCount(), Gui->GetPreferences().EMVSupportEnabled); Gui->ExecuteWaitThreadRoutine (this, &routine); + masterKeyVulnerable = routine.m_masterKeyVulnerable; } switch (DialogMode) @@ -214,6 +216,9 @@ namespace VeraCrypt throw ParameterIncorrect (SRC_POS); } + if (masterKeyVulnerable) + Gui->ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); + EndModal (wxID_OK); } catch (UnportablePassword &e) diff --git a/src/Main/GraphicUserInterface.cpp b/src/Main/GraphicUserInterface.cpp index 9169a548..41bfa100 100644 --- a/src/Main/GraphicUserInterface.cpp +++ b/src/Main/GraphicUserInterface.cpp @@ -191,6 +191,7 @@ namespace VeraCrypt hiddenVolumeMountOptions.Path = volumePath; VolumeType::Enum volumeType = VolumeType::Normal; + bool masterKeyVulnerable = false; // Open both types of volumes while (true) @@ -273,6 +274,13 @@ namespace VeraCrypt } } + // check if volume master key is vulnerable + if (volume->IsMasterKeyVulnerable()) + { + masterKeyVulnerable = true; + ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); + } + if (volumeType == VolumeType::Hidden) hiddenVolume = volume; else @@ -366,6 +374,10 @@ namespace VeraCrypt } ShowWarning ("VOL_HEADER_BACKED_UP"); + + // display again warning that master key is vulnerable + if (masterKeyVulnerable) + ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); } void GraphicUserInterface::BeginInteractiveBusyState (wxWindow *window) @@ -1440,6 +1452,7 @@ namespace VeraCrypt /* force the display of the random enriching interface */ RandomNumberGenerator::SetEnrichedByUserStatus (false); + bool masterKeyVulnerable = false; if (restoreInternalBackup) { // Restore header from the internal backup @@ -1492,6 +1505,8 @@ namespace VeraCrypt return; } + masterKeyVulnerable = volume->IsMasterKeyVulnerable(); + RandomNumberGenerator::Start(); UserEnrichRandomPool (nullptr); @@ -1590,6 +1605,7 @@ namespace VeraCrypt if (decryptRoutine.m_bResult) { + masterKeyVulnerable = layout->GetHeader()->IsMasterKeyVulnerable(); decryptedLayout = layout; break; } @@ -1645,6 +1661,12 @@ namespace VeraCrypt } ShowInfo ("VOL_HEADER_RESTORED"); + + // display warning if the volume master key is vulnerable + if (masterKeyVulnerable) + { + ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); + } } DevicePath GraphicUserInterface::SelectDevice (wxWindow *parent) const diff --git a/src/Main/TextUserInterface.cpp b/src/Main/TextUserInterface.cpp index 8494a45c..bc3f6f5a 100644 --- a/src/Main/TextUserInterface.cpp +++ b/src/Main/TextUserInterface.cpp @@ -314,6 +314,7 @@ namespace VeraCrypt hiddenVolumeMountOptions.EMVSupportEnabled = true; VolumeType::Enum volumeType = VolumeType::Normal; + bool masterKeyVulnerable = false; // Open both types of volumes while (true) @@ -387,6 +388,13 @@ namespace VeraCrypt } } + // check if volume master key is vulnerable + if (volume->IsMasterKeyVulnerable()) + { + masterKeyVulnerable = true; + ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); + } + if (volumeType == VolumeType::Hidden) hiddenVolume = volume; else @@ -454,6 +462,10 @@ namespace VeraCrypt ShowString (L"\n"); ShowInfo ("VOL_HEADER_BACKED_UP"); + + // display again warning that master key is vulnerable + if (masterKeyVulnerable) + ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); } void TextUserInterface::ChangePassword (shared_ptr volumePath, shared_ptr password, int pim, shared_ptr currentHash, shared_ptr keyfiles, shared_ptr newPassword, int newPim, shared_ptr newKeyfiles, shared_ptr newHash) const @@ -532,6 +544,12 @@ namespace VeraCrypt break; } + // display warning if volume master key is vulnerable + if (volume->IsMasterKeyVulnerable()) + { + ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); + } + // New password if (!newPassword.get() && !Preferences.NonInteractive) newPassword = AskPassword (_("Enter new password"), true); @@ -1539,6 +1557,7 @@ namespace VeraCrypt /* force the display of the random enriching interface */ RandomNumberGenerator::SetEnrichedByUserStatus (false); + bool masterKeyVulnerable = false; if (restoreInternalBackup) { // Restore header from the internal backup @@ -1586,6 +1605,8 @@ namespace VeraCrypt throw_err (LangString ["VOLUME_HAS_NO_BACKUP_HEADER"]); } + masterKeyVulnerable = volume->IsMasterKeyVulnerable(); + RandomNumberGenerator::Start(); UserEnrichRandomPool(); @@ -1673,6 +1694,7 @@ namespace VeraCrypt if (layout->GetHeader()->Decrypt (headerBuffer, *passwordKey, options.Pim, kdf, layout->GetSupportedKeyDerivationFunctions(), layout->GetSupportedEncryptionAlgorithms(), layout->GetSupportedEncryptionModes())) { decryptedLayout = layout; + masterKeyVulnerable = layout->GetHeader()->IsMasterKeyVulnerable(); break; } } @@ -1723,6 +1745,11 @@ namespace VeraCrypt ShowString (L"\n"); ShowInfo ("VOL_HEADER_RESTORED"); + // display warning if the volume master key is vulnerable + if (masterKeyVulnerable) + { + ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); + } } void TextUserInterface::SetTerminalEcho (bool enable) diff --git a/src/Main/UserInterface.cpp b/src/Main/UserInterface.cpp index 0f11ec0b..ad2f22b8 100644 --- a/src/Main/UserInterface.cpp +++ b/src/Main/UserInterface.cpp @@ -652,6 +652,7 @@ namespace VeraCrypt bool protectedVolumeMounted = false; bool legacyVolumeMounted = false; + bool vulnerableVolumeMounted = false; foreach_ref (const HostDevice &device, devices) { @@ -694,6 +695,10 @@ namespace VeraCrypt if (newMountedVolumes.back()->EncryptionAlgorithmMinBlockSize == 8) legacyVolumeMounted = true; + + if (newMountedVolumes.back()->MasterKeyVulnerable) + vulnerableVolumeMounted = true; + } catch (DriverError&) { } catch (MissingVolumeData&) { } @@ -708,6 +713,9 @@ namespace VeraCrypt } else { + if (vulnerableVolumeMounted) + ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); + if (someVolumesShared) ShowWarning ("DEVICE_IN_USE_INFO"); @@ -741,10 +749,12 @@ namespace VeraCrypt favorite.ToMountOptions (options); + bool mountPerformed = false; if (Preferences.NonInteractive) { BusyScope busy (this); newMountedVolumes.push_back (Core->MountVolume (options)); + mountPerformed = true; } else { @@ -752,6 +762,7 @@ namespace VeraCrypt { BusyScope busy (this); newMountedVolumes.push_back (Core->MountVolume (options)); + mountPerformed = true; } catch (...) { @@ -769,6 +780,9 @@ namespace VeraCrypt newMountedVolumes.push_back (volume); } } + + if (mountPerformed && newMountedVolumes.back()->MasterKeyVulnerable) + ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); } if (!newMountedVolumes.empty() && GetPreferences().CloseSecurityTokenSessionsAfterMount) @@ -805,6 +819,9 @@ namespace VeraCrypt } } + if (volume->MasterKeyVulnerable) + ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE"); + if (volume->EncryptionAlgorithmMinBlockSize == 8) ShowWarning ("WARN_64_BIT_BLOCK_CIPHER"); -- cgit v1.2.3