mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-05-14 08:31:29 +00:00
Linux/macOS: Implement missing Argon2 KDF support on Unix
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -152,8 +152,8 @@
|
||||
<entry lang="en" key="IDC_MOUNT_OPTIONS">Mount Opti&ons...</entry>
|
||||
<entry lang="en" key="IDC_MOUNT_READONLY">Mount volume as read-&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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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". */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user