1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2026-06-17 10:06:06 -05:00

Reset PIM defaults when changing volume KDF

A SourceForge report pointed out that the password-change and header-KDF dialogs reused the current custom PIM when the user selected a different KDF. That was harmless when all choices used the same PBKDF2 PIM scale, but it is wrong with Argon2 because the same numeric PIM has different security and performance meaning.

Avoid silently carrying a custom PIM across KDF changes in both the Windows and wx dialogs. If the new KDF differs from the current one and the user has not explicitly opened the New PIM field, use the default PIM for the selected KDF instead. Keep preserving the current PIM when the KDF is unchanged.

Enable explicit New PIM entry in the header KDF-only flow, warn before resetting an existing custom PIM to the new KDF default, and validate explicitly entered KDF-only PIM values.

Report the new KDF from the Windows dialog as well as the new PIM so favorite volumes update both stored PIM and pinned KDF metadata after password or header KDF changes, including system favorites. Add translation fallbacks, documentation, and release notes for the new behavior.
This commit is contained in:
Mounir IDRASSI
2026-06-11 04:31:46 +09:00
parent e5415498f4
commit 75857757fe
50 changed files with 452 additions and 77 deletions
+2
View File
@@ -1684,6 +1684,8 @@
<entry lang="en" key="MACOSX_APFS_SYSTEM_STORE">The selected APFS physical store '{0}' contains the currently mounted macOS system volume and cannot be used as a VeraCrypt volume host.</entry>
<entry lang="en" key="MACOSX_DEVICE_NOT_WRITABLE">macOS reports the selected device '{0}' as read-only. Select a writable physical partition or disk.</entry>
<entry lang="en" key="MACOSX_APFS_EROFS_HINT">macOS reported the selected device as read-only. If this is an APFS disk, make sure you selected the physical APFS store partition, not an APFS synthesized volume. Use Disk Utility or 'diskutil list' to identify the physical partition, then retry.</entry>
<entry lang="en" key="FAVORITE_PIM_OR_KDF_CHANGED">This volume is registered as a System Favorite and its PIM and/or KDF settings were changed.\nDo you want VeraCrypt to automatically update the System Favorite configuration (administrator privileges required)?\n\nPlease note that if you answer no, you'll have to update the System Favorite manually.</entry>
<entry lang="en" key="PIM_RESET_ON_KDF_CHANGE_CONFIRM">The selected KDF uses different PIM parameters, so VeraCrypt will not reuse the current custom PIM. The new volume header will use the default PIM for the selected KDF unless you select "Use PIM" in the New section and enter a custom value.\n\nDo you want to continue?</entry>
</localization>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="VeraCrypt">
+93 -14
View File
@@ -40,19 +40,33 @@ namespace VeraCrypt
return true;
}
static bool CheckCustomPimForKdfOnlyChange (VolumePasswordPanel *pimPanel, const shared_ptr <VolumePassword> &password, const shared_ptr <Pkcs5Kdf> &kdf, int currentPim)
static bool CheckCustomPimForKdfOnlyChange (VolumePasswordPanel *pimPanel, const shared_ptr <VolumePassword> &password, const shared_ptr <Pkcs5Kdf> &kdf, int pim)
{
int defaultPim = kdf ? kdf->GetDefaultPim() : 0;
if (!kdf || !password || password->Size() == 0 || currentPim <= 0 || defaultPim <= 0 || currentPim == defaultPim)
if (!kdf || !password || password->Size() == 0 || pim <= 0 || defaultPim <= 0 || pim == defaultPim)
return true;
if (currentPim < defaultPim)
return CheckCustomPimForPassword (pimPanel, password, currentPim, kdf);
if (pim < defaultPim)
return CheckCustomPimForPassword (pimPanel, password, pim, kdf);
Gui->ShowWarning (kdf->GetPimLargeWarningMessageId());
return true;
}
static bool KdfSelectionsEqual (const shared_ptr <Pkcs5Kdf> &left, const shared_ptr <Pkcs5Kdf> &right)
{
if (!left && !right)
return true;
if (!left || !right)
return false;
return left->GetName() == right->GetName();
}
static bool NewKdfSelectionChangesKdf (const shared_ptr <Pkcs5Kdf> &currentKdf, const shared_ptr <Pkcs5Kdf> &newKdf)
{
return newKdf && (!currentKdf || !KdfSelectionsEqual (currentKdf, newKdf));
}
static bool CheckPasswordChangeWarnings (VolumePasswordPanel *passwordPanel, const shared_ptr <VolumePassword> &password, int pim, const shared_ptr <Pkcs5Kdf> &kdf)
{
if (!password || password->Size() == 0)
@@ -89,7 +103,7 @@ namespace VeraCrypt
#endif
ChangePasswordDialog::ChangePasswordDialog (wxWindow* parent, shared_ptr <VolumePath> volumePath, Mode::Enum mode, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, shared_ptr <KeyfileList> newKeyfiles)
: ChangePasswordDialogBase (parent), DialogMode (mode), Path (volumePath)
: ChangePasswordDialogBase (parent), DialogMode (mode), KdfOnlyKdfSelectionInitialized (false), Path (volumePath)
{
bool enableNewPassword = false;
bool enableNewKeyfiles = false;
@@ -134,6 +148,9 @@ namespace VeraCrypt
NewPasswordPanel->UpdateEvent.Connect (EventConnector <ChangePasswordDialog> (this, &ChangePasswordDialog::OnPasswordPanelUpdate));
NewPasswordPanelSizer->Add (NewPasswordPanel, 1, wxALL | wxEXPAND);
if (mode == Mode::ChangePkcs5Prf)
NewPasswordPanel->EnableUsePim (true);
if (mode == Mode::RemoveAllKeyfiles)
NewSizer->Show (false);
@@ -175,6 +192,7 @@ namespace VeraCrypt
shared_ptr <VolumePassword> newPassword;
int newPim = 0;
bool newPimSpecified = false;
if (DialogMode == Mode::ChangePasswordAndKeyfiles)
{
try
@@ -197,13 +215,37 @@ namespace VeraCrypt
else
{
newPassword = currentPassword;
newPim = CurrentPasswordPanel->GetVolumePim();
}
if (DialogMode == Mode::ChangePkcs5Prf)
{
bool kdfChangesKdf = NewKdfSelectionChangesKdf (currentKdf, newKdf);
newPimSpecified = NewPasswordPanel->IsVolumePimSpecified();
if (newPimSpecified)
{
newPim = NewPasswordPanel->GetVolumePim();
if (-1 == newPim)
{
NewPasswordPanel->SetFocusToPimTextCtrl();
return;
}
}
else
{
newPim = kdfChangesKdf ? 0 : currentPim;
}
if (DialogMode == Mode::ChangePkcs5Prf)
{
if (!CheckCustomPimForKdfOnlyChange (CurrentPasswordPanel, newPassword, newKdf, currentPim))
return;
if (kdfChangesKdf && !newPimSpecified && currentPim > 0)
{
if (!Gui->AskYesNo (LangString["PIM_RESET_ON_KDF_CHANGE_CONFIRM"], false, true))
{
NewPasswordPanel->SetFocusToPimCheckBox();
return;
}
}
}
else
{
newPim = currentPim;
}
}
shared_ptr <KeyfileList> newKeyfiles;
@@ -216,7 +258,7 @@ namespace VeraCrypt
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
bool needOpenVolumeForKdf = (DialogMode == Mode::ChangePasswordAndKeyfiles || DialogMode == Mode::ChangePkcs5Prf)
&& !effectiveNewKdf
&& newPassword->Size() > 0
&& newPim > 0;
@@ -228,6 +270,12 @@ namespace VeraCrypt
{
return;
}
else if (DialogMode == Mode::ChangePkcs5Prf
&& newPimSpecified
&& !CheckCustomPimForKdfOnlyChange (NewPasswordPanel, newPassword, effectiveNewKdf, newPim))
{
return;
}
/* force the display of the random enriching interface */
RandomNumberGenerator::SetEnrichedByUserStatus (false);
@@ -265,11 +313,18 @@ namespace VeraCrypt
if (needOpenVolumeForKdf)
{
if (!CheckPasswordChangeWarnings (NewPasswordPanel, newPassword, newPim, effectiveNewKdf))
if (DialogMode == Mode::ChangePasswordAndKeyfiles
&& !CheckPasswordChangeWarnings (NewPasswordPanel, newPassword, newPim, effectiveNewKdf))
{
// The volume was opened only to detect its KDF; no header rewrite has started.
return;
}
else if (DialogMode == Mode::ChangePkcs5Prf
&& newPimSpecified
&& !CheckCustomPimForKdfOnlyChange (NewPasswordPanel, newPassword, effectiveNewKdf, newPim))
{
return;
}
/* force the display of the random enriching interface */
RandomNumberGenerator::SetEnrichedByUserStatus (false);
@@ -350,6 +405,30 @@ namespace VeraCrypt
if (CurrentPasswordPanel->GetVolumePim () == -1)
ok = false;
if (DialogMode == Mode::ChangePkcs5Prf)
{
shared_ptr <Pkcs5Kdf> currentKdf = CurrentPasswordPanel->GetPkcs5Kdf();
shared_ptr <Pkcs5Kdf> newKdf = NewPasswordPanel->GetPkcs5Kdf();
if (!KdfOnlyKdfSelectionInitialized)
{
LastCurrentKdf = currentKdf;
LastNewKdf = newKdf;
KdfOnlyKdfSelectionInitialized = true;
}
else if (!KdfSelectionsEqual (LastCurrentKdf, currentKdf) || !KdfSelectionsEqual (LastNewKdf, newKdf))
{
LastCurrentKdf = currentKdf;
LastNewKdf = newKdf;
if (!NewPasswordPanel->IsVolumePimSpecified() && NewKdfSelectionChangesKdf (currentKdf, newKdf))
NewPasswordPanel->ResetVolumePimToDefault();
}
if (NewPasswordPanel->GetVolumePim () == -1)
ok = false;
}
if (DialogMode == Mode::RemoveAllKeyfiles && (passwordEmpty || keyfilesEmpty))
ok = false;
@@ -377,7 +456,7 @@ namespace VeraCrypt
OKButton->Enable (ok);
if (DialogMode == Mode::ChangePasswordAndKeyfiles)
if (DialogMode == Mode::ChangePasswordAndKeyfiles || DialogMode == Mode::ChangePkcs5Prf)
{
bool pimChanged = (CurrentPasswordPanel->GetVolumePim() != NewPasswordPanel->GetVolumePim());
NewPasswordPanel->UpdatePimHelpText(pimChanged);
+3
View File
@@ -46,6 +46,9 @@ namespace VeraCrypt
void OnPasswordPanelUpdate (EventArgs &args) { OnPasswordPanelUpdate(); }
Mode::Enum DialogMode;
bool KdfOnlyKdfSelectionInitialized;
shared_ptr <Pkcs5Kdf> LastCurrentKdf;
shared_ptr <Pkcs5Kdf> LastNewKdf;
VolumePasswordPanel *CurrentPasswordPanel;
VolumePasswordPanel *NewPasswordPanel;
+40 -1
View File
@@ -153,10 +153,13 @@ namespace VeraCrypt
Layout();
Fit();
Pkcs5PrfChoice->Connect (wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (VolumePasswordPanel::OnPkcs5PrfChoiceSelected), nullptr, this);
}
VolumePasswordPanel::~VolumePasswordPanel ()
{
Pkcs5PrfChoice->Disconnect (wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (VolumePasswordPanel::OnPkcs5PrfChoiceSelected), nullptr, this);
WipeTextCtrl (PasswordTextCtrl);
WipeTextCtrl (ConfirmPasswordTextCtrl);
}
@@ -281,6 +284,40 @@ namespace VeraCrypt
}
}
void VolumePasswordPanel::EnableUsePim (bool pimOnlyDisplay)
{
EnablePimEntry = true;
PimCheckBox->Enable (true);
PimCheckBox->Show (true);
if (pimOnlyDisplay)
DisplayPasswordCheckBox->SetLabel (LangString["IDC_SHOW_PIM"]);
DisplayPasswordCheckBox->Show (true);
Layout();
Fit();
GetParent()->Layout();
GetParent()->Fit();
}
void VolumePasswordPanel::ResetVolumePimToDefault ()
{
if (DisplayPasswordCheckBox->IsChecked() && VolumePimTextCtrl->IsShown())
DisplayPassword (false, &VolumePimTextCtrl, 3);
DisplayPasswordCheckBox->SetValue (false);
SetVolumePim (0);
PimCheckBox->SetValue (false);
PimCheckBox->Show (EnablePimEntry);
VolumePimStaticText->Show (false);
VolumePimTextCtrl->Show (false);
VolumePimHelpStaticText->SetForegroundColour (wxSystemSettings::GetColour (wxSYS_COLOUR_WINDOWTEXT));
VolumePimHelpStaticText->SetLabel (LangString["IDC_PIM_HELP"]);
VolumePimHelpStaticText->Show (false);
Layout();
Fit();
GetParent()->Layout();
GetParent()->Fit();
}
int VolumePasswordPanel::GetHeaderWipeCount () const
{
try
@@ -366,7 +403,8 @@ namespace VeraCrypt
void VolumePasswordPanel::OnDisplayPasswordCheckBoxClick (wxCommandEvent& event)
{
DisplayPassword (event.IsChecked(), &PasswordTextCtrl, 1);
if (PasswordTextCtrl->IsShown())
DisplayPassword (event.IsChecked(), &PasswordTextCtrl, 1);
if (ConfirmPasswordTextCtrl->IsShown())
DisplayPassword (event.IsChecked(), &ConfirmPasswordTextCtrl, 2);
@@ -477,6 +515,7 @@ namespace VeraCrypt
layoutParent->Layout();
layoutParent->Fit();
OnUpdate();
}
}
}
+5 -1
View File
@@ -31,12 +31,15 @@ namespace VeraCrypt
shared_ptr <Pkcs5Kdf> GetPkcs5Kdf () const;
int GetVolumePim () const;
int GetHeaderWipeCount () const;
bool IsVolumePimSpecified () const { return VolumePimTextCtrl->IsEnabled () && VolumePimTextCtrl->IsShown (); }
void SetCacheCheckBoxValidator (const wxGenericValidator &validator) { CacheCheckBox->SetValidator (validator); }
void SetFocusToPasswordTextCtrl () { PasswordTextCtrl->SetSelection (-1, -1); PasswordTextCtrl->SetFocus(); }
void SetFocusToPimCheckBox () { PimCheckBox->SetFocus(); }
void SetFocusToPimTextCtrl () { VolumePimTextCtrl->SetSelection (-1, -1); VolumePimTextCtrl->SetFocus(); }
void ResetVolumePimToDefault ();
void SetVolumePim (int pim);
bool PasswordsMatch () const;
void EnableUsePim () { PimCheckBox->Enable (true); PimCheckBox->Show (true); }
void EnableUsePim (bool pimOnlyDisplay = false);
bool IsUsePimChecked () const { return PimCheckBox->GetValue (); }
void SetUsePimChecked (bool checked) const { PimCheckBox->SetValue (checked); }
bool UpdatePimHelpText (bool pimChanged);
@@ -55,6 +58,7 @@ namespace VeraCrypt
void OnKeyfilesButtonClick (wxCommandEvent& event);
void OnKeyfilesButtonRightClick (wxMouseEvent& event);
void OnKeyfilesButtonRightDown (wxMouseEvent& event);
void OnPkcs5PrfChoiceSelected (wxCommandEvent& event) { OnUpdate(); }
void OnTextChanged (wxCommandEvent& event) { OnUpdate(); }
void OnPimChanged (wxCommandEvent& event) { OnUpdate(); }
void OnUsePimCheckBoxClick( wxCommandEvent& event );
+220 -60
View File
@@ -2538,6 +2538,74 @@ static BOOL CheckKdfOnlyPimForPassword (HWND hwndDlg, const Password *password,
return CheckPasswordLength (hwndDlg, password->Length, pim, FALSE, pimValidationPkcs5, TRUE, FALSE);
}
static int GetSelectedKdfId (HWND hwndDlg, UINT ctrlId)
{
HWND hComboBox = GetDlgItem (hwndDlg, ctrlId);
LRESULT selectedIndex = SendMessage (hComboBox, CB_GETCURSEL, 0, 0);
LRESULT itemData;
if (selectedIndex == CB_ERR)
return 0;
itemData = SendMessage (hComboBox, CB_GETITEMDATA, selectedIndex, 0);
if (itemData == CB_ERR)
return 0;
return (int) itemData;
}
static BOOL NewKdfSelectionChangesKdf (int old_pkcs5, int pkcs5)
{
return (pkcs5 != 0 && (old_pkcs5 == 0 || old_pkcs5 != pkcs5));
}
static BOOL IsNewPimSpecified (HWND hwndDlg)
{
HWND hPim = GetDlgItem (hwndDlg, IDC_PIM);
return IsWindowEnabled (hPim) && IsWindowVisible (hPim);
}
/* The New PIM field can be shown automatically to mirror the current PIM.
* Keep that separate from an explicit user request to write a custom New PIM. */
static BOOL PasswordChangeNewPimExplicitlySpecified = FALSE;
static BOOL PasswordChangeNewPimProgrammaticUpdate = FALSE;
static BOOL IsNewPimExplicitlySpecified (HWND hwndDlg)
{
return PasswordChangeNewPimExplicitlySpecified && IsNewPimSpecified (hwndDlg);
}
static void SetNewPimValueProgrammatically (HWND hwndDlg, int pim)
{
PasswordChangeNewPimProgrammaticUpdate = TRUE;
SetPim (hwndDlg, IDC_PIM, pim);
PasswordChangeNewPimProgrammaticUpdate = FALSE;
}
static void SetNewPimTextProgrammatically (HWND hwndDlg, const wchar_t *pimText)
{
PasswordChangeNewPimProgrammaticUpdate = TRUE;
SetDlgItemText (hwndDlg, IDC_PIM, pimText);
PasswordChangeNewPimProgrammaticUpdate = FALSE;
}
static void ResetNewPimToDefault (HWND hwndDlg)
{
PasswordChangeNewPimExplicitlySpecified = FALSE;
SetNewPimValueProgrammatically (hwndDlg, 0);
SetCheckBox (hwndDlg, IDC_NEW_PIM_ENABLE, FALSE);
ShowWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), SW_SHOW);
ShowWindow (GetDlgItem (hwndDlg, IDT_PIM), SW_HIDE);
ShowWindow (GetDlgItem (hwndDlg, IDC_PIM), SW_HIDE);
ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), SW_HIDE);
}
typedef struct
{
int NewPimValue;
int NewPkcs5Value;
} PasswordChangeDlgResult;
// implementation for support of change password operation in wait dialog mechanism
typedef struct
@@ -2653,7 +2721,7 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
{
static KeyFilesDlgParam newKeyFilesParam;
static BOOL PimValueChangedWarning = FALSE;
static int* NewPimValuePtr = NULL;
static PasswordChangeDlgResult* ResultPtr = NULL;
WORD lw = LOWORD (wParam);
WORD hw = HIWORD (wParam);
@@ -2675,12 +2743,14 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
if (EffectiveVolumePkcs5 == 0)
EffectiveVolumePkcs5 = DefaultVolumePkcs5;
NewPimValuePtr = (int*) lParam;
ResultPtr = (PasswordChangeDlgResult*) lParam;
PimValueChangedWarning = FALSE;
PasswordChangeNewPimExplicitlySpecified = FALSE;
PasswordChangeNewPimProgrammaticUpdate = FALSE;
ZeroMemory (&newKeyFilesParam, sizeof (newKeyFilesParam));
if (NewPimValuePtr)
if (ResultPtr)
{
/* we are in the case of a volume. Store its name to use it in the key file dialog
* this will help avoid using the current container file as a key file
@@ -2759,12 +2829,13 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
LocalizeDialog (hwndDlg, "IDD_PCDM_CHANGE_PKCS5_PRF");
EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDC_VERIFY), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), TRUE);
EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), TRUE);
EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), TRUE);
EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), TRUE);
EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_NEW_KEYFILES), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), TRUE);
SetWindowTextW (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), GetString ("IDC_SHOW_PIM"));
EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_KEYFILES), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PASSWORD), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDT_CONFIRM_PASSWORD), FALSE);
@@ -2843,6 +2914,17 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID), FALSE);
if (pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF)
{
PasswordChangeNewPimExplicitlySpecified = FALSE;
SetNewPimValueProgrammatically (hwndDlg, 0);
EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), FALSE);
EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), FALSE);
}
if (SetTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD, TIMER_INTERVAL_KEYB_LAYOUT_GUARD, NULL) == 0)
{
Error ("CANNOT_SET_TIMER", hwndDlg);
@@ -2981,15 +3063,21 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
IDC_PASSWORD, IDC_VERIFY,
newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL);
if ((lw == IDC_OLD_PIM) && IsWindowEnabled (GetDlgItem (hwndDlg, IDC_PIM)))
if ((lw == IDC_OLD_PIM)
&& pwdChangeDlgMode != PCDM_CHANGE_PKCS5_PRF
&& IsNewPimSpecified (hwndDlg)
&& !NewKdfSelectionChangesKdf (GetSelectedKdfId (hwndDlg, IDC_PKCS5_OLD_PRF_ID), GetSelectedKdfId (hwndDlg, IDC_PKCS5_PRF_ID)))
{
wchar_t tmp[MAX_PIM+1] = {0};
GetDlgItemText (hwndDlg, IDC_OLD_PIM, tmp, MAX_PIM + 1);
SetDlgItemText (hwndDlg, IDC_PIM, tmp);
SetNewPimTextProgrammatically (hwndDlg, tmp);
}
if (lw == IDC_PIM)
{
if (!PasswordChangeNewPimProgrammaticUpdate && IsNewPimSpecified (hwndDlg))
PasswordChangeNewPimExplicitlySpecified = TRUE;
if(GetPim (hwndDlg, IDC_OLD_PIM, 0) != GetPim (hwndDlg, IDC_PIM, 0))
{
PimValueChangedWarning = TRUE;
@@ -3012,8 +3100,10 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM), SW_SHOW);
ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM_HELP), SW_SHOW);
// check also the "Use PIM" for the new password if it is enabled
if (IsWindowEnabled (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE)))
// Preserve the PIM automatically only when the selected KDF is not changing.
if (pwdChangeDlgMode != PCDM_CHANGE_PKCS5_PRF
&& IsWindowEnabled (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE))
&& !NewKdfSelectionChangesKdf (GetSelectedKdfId (hwndDlg, IDC_PKCS5_OLD_PRF_ID), GetSelectedKdfId (hwndDlg, IDC_PKCS5_PRF_ID)))
{
SetCheckBox (hwndDlg, IDC_NEW_PIM_ENABLE, TRUE);
@@ -3030,6 +3120,7 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
if (lw == IDC_NEW_PIM_ENABLE)
{
PasswordChangeNewPimExplicitlySpecified = TRUE;
ShowWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), SW_HIDE);
ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW);
ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW);
@@ -3128,9 +3219,11 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
if (hw == CBN_SELCHANGE)
{
BOOL kdfSelectionChanged = FALSE;
switch (lw)
{
case IDC_PKCS5_PRF_ID:
kdfSelectionChanged = TRUE;
if (bSysEncPwdChangeDlgMode)
{
int new_hash_algo_id = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA,
@@ -3144,6 +3237,22 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
}
}
break;
case IDC_PKCS5_OLD_PRF_ID:
kdfSelectionChanged = TRUE;
break;
}
if (kdfSelectionChanged
&& !bSysEncPwdChangeDlgMode
&& (pwdChangeDlgMode == PCDM_CHANGE_PASSWORD || pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF)
&& IsWindowEnabled (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE))
&& !IsNewPimExplicitlySpecified (hwndDlg)
&& NewKdfSelectionChangesKdf (GetSelectedKdfId (hwndDlg, IDC_PKCS5_OLD_PRF_ID), GetSelectedKdfId (hwndDlg, IDC_PKCS5_PRF_ID)))
{
ResetNewPimToDefault (hwndDlg);
PimValueChangedWarning = FALSE;
SetDlgItemTextW (hwndDlg, IDC_PIM_HELP, (wchar_t *) GetDictionaryValueByInt (IDC_PIM_HELP));
}
return 1;
@@ -3157,7 +3266,8 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
if (lw == IDC_SHOW_PASSWORD_CHPWD_NEW)
{
HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW, IDC_PASSWORD, IDC_VERIFY);
if (pwdChangeDlgMode != PCDM_CHANGE_PKCS5_PRF)
HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW, IDC_PASSWORD, IDC_VERIFY);
HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW, IDC_PIM, 0);
return 1;
}
@@ -3173,15 +3283,25 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
SendMessage (GetDlgItem (hwndDlg, IDC_WIPE_MODE), CB_GETCURSEL, 0, 0),
0);
int nStatus;
int old_pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID), CB_GETITEMDATA,
SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID), CB_GETCURSEL, 0, 0), 0);
int pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA,
SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0);
int old_pkcs5 = GetSelectedKdfId (hwndDlg, IDC_PKCS5_OLD_PRF_ID);
int pkcs5 = GetSelectedKdfId (hwndDlg, IDC_PKCS5_PRF_ID);
int old_pim = GetPim (hwndDlg, IDC_OLD_PIM, 0);
int pim = GetPim (hwndDlg, IDC_PIM, 0);
BOOL newPimSpecified = IsNewPimExplicitlySpecified (hwndDlg);
BOOL newKdfChangesKdf = !bSysEncPwdChangeDlgMode && NewKdfSelectionChangesKdf (old_pkcs5, pkcs5);
BOOL newPimSelectable = (pwdChangeDlgMode == PCDM_CHANGE_PASSWORD || pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF);
int iMaxPasswordLength = (bUseLegacyMaxPasswordLength)? MAX_LEGACY_PASSWORD : MAX_PASSWORD;
if (pwdChangeDlgMode == PCDM_ADD_REMOVE_VOL_KEYFILES || pwdChangeDlgMode == PCDM_REMOVE_ALL_KEYFILES_FROM_VOL)
{
pim = old_pim;
}
else if (newPimSelectable && !newPimSpecified)
{
pim = newKdfChangesKdf ? 0 : old_pim;
}
if (bSysEncPwdChangeDlgMode && !CheckPasswordCharEncoding (GetDlgItem (hwndDlg, IDC_PASSWORD), NULL))
{
Error ("UNSUPPORTED_CHARS_IN_PWD", hwndDlg);
@@ -3202,6 +3322,13 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
return 1;
}
if (newPimSelectable && newKdfChangesKdf && !newPimSpecified && old_pim > 0
&& AskWarnNoYes ("PIM_RESET_ON_KDF_CHANGE_CONFIRM", hwndDlg) != IDYES)
{
SetFocus (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE));
return 1;
}
if (pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF)
{
newKeyFilesParam.EnableKeyFiles = KeyFilesEnable;
@@ -3249,12 +3376,16 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
{
case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL:
case PCDM_ADD_REMOVE_VOL_KEYFILES:
case PCDM_CHANGE_PKCS5_PRF:
memcpy (newPassword.Text, oldPassword.Text, sizeof (newPassword.Text));
newPassword.Length = (unsigned __int32) strlen ((char *) oldPassword.Text);
pim = old_pim;
break;
case PCDM_CHANGE_PKCS5_PRF:
memcpy (newPassword.Text, oldPassword.Text, sizeof (newPassword.Text));
newPassword.Length = (unsigned __int32) strlen ((char *) oldPassword.Text);
break;
default:
if (GetPassword (hwndDlg, IDC_PASSWORD, (LPSTR) newPassword.Text, iMaxPasswordLength + 1, FALSE, TRUE))
newPassword.Length = (unsigned __int32) strlen ((char *) newPassword.Text);
@@ -3300,13 +3431,14 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
ShowWaitDialog(hwndDlg, TRUE, ChangePwdWaitThreadProc, &changePwdParam);
err:
// notify the caller in case the PIM has changed
if (NewPimValuePtr)
if (ResultPtr && nStatus == 0)
{
if (pim != old_pim)
*NewPimValuePtr = pim;
if (newKdfChangesKdf || pim != old_pim)
ResultPtr->NewPimValue = pim;
else
*NewPimValuePtr = -1;
ResultPtr->NewPimValue = -1;
ResultPtr->NewPkcs5Value = newKdfChangesKdf ? pkcs5 : -1;
}
burn (&oldPassword, sizeof (oldPassword));
@@ -6520,10 +6652,71 @@ static BOOL MountAllDevices (HWND hwndDlg, BOOL bPasswordPrompt)
return param.bRet;
}
static bool FavoritePimOrKdfNeedsUpdate (const FavoriteVolume &favorite, int newPimValue, int newPkcs5Value)
{
return ((newPimValue != -1 && favorite.Pim != newPimValue)
|| (newPkcs5Value > 0 && favorite.Pkcs5 != newPkcs5Value));
}
static void UpdateFavoritePimAndKdfValues (FavoriteVolume &favorite, int newPimValue, int newPkcs5Value)
{
if (newPimValue != -1)
favorite.Pim = newPimValue;
if (newPkcs5Value > 0)
favorite.Pkcs5 = newPkcs5Value;
}
static void UpdateFavoritePimAndKdfValues (HWND hwndDlg, const wchar_t *volumePath, int newPimValue, int newPkcs5Value)
{
bool bFavoriteFound = false;
if (newPimValue == -1 && newPkcs5Value <= 0)
return;
for (vector <FavoriteVolume>::iterator favorite = FavoriteVolumes.begin();
favorite != FavoriteVolumes.end(); favorite++)
{
if (favorite->Path == volumePath)
{
bFavoriteFound = true;
if (FavoritePimOrKdfNeedsUpdate (*favorite, newPimValue, newPkcs5Value))
{
UpdateFavoritePimAndKdfValues (*favorite, newPimValue, newPkcs5Value);
SaveFavoriteVolumes (hwndDlg, FavoriteVolumes, false);
}
break;
}
}
if (!bFavoriteFound)
{
for (vector <FavoriteVolume>::iterator favorite = SystemFavoriteVolumes.begin();
favorite != SystemFavoriteVolumes.end(); favorite++)
{
if (favorite->Path == volumePath)
{
bFavoriteFound = true;
if (FavoritePimOrKdfNeedsUpdate (*favorite, newPimValue, newPkcs5Value)
&& AskYesNo ("FAVORITE_PIM_OR_KDF_CHANGED", hwndDlg) == IDYES)
{
UpdateFavoritePimAndKdfValues (*favorite, newPimValue, newPkcs5Value);
SaveFavoriteVolumes (hwndDlg, SystemFavoriteVolumes, true);
}
break;
}
}
}
}
static void ChangePassword (HWND hwndDlg)
{
INT_PTR result;
int newPimValue = -1;
PasswordChangeDlgResult dlgResult;
dlgResult.NewPimValue = -1;
dlgResult.NewPkcs5Value = -1;
GetVolumePath (hwndDlg, szFileName, ARRAYSIZE (szFileName));
@@ -6547,7 +6740,7 @@ static void ChangePassword (HWND hwndDlg)
bSysEncPwdChangeDlgMode = FALSE;
result = DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_PASSWORDCHANGE_DLG), hwndDlg,
(DLGPROC) PasswordChangeDlgProc, (LPARAM) &newPimValue);
(DLGPROC) PasswordChangeDlgProc, (LPARAM) &dlgResult);
if (result == IDOK)
{
@@ -6555,6 +6748,7 @@ static void ChangePassword (HWND hwndDlg)
{
case PCDM_CHANGE_PKCS5_PRF:
Info ("PKCS5_PRF_CHANGED", hwndDlg);
UpdateFavoritePimAndKdfValues (hwndDlg, szFileName, dlgResult.NewPimValue, dlgResult.NewPkcs5Value);
break;
case PCDM_ADD_REMOVE_VOL_KEYFILES:
@@ -6566,41 +6760,7 @@ static void ChangePassword (HWND hwndDlg)
default:
{
Info ("PASSWORD_CHANGED", hwndDlg);
if (newPimValue != -1)
{
// update the encoded volue in favorite XML if found
bool bFavoriteFound = false;
for (vector <FavoriteVolume>::iterator favorite = FavoriteVolumes.begin();
favorite != FavoriteVolumes.end(); favorite++)
{
if (favorite->Path == szFileName)
{
bFavoriteFound = true;
favorite->Pim = newPimValue;
SaveFavoriteVolumes (hwndDlg, FavoriteVolumes, false);
break;
}
}
if (!bFavoriteFound)
{
for (vector <FavoriteVolume>::iterator favorite = SystemFavoriteVolumes.begin();
favorite != SystemFavoriteVolumes.end(); favorite++)
{
if (favorite->Path == szFileName)
{
bFavoriteFound = true;
favorite->Pim = newPimValue;
if (AskYesNo("FAVORITE_PIM_CHANGED", hwndDlg) == IDYES)
{
SaveFavoriteVolumes (hwndDlg, SystemFavoriteVolumes, true);
}
break;
}
}
}
}
UpdateFavoritePimAndKdfValues (hwndDlg, szFileName, dlgResult.NewPimValue, dlgResult.NewPkcs5Value);
}
}
}