1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2026-06-19 02:56:07 -05:00

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
+3 -1
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());
+135 -38
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)
+10 -10
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());
}
}
+4 -3
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;
};
}
+4 -4
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)
{
+16 -10
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;
+1 -1
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: