VeraCrypt
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Common/BootEncryption.cpp4
-rw-r--r--src/Common/Crypto.c5
-rw-r--r--src/Common/Crypto.h1
-rw-r--r--src/Common/Dlgcode.c8
-rw-r--r--src/Common/Pkcs5.c91
-rw-r--r--src/Common/Random.c3
-rw-r--r--src/Common/Volumes.c15
-rw-r--r--src/Format/Tcformat.c4
-rw-r--r--src/Mount/Mount.c4
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);