Linux/macOS: Implement missing Argon2 KDF support on Unix

This commit is contained in:
Mounir IDRASSI
2026-04-18 00:20:32 +09:00
parent e07bd19f20
commit e59eb421fb
81 changed files with 848 additions and 226 deletions

View File

@@ -18,9 +18,30 @@
#include "CommandLineInterface.h"
#include "LanguageStrings.h"
#include "UserInterfaceException.h"
#include "Volume/Pkcs5Kdf.h"
namespace VeraCrypt
{
static shared_ptr <Pkcs5Kdf> FindKdfAlgorithm (const wxString &name)
{
foreach (shared_ptr <Pkcs5Kdf> kdf, Pkcs5Kdf::GetAvailableAlgorithms())
{
wxString kdfName (kdf->GetName());
shared_ptr <Hash> hash = kdf->GetHash();
wxString hashName (hash->GetName());
wxString hashAltName (hash->GetAltName());
if (kdfName.IsSameAs (name, false)
|| (kdf->IsArgon2() && name.IsSameAs (L"Argon2id", false)))
return kdf;
if (!kdf->IsArgon2()
&& (hashName.IsSameAs (name, false) || hashAltName.IsSameAs (name, false)))
return kdf;
}
return shared_ptr <Pkcs5Kdf> ();
}
CommandLineInterface::CommandLineInterface (int argc, wchar_t** argv, UserInterfaceType::Enum interfaceType) :
ArgCommand (CommandId::None),
ArgFilesystem (VolumeCreationOptions::FilesystemType::Unknown),
@@ -67,7 +88,7 @@ namespace VeraCrypt
#if !defined(TC_WINDOWS) && !defined(TC_MACOSX)
parser.AddOption (L"", L"fs-options", _("Filesystem mount options"));
#endif
parser.AddOption (L"", L"hash", _("Hash algorithm"));
parser.AddOption (L"", L"hash", _("Header key derivation algorithm"));
parser.AddSwitch (L"h", L"help", _("Display detailed command line help"), wxCMD_LINE_OPTION_HELP);
parser.AddSwitch (L"", L"import-token-keyfiles", _("Import keyfiles to security token"));
parser.AddOption (L"k", L"keyfiles", _("Keyfiles"));
@@ -78,7 +99,7 @@ namespace VeraCrypt
parser.AddSwitch (L"", L"load-preferences", _("Load user preferences"));
parser.AddSwitch (L"", L"mount", _("Mount volume interactively"));
parser.AddOption (L"m", L"mount-options", _("VeraCrypt volume mount options"));
parser.AddOption (L"", L"new-hash", _("New hash algorithm"));
parser.AddOption (L"", L"new-hash", _("New header key derivation algorithm"));
parser.AddOption (L"", L"new-keyfiles", _("New keyfiles"));
parser.AddOption (L"", L"new-password", _("New password"));
parser.AddOption (L"", L"new-pim", _("New PIM"));
@@ -87,7 +108,7 @@ namespace VeraCrypt
parser.AddOption (L"p", L"password", _("Password"));
parser.AddOption (L"", L"pim", _("PIM"));
parser.AddOption (L"", L"protect-hidden", _("Protect hidden volume"));
parser.AddOption (L"", L"protection-hash", _("Hash algorithm for protected hidden volume"));
parser.AddOption (L"", L"protection-hash", _("Header key derivation algorithm for protected hidden volume"));
parser.AddOption (L"", L"protection-keyfiles", _("Keyfiles for protected hidden volume"));
parser.AddOption (L"", L"protection-password", _("Password for protected hidden volume"));
parser.AddOption (L"", L"protection-pim", _("PIM for protected hidden volume"));
@@ -396,15 +417,7 @@ namespace VeraCrypt
if (parser.Found (L"hash", &str))
{
ArgHash.reset();
foreach (shared_ptr <Hash> hash, Hash::GetAvailableAlgorithms())
{
wxString hashName (hash->GetName());
wxString hashAltName (hash->GetAltName());
if (hashName.IsSameAs (str, false) || hashAltName.IsSameAs (str, false))
ArgHash = hash;
}
ArgHash = FindKdfAlgorithm (str);
if (!ArgHash)
throw_err (LangString["UNKNOWN_OPTION"] + L": " + str);
@@ -412,15 +425,7 @@ namespace VeraCrypt
if (parser.Found (L"new-hash", &str))
{
ArgNewHash.reset();
foreach (shared_ptr <Hash> hash, Hash::GetAvailableAlgorithms())
{
wxString hashName (hash->GetName());
wxString hashAltName (hash->GetAltName());
if (hashName.IsSameAs (str, false) || hashAltName.IsSameAs (str, false))
ArgNewHash = hash;
}
ArgNewHash = FindKdfAlgorithm (str);
if (!ArgNewHash)
throw_err (LangString["UNKNOWN_OPTION"] + L": " + str);
@@ -558,19 +563,11 @@ namespace VeraCrypt
if (parser.Found (L"protection-hash", &str))
{
bool bHashFound = false;
foreach (shared_ptr <Hash> hash, Hash::GetAvailableAlgorithms())
{
wxString hashName (hash->GetName());
wxString hashAltName (hash->GetAltName());
if (hashName.IsSameAs (str, false) || hashAltName.IsSameAs (str, false))
{
bHashFound = true;
ArgMountOptions.ProtectionKdf = Pkcs5Kdf::GetAlgorithm (*hash);
}
}
shared_ptr <Pkcs5Kdf> kdf = FindKdfAlgorithm (str);
if (kdf)
ArgMountOptions.ProtectionKdf = kdf;
if (!bHashFound)
if (!kdf)
throw_err (LangString["UNKNOWN_OPTION"] + L": " + str);
}

View File

@@ -20,6 +20,7 @@
#include "Core/VolumeCreator.h"
#include "UserPreferences.h"
#include "UserInterfaceType.h"
#include "Volume/Pkcs5Kdf.h"
namespace VeraCrypt
{
@@ -66,11 +67,11 @@ namespace VeraCrypt
shared_ptr <FilePath> ArgFilePath;
VolumeCreationOptions::FilesystemType::Enum ArgFilesystem;
bool ArgForce;
shared_ptr <Hash> ArgHash;
shared_ptr <Pkcs5Kdf> ArgHash;
shared_ptr <KeyfileList> ArgKeyfiles;
MountOptions ArgMountOptions;
shared_ptr <DirectoryPath> ArgMountPoint;
shared_ptr <Hash> ArgNewHash;
shared_ptr <Pkcs5Kdf> ArgNewHash;
shared_ptr <KeyfileList> ArgNewKeyfiles;
shared_ptr <VolumePassword> ArgNewPassword;
int ArgNewPim;

View File

@@ -299,7 +299,9 @@ namespace VeraCrypt
for (int i = 1; i <= 2; i++)
{
prf->DeriveKey (dk, password, pim, salt);
int derivationResult = prf->DeriveKey (dk, password, pim, salt);
if (derivationResult != 0)
throw ExternalException (SRC_POS, prf->GetDerivationFailureMessage (derivationResult));
}
time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue());

View File

@@ -18,6 +18,65 @@
namespace VeraCrypt
{
static bool CheckCustomPimForPassword (VolumePasswordPanel *pimPanel, const shared_ptr <VolumePassword> &password, int pim, const shared_ptr <Pkcs5Kdf> &kdf)
{
int defaultPim = kdf ? kdf->GetDefaultPim() : 0;
if (!password || password->Size() == 0 || pim <= 0 || defaultPim <= 0 || pim >= defaultPim)
return true;
if (password->Size() < VolumePassword::SmallPimPasswordSizeThreshold)
{
Gui->ShowError (kdf ? kdf->GetPimRequireLongPasswordMessageId() : "PIM_REQUIRE_LONG_PASSWORD");
pimPanel->SetFocusToPimTextCtrl();
return false;
}
if (!Gui->AskYesNo (LangString [kdf ? kdf->GetPimSmallWarningMessageId() : "PIM_SMALL_WARNING"], false, true))
{
pimPanel->SetFocusToPimTextCtrl();
return false;
}
return true;
}
static bool CheckCustomPimForKdfOnlyChange (VolumePasswordPanel *pimPanel, const shared_ptr <VolumePassword> &password, const shared_ptr <Pkcs5Kdf> &kdf, int currentPim)
{
int defaultPim = kdf ? kdf->GetDefaultPim() : 0;
if (!kdf || !password || password->Size() == 0 || currentPim <= 0 || defaultPim <= 0 || currentPim == defaultPim)
return true;
if (currentPim < defaultPim)
return CheckCustomPimForPassword (pimPanel, password, currentPim, kdf);
Gui->ShowWarning (kdf->GetPimLargeWarningMessageId());
return true;
}
static bool CheckPasswordChangeWarnings (VolumePasswordPanel *passwordPanel, const shared_ptr <VolumePassword> &password, int pim, const shared_ptr <Pkcs5Kdf> &kdf)
{
if (!password || password->Size() == 0)
return true;
if (password->Size() < VolumePassword::WarningSizeThreshold)
{
if (!CheckCustomPimForPassword (passwordPanel, password, pim, kdf))
return false;
if (!Gui->AskYesNo (LangString ["PASSWORD_LENGTH_WARNING"], false, true))
{
passwordPanel->SetFocusToPasswordTextCtrl();
return false;
}
}
else if (!CheckCustomPimForPassword (passwordPanel, password, pim, kdf))
{
return false;
}
return true;
}
#ifdef TC_MACOSX
bool ChangePasswordDialog::ProcessEvent(wxEvent& event)
@@ -102,11 +161,17 @@ namespace VeraCrypt
{
shared_ptr <Pkcs5Kdf> currentKdf = CurrentPasswordPanel->GetPkcs5Kdf();
int currentPim = CurrentPasswordPanel->GetVolumePim();
shared_ptr <Pkcs5Kdf> newKdf = NewPasswordPanel->GetPkcs5Kdf();
if (-1 == currentPim)
{
CurrentPasswordPanel->SetFocusToPimTextCtrl();
return;
}
shared_ptr <VolumePassword> currentPassword = CurrentPasswordPanel->GetPassword();
shared_ptr <KeyfileList> currentKeyfiles = CurrentPasswordPanel->GetKeyfiles();
bool preserveTimestamps = Gui->GetPreferences().DefaultMountOptions.PreserveTimestamps;
bool emvSupportEnabled = Gui->GetPreferences().EMVSupportEnabled;
int headerWipeCount = NewPasswordPanel->GetHeaderWipeCount();
shared_ptr <VolumePassword> newPassword;
int newPim = 0;
@@ -128,50 +193,47 @@ namespace VeraCrypt
NewPasswordPanel->SetFocusToPimTextCtrl();
return;
}
if (newPassword->Size() > 0)
{
if (newPassword->Size() < VolumePassword::WarningSizeThreshold)
{
if (newPim > 0 && newPim < 485)
{
Gui->ShowError ("PIM_REQUIRE_LONG_PASSWORD");
return;
}
if (!Gui->AskYesNo (LangString ["PASSWORD_LENGTH_WARNING"], false, true))
{
NewPasswordPanel->SetFocusToPasswordTextCtrl();
return;
}
}
else if (newPim > 0 && newPim < 485)
{
if (!Gui->AskYesNo (LangString ["PIM_SMALL_WARNING"], false, true))
{
NewPasswordPanel->SetFocusToPimTextCtrl();
return;
}
}
}
}
else
{
newPassword = CurrentPasswordPanel->GetPassword();
newPassword = currentPassword;
newPim = CurrentPasswordPanel->GetVolumePim();
}
if (DialogMode == Mode::ChangePkcs5Prf)
{
if (!CheckCustomPimForKdfOnlyChange (CurrentPasswordPanel, newPassword, newKdf, currentPim))
return;
}
shared_ptr <KeyfileList> newKeyfiles;
if (DialogMode == Mode::ChangePasswordAndKeyfiles || DialogMode == Mode::ChangeKeyfiles)
newKeyfiles = NewPasswordPanel->GetKeyfiles();
else if (DialogMode != Mode::RemoveAllKeyfiles)
newKeyfiles = CurrentPasswordPanel->GetKeyfiles();
/* force the display of the random enriching interface */
RandomNumberGenerator::SetEnrichedByUserStatus (false);
Gui->UserEnrichRandomPool (this, NewPasswordPanel->GetPkcs5Kdf() ? NewPasswordPanel->GetPkcs5Kdf()->GetHash() : shared_ptr <Hash>());
newKeyfiles = currentKeyfiles;
shared_ptr <Pkcs5Kdf> effectiveNewKdf = newKdf ? newKdf : currentKdf;
shared_ptr <Volume> openVolume;
bool masterKeyVulnerable = false;
// If the unchanged KDF is not known yet, open the header before applying KDF-specific PIM limits.
bool needOpenVolumeForKdf = DialogMode == Mode::ChangePasswordAndKeyfiles
&& !effectiveNewKdf
&& newPassword->Size() > 0
&& newPim > 0;
if (!needOpenVolumeForKdf)
{
if (DialogMode == Mode::ChangePasswordAndKeyfiles
&& !CheckPasswordChangeWarnings (NewPasswordPanel, newPassword, newPim, effectiveNewKdf))
{
return;
}
/* force the display of the random enriching interface */
RandomNumberGenerator::SetEnrichedByUserStatus (false);
Gui->UserEnrichRandomPool (this, newKdf ? newKdf->GetHash() : shared_ptr <Hash>());
}
{
#ifdef TC_UNIX
// Temporarily take ownership of a device if the user is not an administrator
@@ -189,12 +251,47 @@ namespace VeraCrypt
Core->SetFileOwner (finally_arg, finally_arg2);
});
#endif
wxBusyCursor busy;
ChangePasswordThreadRoutine routine(Path, Gui->GetPreferences().DefaultMountOptions.PreserveTimestamps,
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;
if (needOpenVolumeForKdf)
{
wxBusyCursor busy;
OpenVolumeThreadRoutine openRoutine(Path, preserveTimestamps, currentPassword, currentPim, currentKdf, currentKeyfiles, emvSupportEnabled);
Gui->ExecuteWaitThreadRoutine (this, &openRoutine);
openVolume = openRoutine.m_pVolume;
if (openVolume)
effectiveNewKdf = openVolume->GetPkcs5Kdf();
if (!effectiveNewKdf)
throw ParameterIncorrect (SRC_POS);
}
if (needOpenVolumeForKdf)
{
if (!CheckPasswordChangeWarnings (NewPasswordPanel, newPassword, newPim, effectiveNewKdf))
{
// The volume was opened only to detect its KDF; no header rewrite has started.
return;
}
/* force the display of the random enriching interface */
RandomNumberGenerator::SetEnrichedByUserStatus (false);
Gui->UserEnrichRandomPool (this, newKdf ? newKdf->GetHash() : shared_ptr <Hash>());
}
if (openVolume)
{
wxBusyCursor busy;
ChangePasswordThreadRoutine routine(openVolume, newPassword, newPim, newKeyfiles, newKdf, headerWipeCount, emvSupportEnabled);
Gui->ExecuteWaitThreadRoutine (this, &routine);
masterKeyVulnerable = routine.m_masterKeyVulnerable;
}
else
{
wxBusyCursor busy;
ChangePasswordThreadRoutine routine(Path, preserveTimestamps,
currentPassword, currentPim, currentKdf, currentKeyfiles,
newPassword, newPim, newKeyfiles, newKdf, headerWipeCount, emvSupportEnabled);
Gui->ExecuteWaitThreadRoutine (this, &routine);
masterKeyVulnerable = routine.m_masterKeyVulnerable;
}
}
switch (DialogMode)

View File

@@ -12,7 +12,7 @@
#include "System.h"
#include "Volume/EncryptionTest.h"
#include "Volume/Hash.h"
#include "Volume/Pkcs5Kdf.h"
#include "Main/GraphicUserInterface.h"
#include "BenchmarkDialog.h"
#include "EncryptionOptionsWizardPage.h"
@@ -36,11 +36,11 @@ namespace VeraCrypt
EncryptionAlgorithmChoice->Select (0);
Hashes = Hash::GetAvailableAlgorithms();
foreach (shared_ptr <Hash> hash, Hashes)
Kdfs = Pkcs5Kdf::GetAvailableAlgorithms();
foreach (shared_ptr <Pkcs5Kdf> kdf, Kdfs)
{
if (!hash->IsDeprecated())
HashChoice->Append (hash->GetName(), hash.get());
if (!kdf->IsDeprecated())
HashChoice->Append (kdf->GetName(), kdf.get());
}
HashChoice->Select (0);
@@ -68,9 +68,9 @@ namespace VeraCrypt
return Gui->GetSelectedData <EncryptionAlgorithm> (EncryptionAlgorithmChoice)->GetNew();
}
shared_ptr <Hash> EncryptionOptionsWizardPage::GetHash () const
shared_ptr <Pkcs5Kdf> EncryptionOptionsWizardPage::GetPkcs5Kdf () const
{
return Gui->GetSelectedData <Hash> (HashChoice)->GetNew();
return shared_ptr <Pkcs5Kdf> (Gui->GetSelectedData <Pkcs5Kdf> (HashChoice)->Clone());
}
void EncryptionOptionsWizardPage::OnBenchmarkButtonClick (wxCommandEvent& event)
@@ -155,9 +155,9 @@ namespace VeraCrypt
}
}
void EncryptionOptionsWizardPage::SetHash (shared_ptr <Hash> hash)
void EncryptionOptionsWizardPage::SetPkcs5Kdf (shared_ptr <Pkcs5Kdf> kdf)
{
if (hash)
HashChoice->SetStringSelection (hash->GetName());
if (kdf)
HashChoice->SetStringSelection (kdf->GetName());
}
}

View File

@@ -14,6 +14,7 @@
#define TC_HEADER_Main_Forms_EncryptionOptionsWizardPage
#include "Forms.h"
#include "Volume/Pkcs5Kdf.h"
namespace VeraCrypt
{
@@ -26,11 +27,11 @@ namespace VeraCrypt
~EncryptionOptionsWizardPage ();
#endif
shared_ptr <EncryptionAlgorithm> GetEncryptionAlgorithm () const;
shared_ptr <Hash> GetHash () const;
shared_ptr <Pkcs5Kdf> GetPkcs5Kdf () const;
bool IsValid () { return true; }
void SetPageText (const wxString &text) { }
void SetEncryptionAlgorithm (shared_ptr <EncryptionAlgorithm> algorithm);
void SetHash (shared_ptr <Hash> hash);
void SetPkcs5Kdf (shared_ptr <Pkcs5Kdf> kdf);
protected:
void OnBenchmarkButtonClick (wxCommandEvent& event);
@@ -44,7 +45,7 @@ namespace VeraCrypt
void HandleOnSize( wxSizeEvent& event );
#endif
EncryptionAlgorithmList EncryptionAlgorithms;
HashList Hashes;
Pkcs5KdfList Kdfs;
};
}

View File

@@ -651,7 +651,7 @@ namespace VeraCrypt
MountOptions mountOptions (GetPreferences().DefaultMountOptions);
if (CmdLine->ArgHash)
{
mountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash);
mountOptions.Kdf = CmdLine->ArgHash;
}
if (CmdLine->ArgPim > 0)
{
@@ -676,7 +676,7 @@ namespace VeraCrypt
MountOptions mountOptions (GetPreferences().DefaultMountOptions);
if (CmdLine->ArgHash)
{
mountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash);
mountOptions.Kdf = CmdLine->ArgHash;
}
if (CmdLine->ArgPim > 0)
{
@@ -707,7 +707,7 @@ namespace VeraCrypt
mountOptions.Path = GetSelectedVolumePath();
if (CmdLine->ArgHash)
{
mountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash);
mountOptions.Kdf = CmdLine->ArgHash;
}
if (CmdLine->ArgPim > 0)
{
@@ -962,7 +962,7 @@ namespace VeraCrypt
MountOptions mountOptions (GetPreferences().DefaultMountOptions);
if (CmdLine->ArgHash)
{
mountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash);
mountOptions.Kdf = CmdLine->ArgHash;
}
if (CmdLine->ArgPim > 0)
{

View File

@@ -174,7 +174,7 @@ namespace VeraCrypt
page->SetPageTitle (LangString["CIPHER_TITLE"]);
page->SetEncryptionAlgorithm (SelectedEncryptionAlgorithm);
page->SetHash (SelectedHash);
page->SetPkcs5Kdf (SelectedKdf);
return page;
}
@@ -249,7 +249,7 @@ namespace VeraCrypt
else
page->SetPageTitle (LangString["PIM_TITLE"]);
page->SetPageText (LangString["PIM_HELP"]);
page->SetPageText (LangString[SelectedKdf ? SelectedKdf->GetPimHelpMessageId() : "PIM_HELP"]);
page->SetVolumePim (Pim);
return page;
}
@@ -708,10 +708,10 @@ namespace VeraCrypt
{
EncryptionOptionsWizardPage *page = dynamic_cast <EncryptionOptionsWizardPage *> (GetCurrentPage());
SelectedEncryptionAlgorithm = page->GetEncryptionAlgorithm ();
SelectedHash = page->GetHash ();
SelectedKdf = page->GetPkcs5Kdf ();
if (forward)
RandomNumberGenerator::SetHash (SelectedHash);
RandomNumberGenerator::SetHash (SelectedKdf->GetHash());
if (SelectedVolumePath.IsDevice() && (OuterVolume || SelectedVolumeType != VolumeType::Hidden))
return Step::VolumePassword;
@@ -870,17 +870,23 @@ namespace VeraCrypt
if (forward && Password && !Password->IsEmpty())
{
if (Password->Size() < VolumePassword::WarningSizeThreshold)
if (!SelectedKdf)
{
if (Pim > 0 && Pim < 485)
Gui->ShowError ("PARAMETER_INCORRECT");
return GetCurrentStep();
}
if (Password->Size() < VolumePassword::SmallPimPasswordSizeThreshold)
{
if (Pim > 0 && Pim < SelectedKdf->GetDefaultPim())
{
Gui->ShowError ("PIM_REQUIRE_LONG_PASSWORD");
Gui->ShowError (SelectedKdf->GetPimRequireLongPasswordMessageId());
return GetCurrentStep();
}
}
else if (Pim > 0 && Pim < 485)
else if (Pim > 0 && Pim < SelectedKdf->GetDefaultPim())
{
if (!Gui->AskYesNo (LangString["PIM_SMALL_WARNING"], false, true))
if (!Gui->AskYesNo (LangString[SelectedKdf->GetPimSmallWarningMessageId()], false, true))
{
return GetCurrentStep();
}
@@ -1031,7 +1037,7 @@ namespace VeraCrypt
options->Quick = QuickFormatEnabled;
options->Size = VolumeSize;
options->Type = OuterVolume ? VolumeType::Normal : SelectedVolumeType;
options->VolumeHeaderKdf = Pkcs5Kdf::GetAlgorithm (*SelectedHash);
options->VolumeHeaderKdf = SelectedKdf;
options->EMVSupportEnabled = Gui->GetPreferences().EMVSupportEnabled;

View File

@@ -87,7 +87,7 @@ namespace VeraCrypt
int OuterPim;
shared_ptr <Pkcs5Kdf> Kdf;
uint32 SectorSize;
shared_ptr <Hash> SelectedHash;
shared_ptr <Pkcs5Kdf> SelectedKdf;
uint64 VolumeSize;
private:

View File

@@ -34,7 +34,7 @@ namespace VeraCrypt
virtual void BackupVolumeHeaders (shared_ptr <VolumePath> volumePath) const;
virtual void BeginBusyState () const { wxBeginBusyCursor(); }
virtual void BeginInteractiveBusyState (wxWindow *window);
virtual void ChangePassword (shared_ptr <VolumePath> volumePath = shared_ptr <VolumePath>(), shared_ptr <VolumePassword> password = shared_ptr <VolumePassword>(), int pim = 0, shared_ptr <Hash> currentHash = shared_ptr <Hash>(), shared_ptr <KeyfileList> keyfiles = shared_ptr <KeyfileList>(), shared_ptr <VolumePassword> newPassword = shared_ptr <VolumePassword>(), int newPim = 0, shared_ptr <KeyfileList> newKeyfiles = shared_ptr <KeyfileList>(), shared_ptr <Hash> newHash = shared_ptr <Hash>()) const { ThrowTextModeRequired(); }
virtual void ChangePassword (shared_ptr <VolumePath> volumePath = shared_ptr <VolumePath>(), shared_ptr <VolumePassword> password = shared_ptr <VolumePassword>(), int pim = 0, shared_ptr <Pkcs5Kdf> currentKdf = shared_ptr <Pkcs5Kdf>(), shared_ptr <KeyfileList> keyfiles = shared_ptr <KeyfileList>(), shared_ptr <VolumePassword> newPassword = shared_ptr <VolumePassword>(), int newPim = 0, shared_ptr <KeyfileList> newKeyfiles = shared_ptr <KeyfileList>(), shared_ptr <Pkcs5Kdf> newKdf = shared_ptr <Pkcs5Kdf>()) const { ThrowTextModeRequired(); }
wxHyperlinkCtrl *CreateHyperlink (wxWindow *parent, const wxString &linkUrl, const wxString &linkText) const;
virtual void CreateKeyfile (shared_ptr <FilePath> keyfilePath = shared_ptr <FilePath>()) const;
virtual void CreateVolume (shared_ptr <VolumeCreationOptions> options) const { ThrowTextModeRequired(); }

View File

@@ -30,6 +30,30 @@
namespace VeraCrypt
{
static bool CheckCustomPimForPassword (const TextUserInterface *ui, const shared_ptr <VolumePassword> &password, int pim, const shared_ptr <Pkcs5Kdf> &kdf, bool interactive)
{
int defaultPim = kdf ? kdf->GetDefaultPim() : 0;
if (!password || password->Size() == 0 || pim <= 0 || defaultPim <= 0 || pim >= defaultPim)
return true;
if (password->Size() < VolumePassword::SmallPimPasswordSizeThreshold)
{
const char *messageId = kdf ? kdf->GetPimRequireLongPasswordMessageId() : "PIM_REQUIRE_LONG_PASSWORD";
if (interactive)
{
ui->ShowError (messageId);
return false;
}
throw_err (LangString [messageId]);
}
if (interactive && !ui->AskYesNo (LangString [kdf ? kdf->GetPimSmallWarningMessageId() : "PIM_SMALL_WARNING"], false, true))
return false;
return true;
}
class AdminPasswordTextRequestHandler : public GetStringFunctor
{
public:
@@ -295,11 +319,7 @@ namespace VeraCrypt
ShowInfo ("EXTERNAL_VOL_HEADER_BAK_FIRST_INFO");
shared_ptr <Pkcs5Kdf> kdf;
if (CmdLine->ArgHash)
{
kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash);
}
shared_ptr <Pkcs5Kdf> kdf = CmdLine->ArgHash;
shared_ptr <Volume> normalVolume;
shared_ptr <Volume> hiddenVolume;
@@ -468,7 +488,7 @@ namespace VeraCrypt
ShowWarning ("ERR_XTS_MASTERKEY_VULNERABLE");
}
void TextUserInterface::ChangePassword (shared_ptr <VolumePath> volumePath, shared_ptr <VolumePassword> password, int pim, shared_ptr <Hash> currentHash, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Hash> newHash) const
void TextUserInterface::ChangePassword (shared_ptr <VolumePath> volumePath, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> currentKdf, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> newKdf) const
{
shared_ptr <Volume> volume;
@@ -487,11 +507,7 @@ namespace VeraCrypt
bool passwordInteractive = !password.get();
bool keyfilesInteractive = !keyfiles.get();
shared_ptr<Pkcs5Kdf> kdf;
if (currentHash)
{
kdf = Pkcs5Kdf::GetAlgorithm (*currentHash);
}
shared_ptr <Pkcs5Kdf> kdf = currentKdf;
while (true)
{
@@ -555,8 +571,24 @@ namespace VeraCrypt
newPassword = AskPassword (_("Enter new password"), true);
// New PIM
if ((newPim < 0) && !Preferences.NonInteractive)
newPim = AskPim (_("Enter new PIM"));
shared_ptr <Pkcs5Kdf> effectiveNewKdf = newKdf ? newKdf : volume->GetPkcs5Kdf();
bool newPimInteractive = false;
while (true)
{
if ((newPim < 0) && !Preferences.NonInteractive)
{
newPim = AskPim (_("Enter new PIM"));
newPimInteractive = true;
}
if (CheckCustomPimForPassword (this, newPassword, newPim, effectiveNewKdf, !Preferences.NonInteractive))
break;
if (!newPimInteractive)
throw UserAbort (SRC_POS);
newPim = -1;
}
// New keyfiles
if (!newKeyfiles.get() && !Preferences.NonInteractive)
@@ -571,8 +603,7 @@ namespace VeraCrypt
RandomNumberGenerator::SetEnrichedByUserStatus (false);
UserEnrichRandomPool();
Core->ChangePassword (volume, newPassword, newPim, newKeyfiles, true,
newHash ? Pkcs5Kdf::GetAlgorithm (*newHash) : shared_ptr <Pkcs5Kdf>());
Core->ChangePassword (volume, newPassword, newPim, newKeyfiles, true, newKdf);
ShowInfo ("PASSWORD_CHANGED");
}
@@ -845,27 +876,26 @@ namespace VeraCrypt
options->EA = encryptionAlgorithms[AskSelection (encryptionAlgorithms.size(), 1) - 1];
}
// Hash algorithm
// Header key derivation function
if (!options->VolumeHeaderKdf)
{
if (Preferences.NonInteractive)
throw MissingArgument (SRC_POS);
ShowInfo (_("\nHash algorithm:"));
ShowInfo (_("\nKey derivation function:"));
vector < shared_ptr <Hash> > hashes;
foreach (shared_ptr <Hash> hash, Hash::GetAvailableAlgorithms())
vector < shared_ptr <Pkcs5Kdf> > kdfs;
foreach (shared_ptr <Pkcs5Kdf> kdf, Pkcs5Kdf::GetAvailableAlgorithms())
{
if (!hash->IsDeprecated())
if (!kdf->IsDeprecated())
{
ShowString (StringFormatter (L" {0}) {1}\n", (uint32) hashes.size() + 1, hash->GetName()));
hashes.push_back (hash);
ShowString (StringFormatter (L" {0}) {1}\n", (uint32) kdfs.size() + 1, kdf->GetName()));
kdfs.push_back (kdf);
}
}
shared_ptr <Hash> selectedHash = hashes[AskSelection (hashes.size(), 1) - 1];
RandomNumberGenerator::SetHash (selectedHash);
options->VolumeHeaderKdf = Pkcs5Kdf::GetAlgorithm (*selectedHash);
options->VolumeHeaderKdf = kdfs[AskSelection (kdfs.size(), 1) - 1];
RandomNumberGenerator::SetHash (options->VolumeHeaderKdf->GetHash());
}
@@ -939,10 +969,23 @@ namespace VeraCrypt
}
// PIM
if ((options->Pim < 0) && !Preferences.NonInteractive)
bool pimInteractive = false;
while (true)
{
ShowString (L"\n");
options->Pim = AskPim (_("Enter PIM"));
if ((options->Pim < 0) && !Preferences.NonInteractive)
{
ShowString (L"\n");
options->Pim = AskPim (_("Enter PIM"));
pimInteractive = true;
}
if (CheckCustomPimForPassword (this, options->Password, options->Pim, options->VolumeHeaderKdf, !Preferences.NonInteractive))
break;
if (!pimInteractive)
throw UserAbort (SRC_POS);
options->Pim = -1;
}
// Keyfiles
@@ -1546,11 +1589,7 @@ namespace VeraCrypt
// Ask whether to restore internal or external backup
bool restoreInternalBackup;
shared_ptr <Pkcs5Kdf> kdf;
if (CmdLine->ArgHash)
{
kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash);
}
shared_ptr <Pkcs5Kdf> kdf = CmdLine->ArgHash;
ShowInfo (LangString["HEADER_RESTORE_EXTERNAL_INTERNAL"]);
ShowInfo (L"\n1) " + LangString["HEADER_RESTORE_INTERNAL"]);
@@ -1799,7 +1838,7 @@ namespace VeraCrypt
return;
if (CmdLine->ArgHash)
RandomNumberGenerator::SetHash (CmdLine->ArgHash);
RandomNumberGenerator::SetHash (CmdLine->ArgHash->GetHash());
if (!CmdLine->ArgRandomSourcePath.IsEmpty())
{

View File

@@ -37,7 +37,7 @@ namespace VeraCrypt
virtual bool AskYesNo (const wxString &message, bool defaultYes = false, bool warning = false) const;
virtual void BackupVolumeHeaders (shared_ptr <VolumePath> volumePath) const;
virtual void BeginBusyState () const { }
virtual void ChangePassword (shared_ptr <VolumePath> volumePath = shared_ptr <VolumePath>(), shared_ptr <VolumePassword> password = shared_ptr <VolumePassword>(), int pim = 0, shared_ptr <Hash> currentHash = shared_ptr <Hash>(), shared_ptr <KeyfileList> keyfiles = shared_ptr <KeyfileList>(), shared_ptr <VolumePassword> newPassword = shared_ptr <VolumePassword>(), int newPim = 0, shared_ptr <KeyfileList> newKeyfiles = shared_ptr <KeyfileList>(), shared_ptr <Hash> newHash = shared_ptr <Hash>()) const;
virtual void ChangePassword (shared_ptr <VolumePath> volumePath = shared_ptr <VolumePath>(), shared_ptr <VolumePassword> password = shared_ptr <VolumePassword>(), int pim = 0, shared_ptr <Pkcs5Kdf> currentKdf = shared_ptr <Pkcs5Kdf>(), shared_ptr <KeyfileList> keyfiles = shared_ptr <KeyfileList>(), shared_ptr <VolumePassword> newPassword = shared_ptr <VolumePassword>(), int newPim = 0, shared_ptr <KeyfileList> newKeyfiles = shared_ptr <KeyfileList>(), shared_ptr <Pkcs5Kdf> newKdf = shared_ptr <Pkcs5Kdf>()) const;
virtual void CreateKeyfile (shared_ptr <FilePath> keyfilePath = shared_ptr <FilePath>()) const;
virtual void CreateVolume (shared_ptr <VolumeCreationOptions> options) const;
virtual void DeleteSecurityTokenKeyfiles () const;

View File

@@ -1010,7 +1010,7 @@ const FileManager fileManagers[] = {
cmdLine.ArgMountOptions.SharedAccessAllowed = cmdLine.ArgForce;
if (cmdLine.ArgHash)
{
cmdLine.ArgMountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*cmdLine.ArgHash);
cmdLine.ArgMountOptions.Kdf = cmdLine.ArgHash;
}
@@ -1108,8 +1108,8 @@ const FileManager fileManagers[] = {
if (cmdLine.ArgHash)
{
options->VolumeHeaderKdf = Pkcs5Kdf::GetAlgorithm (*cmdLine.ArgHash);
RandomNumberGenerator::SetHash (cmdLine.ArgHash);
options->VolumeHeaderKdf = cmdLine.ArgHash;
RandomNumberGenerator::SetHash (cmdLine.ArgHash->GetHash());
}
options->EA = cmdLine.ArgEncryptionAlgorithm;
@@ -1270,9 +1270,9 @@ const FileManager fileManagers[] = {
" This option is not available on some platforms.\n"
"\n"
"--hash=HASH\n"
" Use specified hash algorithm when creating a new volume or changing password\n"
" and/or keyfiles. This option also specifies the mixing PRF of the random\n"
" number generator.\n"
" Use specified header key derivation algorithm when creating a new volume\n"
" or changing password and/or keyfiles. This option also specifies the\n"
" mixing hash of the random number generator.\n"
"\n"
"-k, --keyfiles=KEYFILE1[,KEYFILE2,KEYFILE3,...]\n"
" Use specified keyfiles when mounting a volume or when changing password\n"

View File

@@ -33,7 +33,7 @@ namespace VeraCrypt
virtual bool AskYesNo (const wxString &message, bool defaultYes = false, bool warning = false) const = 0;
virtual void BackupVolumeHeaders (shared_ptr <VolumePath> volumePath) const = 0;
virtual void BeginBusyState () const = 0;
virtual void ChangePassword (shared_ptr <VolumePath> volumePath = shared_ptr <VolumePath>(), shared_ptr <VolumePassword> password = shared_ptr <VolumePassword>(), int pim = 0, shared_ptr <Hash> currentHash = shared_ptr <Hash>(), shared_ptr <KeyfileList> keyfiles = shared_ptr <KeyfileList>(), shared_ptr <VolumePassword> newPassword = shared_ptr <VolumePassword>(), int newPim = 0, shared_ptr <KeyfileList> newKeyfiles = shared_ptr <KeyfileList>(), shared_ptr <Hash> newHash = shared_ptr <Hash>()) const = 0;
virtual void ChangePassword (shared_ptr <VolumePath> volumePath = shared_ptr <VolumePath>(), shared_ptr <VolumePassword> password = shared_ptr <VolumePassword>(), int pim = 0, shared_ptr <Pkcs5Kdf> currentKdf = shared_ptr <Pkcs5Kdf>(), shared_ptr <KeyfileList> keyfiles = shared_ptr <KeyfileList>(), shared_ptr <VolumePassword> newPassword = shared_ptr <VolumePassword>(), int newPim = 0, shared_ptr <KeyfileList> newKeyfiles = shared_ptr <KeyfileList>(), shared_ptr <Pkcs5Kdf> newKdf = shared_ptr <Pkcs5Kdf>()) const = 0;
virtual void CheckRequirementsForMountingVolume () const;
virtual void CloseExplorerWindows (shared_ptr <VolumeInfo> mountedVolume) const;
virtual void CreateKeyfile (shared_ptr <FilePath> keyfilePath = shared_ptr <FilePath>()) const = 0;