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

@@ -84,7 +84,7 @@ BEGIN
COMBOBOX IDC_PKCS5_PRF_ID,134,154,91,90,CBS_DROPDOWNLIST | WS_TABSTOP
EDITTEXT IDC_PIM,134,174,42,14,ES_RIGHT | ES_PASSWORD | ES_AUTOHSCROLL | ES_NUMBER | NOT WS_VISIBLE
CONTROL "Use P&IM",IDC_PIM_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,134,179,97,10
LTEXT "(Empty or 0 for default iterations)",IDC_PIM_HELP,181,177,121,8,NOT WS_VISIBLE
LTEXT "(Empty or 0 for defaults)",IDC_PIM_HELP,181,177,121,8,NOT WS_VISIBLE
CONTROL "&Display password",IDC_SHOW_PASSWORD_MO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,134,192,90,10
CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE_HIDVOL_PROT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,134,205,90,10
PUSHBUTTON "&Keyfiles...",IDC_KEYFILES_HIDVOL_PROT,239,201,60,14

View File

@@ -66,6 +66,7 @@ enum
#define BLAKE2S_BLOCKSIZE 64
#define BLAKE2S_DIGESTSIZE 32
#define BLAKE2B_DIGESTSIZE 64
#define SHA256_BLOCKSIZE 64
#define SHA256_DIGESTSIZE 32

View File

@@ -152,8 +152,8 @@
<entry lang="en" key="IDC_MOUNT_OPTIONS">Mount Opti&amp;ons...</entry>
<entry lang="en" key="IDC_MOUNT_READONLY">Mount volume as read-&amp;only</entry>
<entry lang="en" key="IDC_NEW_KEYFILES">Keyfiles...</entry>
<entry lang="en" key="IDC_OLD_PIM_HELP">(Empty or 0 for default iterations)</entry>
<entry lang="en" key="IDC_PIM_HELP">(Empty or 0 for default iterations)</entry>
<entry lang="en" key="IDC_OLD_PIM_HELP">(Empty or 0 for defaults)</entry>
<entry lang="en" key="IDC_PIM_HELP">(Empty or 0 for defaults)</entry>
<entry lang="en" key="IDC_PREF_BKG_TASK_ENABLE">Enabled</entry>
<entry lang="en" key="IDC_PREF_CACHE_PASSWORDS">Cache passwords in driver memory</entry>
<entry lang="en" key="IDC_PREF_UNMOUNT_INACTIVE">Auto-unmount volume after no data has been read/written to it for</entry>
@@ -644,10 +644,13 @@
<entry lang="en" key="PIM_HIDVOL_TITLE">Hidden Volume PIM</entry>
<entry lang="en" key="PIM_HIDDEN_OS_TITLE">PIM for Hidden Operating System</entry>
<entry lang="en" key="PIM_HELP">PIM (Personal Iterations Multiplier) is a value that controls the number of iterations used by the header key derivation as follows:\n Iterations = 15000 + (PIM x 1000).\n\nWhen left empty or set to 0, VeraCrypt will use a default value (485) that ensures a high security.\n\nWhen the password is less than 20 characters, PIM can't be smaller than 485 in order to maintain a minimal security level.\nWhen the password is 20 characters or more, PIM can be set to any value.\n\nA PIM value larger than 485 will lead to slower mount. A small PIM value (less than 485) will lead to a quicker mount but it can reduce security if the password is not strong enough.</entry>
<entry lang="en" key="PIM_ARGON2_HELP">PIM (Personal Iterations Multiplier) controls the memory and time costs used by Argon2id header key derivation as follows:\n Memory = min(64 MiB + ((PIM - 1) x 32 MiB), 1024 MiB)\n Iterations = 3 + ((PIM - 1) / 3) for PIM 31 or lower, then 13 + (PIM - 31)\n\nWhen left empty or set to 0, VeraCrypt will use the default Argon2 PIM (12), which uses 416 MiB of memory and 6 iterations.\n\nWhen the password is less than 20 characters, Argon2 PIM can't be smaller than 12 in order to maintain a minimal security level.\nWhen the password is 20 characters or more, Argon2 PIM can be set to any value.\n\nAn Argon2 PIM larger than 12 increases memory usage up to 1024 MiB and then increases iterations. This will lead to slower mounting. A small Argon2 PIM (less than 12) will lead to quicker mounting but it can reduce security if the password is not strong enough.</entry>
<entry lang="en" key="PIM_SYSENC_HELP">PIM (Personal Iterations Multiplier) is a value that controls the number of iterations used by the header key derivation as follows:\n Iterations = PIM x 2048.\n\nWhen left empty or set to 0, VeraCrypt will use a default value that ensures a high security.\n\nWhen the password is less than 20 characters, PIM can't be smaller than 98 in order to maintain a minimal security level.\nWhen the password is 20 characters or more, PIM can be set to any value.\n\nA PIM value larger than 98 will lead to slower boot. A small PIM value (less than 98) will lead to a quicker boot but it can reduce security if the password is not strong enough.</entry>
<entry lang="en" key="PIM_SYSENC_CHANGE_WARNING">Remember Number to Boot System</entry>
<entry lang="en" key="PIM_LARGE_WARNING">You have chosen a PIM value that is larger than VeraCrypt default value.\nPlease note that this will lead to much slower mount/boot.</entry>
<entry lang="en" key="PIM_ARGON2_LARGE_WARNING">You have chosen an Argon2 PIM value that is larger than VeraCrypt default value.\nPlease note that this can require more memory and lead to much slower mounting.</entry>
<entry lang="en" key="PIM_SMALL_WARNING">You have chosen a Personal Iterations Multiplier (PIM) that is smaller than the default VeraCrypt value. Please note that if your password is not strong enough, this could lead to a weaker security.\n\nDo you confirm that you are using a strong password?</entry>
<entry lang="en" key="PIM_ARGON2_SMALL_WARNING">You have chosen an Argon2 PIM value that is smaller than the default VeraCrypt value. Please note that if your password is not strong enough, this could lead to weaker security.\n\nDo you confirm that you are using a strong password?</entry>
<entry lang="en" key="PIM_SYSENC_TOO_BIG">Personal Iterations Multiplier (PIM) maximum value for system encryption is 65535.</entry>
<entry lang="en" key="PIM_TITLE">Volume PIM</entry>
<entry lang="en" key="HIDDEN_FILES_PRESENT_IN_KEYFILE_PATH">\n\nWARNING: Hidden file(s) have been found in a keyfile search path. Such hidden files cannot be used as keyfiles. If you need to use them as keyfiles, remove their 'Hidden' attribute (right-click each of them, select 'Properties', uncheck 'Hidden' and click OK). Note: Hidden files are visible only if the corresponding option is enabled (Computer > Organize > 'Folder and search options' > View).</entry>
@@ -1104,6 +1107,7 @@
<entry lang="en" key="ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE">This algorithm is not supported for TrueCrypt mode.</entry>
<entry lang="en" key="PIM_NOT_SUPPORTED_FOR_TRUECRYPT_MODE">PIM (Personal Iterations Multiplier) not supported for TrueCrypt mode.</entry>
<entry lang="en" key="PIM_REQUIRE_LONG_PASSWORD">Password must contain 20 or more characters in order to use the specified PIM.\nShorter passwords can only be used if the PIM is 485 or greater.</entry>
<entry lang="en" key="PIM_ARGON2_REQUIRE_LONG_PASSWORD">Password must contain 20 or more characters in order to use the specified Argon2 PIM.\nShorter passwords can only be used if the Argon2 PIM is 12 or greater.</entry>
<entry lang="en" key="BOOT_PIM_REQUIRE_LONG_PASSWORD">Pre-boot authentication Password must contain 20 or more characters in order to use the specified PIM.\nShorter passwords can only be used if the PIM is 98 or greater.</entry>
<entry lang="en" key="KEYFILES_NOT_SUPPORTED_FOR_SYS_ENCRYPTION">Keyfiles are currently not supported for system encryption.</entry>
<entry lang="en" key="CANNOT_RESTORE_KEYBOARD_LAYOUT">Warning: VeraCrypt could not restore the original keyboard layout. This may cause you to enter a password incorrectly.</entry>

View File

@@ -136,13 +136,32 @@ BOOL CheckPasswordCharEncoding (HWND hPassword, Password *ptrPw)
BOOL CheckPasswordLength (HWND hwndDlg, unsigned __int32 passwordLength, int pim, BOOL bForBoot, int bootPRF, BOOL bSkipPasswordWarning, BOOL bSkipPimWarning)
{
BOOL bootPimCondition = (bForBoot && (bootPRF != SHA512 && bootPRF != WHIRLPOOL))? TRUE : FALSE;
BOOL bCustomPimSmall = ((pim != 0) && (pim < (bootPimCondition? 98 : bootPRF == ARGON2? 12 : 485)))? TRUE : FALSE;
BOOL bootPimCondition = FALSE;
BOOL argon2PimCondition = FALSE;
int defaultPim;
BOOL bCustomPimSmall;
const char *pimRequireLongPasswordMessage = "PIM_REQUIRE_LONG_PASSWORD";
const char *pimLargeWarningMessage = "PIM_LARGE_WARNING";
const char *pimSmallWarningMessage = "PIM_SMALL_WARNING";
#ifndef VC_DCS_DISABLE_ARGON2
argon2PimCondition = (bootPRF == ARGON2)? TRUE : FALSE;
#endif
bootPimCondition = (!argon2PimCondition && bForBoot && (bootPRF != SHA512 && bootPRF != WHIRLPOOL))? TRUE : FALSE;
defaultPim = bootPimCondition? 98 : argon2PimCondition? 12 : 485;
bCustomPimSmall = ((pim != 0) && (pim < defaultPim))? TRUE : FALSE;
if (bootPimCondition)
pimRequireLongPasswordMessage = "BOOT_PIM_REQUIRE_LONG_PASSWORD";
else if (argon2PimCondition)
{
pimRequireLongPasswordMessage = "PIM_ARGON2_REQUIRE_LONG_PASSWORD";
pimLargeWarningMessage = "PIM_ARGON2_LARGE_WARNING";
pimSmallWarningMessage = "PIM_ARGON2_SMALL_WARNING";
}
if (passwordLength < PASSWORD_LEN_WARNING)
{
if (bCustomPimSmall)
{
Error (bootPimCondition? "BOOT_PIM_REQUIRE_LONG_PASSWORD": "PIM_REQUIRE_LONG_PASSWORD", hwndDlg);
Error (pimRequireLongPasswordMessage, hwndDlg);
return FALSE;
}
@@ -154,15 +173,15 @@ BOOL CheckPasswordLength (HWND hwndDlg, unsigned __int32 passwordLength, int pim
#ifndef _DEBUG
else if (bCustomPimSmall)
{
if (!bSkipPimWarning && AskWarnNoYes ("PIM_SMALL_WARNING", hwndDlg) != IDYES)
if (!bSkipPimWarning && AskWarnNoYes (pimSmallWarningMessage, hwndDlg) != IDYES)
return FALSE;
}
#endif
if ((pim != 0) && (pim > (bootPimCondition? 98 : bootPRF == ARGON2? 12 : 485)))
if ((pim != 0) && (pim > defaultPim))
{
// warn that mount/boot will take more time
Warning ("PIM_LARGE_WARNING", hwndDlg);
Warning (pimLargeWarningMessage, hwndDlg);
}
return TRUE;
@@ -404,6 +423,12 @@ int ChangePwd (const wchar_t *lpszVolume, Password *oldPassword, int old_pkcs5,
if (pkcs5 != 0)
cryptoInfo->pkcs5 = pkcs5;
if (pkcs5 == 0 && old_pkcs5 == 0 && !CheckPasswordLength (hwndDlg, newPassword->Length, pim, FALSE, cryptoInfo->pkcs5, TRUE, FALSE))
{
nStatus = ERR_USER_ABORT;
goto error;
}
RandSetHashFunction (cryptoInfo->pkcs5);
NormalCursor();
@@ -567,4 +592,3 @@ error:
return nStatus;
}

View File

@@ -1337,15 +1337,16 @@ int is_pkcs5_prf_supported (int pkcs5_prf_id, PRF_BOOT_TYPE bootType)
}
#ifndef VC_DCS_DISABLE_ARGON2
void derive_key_argon2(const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, uint32 memcost, unsigned char *dk, int dklen, volatile long *pAbortKeyDerivation)
int derive_key_argon2(const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, uint32 memcost, unsigned char *dk, int dklen, volatile long *pAbortKeyDerivation)
{
int result;
#if defined (DEVICE_DRIVER) && !defined(_M_ARM64)
NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
XSTATE_SAVE SaveState;
if (HasSAVX2())
saveStatus = KeSaveExtendedProcessorState(XSTATE_MASK_GSSE, &SaveState);
#endif
if (0 != argon2id_hash_raw(
result = argon2id_hash_raw(
iterations, // number of iterations
memcost, // memory cost in KiB
1, // parallelism factor (number of threads)
@@ -1353,15 +1354,17 @@ void derive_key_argon2(const unsigned char *pwd, int pwd_len, const unsigned cha
salt, salt_len, // salt and its length
dk, dklen,// derived key and its length
pAbortKeyDerivation
))
);
if (0 != result)
{
// If the Argon2 derivation fails, we fill the derived key with zeroes
// If the Argon2 derivation fails, ensure unchecked legacy callers cannot use stale data.
memset(dk, 0, dklen);
}
#if defined (DEVICE_DRIVER) && !defined(_M_ARM64)
if (NT_SUCCESS(saveStatus))
KeRestoreExtendedProcessorState(&SaveState);
#endif
return result;
}
/**

View File

@@ -45,7 +45,7 @@ int get_pkcs5_iteration_count (int pkcs5_prf_id, int pim, BOOL bBoot, int* pMemo
wchar_t *get_kdf_name (int kdf_id);
#ifndef VC_DCS_DISABLE_ARGON2
void derive_key_argon2(const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, uint32 memcost, unsigned char *dk, int dklen, long volatile *pAbortKeyDerivation);
int derive_key_argon2(const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, uint32 memcost, unsigned char *dk, int dklen, long volatile *pAbortKeyDerivation);
void get_argon2_params(int pim, int* pIterations, int* pMemcost);
#endif

View File

@@ -277,11 +277,14 @@ BOOL Randmix ()
digestSize = SHA256_DIGESTSIZE;
break;
#ifndef WOLFCRYPT_BACKEND
case BLAKE2S:
case ARGON2: // in case of Argon2, we use Blake2s
digestSize = BLAKE2S_DIGESTSIZE;
break;
#ifndef WOLFCRYPT_BACKEND
case BLAKE2S:
digestSize = BLAKE2S_DIGESTSIZE;
break;
case ARGON2:
digestSize = BLAKE2B_DIGESTSIZE;
break;
case WHIRLPOOL:
digestSize = WHIRLPOOL_DIGESTSIZE;
@@ -366,10 +369,13 @@ BOOL Randmix ()
break;
#ifndef WOLFCRYPT_BACKEND
case BLAKE2S:
case ARGON2: // in case of Argon2, we use Blake2s
burn (&bctx, sizeof(bctx));
break;
case BLAKE2S:
burn (&bctx, sizeof(bctx));
break;
case ARGON2:
burn (&b2ctx, sizeof(b2ctx));
break;
case WHIRLPOOL:
burn (&wctx, sizeof(wctx));
@@ -974,4 +980,3 @@ BOOL FastPoll (void)
return TRUE;
}

View File

@@ -21,7 +21,8 @@ extern "C" {
/* RNG defines & pool pointers */
#define RNG_POOL_SIZE 320 // Must be divisible by the size of the output of each of the implemented hash functions. (in bytes)
#if RNG_POOL_SIZE % SHA512_DIGESTSIZE || RNG_POOL_SIZE % WHIRLPOOL_DIGESTSIZE || RNG_POOL_SIZE % BLAKE2S_DIGESTSIZE
#if RNG_POOL_SIZE % SHA512_DIGESTSIZE || RNG_POOL_SIZE % WHIRLPOOL_DIGESTSIZE || RNG_POOL_SIZE % BLAKE2S_DIGESTSIZE \
|| (!defined(VC_DCS_DISABLE_ARGON2) && RNG_POOL_SIZE % BLAKE2B_DIGESTSIZE)
#error RNG_POOL_SIZE must be divisible by the size of the output of each of the implemented hash functions.
#endif

View File

@@ -76,6 +76,7 @@ namespace VeraCrypt
int m_pim;
shared_ptr <Pkcs5Kdf> m_kdf;
shared_ptr <KeyfileList> m_keyfiles;
shared_ptr <Volume> m_openVolume;
shared_ptr <VolumePassword> m_newPassword;
int m_newPim;
shared_ptr <KeyfileList> m_newKeyfiles;
@@ -83,10 +84,15 @@ namespace VeraCrypt
int m_wipeCount;
bool m_emvSupportEnabled;
bool m_masterKeyVulnerable;
ChangePasswordThreadRoutine(shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> newPkcs5Kdf, int wipeCount, bool emvSupportEnabled) : m_volumePath(volumePath), m_preserveTimestamps(preserveTimestamps), m_password(password), m_pim(pim), m_kdf(kdf), m_keyfiles(keyfiles), m_newPassword(newPassword), m_newPim(newPim), m_newKeyfiles(newKeyfiles), m_newPkcs5Kdf(newPkcs5Kdf), m_wipeCount(wipeCount), m_emvSupportEnabled(emvSupportEnabled), m_masterKeyVulnerable(false) {}
ChangePasswordThreadRoutine(shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> newPkcs5Kdf, int wipeCount, bool emvSupportEnabled) : m_volumePath(volumePath), m_preserveTimestamps(preserveTimestamps), m_password(password), m_pim(pim), m_kdf(kdf), m_keyfiles(keyfiles), m_openVolume(), m_newPassword(newPassword), m_newPim(newPim), m_newKeyfiles(newKeyfiles), m_newPkcs5Kdf(newPkcs5Kdf), m_wipeCount(wipeCount), m_emvSupportEnabled(emvSupportEnabled), m_masterKeyVulnerable(false) {}
ChangePasswordThreadRoutine(shared_ptr <Volume> openVolume, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> newPkcs5Kdf, int wipeCount, bool emvSupportEnabled) : m_volumePath(), m_preserveTimestamps(false), m_password(), m_pim(0), m_kdf(), m_keyfiles(), m_openVolume(openVolume), m_newPassword(newPassword), m_newPim(newPim), m_newKeyfiles(newKeyfiles), m_newPkcs5Kdf(newPkcs5Kdf), m_wipeCount(wipeCount), m_emvSupportEnabled(emvSupportEnabled), m_masterKeyVulnerable(false) {}
virtual ~ChangePasswordThreadRoutine() { }
virtual void ExecutionCode(void) {
shared_ptr <Volume> openVolume = Core->ChangePassword(m_volumePath, m_preserveTimestamps, m_password, m_pim, m_kdf, m_keyfiles, m_newPassword, m_newPim, m_newKeyfiles, m_emvSupportEnabled, m_newPkcs5Kdf, m_wipeCount);
shared_ptr <Volume> openVolume = m_openVolume;
if (openVolume)
Core->ChangePassword(openVolume, m_newPassword, m_newPim, m_newKeyfiles, m_emvSupportEnabled, m_newPkcs5Kdf, m_wipeCount);
else
openVolume = Core->ChangePassword(m_volumePath, m_preserveTimestamps, m_password, m_pim, m_kdf, m_keyfiles, m_newPassword, m_newPim, m_newKeyfiles, m_emvSupportEnabled, m_newPkcs5Kdf, m_wipeCount);
m_masterKeyVulnerable = openVolume->IsMasterKeyVulnerable();
}
};

View File

@@ -67,7 +67,9 @@ namespace VeraCrypt
else
RandomNumberGenerator::GetDataFast (newSalt);
newPkcs5Kdf->DeriveKey (newHeaderKey, *password, newPim, newSalt);
int derivationResult = newPkcs5Kdf->DeriveKey (newHeaderKey, *password, newPim, newSalt);
if (derivationResult != 0)
throw ExternalException (SRC_POS, newPkcs5Kdf->GetDerivationFailureMessage (derivationResult));
openVolume->ReEncryptHeader (backupHeader, newSalt, newHeaderKey, newPkcs5Kdf);
openVolume->GetFile()->Flush();
@@ -289,7 +291,9 @@ namespace VeraCrypt
shared_ptr <VolumePassword> passwordKey (Keyfile::ApplyListToPassword (keyfiles, password, emvSupportEnabled));
RandomNumberGenerator::GetData (newSalt);
pkcs5Kdf->DeriveKey (newHeaderKey, *passwordKey, pim, newSalt);
int derivationResult = pkcs5Kdf->DeriveKey (newHeaderKey, *passwordKey, pim, newSalt);
if (derivationResult != 0)
throw ExternalException (SRC_POS, pkcs5Kdf->GetDerivationFailureMessage (derivationResult));
header->EncryptNew (newHeaderBuffer, newSalt, newHeaderKey, pkcs5Kdf);
}

View File

@@ -143,7 +143,9 @@ namespace VeraCrypt
SecureBuffer backupHeaderSalt (VolumeHeader::GetSaltSize());
RandomNumberGenerator::GetData (backupHeaderSalt);
Options->VolumeHeaderKdf->DeriveKey (HeaderKey, *PasswordKey, Options->Pim, backupHeaderSalt);
int derivationResult = Options->VolumeHeaderKdf->DeriveKey (HeaderKey, *PasswordKey, Options->Pim, backupHeaderSalt);
if (derivationResult != 0)
throw ExternalException (SRC_POS, Options->VolumeHeaderKdf->GetDerivationFailureMessage (derivationResult));
Layout->GetHeader()->EncryptNew (backupHeader, backupHeaderSalt, HeaderKey, Options->VolumeHeaderKdf);
@@ -316,7 +318,9 @@ namespace VeraCrypt
// Header key
HeaderKey.Allocate (VolumeHeader::GetLargestSerializedKeySize());
PasswordKey = Keyfile::ApplyListToPassword (options->Keyfiles, options->Password, options->EMVSupportEnabled);
options->VolumeHeaderKdf->DeriveKey (HeaderKey, *PasswordKey, options->Pim, salt);
int derivationResult = options->VolumeHeaderKdf->DeriveKey (HeaderKey, *PasswordKey, options->Pim, salt);
if (derivationResult != 0)
throw ExternalException (SRC_POS, options->VolumeHeaderKdf->GetDerivationFailureMessage (derivationResult));
headerOptions.HeaderKey = HeaderKey;
header->Create (headerBuffer, headerOptions);

View File

@@ -97,7 +97,7 @@ BEGIN
RTEXT "Password:",IDT_PASSWORD,0,10,65,13
RTEXT "KDF:",IDT_KDF,0,27,65,13
RTEXT "Volume PIM:",IDT_PIM,0,46,65,13,NOT WS_VISIBLE
LTEXT "(Empty or 0 for default iterations)",IDC_PIM_HELP,115,46,189,8,NOT WS_VISIBLE
LTEXT "(Empty or 0 for defaults)",IDC_PIM_HELP,115,46,189,8,NOT WS_VISIBLE
END
IDD_EXPAND_PROGRESS_DLG DIALOGEX 0, 0, 376, 283

View File

@@ -230,7 +230,7 @@ BEGIN
EDITTEXT IDC_PASSWORD_DIRECT,75,2,198,14,ES_PASSWORD | ES_AUTOHSCROLL
COMBOBOX IDC_PKCS5_PRF_ID,75,17,131,90,CBS_DROPDOWNLIST | WS_TABSTOP
EDITTEXT IDC_PIM,75,32,42,14,ES_RIGHT | ES_PASSWORD | ES_AUTOHSCROLL | ES_NUMBER | NOT WS_VISIBLE
LTEXT "(Empty or 0 for default iterations)",IDC_PIM_HELP,121,34,152,8,NOT WS_VISIBLE
LTEXT "(Empty or 0 for defaults)",IDC_PIM_HELP,121,34,152,8,NOT WS_VISIBLE
CONTROL "&Display password",IDC_SHOW_PASSWORD_SINGLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,75,46,109,11,WS_EX_TRANSPARENT
CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,75,57,106,11
PUSHBUTTON "&Keyfiles...",IDC_KEY_FILES,188,54,85,14
@@ -449,7 +449,7 @@ BEGIN
CONTROL "Display PIM",IDC_SHOW_PIM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,74,17,196,10
LTEXT "",IDC_BOX_HELP,0,32,273,142
RTEXT "Volume PIM:",IDT_PIM,1,3,69,8
LTEXT "(Empty or 0 for default iterations)",IDC_PIM_HELP,120,3,153,8
LTEXT "(Empty or 0 for defaults)",IDC_PIM_HELP,120,3,153,8
LTEXT "Information on PIM",IDC_LINK_PIM_INFO,0,179,273,8,SS_NOTIFY
END

View File

@@ -792,6 +792,22 @@ static BOOL CreatingHiddenSysVol (void)
&& bHiddenVol && !bHiddenVolHost);
}
static const char *GetPimHelpStringId (int pkcs5Prf, BOOL systemEncryption)
{
#if !defined (WOLFCRYPT_BACKEND) && !defined (VC_DCS_DISABLE_ARGON2)
if (pkcs5Prf == ARGON2)
return "PIM_ARGON2_HELP";
#endif
#ifndef WOLFCRYPT_BACKEND
if (systemEncryption && pkcs5Prf != SHA512 && pkcs5Prf != WHIRLPOOL)
return "PIM_SYSENC_HELP";
#else
if (systemEncryption && pkcs5Prf != SHA512)
return "PIM_SYSENC_HELP";
#endif
return "PIM_HELP";
}
static void LoadSettingsAndCheckModified (HWND hwndDlg, BOOL bOnlyCheckModified, BOOL* pbSettingsModified, BOOL* pbHistoryModified)
{
if (!bOnlyCheckModified)
@@ -4500,11 +4516,7 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
}
SetFocus (GetDlgItem (hwndDlg, IDC_PIM));
#ifndef WOLFCRYPT_BACKEND
SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (SysEncInEffect () && hash_algo != SHA512 && hash_algo != WHIRLPOOL? "PIM_SYSENC_HELP" : "PIM_HELP"));
#else
SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (SysEncInEffect () && hash_algo != SHA512? "PIM_SYSENC_HELP" : "PIM_HELP"));
#endif
SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (GetPimHelpStringId (hash_algo, SysEncInEffect ())));
ToHyperlink (hwndDlg, IDC_LINK_PIM_INFO);
if (CreatingHiddenSysVol())

View File

@@ -205,7 +205,7 @@ static int CreateVolumeInternal(const VeraCryptFormatOptions* options)
if (options->password)
{
if (!CheckPasswordLength(NULL, (int)strlen(options->password), options->pim, FALSE, 0, TRUE, TRUE))
if (!CheckPasswordLength(NULL, (int)strlen(options->password), options->pim, FALSE, hash_algo, TRUE, TRUE))
{
return VCF_ERROR_PASSWORD_POLICY;
}

View File

@@ -66,7 +66,7 @@ typedef struct _VeraCryptFormatOptions
/** The encryption algorithm to use. E.g., L"AES", L"Serpent", L"Twofish", L"AES-Twofish-Serpent". */
const wchar_t* encryptionAlgorithm;
/** The header key derivation and random pool hash algorithm. E.g., L"SHA-512", L"RIPEMD-160", L"Whirlpool", L"BLAKE2s-256", L"SHA-256". */
/** The header key derivation algorithm and random pool hash selector. E.g., L"Argon2" (Argon2id KDF), L"SHA-512", L"RIPEMD-160", L"Whirlpool", L"BLAKE2s-256", L"SHA-256". */
const wchar_t* hashAlgorithm;
/** The filesystem for the new volume. E.g., L"NTFS", L"FAT", L"ExFAT", L"ReFS", or L"None". */

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;

View File

@@ -2919,6 +2919,7 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
&& pwdChangeDlgMode == PCDM_CHANGE_PASSWORD)
{
int bootPRF = pkcs5;
int pimValidationValue = pim;
if (bSysEncPwdChangeDlgMode)
{
try
@@ -2930,7 +2931,17 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
catch(...)
{}
}
if (!CheckPasswordLength (hwndDlg, GetWindowTextLength(GetDlgItem (hwndDlg, IDC_PASSWORD)), pim, bSysEncPwdChangeDlgMode, bootPRF, FALSE, FALSE))
else if (bootPRF == 0)
{
bootPRF = old_pkcs5;
if (bootPRF == 0)
{
/* Both current and new KDFs are autodetected. ChangePwd() repeats this
PIM/password-length validation after opening the header with the detected KDF. */
pimValidationValue = 0;
}
}
if (!CheckPasswordLength (hwndDlg, GetWindowTextLength(GetDlgItem (hwndDlg, IDC_PASSWORD)), pimValidationValue, bSysEncPwdChangeDlgMode, bootPRF, FALSE, FALSE))
return 1;
}

View File

@@ -172,9 +172,9 @@ BEGIN
RTEXT "Wipe mode:",IDT_WIPE_MODE,9,220,74,8,0,WS_EX_RIGHT
RTEXT "KDF:",IDT_KDF,12,34,74,10,SS_CENTERIMAGE
RTEXT "Volume PIM:",IDT_OLD_PIM,12,54,74,10,NOT WS_VISIBLE
LTEXT "(Empty or 0 for default iterations)",IDC_OLD_PIM_HELP,135,54,196,8,NOT WS_VISIBLE
LTEXT "(Empty or 0 for defaults)",IDC_OLD_PIM_HELP,135,54,196,8,NOT WS_VISIBLE
RTEXT "Volume PIM:",IDT_PIM,9,157,75,16,NOT WS_VISIBLE
LTEXT "(Empty or 0 for default iterations)",IDC_PIM_HELP,135,157,197,8,NOT WS_VISIBLE
LTEXT "(Empty or 0 for defaults)",IDC_PIM_HELP,135,157,197,8,NOT WS_VISIBLE
END
IDD_MOUNT_DLG DIALOGEX 0, 0, 375, 271
@@ -222,7 +222,7 @@ BEGIN
CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,70,87,99,11
PUSHBUTTON "&Keyfiles...",IDC_KEY_FILES,173,84,75,14
PUSHBUTTON "Mount Opti&ons...",IDC_MOUNT_OPTIONS,252,84,69,14
LTEXT "(Empty or 0 for default iterations)",IDC_PIM_HELP,115,46,199,8,NOT WS_VISIBLE
LTEXT "(Empty or 0 for defaults)",IDC_PIM_HELP,115,46,199,8,NOT WS_VISIBLE
DEFPUSHBUTTON "OK",IDOK,252,8,69,14
PUSHBUTTON "Cancel",IDCANCEL,252,25,69,14
RTEXT "Password:",IDT_PASSWORD,0,10,65,13
@@ -413,7 +413,7 @@ BEGIN
LTEXT "Label of selected favorite volume:",IDT_FAVORITE_LABEL,18,215,202,8
GROUPBOX "Global Settings",IDC_FAV_VOL_OPTIONS_GLOBAL_SETTINGS_BOX,7,300,366,42
EDITTEXT IDC_PIM,87,183,42,13,ES_RIGHT | ES_PASSWORD | ES_AUTOHSCROLL | ES_NUMBER
LTEXT "(Empty or 0 for default iterations)",IDC_PIM_HELP,135,186,189,8
LTEXT "(Empty or 0 for defaults)",IDC_PIM_HELP,135,186,189,8
LTEXT "Volume PIM:",IDT_PIM,18,185,65,8
CONTROL "Display PIM",IDC_SHOW_PIM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,200,150,10
CONTROL "Use favorite label as Explorer drive label",IDC_FAVORITE_USE_LABEL_IN_EXPLORER,

View File

@@ -21,9 +21,47 @@
#endif
#include "EncryptionTest.h"
#include "Pkcs5Kdf.h"
#include "VolumeHeader.h"
namespace VeraCrypt
{
#if !defined (WOLFCRYPT_BACKEND) && !defined (VC_DCS_DISABLE_ARGON2)
class FailingArgon2Kdf : public Pkcs5Kdf
{
public:
FailingArgon2Kdf () : Pkcs5Kdf() { }
virtual ~FailingArgon2Kdf () { }
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const
{
(void) key;
(void) password;
(void) pim;
(void) salt;
return 1;
}
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{
(void) key;
(void) password;
(void) salt;
(void) iterationCount;
return 1;
}
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Blake2b); }
virtual int GetIterationCount (int pim) const { return 1; }
virtual wstring GetName () const { return L"Argon2"; }
virtual Pkcs5Kdf* Clone () const { return new FailingArgon2Kdf(); }
virtual bool IsArgon2 () const { return true; }
private:
FailingArgon2Kdf (const FailingArgon2Kdf &);
FailingArgon2Kdf &operator= (const FailingArgon2Kdf &);
};
#endif
void EncryptionTest::TestAll ()
{
TestAll (false);
@@ -1127,37 +1165,131 @@ namespace VeraCrypt
#ifndef WOLFCRYPT_BACKEND
Pkcs5HmacBlake2s pkcs5HmacBlake2s;
pkcs5HmacBlake2s.DeriveKey (derivedKey, password, salt, 5);
if (pkcs5HmacBlake2s.DeriveKey (derivedKey, password, salt, 5) != 0)
throw TestFailed (SRC_POS);
if (memcmp (derivedKey.Ptr(), "\x8d\x51\xfa\x31", 4) != 0)
throw TestFailed (SRC_POS);
Pkcs5HmacSha512 pkcs5HmacSha512;
pkcs5HmacSha512.DeriveKey (derivedKey, password, salt, 5);
if (pkcs5HmacSha512.DeriveKey (derivedKey, password, salt, 5) != 0)
throw TestFailed (SRC_POS);
if (memcmp (derivedKey.Ptr(), "\x13\x64\xae\xf8", 4) != 0)
throw TestFailed (SRC_POS);
Pkcs5HmacWhirlpool pkcs5HmacWhirlpool;
pkcs5HmacWhirlpool.DeriveKey (derivedKey, password, salt, 5);
if (pkcs5HmacWhirlpool.DeriveKey (derivedKey, password, salt, 5) != 0)
throw TestFailed (SRC_POS);
if (memcmp (derivedKey.Ptr(), "\x50\x7c\x36\x6f", 4) != 0)
throw TestFailed (SRC_POS);
Pkcs5HmacSha256 pkcs5HmacSha256;
pkcs5HmacSha256.DeriveKey (derivedKey, password, salt, 5);
if (pkcs5HmacSha256.DeriveKey (derivedKey, password, salt, 5) != 0)
throw TestFailed (SRC_POS);
if (memcmp (derivedKey.Ptr(), "\xf2\xa0\x4f\xb2", 4) != 0)
throw TestFailed (SRC_POS);
Pkcs5HmacStreebog pkcs5HmacStreebog;
pkcs5HmacStreebog.DeriveKey (derivedKey, password, salt, 5);
if (pkcs5HmacStreebog.DeriveKey (derivedKey, password, salt, 5) != 0)
throw TestFailed (SRC_POS);
if (memcmp (derivedKey.Ptr(), "\xd0\x53\xa2\x30", 4) != 0)
throw TestFailed (SRC_POS);
#ifndef VC_DCS_DISABLE_ARGON2
Pkcs5Argon2 pkcs5Argon2;
static const uint8 argon2SaltData[] = { 's', 'o', 'm', 'e', 's', 'a', 'l', 't' };
static const uint8 argon2Pim1DerivedKey[] =
{
0x9e, 0x87, 0x89, 0xc8, 0xb4, 0x28, 0x34, 0x22,
0x0a, 0xfc, 0x00, 0x08, 0x5a, 0xc7, 0x3a, 0xcc,
0x30, 0x86, 0x51, 0x21, 0x69, 0x94, 0xab, 0xbf,
0xdd, 0xd6, 0x9b, 0x25, 0x92, 0x03, 0x2e, 0xfd
};
ConstBufferPtr argon2Salt (argon2SaltData, sizeof (argon2SaltData));
Buffer argon2DerivedKey (sizeof (argon2Pim1DerivedKey));
// PIM 1 maps to Argon2id t=3, m=64 MiB, p=1.
if (pkcs5Argon2.DeriveKey (argon2DerivedKey, password, 1, argon2Salt) != 0)
throw TestFailed (SRC_POS);
if (memcmp (argon2DerivedKey.Ptr(), argon2Pim1DerivedKey, sizeof (argon2Pim1DerivedKey)) != 0)
throw TestFailed (SRC_POS);
try
{
if (pkcs5Argon2.DeriveKey (derivedKey, password, salt, 5) != 0)
throw TestFailed (SRC_POS);
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect&)
{
}
shared_ptr <Pkcs5Kdf> sha512Kdf (new Pkcs5HmacSha512);
shared_ptr <Pkcs5Kdf> failingArgon2Kdf (new FailingArgon2Kdf);
shared_ptr <EncryptionAlgorithm> ea (new AES);
SecureBuffer headerBuffer (TC_VOLUME_HEADER_SIZE);
SecureBuffer dataKey (ea->GetKeySize() * 2);
SecureBuffer headerSalt (VolumeHeader::GetSaltSize());
SecureBuffer headerKey (VolumeHeader::GetLargestSerializedKeySize());
for (size_t i = 0; i < dataKey.Size(); ++i)
dataKey.Ptr()[i] = (uint8) (i + 1);
for (size_t i = 0; i < headerSalt.Size(); ++i)
headerSalt.Ptr()[i] = (uint8) (i + 2);
if (sha512Kdf->DeriveKey (headerKey, password, 1, headerSalt) != 0)
throw TestFailed (SRC_POS);
VolumeHeaderCreationOptions options;
options.DataKey = dataKey;
options.EA = ea;
options.Kdf = sha512Kdf;
options.HeaderKey = headerKey;
options.Salt = headerSalt;
options.SectorSize = TC_SECTOR_SIZE_FILE_HOSTED_VOLUME;
options.VolumeDataStart = TC_VOLUME_HEADER_GROUP_SIZE;
options.VolumeDataSize = TC_MIN_VOLUME_SIZE;
options.Type = VolumeType::Normal;
VolumeHeader header (TC_VOLUME_HEADER_SIZE);
header.Create (headerBuffer, options);
Pkcs5KdfList kdfs;
kdfs.push_back (failingArgon2Kdf);
kdfs.push_back (sha512Kdf);
EncryptionAlgorithmList encryptionAlgorithms;
encryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AES));
EncryptionModeList encryptionModes;
encryptionModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS));
VolumeHeader decryptedHeader (TC_VOLUME_HEADER_SIZE);
if (!decryptedHeader.Decrypt (headerBuffer, password, 1, shared_ptr <Pkcs5Kdf> (), kdfs, encryptionAlgorithms, encryptionModes)
|| decryptedHeader.GetPkcs5Kdf()->GetName() != sha512Kdf->GetName())
{
throw TestFailed (SRC_POS);
}
try
{
decryptedHeader.Decrypt (headerBuffer, password, 1, failingArgon2Kdf, kdfs, encryptionAlgorithms, encryptionModes);
throw TestFailed (SRC_POS);
}
catch (ExternalException&)
{
}
#endif
#else
Pkcs5HmacSha256 pkcs5HmacSha256;
pkcs5HmacSha256.DeriveKey (derivedKey, password, salt, 5);
if (pkcs5HmacSha256.DeriveKey (derivedKey, password, salt, 5) != 0)
throw TestFailed (SRC_POS);
if (memcmp (derivedKey.Ptr(), "\x64\xf3\xa5\xa3", 4) != 0)
throw TestFailed (SRC_POS);
Pkcs5HmacSha512 pkcs5HmacSha512;
pkcs5HmacSha512.DeriveKey (derivedKey, password, salt, 5);
if (pkcs5HmacSha512.DeriveKey (derivedKey, password, salt, 5) != 0)
throw TestFailed (SRC_POS);
if (memcmp (derivedKey.Ptr(), "\x55\xa1\x76\xbb", 4) != 0)
throw TestFailed (SRC_POS);
#endif

View File

@@ -11,8 +11,12 @@
*/
#include "Common/Pkcs5.h"
#include "Platform/StringConverter.h"
#include "Pkcs5Kdf.h"
#include "VolumePassword.h"
#if !defined (WOLFCRYPT_BACKEND) && !defined (VC_DCS_DISABLE_ARGON2)
#include "argon2.h"
#endif
namespace VeraCrypt
{
@@ -24,16 +28,22 @@ namespace VeraCrypt
{
}
void Pkcs5Kdf::DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const
int Pkcs5Kdf::DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const
{
DeriveKey (key, password, salt, GetIterationCount(pim));
return DeriveKey (key, password, salt, GetIterationCount(pim));
}
wstring Pkcs5Kdf::GetDerivationFailureMessage (int result) const
{
(void) result;
return L"Key derivation failed";
}
shared_ptr <Pkcs5Kdf> Pkcs5Kdf::GetAlgorithm (const wstring &name)
{
foreach (shared_ptr <Pkcs5Kdf> kdf, GetAvailableAlgorithms())
{
if (kdf->GetName() == name)
if (kdf->GetName() == name || (kdf->IsArgon2() && name == L"Argon2id"))
return kdf;
}
throw ParameterIncorrect (SRC_POS);
@@ -43,6 +53,9 @@ namespace VeraCrypt
{
foreach (shared_ptr <Pkcs5Kdf> kdf, GetAvailableAlgorithms())
{
if (kdf->IsArgon2())
continue;
if (typeid (*kdf->GetHash()) == typeid (hash))
return kdf;
}
@@ -60,6 +73,9 @@ namespace VeraCrypt
l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5HmacBlake2s ()));
l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5HmacWhirlpool ()));
l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5HmacStreebog ()));
#ifndef VC_DCS_DISABLE_ARGON2
l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5Argon2 ()));
#endif
#endif
return l;
}
@@ -71,54 +87,96 @@ namespace VeraCrypt
}
#ifndef WOLFCRYPT_BACKEND
void Pkcs5HmacBlake2s_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
int Pkcs5HmacBlake2s_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{
ValidateParameters (key, password, salt, iterationCount);
derive_key_blake2s (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
return 0;
}
void Pkcs5HmacBlake2s::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
int Pkcs5HmacBlake2s::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{
ValidateParameters (key, password, salt, iterationCount);
derive_key_blake2s (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
return 0;
}
#endif
void Pkcs5HmacSha256_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
int Pkcs5HmacSha256_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{
ValidateParameters (key, password, salt, iterationCount);
derive_key_sha256 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
return 0;
}
void Pkcs5HmacSha256::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
int Pkcs5HmacSha256::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{
ValidateParameters (key, password, salt, iterationCount);
derive_key_sha256 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
return 0;
}
void Pkcs5HmacSha512::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
int Pkcs5HmacSha512::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{
ValidateParameters (key, password, salt, iterationCount);
derive_key_sha512 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
return 0;
}
#ifndef WOLFCRYPT_BACKEND
void Pkcs5HmacWhirlpool::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
int Pkcs5HmacWhirlpool::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{
ValidateParameters (key, password, salt, iterationCount);
derive_key_whirlpool (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
return 0;
}
void Pkcs5HmacStreebog::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
int Pkcs5HmacStreebog::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{
ValidateParameters (key, password, salt, iterationCount);
derive_key_streebog (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
return 0;
}
#ifndef VC_DCS_DISABLE_ARGON2
int Pkcs5Argon2::DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const
{
int iterationCount;
int memoryCost;
get_argon2_params (pim, &iterationCount, &memoryCost);
ValidateParameters (key, password, salt, iterationCount);
return derive_key_argon2 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, memoryCost, key.Get(), (int) key.Size(), NULL);
}
int Pkcs5Argon2::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{
(void) key;
(void) password;
(void) salt;
(void) iterationCount;
throw ParameterIncorrect (SRC_POS);
}
wstring Pkcs5Argon2::GetDerivationFailureMessage (int result) const
{
return L"Argon2 key derivation failed: " + StringConverter::ToWide (argon2_error_message (result));
}
int Pkcs5Argon2::GetIterationCount (int pim) const
{
int iterationCount;
int memoryCost;
get_argon2_params (pim, &iterationCount, &memoryCost);
return iterationCount;
}
#endif
void Pkcs5HmacStreebog_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
int Pkcs5HmacStreebog_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{
ValidateParameters (key, password, salt, iterationCount);
derive_key_streebog (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
return 0;
}
#endif
}

View File

@@ -27,15 +27,22 @@ namespace VeraCrypt
public:
virtual ~Pkcs5Kdf ();
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const;
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const = 0;
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const;
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const = 0;
static shared_ptr <Pkcs5Kdf> GetAlgorithm (const wstring &name);
static shared_ptr <Pkcs5Kdf> GetAlgorithm (const Hash &hash);
static Pkcs5KdfList GetAvailableAlgorithms ();
virtual shared_ptr <Hash> GetHash () const = 0;
virtual wstring GetDerivationFailureMessage (int result) const;
virtual int GetDefaultPim () const { return 485; }
virtual const char *GetPimHelpMessageId () const { return "PIM_HELP"; }
virtual const char *GetPimLargeWarningMessageId () const { return "PIM_LARGE_WARNING"; }
virtual const char *GetPimSmallWarningMessageId () const { return "PIM_SMALL_WARNING"; }
virtual const char *GetPimRequireLongPasswordMessageId () const { return "PIM_REQUIRE_LONG_PASSWORD"; }
virtual int GetIterationCount (int pim) const = 0;
virtual wstring GetName () const = 0;
virtual Pkcs5Kdf* Clone () const = 0;
virtual bool IsArgon2 () const { return false; }
virtual bool IsDeprecated () const { return GetHash()->IsDeprecated(); }
protected:
@@ -55,8 +62,9 @@ namespace VeraCrypt
Pkcs5HmacBlake2s_Boot () : Pkcs5Kdf() { }
virtual ~Pkcs5HmacBlake2s_Boot () { }
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Blake2s); }
virtual int GetDefaultPim () const { return 98; }
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 200000 : (pim * 2048); }
virtual wstring GetName () const { return L"HMAC-BLAKE2s-256"; }
virtual Pkcs5Kdf* Clone () const { return new Pkcs5HmacBlake2s_Boot(); }
@@ -72,7 +80,7 @@ namespace VeraCrypt
Pkcs5HmacBlake2s () : Pkcs5Kdf() { }
virtual ~Pkcs5HmacBlake2s () { }
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Blake2s); }
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 500000 : (15000 + (pim * 1000)); }
virtual wstring GetName () const { return L"HMAC-BLAKE2s-256"; }
@@ -90,8 +98,9 @@ namespace VeraCrypt
Pkcs5HmacSha256_Boot () : Pkcs5Kdf() { }
virtual ~Pkcs5HmacSha256_Boot () { }
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Sha256); }
virtual int GetDefaultPim () const { return 98; }
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 200000 : (pim * 2048); }
virtual wstring GetName () const { return L"HMAC-SHA-256"; }
virtual Pkcs5Kdf* Clone () const { return new Pkcs5HmacSha256_Boot(); }
@@ -107,7 +116,7 @@ namespace VeraCrypt
Pkcs5HmacSha256 () : Pkcs5Kdf() { }
virtual ~Pkcs5HmacSha256 () { }
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Sha256); }
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 500000 : (15000 + (pim * 1000)); }
virtual wstring GetName () const { return L"HMAC-SHA-256"; }
@@ -124,7 +133,7 @@ namespace VeraCrypt
Pkcs5HmacSha512 () : Pkcs5Kdf() { }
virtual ~Pkcs5HmacSha512 () { }
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Sha512); }
virtual int GetIterationCount (int pim) const { return (pim <= 0 ? 500000 : (15000 + (pim * 1000))); }
virtual wstring GetName () const { return L"HMAC-SHA-512"; }
@@ -141,7 +150,7 @@ namespace VeraCrypt
Pkcs5HmacWhirlpool () : Pkcs5Kdf() { }
virtual ~Pkcs5HmacWhirlpool () { }
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Whirlpool); }
virtual int GetIterationCount (int pim) const { return (pim <= 0 ? 500000 : (15000 + (pim * 1000))); }
virtual wstring GetName () const { return L"HMAC-Whirlpool"; }
@@ -158,7 +167,7 @@ namespace VeraCrypt
Pkcs5HmacStreebog () : Pkcs5Kdf() { }
virtual ~Pkcs5HmacStreebog () { }
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Streebog); }
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 500000 : (15000 + (pim * 1000)); }
virtual wstring GetName () const { return L"HMAC-Streebog"; }
@@ -168,6 +177,33 @@ namespace VeraCrypt
Pkcs5HmacStreebog (const Pkcs5HmacStreebog &);
Pkcs5HmacStreebog &operator= (const Pkcs5HmacStreebog &);
};
#ifndef VC_DCS_DISABLE_ARGON2
class Pkcs5Argon2 : public Pkcs5Kdf
{
public:
Pkcs5Argon2 () : Pkcs5Kdf() { }
virtual ~Pkcs5Argon2 () { }
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const;
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual wstring GetDerivationFailureMessage (int result) const;
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Blake2b); }
virtual int GetDefaultPim () const { return 12; }
virtual const char *GetPimHelpMessageId () const { return "PIM_ARGON2_HELP"; }
virtual const char *GetPimLargeWarningMessageId () const { return "PIM_ARGON2_LARGE_WARNING"; }
virtual const char *GetPimSmallWarningMessageId () const { return "PIM_ARGON2_SMALL_WARNING"; }
virtual const char *GetPimRequireLongPasswordMessageId () const { return "PIM_ARGON2_REQUIRE_LONG_PASSWORD"; }
virtual int GetIterationCount (int pim) const;
virtual wstring GetName () const { return L"Argon2"; }
virtual Pkcs5Kdf* Clone () const { return new Pkcs5Argon2(); }
virtual bool IsArgon2 () const { return true; }
private:
Pkcs5Argon2 (const Pkcs5Argon2 &);
Pkcs5Argon2 &operator= (const Pkcs5Argon2 &);
};
#endif
class Pkcs5HmacStreebog_Boot : public Pkcs5Kdf
{
@@ -175,8 +211,9 @@ namespace VeraCrypt
Pkcs5HmacStreebog_Boot () : Pkcs5Kdf() { }
virtual ~Pkcs5HmacStreebog_Boot () { }
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Streebog); }
virtual int GetDefaultPim () const { return 98; }
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 200000 : pim * 2048; }
virtual wstring GetName () const { return L"HMAC-Streebog"; }
virtual Pkcs5Kdf* Clone () const { return new Pkcs5HmacStreebog_Boot(); }

View File

@@ -107,7 +107,14 @@ namespace VeraCrypt
if (kdf && (kdf->GetName() != pkcs5->GetName()))
continue;
pkcs5->DeriveKey (headerKey, password, pim, salt);
int derivationResult = pkcs5->DeriveKey (headerKey, password, pim, salt);
if (derivationResult != 0)
{
if (!kdf)
continue;
throw ExternalException (SRC_POS, pkcs5->GetDerivationFailureMessage (derivationResult));
}
foreach (shared_ptr <EncryptionMode> mode, encryptionModes)
{

View File

@@ -18,6 +18,7 @@ namespace VeraCrypt
{
const size_t VolumePassword::MaxLegacySize = 64;
const size_t VolumePassword::MaxSize = 128;
const size_t VolumePassword::SmallPimPasswordSizeThreshold = 20;
const size_t VolumePassword::WarningSizeThreshold = 12;
VolumePassword::VolumePassword () : PasswordSize (0)

View File

@@ -43,6 +43,7 @@ namespace VeraCrypt
static const size_t MaxLegacySize;
static const size_t MaxSize;
static const size_t SmallPimPasswordSizeThreshold;
static const size_t WarningSizeThreshold;
protected: