1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-11 11:08:02 -06:00

Windows: Add support for Argon2id as an alternative to PBKDF2 key derivation

This commit is contained in:
Mounir IDRASSI
2025-06-25 15:44:31 +09:00
parent 228129362a
commit 3c17b8ced2
35 changed files with 4609 additions and 72 deletions

View File

@@ -192,6 +192,8 @@ int ReadVolumeHeader (BOOL bBoot, unsigned char *encryptedHeader, Password *pass
size_t encryptionThreadCount = GetEncryptionThreadCount();
LONG *outstandingWorkItemCount = NULL;
int i;
int iterationsCount = 0;
int memoryCost = 0;
#endif
size_t queuedWorkItems = 0;
@@ -307,6 +309,10 @@ int ReadVolumeHeader (BOOL bBoot, unsigned char *encryptedHeader, Password *pass
if (selected_pkcs5_prf != 0 && enqPkcs5Prf != selected_pkcs5_prf)
continue;
// we don't support Argon2 in pre-boot authentication
if (bBoot && (enqPkcs5Prf == ARGON2))
continue;
#if !defined(_UEFI)
if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1))
{
@@ -322,9 +328,10 @@ int ReadVolumeHeader (BOOL bBoot, unsigned char *encryptedHeader, Password *pass
item->KeyReady = FALSE;
item->Pkcs5Prf = enqPkcs5Prf;
iterationsCount = get_pkcs5_iteration_count (enqPkcs5Prf, pim, bBoot, &memoryCost);
EncryptionThreadPoolBeginKeyDerivation (keyDerivationCompletedEvent, noOutstandingWorkItemEvent,
&item->KeyReady, outstandingWorkItemCount, enqPkcs5Prf, keyInfo->userKey,
keyInfo->keyLength, keyInfo->salt, get_pkcs5_iteration_count (enqPkcs5Prf, pim, bBoot), item->DerivedKey);
keyInfo->keyLength, keyInfo->salt, iterationsCount, memoryCost, item->DerivedKey);
++queuedWorkItems;
break;
@@ -346,7 +353,9 @@ int ReadVolumeHeader (BOOL bBoot, unsigned char *encryptedHeader, Password *pass
if (!item->Free && InterlockedExchangeAdd (&item->KeyReady, 0) == TRUE)
{
pkcs5_prf = item->Pkcs5Prf;
keyInfo->noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, bBoot);
iterationsCount = get_pkcs5_iteration_count (pkcs5_prf, pim, bBoot, &memoryCost);
keyInfo->noIterations = iterationsCount;
keyInfo->memoryCost = memoryCost;
memcpy (dk, item->DerivedKey, sizeof (dk));
item->Free = TRUE;
@@ -365,7 +374,9 @@ KeyReady: ;
#endif // !defined(_UEFI)
{
pkcs5_prf = enqPkcs5Prf;
keyInfo->noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, pim, bBoot);
iterationsCount = get_pkcs5_iteration_count (enqPkcs5Prf, pim, bBoot, &memoryCost);
keyInfo->noIterations = iterationsCount;
keyInfo->memoryCost = memoryCost;
switch (pkcs5_prf)
{
@@ -379,23 +390,29 @@ KeyReady: ;
PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize());
break;
#ifndef WOLFCRYPT_BACKEND
case BLAKE2S:
#ifndef WOLFCRYPT_BACKEND
case BLAKE2S:
derive_key_blake2s (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize());
break;
case WHIRLPOOL:
case WHIRLPOOL:
derive_key_whirlpool (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize());
break;
case STREEBOG:
case STREEBOG:
derive_key_streebog(keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize());
break;
#endif
case ARGON2:
derive_key_argon2(keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, keyInfo->memoryCost, dk, GetMaxPkcs5OutSize());
break;
#endif
default:
// Unknown/wrong ID
TC_THROW_FATAL_EXCEPTION;
@@ -540,6 +557,7 @@ KeyReady: ;
{
cryptoInfo->pkcs5 = pkcs5_prf;
cryptoInfo->noIterations = keyInfo->noIterations;
cryptoInfo->memoryCost = keyInfo->memoryCost;
cryptoInfo->volumePim = pim;
goto ret;
}
@@ -571,6 +589,7 @@ KeyReady: ;
// PKCS #5
cryptoInfo->pkcs5 = pkcs5_prf;
cryptoInfo->noIterations = keyInfo->noIterations;
cryptoInfo->memoryCost = keyInfo->memoryCost;
cryptoInfo->volumePim = pim;
// Init the cipher with the decrypted master key
@@ -900,6 +919,13 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, unsigned char *header,
if (pim < 0)
pim = 0;
// we don't support Argon2 in pre-boot authentication
if (bBoot && (pkcs5_prf == ARGON2))
{
crypto_close (cryptoInfo);
return ERR_PARAMETER_INCORRECT;
}
memset (header, 0, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
#if !defined(_UEFI)
VirtualLock (&keyInfo, sizeof (keyInfo));
@@ -952,12 +978,13 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, unsigned char *header,
{
memcpy (keyInfo.userKey, password->Text, nUserKeyLen);
keyInfo.keyLength = nUserKeyLen;
keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, bBoot);
keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, bBoot, &keyInfo.memoryCost);
}
else
{
keyInfo.keyLength = 0;
keyInfo.noIterations = 0;
keyInfo.memoryCost = 0;
}
// User selected encryption algorithm
@@ -966,6 +993,7 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, unsigned char *header,
// User selected PRF
cryptoInfo->pkcs5 = pkcs5_prf;
cryptoInfo->noIterations = keyInfo.noIterations;
cryptoInfo->memoryCost = keyInfo.memoryCost;
cryptoInfo->volumePim = pim;
// Mode of operation
@@ -1013,6 +1041,11 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, unsigned char *header,
derive_key_streebog(keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
break;
case ARGON2:
derive_key_argon2(keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, keyInfo.memoryCost, dk, GetMaxPkcs5OutSize());
break;
#endif
default:
// Unknown/wrong ID