diff options
-rw-r--r-- | src/Common/BootEncryption.cpp | 4 | ||||
-rw-r--r-- | src/Common/Crypto.c | 5 | ||||
-rw-r--r-- | src/Common/Crypto.h | 1 | ||||
-rw-r--r-- | src/Common/Dlgcode.c | 8 | ||||
-rw-r--r-- | src/Common/Pkcs5.c | 91 | ||||
-rw-r--r-- | src/Common/Random.c | 3 | ||||
-rw-r--r-- | src/Common/Volumes.c | 15 | ||||
-rw-r--r-- | src/Format/Tcformat.c | 4 | ||||
-rw-r--r-- | src/Mount/Mount.c | 4 |
9 files changed, 117 insertions, 18 deletions
diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp index c22e5526..5b11aa72 100644 --- a/src/Common/BootEncryption.cpp +++ b/src/Common/BootEncryption.cpp @@ -1741,6 +1741,10 @@ namespace VeraCrypt if (!bIsGPT && pkcs5_prf != BLAKE2S && pkcs5_prf != SHA256) throw ParameterIncorrect (SRC_POS); + // we don't support Argon2 for system encryption for now + if (pkcs5_prf == ARGON2) + throw ParameterIncorrect (SRC_POS); + int bootSectorId = 0; int bootLoaderId = 0; diff --git a/src/Common/Crypto.c b/src/Common/Crypto.c index 4ed60c03..aea52d42 100644 --- a/src/Common/Crypto.c +++ b/src/Common/Crypto.c @@ -822,6 +822,11 @@ BOOL HashForSystemEncryption (int hashId) } +BOOL HashIsAvailable (int hashId) +{ + return (hashId != ARGON2) && (HashGet(hashId) != 0); // Argon2 is not a hash function +} + // Returns the largest key size needed by an EA for the specified mode of operation int EAGetLargestKeyForMode (int mode) { diff --git a/src/Common/Crypto.h b/src/Common/Crypto.h index bb66e307..b558e983 100644 --- a/src/Common/Crypto.h +++ b/src/Common/Crypto.h @@ -378,6 +378,7 @@ Hash *HashGet (int id); void HashGetName2 (wchar_t *buf, size_t bufLen, int hashId); BOOL HashIsDeprecated (int hashId); BOOL HashForSystemEncryption (int hashId); +BOOL HashIsAvailable (int hashId); int GetMaxPkcs5OutSize (void); #endif diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index a6874e5f..05aa813a 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -6289,6 +6289,10 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg) { if (benchmarkPreBoot && !benchmarkGPT && !HashForSystemEncryption (thid)) continue; + + // we don't support Argon2 for system encryption + if (benchmarkPreBoot && thid == ARGON2) + continue; if (QueryPerformanceCounter (&performanceCountStart) == 0) goto counter_error; @@ -6800,7 +6804,7 @@ static BOOL CALLBACK RandomPoolEnrichementDlgProc (HWND hwndDlg, UINT msg, WPARA SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++) { - if (!HashIsDeprecated (hid)) + if (!HashIsDeprecated (hid) && HashIsAvailable (hid)) AddComboPair (hComboBox, HashGetName(hid), hid); } SelectAlgo (hComboBox, &hash_algo); @@ -6995,7 +6999,7 @@ BOOL CALLBACK KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++) { - if (!HashIsDeprecated (hid)) + if (!HashIsDeprecated (hid) && HashIsAvailable (hid)) AddComboPair (hComboBox, HashGetName(hid), hid); } SelectAlgo (hComboBox, &hash_algo); diff --git a/src/Common/Pkcs5.c b/src/Common/Pkcs5.c index 0369896c..25c65886 100644 --- a/src/Common/Pkcs5.c +++ b/src/Common/Pkcs5.c @@ -1349,6 +1349,9 @@ int is_pkcs5_prf_supported (int pkcs5_prf_id, PRF_BOOT_TYPE bootType) || (bootType != PRF_BOOT_MBR && (pkcs5_prf_id < FIRST_PRF_ID || pkcs5_prf_id > LAST_PRF_ID)) ) return 0; + // we don't support Argon2 in pre-boot authentication + if ((bootType == PRF_BOOT_MBR || bootType == PRF_BOOT_GPT) && pkcs5_prf_id == ARGON2) + return 0; return 1; @@ -1358,23 +1361,89 @@ void derive_key_argon2(char *pwd, int pwd_len, char *salt, int salt_len, uint32 { //TODO: Implement Argon2 derivation // In case of failure, just fill the derived key dk with zeroes + memset(dk, 0, dklen); } +/** + * get_argon2_params + * + * This function calculates the memory cost (in KiB) and time cost (iterations) for + * the Argon2id key derivation function based on the Personal Iteration Multiplier (PIM) value. + * + * Parameters: + * - pim: The Personal Iteration Multiplier (PIM), which controls the memory and time costs. + * If pim < 0, it is clamped to 0. + * If pim == 0, the default value of 12 is used. + * - pIterations: Pointer to an integer where the calculated time cost (iterations) will be stored. + * - pMemcost: Pointer to an integer where the calculated memory cost (in KiB) will be stored. + * + * Formulas: + * - Memory Cost (m_cost) in MiB: + * m_cost(pim) = min(64 MiB + (pim - 1) * 32 MiB, 1024 MiB) + * This formula increases the memory cost by 32 MiB for each increment of PIM, starting from 64 MiB. + * The memory cost is capped at 1024 MiB when PIM reaches 31 or higher. + * The result is converted to KiB before being stored in *pMemcost: + * *pMemcost = m_cost(pim) * 1024 + * + * - Time Cost (t_cost) in iterations: + * If PIM <= 31: + * t_cost(pim) = 3 + floor((pim - 1) / 3) + * If PIM > 31: + * t_cost(pim) = 13 + (pim - 31) + * This formula increases the time cost by 1 iteration for every 3 increments of PIM when PIM <= 31. + * For PIM > 31, the time cost increases by 1 iteration for each increment in PIM. + * The calculated time cost is stored in *pIterations. + * + * Example: + * - For PIM = 12: + * Memory Cost = 64 + (12 - 1) * 32 = 416 MiB (425,984 KiB) + * Time Cost = 3 + floor((12 - 1) / 3) = 6 iterations + * + * - For PIM = 31: + * Memory Cost = 64 + (31 - 1) * 32 = 1024 MiB (capped) + * Time Cost = 3 + floor((31 - 1) / 3) = 13 iterations + * + * - For PIM = 32: + * Memory Cost = 1024 MiB (capped) + * Time Cost = 13 + (32 - 31) = 14 iterations + * + */ 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; + // Ensure PIM is at least 0 + if (pim < 0) + { + pim = 0; + } + + // Default PIM value is 12 + // which leads to 416 MiB memory cost and 6 iterations + if (pim == 0) + { + pim = 12; } - *pIterations = iterations; - *pMemcost = memcost; + // Compute the memory cost (m_cost) in MiB + int m_cost_mib = 64 + (pim - 1) * 32; + + // Cap the memory cost at 1024 MiB + if (m_cost_mib > 1024) + { + m_cost_mib = 1024; + } + + // Convert memory cost to KiB for Argon2 + *pMemcost = m_cost_mib * 1024; // m_cost in KiB + + // Compute the time cost (t_cost) + if (pim <= 31) + { + *pIterations = 3 + ((pim - 1) / 3); + } + else + { + *pIterations = 13 + (pim - 31); + } } #endif //!TC_WINDOWS_BOOT diff --git a/src/Common/Random.c b/src/Common/Random.c index 1cfa6fcf..18292b31 100644 --- a/src/Common/Random.c +++ b/src/Common/Random.c @@ -364,7 +364,8 @@ BOOL Randmix () break; #ifndef WOLFCRYPT_BACKEND - case BLAKE2S: + case ARGON2: // in case of Argon2, we use Blake2s + case BLAKE2S: burn (&bctx, sizeof(bctx)); break; diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c index a57a8319..0551f0b9 100644 --- a/src/Common/Volumes.c +++ b/src/Common/Volumes.c @@ -308,6 +308,14 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int // if a PRF is specified, we skip all other PRFs if (selected_pkcs5_prf != 0 && enqPkcs5Prf != selected_pkcs5_prf) continue; + + // we don't support Argon2 in pre-boot authentication + if (bBoot && (enqPkcs5Prf == ARGON2)) + continue; + + // For now, we don't included Argon2 in automatic detection + if (selected_pkcs5_prf == 0 && enqPkcs5Prf == ARGON2) + continue; #if !defined(_UEFI) if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1)) @@ -923,6 +931,13 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, 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)); diff --git a/src/Format/Tcformat.c b/src/Format/Tcformat.c index 658d3797..3134c816 100644 --- a/src/Format/Tcformat.c +++ b/src/Format/Tcformat.c @@ -4195,7 +4195,7 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++) { - if ((!HashIsDeprecated (hid)) && (bSystemIsGPT || HashForSystemEncryption (hid))) + if ((!HashIsDeprecated (hid)) && (bSystemIsGPT || HashForSystemEncryption (hid)) && (hid != ARGON2)) // We don't support Argon2 for system encryption AddComboPair (GetDlgItem (hwndDlg, IDC_COMBO_BOX_HASH_ALGO), HashGetName(hid), hid); } } @@ -5988,7 +5988,7 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa { HWND hHashAlgoItem = GetDlgItem (hwndDlg, IDC_COMBO_BOX_HASH_ALGO); int selectedAlgo = (int) SendMessage (hHashAlgoItem, CB_GETITEMDATA, SendMessage (hHashAlgoItem, CB_GETCURSEL, 0, 0), 0); - if (!bSystemIsGPT && !HashForSystemEncryption(selectedAlgo)) + if ((!bSystemIsGPT && !HashForSystemEncryption(selectedAlgo)) || (selectedAlgo == ARGON2)) { hash_algo = DEFAULT_HASH_ALGORITHM_BOOT; RandSetHashFunction (DEFAULT_HASH_ALGORITHM_BOOT); diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index a851ebef..c2da8440 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -2749,7 +2749,7 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR int new_hash_algo_id = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0); - if (new_hash_algo_id != 0 && !bSystemIsGPT && !HashForSystemEncryption(new_hash_algo_id)) + if (new_hash_algo_id != 0 && (!bSystemIsGPT && !HashForSystemEncryption(new_hash_algo_id)) || (new_hash_algo_id == ARGON2)) { int new_hash_algo_id = DEFAULT_HASH_ALGORITHM_BOOT; Info ("ALGO_NOT_SUPPORTED_FOR_SYS_ENCRYPTION", hwndDlg); @@ -3094,7 +3094,7 @@ BOOL CALLBACK PasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++) { - if (bSystemIsGPT || HashForSystemEncryption(i)) + if ((bSystemIsGPT || HashForSystemEncryption(i)) && (i != ARGON2)) { nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i)); SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i); |