mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-05-21 21:30:48 -05: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>
|
||||
|
||||
+31
-7
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+7
-4
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
|
||||
+15
-10
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user