From 7735b983bf3794b033406a7bcbfb414faee86c09 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sat, 24 Aug 2024 11:26:55 +0200 Subject: Windows: Implement foundations for Argon2 support as a KDF in addition to PBKDF2 --- src/Common/BootEncryption.cpp | 2 ++ src/Common/Crypto.c | 1 + src/Common/Crypto.h | 3 +++ src/Common/Dlgcode.c | 37 ++++++++++++++++++++++++++++++------- src/Common/EncryptionThreadPool.c | 9 ++++++++- src/Common/EncryptionThreadPool.h | 2 +- src/Common/Language.xml | 1 + src/Common/Pkcs5.c | 38 +++++++++++++++++++++++++++++++++++++- src/Common/Pkcs5.h | 6 +++++- src/Common/Random.c | 6 ++++-- src/Common/Volumes.c | 36 ++++++++++++++++++++++++++++-------- 11 files changed, 120 insertions(+), 21 deletions(-) diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp index f79e7339..c22e5526 100644 --- a/src/Common/BootEncryption.cpp +++ b/src/Common/BootEncryption.cpp @@ -1707,6 +1707,8 @@ namespace VeraCrypt pkcs5_prf = WHIRLPOOL; else if (_stricmp(request.BootPrfAlgorithmName, "Streebog") == 0) pkcs5_prf = STREEBOG; + else if (_stricmp(request.BootPrfAlgorithmName, "Argon2") == 0) + pkcs5_prf = ARGON2; #endif else if (strlen(request.BootPrfAlgorithmName) == 0) // case of version < 1.0f pkcs5_prf = BLAKE2S; diff --git a/src/Common/Crypto.c b/src/Common/Crypto.c index 9c4ee5a3..4ed60c03 100644 --- a/src/Common/Crypto.c +++ b/src/Common/Crypto.c @@ -132,6 +132,7 @@ static Hash Hashes[] = { BLAKE2S, L"BLAKE2s-256", FALSE, TRUE }, { WHIRLPOOL, L"Whirlpool", FALSE, FALSE }, { STREEBOG, L"Streebog", FALSE, FALSE }, + { ARGON2, L"Argon2", FALSE, FALSE }, #endif { 0, 0, 0 } }; diff --git a/src/Common/Crypto.h b/src/Common/Crypto.h index 89d22f0e..bb66e307 100644 --- a/src/Common/Crypto.h +++ b/src/Common/Crypto.h @@ -55,6 +55,7 @@ enum SHA256, BLAKE2S, STREEBOG, + ARGON2, HASH_ENUM_END_ID }; @@ -226,6 +227,7 @@ typedef struct typedef struct keyInfo_t { int noIterations; /* Number of times to iterate (PKCS-5) */ + int memoryCost; /* Memory cost factor (PKCS-5) */ int keyLength; /* Length of the key */ uint64 dummy; /* Dummy field to ensure 16-byte alignment of this structure */ __int8 salt[PKCS5_SALT_SIZE]; /* PKCS-5 salt */ @@ -257,6 +259,7 @@ typedef struct CRYPTO_INFO_t #endif int noIterations; + int memoryCost; int volumePim; BOOL bProtectHiddenVolume; // Indicates whether the volume contains a hidden volume to be protected against overwriting diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index b91167d4..a6874e5f 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -367,6 +367,8 @@ typedef struct unsigned __int64 encSpeed; unsigned __int64 decSpeed; unsigned __int64 meanBytesPerSec; + unsigned __int64 iterations; + unsigned __int64 memoryCost; } BENCHMARK_REC; BENCHMARK_REC benchmarkTable [BENCHMARK_MAX_ITEMS]; @@ -6014,6 +6016,11 @@ static void ResetBenchmarkList (HWND hwndDlg) LvCol.cx = CompensateXDPI (80); LvCol.fmt = LVCFMT_RIGHT; SendMessageW (hList,LVM_INSERTCOLUMNW,2,(LPARAM)&LvCol); + + LvCol.pszText = GetString ("MEMORY_COST"); + LvCol.cx = CompensateXDPI (80); + LvCol.fmt = LVCFMT_RIGHT; + SendMessageW (hList,LVM_INSERTCOLUMNW,3,(LPARAM)&LvCol); break; } } @@ -6111,10 +6118,14 @@ static void DisplayBenchmarkResults (HWND hwndDlg) LvItem.iSubItem = 1; LvItem.pszText = item1; SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem); - swprintf_s (item1, sizeof(item1) / sizeof(item1[0]), L"%d", (int) benchmarkTable[i].decSpeed); + swprintf_s (item1, sizeof(item1) / sizeof(item1[0]), L"%d", (int) benchmarkTable[i].iterations); LvItem.iSubItem = 2; LvItem.pszText = item1; SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem); + swprintf_s (item1, sizeof(item1) / sizeof(item1[0]), L"%d", (int) benchmarkTable[i].memoryCost); + LvItem.iSubItem = 3; + LvItem.pszText = item1; + SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem); break; } } @@ -6203,6 +6214,9 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg) for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++) { + // Skip Argon2 since it is not a hash function + if (hid == ARGON2) + continue; if (QueryPerformanceCounter (&performanceCountStart) == 0) goto counter_error; @@ -6268,6 +6282,8 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg) int thid, i; char dk[MASTER_KEYDATA_SIZE]; char *tmp_salt = {"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF\x01\x23\x45\x67\x89\xAB\xCD\xEF\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF\x01\x23\x45\x67\x89\xAB\xCD\xEF\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"}; + int memoryCost = 0; + int iterations = 0; for (thid = FIRST_PRF_ID; thid <= LAST_PRF_ID; thid++) { @@ -6279,32 +6295,38 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg) for (i = 1; i <= 2; i++) { + iterations = get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot, &memoryCost); switch (thid) { case SHA512: /* PKCS-5 test with HMAC-SHA-512 used as the PRF */ - derive_key_sha512 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE); + derive_key_sha512 ("passphrase-1234567890", 21, tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE); break; case SHA256: /* PKCS-5 test with HMAC-SHA-256 used as the PRF */ - derive_key_sha256 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE); + derive_key_sha256 ("passphrase-1234567890", 21, tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE); break; #ifndef WOLFCRYPT_BACKEND case BLAKE2S: /* PKCS-5 test with HMAC-BLAKE2s used as the PRF */ - derive_key_blake2s ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE); + derive_key_blake2s ("passphrase-1234567890", 21, tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE); break; case WHIRLPOOL: /* PKCS-5 test with HMAC-Whirlpool used as the PRF */ - derive_key_whirlpool ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE); + derive_key_whirlpool ("passphrase-1234567890", 21, tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE); break; case STREEBOG: /* PKCS-5 test with HMAC-STREEBOG used as the PRF */ - derive_key_streebog("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE); + derive_key_streebog("passphrase-1234567890", 21, tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE); + break; + + case ARGON2: + /* test with ARGON2 used as the PRF */ + derive_key_argon2 ("passphrase-1234567890", 21, tmp_salt, 64, iterations, memoryCost, dk, MASTER_KEYDATA_SIZE); break; } #endif @@ -6315,7 +6337,8 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg) benchmarkTable[benchmarkTotalItems].encSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart; benchmarkTable[benchmarkTotalItems].id = thid; - benchmarkTable[benchmarkTotalItems].decSpeed = get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot); + benchmarkTable[benchmarkTotalItems].iterations = iterations; + benchmarkTable[benchmarkTotalItems].memoryCost = memoryCost; benchmarkTable[benchmarkTotalItems].meanBytesPerSec = (unsigned __int64) (1000 * ((float) benchmarkTable[benchmarkTotalItems].encSpeed / benchmarkPerformanceFrequency.QuadPart / 2)); if (benchmarkPreBoot) { diff --git a/src/Common/EncryptionThreadPool.c b/src/Common/EncryptionThreadPool.c index 79f1c890..a4be9a54 100644 --- a/src/Common/EncryptionThreadPool.c +++ b/src/Common/EncryptionThreadPool.c @@ -100,6 +100,7 @@ typedef struct EncryptionThreadPoolWorkItemStruct LONG *CompletionFlag; char *DerivedKey; int IterationCount; + int Memorycost; TC_EVENT *NoOutstandingWorkItemEvent; LONG *OutstandingWorkItemCount; char *Password; @@ -273,6 +274,11 @@ static TC_THREAD_PROC EncryptionThreadProc (void *threadArg) workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize()); break; + case ARGON2: + derive_key_argon2(workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE, + workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.Memorycost, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize()); + break; + default: TC_THROW_FATAL_EXCEPTION; } @@ -533,7 +539,7 @@ void EncryptionThreadPoolStop () } -void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, char *derivedKey) +void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, int memoryCost, char *derivedKey) { EncryptionThreadPoolWorkItem *workItem; @@ -556,6 +562,7 @@ void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT workItem->KeyDerivation.CompletionFlag = completionFlag; workItem->KeyDerivation.DerivedKey = derivedKey; workItem->KeyDerivation.IterationCount = iterationCount; + workItem->KeyDerivation.Memorycost = memoryCost; workItem->KeyDerivation.NoOutstandingWorkItemEvent = noOutstandingWorkItemEvent; workItem->KeyDerivation.OutstandingWorkItemCount = outstandingWorkItemCount; workItem->KeyDerivation.Password = password; diff --git a/src/Common/EncryptionThreadPool.h b/src/Common/EncryptionThreadPool.h index 71df4e4d..32354a66 100644 --- a/src/Common/EncryptionThreadPool.h +++ b/src/Common/EncryptionThreadPool.h @@ -32,7 +32,7 @@ typedef enum size_t GetCpuCount (WORD* pGroupCount); #endif -void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, char *derivedKey); +void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, int memoryCost, char *derivedKey); void EncryptionThreadPoolBeginReadVolumeHeaderFinalization (TC_EVENT *keyDerivationCompletedEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG* outstandingWorkItemCount, void* keyInfoBuffer, int keyInfoBufferSize, void* keyDerivationWorkItems, int keyDerivationWorkItemsSize); void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, uint8 *data, const UINT64_STRUCT *startUnitNo, uint32 unitCount, PCRYPTO_INFO cryptoInfo); BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount); diff --git a/src/Common/Language.xml b/src/Common/Language.xml index 9821bbe9..172179af 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -1641,6 +1641,7 @@ WARNING: The volume's master key is vulnerable to an attack that compromises data security.\n\nPlease create a new volume and transfer the data to it. WARNING: The encrypted system's master key is vulnerable to an attack that compromises data security.\nPlease decrypt the system partition/drive and then re-encrypt it. WARNING: The volume's master key has a security vulnerability. + Memory Cost diff --git a/src/Common/Pkcs5.c b/src/Common/Pkcs5.c index d81078e8..0369896c 100644 --- a/src/Common/Pkcs5.c +++ b/src/Common/Pkcs5.c @@ -1271,6 +1271,9 @@ wchar_t *get_pkcs5_prf_name (int pkcs5_prf_id) case STREEBOG: return L"HMAC-STREEBOG"; + case ARGON2: + return L"Argon2"; + default: return L"(Unknown)"; } @@ -1278,14 +1281,17 @@ wchar_t *get_pkcs5_prf_name (int pkcs5_prf_id) -int get_pkcs5_iteration_count (int pkcs5_prf_id, int pim, BOOL bBoot) +int get_pkcs5_iteration_count (int pkcs5_prf_id, int pim, BOOL bBoot, int* pMemoryCost) { if ( (pim < 0) ) { + *pMemoryCost = 0; return 0; } + *pMemoryCost = 0; + switch (pkcs5_prf_id) { @@ -1319,6 +1325,13 @@ int get_pkcs5_iteration_count (int pkcs5_prf_id, int pim, BOOL bBoot) return bBoot? pim * 2048 : 15000 + pim * 1000; } + case ARGON2: + { + int iterations; + get_argon2_params (pim, &iterations, pMemoryCost); + return iterations; + } + default: TC_THROW_FATAL_EXCEPTION; // Unknown/wrong ID } @@ -1341,4 +1354,27 @@ int is_pkcs5_prf_supported (int pkcs5_prf_id, PRF_BOOT_TYPE bootType) } +void derive_key_argon2(char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, uint32 memcost, char *dk, int dklen) +{ + //TODO: Implement Argon2 derivation + // In case of failure, just fill the derived key dk with zeroes +} + +void get_argon2_params(int pim, int* pIterations, int* pMemcost) +{ + int memcost = 16 * 1024 + pim * 512; + int iterations; + + if (memcost <= 64 * 1024) { + // For memory costs up to 64 MB + iterations = 100 - (pim * 85) / 96; + } else { + // For memory costs above 64 MB + iterations = 15 - ((pim - 96) * 10) / 192; + } + + *pIterations = iterations; + *pMemcost = memcost; +} + #endif //!TC_WINDOWS_BOOT diff --git a/src/Common/Pkcs5.h b/src/Common/Pkcs5.h index a9abeec5..ae04b92d 100644 --- a/src/Common/Pkcs5.h +++ b/src/Common/Pkcs5.h @@ -40,9 +40,13 @@ void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, uin void hmac_streebog (char *k, int32 lk, char *d, int32 ld); void derive_key_streebog (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen); -int get_pkcs5_iteration_count (int pkcs5_prf_id, int pim, BOOL bBoot); +int get_pkcs5_iteration_count (int pkcs5_prf_id, int pim, BOOL bBoot, int* pMemoryCost); wchar_t *get_pkcs5_prf_name (int pkcs5_prf_id); +void derive_key_argon2(char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, uint32 memcost, char *dk, int dklen); +void get_argon2_params(int pim, int* pIterations, int* pMemcost); + + /* check if given PRF supported.*/ typedef enum { diff --git a/src/Common/Random.c b/src/Common/Random.c index ee3fcf53..1cfa6fcf 100644 --- a/src/Common/Random.c +++ b/src/Common/Random.c @@ -282,7 +282,8 @@ BOOL Randmix () break; #ifndef WOLFCRYPT_BACKEND - case BLAKE2S: + case ARGON2: // in case of Argon2, we use Blake2s + case BLAKE2S: digestSize = BLAKE2S_DIGESTSIZE; break; @@ -319,7 +320,8 @@ BOOL Randmix () break; #ifndef WOLFCRYPT_BACKEND - case BLAKE2S: + case ARGON2: // in case of Argon2, we use Blake2s + case BLAKE2S: blake2s_init(&bctx); blake2s_update(&bctx, pRandPool, RNG_POOL_SIZE); blake2s_final(&bctx, hashOutputBuffer); diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c index 7ee519f6..a57a8319 100644 --- a/src/Common/Volumes.c +++ b/src/Common/Volumes.c @@ -192,6 +192,8 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int size_t encryptionThreadCount = GetEncryptionThreadCount(); LONG *outstandingWorkItemCount = NULL; int i; + int iterationsCount = 0; + int memoryCost = 0; #endif size_t queuedWorkItems = 0; @@ -322,9 +324,10 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int 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 +349,9 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int 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 +370,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) { @@ -380,21 +387,25 @@ KeyReady: ; break; #ifndef WOLFCRYPT_BACKEND - case BLAKE2S: + 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; + + 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 @@ -540,6 +551,7 @@ KeyReady: ; { cryptoInfo->pkcs5 = pkcs5_prf; cryptoInfo->noIterations = keyInfo->noIterations; + cryptoInfo->memoryCost = keyInfo->memoryCost; cryptoInfo->volumePim = pim; goto ret; } @@ -581,6 +593,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 @@ -962,12 +975,13 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, { 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 @@ -976,6 +990,7 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, // User selected PRF cryptoInfo->pkcs5 = pkcs5_prf; cryptoInfo->noIterations = keyInfo.noIterations; + cryptoInfo->memoryCost = keyInfo.memoryCost; cryptoInfo->volumePim = pim; // Mode of operation @@ -1023,6 +1038,11 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, 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 -- cgit v1.2.3