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

Windows: speedup PRF autodetection mode by implementing abort mechanism in PBKDF2/Argon2 primitives

This commit is contained in:
Mounir IDRASSI
2025-06-29 21:44:32 +09:00
parent 95659a8563
commit 9dc24ba7d0
21 changed files with 437 additions and 228 deletions

View File

@@ -6445,32 +6445,32 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg)
case SHA512: case SHA512:
/* PKCS-5 test with HMAC-SHA-512 used as the PRF */ /* PKCS-5 test with HMAC-SHA-512 used as the PRF */
derive_key_sha512 ((const unsigned char*) "passphrase-1234567890", 21, (const unsigned char*) tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE); derive_key_sha512 ((const unsigned char*) "passphrase-1234567890", 21, (const unsigned char*) tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE, NULL);
break; break;
case SHA256: case SHA256:
/* PKCS-5 test with HMAC-SHA-256 used as the PRF */ /* PKCS-5 test with HMAC-SHA-256 used as the PRF */
derive_key_sha256 ((const unsigned char*)"passphrase-1234567890", 21, (const unsigned char*)tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE); derive_key_sha256 ((const unsigned char*)"passphrase-1234567890", 21, (const unsigned char*)tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE, NULL);
break; break;
#ifndef WOLFCRYPT_BACKEND #ifndef WOLFCRYPT_BACKEND
case BLAKE2S: case BLAKE2S:
/* PKCS-5 test with HMAC-BLAKE2s used as the PRF */ /* PKCS-5 test with HMAC-BLAKE2s used as the PRF */
derive_key_blake2s ((const unsigned char*)"passphrase-1234567890", 21, (const unsigned char*)tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE); derive_key_blake2s ((const unsigned char*)"passphrase-1234567890", 21, (const unsigned char*)tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE, NULL);
break; break;
case WHIRLPOOL: case WHIRLPOOL:
/* PKCS-5 test with HMAC-Whirlpool used as the PRF */ /* PKCS-5 test with HMAC-Whirlpool used as the PRF */
derive_key_whirlpool ((const unsigned char*)"passphrase-1234567890", 21, (const unsigned char*)tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE); derive_key_whirlpool ((const unsigned char*)"passphrase-1234567890", 21, (const unsigned char*)tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE, NULL);
break; break;
case STREEBOG: case STREEBOG:
/* PKCS-5 test with HMAC-STREEBOG used as the PRF */ /* PKCS-5 test with HMAC-STREEBOG used as the PRF */
derive_key_streebog((const unsigned char*)"passphrase-1234567890", 21, (const unsigned char*)tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE); derive_key_streebog((const unsigned char*)"passphrase-1234567890", 21, (const unsigned char*)tmp_salt, 64, iterations, dk, MASTER_KEYDATA_SIZE, NULL);
break; break;
case ARGON2: case ARGON2:
/* test with ARGON2 used as the PRF */ /* test with ARGON2 used as the PRF */
derive_key_argon2 ((const unsigned char*) "passphrase-1234567890", 21, (const unsigned char*)tmp_salt, 64, iterations, memoryCost, dk, MASTER_KEYDATA_SIZE); derive_key_argon2 ((const unsigned char*) "passphrase-1234567890", 21, (const unsigned char*)tmp_salt, 64, iterations, memoryCost, dk, MASTER_KEYDATA_SIZE, NULL);
break; break;
} }
#endif #endif

View File

@@ -107,7 +107,7 @@ typedef struct EncryptionThreadPoolWorkItemStruct
int PasswordLength; int PasswordLength;
int Pkcs5Prf; int Pkcs5Prf;
unsigned char *Salt; unsigned char *Salt;
LONG volatile *pAbortKeyDerivation;
} KeyDerivation; } KeyDerivation;
struct struct
@@ -245,32 +245,32 @@ static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
{ {
case BLAKE2S: case BLAKE2S:
derive_key_blake2s (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE, derive_key_blake2s (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize()); workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize(), workItem->KeyDerivation.pAbortKeyDerivation);
break; break;
case SHA512: case SHA512:
derive_key_sha512 (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE, derive_key_sha512 (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize()); workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize(), workItem->KeyDerivation.pAbortKeyDerivation);
break; break;
case WHIRLPOOL: case WHIRLPOOL:
derive_key_whirlpool (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE, derive_key_whirlpool (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize()); workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize(), workItem->KeyDerivation.pAbortKeyDerivation);
break; break;
case SHA256: case SHA256:
derive_key_sha256 (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE, derive_key_sha256 (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize()); workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize(), workItem->KeyDerivation.pAbortKeyDerivation);
break; break;
case STREEBOG: case STREEBOG:
derive_key_streebog(workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE, derive_key_streebog(workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize()); workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize(), workItem->KeyDerivation.pAbortKeyDerivation);
break; break;
case ARGON2: case ARGON2:
derive_key_argon2(workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE, 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()); workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.Memorycost, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize(), workItem->KeyDerivation.pAbortKeyDerivation);
break; break;
default: default:
@@ -533,7 +533,7 @@ void EncryptionThreadPoolStop ()
} }
void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, unsigned char *password, int passwordLength, unsigned char *salt, int iterationCount, int memoryCost, unsigned char *derivedKey) void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, unsigned char *password, int passwordLength, unsigned char *salt, int iterationCount, int memoryCost, unsigned char *derivedKey, LONG volatile *pAbortKeyDerivation)
{ {
EncryptionThreadPoolWorkItem *workItem; EncryptionThreadPoolWorkItem *workItem;
@@ -563,6 +563,7 @@ void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT
workItem->KeyDerivation.PasswordLength = passwordLength; workItem->KeyDerivation.PasswordLength = passwordLength;
workItem->KeyDerivation.Pkcs5Prf = pkcs5Prf; workItem->KeyDerivation.Pkcs5Prf = pkcs5Prf;
workItem->KeyDerivation.Salt = salt; workItem->KeyDerivation.Salt = salt;
workItem->KeyDerivation.pAbortKeyDerivation = pAbortKeyDerivation;
InterlockedIncrement (outstandingWorkItemCount); InterlockedIncrement (outstandingWorkItemCount);
TC_CLEAR_EVENT (*noOutstandingWorkItemEvent); TC_CLEAR_EVENT (*noOutstandingWorkItemEvent);

View File

@@ -32,7 +32,7 @@ typedef enum
size_t GetCpuCount (WORD* pGroupCount); size_t GetCpuCount (WORD* pGroupCount);
#endif #endif
void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, unsigned char *password, int passwordLength, unsigned char *salt, int iterationCount, int memoryCost, unsigned char *derivedKey); void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, unsigned char *password, int passwordLength, unsigned char *salt, int iterationCount, int memoryCost, unsigned char *derivedKey, LONG volatile *pAbortKeyDerivation);
void EncryptionThreadPoolBeginReadVolumeHeaderFinalization (TC_EVENT *keyDerivationCompletedEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG* outstandingWorkItemCount, void* keyInfoBuffer, int keyInfoBufferSize, void* keyDerivationWorkItems, int keyDerivationWorkItemsSize); 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); void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, uint8 *data, const UINT64_STRUCT *startUnitNo, uint32 unitCount, PCRYPTO_INFO cryptoInfo);
BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount); BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount);

View File

@@ -145,7 +145,11 @@ void hmac_sha256
} }
#endif #endif
static void derive_u_sha256 (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_sha256_ctx* hmac) static void derive_u_sha256 (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_sha256_ctx* hmac
#ifndef TC_WINDOWS_BOOT
, long volatile *pAbortKeyDerivation
#endif
)
{ {
unsigned char* k = hmac->k; unsigned char* k = hmac->k;
unsigned char* u = hmac->u; unsigned char* u = hmac->u;
@@ -186,6 +190,11 @@ static void derive_u_sha256 (const unsigned char *salt, int salt_len, uint32 ite
/* remaining iterations */ /* remaining iterations */
while (c > 1) while (c > 1)
{ {
#ifndef TC_WINDOWS_BOOT
// CANCELLATION CHECK: Check every 1024 iterations
if (pAbortKeyDerivation && (c & 1023) == 0 && *pAbortKeyDerivation == 1)
return; // Abort derivation
#endif
hmac_sha256_internal (k, SHA256_DIGESTSIZE, hmac); hmac_sha256_internal (k, SHA256_DIGESTSIZE, hmac);
for (i = 0; i < SHA256_DIGESTSIZE; i++) for (i = 0; i < SHA256_DIGESTSIZE; i++)
{ {
@@ -196,7 +205,11 @@ static void derive_u_sha256 (const unsigned char *salt, int salt_len, uint32 ite
} }
void derive_key_sha256 (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen) void derive_key_sha256 (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen
#ifndef TC_WINDOWS_BOOT
, long volatile *pAbortKeyDerivation
#endif
)
{ {
hmac_sha256_ctx hmac; hmac_sha256_ctx hmac;
sha256_ctx* ctx; sha256_ctx* ctx;
@@ -264,20 +277,36 @@ void derive_key_sha256 (const unsigned char *pwd, int pwd_len, const unsigned ch
/* first l - 1 blocks */ /* first l - 1 blocks */
for (b = 1; b < l; b++) for (b = 1; b < l; b++)
{ {
#ifndef TC_WINDOWS_BOOT
derive_u_sha256 (salt, salt_len, iterations, b, &hmac, pAbortKeyDerivation);
// Check if the derivation was aborted
if (pAbortKeyDerivation && *pAbortKeyDerivation == 1)
goto cancelled;
#else
derive_u_sha256 (salt, salt_len, iterations, b, &hmac); derive_u_sha256 (salt, salt_len, iterations, b, &hmac);
#endif
memcpy (dk, hmac.u, SHA256_DIGESTSIZE); memcpy (dk, hmac.u, SHA256_DIGESTSIZE);
dk += SHA256_DIGESTSIZE; dk += SHA256_DIGESTSIZE;
} }
/* last block */ /* last block */
#ifndef TC_WINDOWS_BOOT
derive_u_sha256 (salt, salt_len, iterations, b, &hmac, pAbortKeyDerivation);
// Check if the derivation was aborted (in case of only one block)
if (pAbortKeyDerivation && *pAbortKeyDerivation == 1)
goto cancelled;
#else
derive_u_sha256 (salt, salt_len, iterations, b, &hmac); derive_u_sha256 (salt, salt_len, iterations, b, &hmac);
#endif
memcpy (dk, hmac.u, r); memcpy (dk, hmac.u, r);
#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) #if defined (DEVICE_DRIVER) && !defined(_M_ARM64)
if (NT_SUCCESS (saveStatus)) if (NT_SUCCESS (saveStatus))
KeRestoreExtendedProcessorState(&SaveState); KeRestoreExtendedProcessorState(&SaveState);
#endif #endif
#ifndef TC_WINDOWS_BOOT
cancelled:
#endif
/* Prevent possible leaks. */ /* Prevent possible leaks. */
burn (&hmac, sizeof(hmac)); burn (&hmac, sizeof(hmac));
#ifndef TC_WINDOWS_BOOT #ifndef TC_WINDOWS_BOOT
@@ -395,7 +424,7 @@ void hmac_sha512
burn (key, sizeof(key)); burn (key, sizeof(key));
} }
static void derive_u_sha512 (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_sha512_ctx* hmac) static void derive_u_sha512 (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_sha512_ctx* hmac, long volatile *pAbortKeyDerivation)
{ {
unsigned char* k = hmac->k; unsigned char* k = hmac->k;
unsigned char* u = hmac->u; unsigned char* u = hmac->u;
@@ -413,6 +442,9 @@ static void derive_u_sha512 (const unsigned char *salt, int salt_len, uint32 ite
/* remaining iterations */ /* remaining iterations */
for (c = 1; c < iterations; c++) for (c = 1; c < iterations; c++)
{ {
// CANCELLATION CHECK: Check every 1024 iterations
if (pAbortKeyDerivation && (c & 1023) == 0 && *pAbortKeyDerivation == 1)
return; // Abort derivation
hmac_sha512_internal (k, SHA512_DIGESTSIZE, hmac); hmac_sha512_internal (k, SHA512_DIGESTSIZE, hmac);
for (i = 0; i < SHA512_DIGESTSIZE; i++) for (i = 0; i < SHA512_DIGESTSIZE; i++)
{ {
@@ -422,7 +454,7 @@ static void derive_u_sha512 (const unsigned char *salt, int salt_len, uint32 ite
} }
void derive_key_sha512 (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen) void derive_key_sha512 (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen, long volatile *pAbortKeyDerivation)
{ {
hmac_sha512_ctx hmac; hmac_sha512_ctx hmac;
sha512_ctx* ctx; sha512_ctx* ctx;
@@ -489,20 +521,26 @@ void derive_key_sha512 (const unsigned char *pwd, int pwd_len, const unsigned ch
/* first l - 1 blocks */ /* first l - 1 blocks */
for (b = 1; b < l; b++) for (b = 1; b < l; b++)
{ {
derive_u_sha512 (salt, salt_len, iterations, b, &hmac); derive_u_sha512 (salt, salt_len, iterations, b, &hmac, pAbortKeyDerivation);
// Check if the derivation was aborted
if (pAbortKeyDerivation && *pAbortKeyDerivation == 1)
goto cancelled;
memcpy (dk, hmac.u, SHA512_DIGESTSIZE); memcpy (dk, hmac.u, SHA512_DIGESTSIZE);
dk += SHA512_DIGESTSIZE; dk += SHA512_DIGESTSIZE;
} }
/* last block */ /* last block */
derive_u_sha512 (salt, salt_len, iterations, b, &hmac); derive_u_sha512 (salt, salt_len, iterations, b, &hmac, pAbortKeyDerivation);
// Check if the derivation was aborted (in case of only one block)
if (pAbortKeyDerivation && *pAbortKeyDerivation == 1)
goto cancelled;
memcpy (dk, hmac.u, r); memcpy (dk, hmac.u, r);
#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) #if defined (DEVICE_DRIVER) && !defined(_M_ARM64)
if (NT_SUCCESS (saveStatus)) if (NT_SUCCESS (saveStatus))
KeRestoreExtendedProcessorState(&SaveState); KeRestoreExtendedProcessorState(&SaveState);
#endif #endif
cancelled:
/* Prevent possible leaks. */ /* Prevent possible leaks. */
burn (&hmac, sizeof(hmac)); burn (&hmac, sizeof(hmac));
burn (key, sizeof(key)); burn (key, sizeof(key));
@@ -619,7 +657,11 @@ void hmac_blake2s
} }
#endif #endif
static void derive_u_blake2s (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_blake2s_ctx* hmac) static void derive_u_blake2s (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_blake2s_ctx* hmac
#ifndef TC_WINDOWS_BOOT
, volatile long *pAbortKeyDerivation
#endif
)
{ {
unsigned char* k = hmac->k; unsigned char* k = hmac->k;
unsigned char* u = hmac->u; unsigned char* u = hmac->u;
@@ -660,6 +702,11 @@ static void derive_u_blake2s (const unsigned char *salt, int salt_len, uint32 it
/* remaining iterations */ /* remaining iterations */
while (c > 1) while (c > 1)
{ {
#ifndef TC_WINDOWS_BOOT
// CANCELLATION CHECK: Check every 1024 iterations
if (pAbortKeyDerivation && (c & 1023) == 0 && *pAbortKeyDerivation)
return; // Abort derivation
#endif
hmac_blake2s_internal (k, BLAKE2S_DIGESTSIZE, hmac); hmac_blake2s_internal (k, BLAKE2S_DIGESTSIZE, hmac);
for (i = 0; i < BLAKE2S_DIGESTSIZE; i++) for (i = 0; i < BLAKE2S_DIGESTSIZE; i++)
{ {
@@ -670,7 +717,11 @@ static void derive_u_blake2s (const unsigned char *salt, int salt_len, uint32 it
} }
void derive_key_blake2s (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen) void derive_key_blake2s (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen
#ifndef TC_WINDOWS_BOOT
, volatile long *pAbortKeyDerivation
#endif
)
{ {
hmac_blake2s_ctx hmac; hmac_blake2s_ctx hmac;
blake2s_state* ctx; blake2s_state* ctx;
@@ -738,20 +789,36 @@ void derive_key_blake2s (const unsigned char *pwd, int pwd_len, const unsigned c
/* first l - 1 blocks */ /* first l - 1 blocks */
for (b = 1; b < l; b++) for (b = 1; b < l; b++)
{ {
#ifndef TC_WINDOWS_BOOT
derive_u_blake2s (salt, salt_len, iterations, b, &hmac, pAbortKeyDerivation);
// Check if the derivation was aborted
if (pAbortKeyDerivation && *pAbortKeyDerivation)
goto cancelled;
#else
derive_u_blake2s (salt, salt_len, iterations, b, &hmac); derive_u_blake2s (salt, salt_len, iterations, b, &hmac);
#endif
memcpy (dk, hmac.u, BLAKE2S_DIGESTSIZE); memcpy (dk, hmac.u, BLAKE2S_DIGESTSIZE);
dk += BLAKE2S_DIGESTSIZE; dk += BLAKE2S_DIGESTSIZE;
} }
/* last block */ /* last block */
#ifndef TC_WINDOWS_BOOT
derive_u_blake2s (salt, salt_len, iterations, b, &hmac, pAbortKeyDerivation);
// Check if the derivation was aborted (in case of only one block)
if (pAbortKeyDerivation && *pAbortKeyDerivation)
goto cancelled;
#else
derive_u_blake2s (salt, salt_len, iterations, b, &hmac); derive_u_blake2s (salt, salt_len, iterations, b, &hmac);
#endif
memcpy (dk, hmac.u, r); memcpy (dk, hmac.u, r);
#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) #if defined (DEVICE_DRIVER) && !defined(_M_ARM64)
if (NT_SUCCESS (saveStatus)) if (NT_SUCCESS (saveStatus))
KeRestoreExtendedProcessorState(&SaveState); KeRestoreExtendedProcessorState(&SaveState);
#endif #endif
#ifndef TC_WINDOWS_BOOT
cancelled:
#endif
/* Prevent possible leaks. */ /* Prevent possible leaks. */
burn (&hmac, sizeof(hmac)); burn (&hmac, sizeof(hmac));
#ifndef TC_WINDOWS_BOOT #ifndef TC_WINDOWS_BOOT
@@ -856,7 +923,7 @@ void hmac_whirlpool
burn(&hmac, sizeof(hmac)); burn(&hmac, sizeof(hmac));
} }
static void derive_u_whirlpool (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_whirlpool_ctx* hmac) static void derive_u_whirlpool (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_whirlpool_ctx* hmac, volatile long *pAbortKeyDerivation)
{ {
unsigned char* u = hmac->u; unsigned char* u = hmac->u;
unsigned char* k = hmac->k; unsigned char* k = hmac->k;
@@ -874,6 +941,9 @@ static void derive_u_whirlpool (const unsigned char *salt, int salt_len, uint32
/* remaining iterations */ /* remaining iterations */
for (c = 1; c < iterations; c++) for (c = 1; c < iterations; c++)
{ {
// CANCELLATION CHECK: Check every 1024 iterations
if (pAbortKeyDerivation && (c & 1023) == 0 && *pAbortKeyDerivation)
return; // Abort derivation
hmac_whirlpool_internal (k, WHIRLPOOL_DIGESTSIZE, hmac); hmac_whirlpool_internal (k, WHIRLPOOL_DIGESTSIZE, hmac);
for (i = 0; i < WHIRLPOOL_DIGESTSIZE; i++) for (i = 0; i < WHIRLPOOL_DIGESTSIZE; i++)
{ {
@@ -882,7 +952,7 @@ static void derive_u_whirlpool (const unsigned char *salt, int salt_len, uint32
} }
} }
void derive_key_whirlpool (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen) void derive_key_whirlpool (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen, volatile long *pAbortKeyDerivation)
{ {
hmac_whirlpool_ctx hmac; hmac_whirlpool_ctx hmac;
WHIRLPOOL_CTX* ctx; WHIRLPOOL_CTX* ctx;
@@ -942,15 +1012,21 @@ void derive_key_whirlpool (const unsigned char *pwd, int pwd_len, const unsigned
/* first l - 1 blocks */ /* first l - 1 blocks */
for (b = 1; b < l; b++) for (b = 1; b < l; b++)
{ {
derive_u_whirlpool (salt, salt_len, iterations, b, &hmac); derive_u_whirlpool (salt, salt_len, iterations, b, &hmac, pAbortKeyDerivation);
// Check if the derivation was aborted
if (pAbortKeyDerivation && *pAbortKeyDerivation)
goto cancelled;
memcpy (dk, hmac.u, WHIRLPOOL_DIGESTSIZE); memcpy (dk, hmac.u, WHIRLPOOL_DIGESTSIZE);
dk += WHIRLPOOL_DIGESTSIZE; dk += WHIRLPOOL_DIGESTSIZE;
} }
/* last block */ /* last block */
derive_u_whirlpool (salt, salt_len, iterations, b, &hmac); derive_u_whirlpool (salt, salt_len, iterations, b, &hmac, pAbortKeyDerivation);
// Check if the derivation was aborted (in case of only one block)
if (pAbortKeyDerivation && *pAbortKeyDerivation)
goto cancelled;
memcpy (dk, hmac.u, r); memcpy (dk, hmac.u, r);
cancelled:
/* Prevent possible leaks. */ /* Prevent possible leaks. */
burn (&hmac, sizeof(hmac)); burn (&hmac, sizeof(hmac));
burn (key, sizeof(key)); burn (key, sizeof(key));
@@ -1050,7 +1126,7 @@ void hmac_streebog
burn(&hmac, sizeof(hmac)); burn(&hmac, sizeof(hmac));
} }
static void derive_u_streebog (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_streebog_ctx* hmac) static void derive_u_streebog (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_streebog_ctx* hmac, volatile long *pAbortKeyDerivation)
{ {
unsigned char* u = hmac->u; unsigned char* u = hmac->u;
unsigned char* k = hmac->k; unsigned char* k = hmac->k;
@@ -1068,6 +1144,9 @@ static void derive_u_streebog (const unsigned char *salt, int salt_len, uint32 i
/* remaining iterations */ /* remaining iterations */
for (c = 1; c < iterations; c++) for (c = 1; c < iterations; c++)
{ {
// CANCELLATION CHECK: Check every 1024 iterations
if (pAbortKeyDerivation && (c & 1023) == 0 && *pAbortKeyDerivation)
return; // Abort derivation
hmac_streebog_internal (k, STREEBOG_DIGESTSIZE, hmac); hmac_streebog_internal (k, STREEBOG_DIGESTSIZE, hmac);
for (i = 0; i < STREEBOG_DIGESTSIZE; i++) for (i = 0; i < STREEBOG_DIGESTSIZE; i++)
{ {
@@ -1076,7 +1155,7 @@ static void derive_u_streebog (const unsigned char *salt, int salt_len, uint32 i
} }
} }
void derive_key_streebog (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen) void derive_key_streebog (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen, volatile long *pAbortKeyDerivation)
{ {
hmac_streebog_ctx hmac; hmac_streebog_ctx hmac;
STREEBOG_CTX* ctx; STREEBOG_CTX* ctx;
@@ -1136,15 +1215,21 @@ void derive_key_streebog (const unsigned char *pwd, int pwd_len, const unsigned
/* first l - 1 blocks */ /* first l - 1 blocks */
for (b = 1; b < l; b++) for (b = 1; b < l; b++)
{ {
derive_u_streebog (salt, salt_len, iterations, b, &hmac); derive_u_streebog (salt, salt_len, iterations, b, &hmac, pAbortKeyDerivation);
// Check if the derivation was aborted
if (pAbortKeyDerivation && *pAbortKeyDerivation)
goto cancelled;
memcpy (dk, hmac.u, STREEBOG_DIGESTSIZE); memcpy (dk, hmac.u, STREEBOG_DIGESTSIZE);
dk += STREEBOG_DIGESTSIZE; dk += STREEBOG_DIGESTSIZE;
} }
/* last block */ /* last block */
derive_u_streebog (salt, salt_len, iterations, b, &hmac); derive_u_streebog (salt, salt_len, iterations, b, &hmac, pAbortKeyDerivation);
// Check if the derivation was aborted (in case of only one block)
if (pAbortKeyDerivation && *pAbortKeyDerivation)
goto cancelled;
memcpy (dk, hmac.u, r); memcpy (dk, hmac.u, r);
cancelled:
/* Prevent possible leaks. */ /* Prevent possible leaks. */
burn (&hmac, sizeof(hmac)); burn (&hmac, sizeof(hmac));
burn (key, sizeof(key)); burn (key, sizeof(key));
@@ -1245,7 +1330,7 @@ int is_pkcs5_prf_supported (int pkcs5_prf_id, PRF_BOOT_TYPE bootType)
} }
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) 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)
{ {
#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) #if defined (DEVICE_DRIVER) && !defined(_M_ARM64)
NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
@@ -1259,7 +1344,8 @@ void derive_key_argon2(const unsigned char *pwd, int pwd_len, const unsigned cha
1, // parallelism factor (number of threads) 1, // parallelism factor (number of threads)
pwd, pwd_len, // password and its length pwd, pwd_len, // password and its length
salt, salt_len, // salt and its length salt, salt_len, // salt and its length
dk, dklen// derived key and its length dk, dklen,// derived key and its length
pAbortKeyDerivation
)) ))
{ {
// If the Argon2 derivation fails, we fill the derived key with zeroes // If the Argon2 derivation fails, we fill the derived key with zeroes

View File

@@ -20,30 +20,31 @@
extern "C" extern "C"
{ {
#endif #endif
#ifndef TC_WINDOWS_BOOT
/* output written to input_digest which must be at lease 32 bytes long */ /* output written to input_digest which must be at lease 32 bytes long */
void hmac_blake2s (unsigned char *key, int keylen, unsigned char *input_digest, int len); void hmac_blake2s (unsigned char *key, int keylen, unsigned char *input_digest, int len);
void derive_key_blake2s (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen); void derive_key_blake2s (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen, long volatile *pAbortKeyDerivation);
/* output written to d which must be at lease 32 bytes long */ /* output written to d which must be at lease 32 bytes long */
void hmac_sha256 (unsigned char *k, int lk, unsigned char *d, int ld); void hmac_sha256 (unsigned char *k, int lk, unsigned char *d, int ld);
void derive_key_sha256 (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen); void derive_key_sha256 (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen, long volatile *pAbortKeyDerivation);
#ifndef TC_WINDOWS_BOOT
/* output written to d which must be at lease 64 bytes long */ /* output written to d which must be at lease 64 bytes long */
void hmac_sha512 (unsigned char *k, int lk, unsigned char *d, int ld); void hmac_sha512 (unsigned char *k, int lk, unsigned char *d, int ld);
void derive_key_sha512 (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen); void derive_key_sha512 (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen, long volatile *pAbortKeyDerivation);
/* output written to d which must be at lease 64 bytes long */ /* output written to d which must be at lease 64 bytes long */
void hmac_whirlpool (unsigned char *k, int lk, unsigned char *d, int ld); void hmac_whirlpool (unsigned char *k, int lk, unsigned char *d, int ld);
void derive_key_whirlpool (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen); void derive_key_whirlpool (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen, long volatile *pAbortKeyDerivation);
void hmac_streebog (unsigned char *k, int lk, unsigned char *d, int ld); void hmac_streebog (unsigned char *k, int lk, unsigned char *d, int ld);
void derive_key_streebog (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen); void derive_key_streebog (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen, long volatile *pAbortKeyDerivation);
int get_pkcs5_iteration_count (int pkcs5_prf_id, int pim, BOOL bBoot, int* pMemoryCost); 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); wchar_t *get_pkcs5_prf_name (int pkcs5_prf_id);
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); 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);
void get_argon2_params(int pim, int* pIterations, int* pMemcost); void get_argon2_params(int pim, int* pIterations, int* pMemcost);
/* check if given PRF supported.*/ /* check if given PRF supported.*/
@@ -55,6 +56,15 @@ typedef enum
} PRF_BOOT_TYPE; } PRF_BOOT_TYPE;
int is_pkcs5_prf_supported (int pkcs5_prf_id, PRF_BOOT_TYPE bootType); int is_pkcs5_prf_supported (int pkcs5_prf_id, PRF_BOOT_TYPE bootType);
#else // TC_WINDOWS_BOOT
/* output written to input_digest which must be at lease 32 bytes long */
void hmac_blake2s (unsigned char *key, int keylen, unsigned char *input_digest, int len);
void derive_key_blake2s (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen);
/* output written to d which must be at lease 32 bytes long */
void hmac_sha256 (unsigned char *k, int lk, unsigned char *d, int ld);
void derive_key_sha256 (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen);
#endif #endif
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@@ -1681,64 +1681,64 @@ BOOL test_pkcs5 ()
return FALSE; return FALSE;
#endif #endif
/* PKCS-5 test 1 with HMAC-SHA-256 used as the PRF (https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00) */ /* PKCS-5 test 1 with HMAC-SHA-256 used as the PRF (https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00) */
derive_key_sha256 ((unsigned char*) "passwd", 6, (unsigned char*) "\x73\x61\x6C\x74", 4, 1, dk, 64); derive_key_sha256 ((unsigned char*) "passwd", 6, (unsigned char*) "\x73\x61\x6C\x74", 4, 1, dk, 64, NULL);
if (memcmp (dk, "\x55\xac\x04\x6e\x56\xe3\x08\x9f\xec\x16\x91\xc2\x25\x44\xb6\x05\xf9\x41\x85\x21\x6d\xde\x04\x65\xe6\x8b\x9d\x57\xc2\x0d\xac\xbc\x49\xca\x9c\xcc\xf1\x79\xb6\x45\x99\x16\x64\xb3\x9d\x77\xef\x31\x7c\x71\xb8\x45\xb1\xe3\x0b\xd5\x09\x11\x20\x41\xd3\xa1\x97\x83", 64) != 0) if (memcmp (dk, "\x55\xac\x04\x6e\x56\xe3\x08\x9f\xec\x16\x91\xc2\x25\x44\xb6\x05\xf9\x41\x85\x21\x6d\xde\x04\x65\xe6\x8b\x9d\x57\xc2\x0d\xac\xbc\x49\xca\x9c\xcc\xf1\x79\xb6\x45\x99\x16\x64\xb3\x9d\x77\xef\x31\x7c\x71\xb8\x45\xb1\xe3\x0b\xd5\x09\x11\x20\x41\xd3\xa1\x97\x83", 64) != 0)
return FALSE; return FALSE;
/* PKCS-5 test 2 with HMAC-SHA-256 used as the PRF (https://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors) */ /* PKCS-5 test 2 with HMAC-SHA-256 used as the PRF (https://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors) */
derive_key_sha256 ((unsigned char*) "password", 8, (unsigned char*) "\x73\x61\x6C\x74", 4, 2, dk, 32); derive_key_sha256 ((unsigned char*) "password", 8, (unsigned char*) "\x73\x61\x6C\x74", 4, 2, dk, 32, NULL);
if (memcmp (dk, "\xae\x4d\x0c\x95\xaf\x6b\x46\xd3\x2d\x0a\xdf\xf9\x28\xf0\x6d\xd0\x2a\x30\x3f\x8e\xf3\xc2\x51\xdf\xd6\xe2\xd8\x5a\x95\x47\x4c\x43", 32) != 0) if (memcmp (dk, "\xae\x4d\x0c\x95\xaf\x6b\x46\xd3\x2d\x0a\xdf\xf9\x28\xf0\x6d\xd0\x2a\x30\x3f\x8e\xf3\xc2\x51\xdf\xd6\xe2\xd8\x5a\x95\x47\x4c\x43", 32) != 0)
return FALSE; return FALSE;
/* PKCS-5 test 3 with HMAC-SHA-256 used as the PRF (MS CryptoAPI) */ /* PKCS-5 test 3 with HMAC-SHA-256 used as the PRF (MS CryptoAPI) */
derive_key_sha256 ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4); derive_key_sha256 ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4, NULL);
if (memcmp (dk, "\xf2\xa0\x4f\xb2", 4) != 0) if (memcmp (dk, "\xf2\xa0\x4f\xb2", 4) != 0)
return FALSE; return FALSE;
/* PKCS-5 test 4 with HMAC-SHA-256 used as the PRF (MS CryptoAPI) */ /* PKCS-5 test 4 with HMAC-SHA-256 used as the PRF (MS CryptoAPI) */
derive_key_sha256 ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 144); derive_key_sha256 ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 144, NULL);
if (memcmp (dk, "\xf2\xa0\x4f\xb2\xd3\xe9\xa5\xd8\x51\x0b\x5c\x06\xdf\x70\x8e\x24\xe9\xc7\xd9\x15\x3d\x22\xcd\xde\xb8\xa6\xdb\xfd\x71\x85\xc6\x99\x32\xc0\xee\x37\x27\xf7\x24\xcf\xea\xa6\xac\x73\xa1\x4c\x4e\x52\x9b\x94\xf3\x54\x06\xfc\x04\x65\xa1\x0a\x24\xfe\xf0\x98\x1d\xa6\x22\x28\xeb\x24\x55\x74\xce\x6a\x3a\x28\xe2\x04\x3a\x59\x13\xec\x3f\xf2\xdb\xcf\x58\xdd\x53\xd9\xf9\x17\xf6\xda\x74\x06\x3c\x0b\x66\xf5\x0f\xf5\x58\xa3\x27\x52\x8c\x5b\x07\x91\xd0\x81\xeb\xb6\xbc\x30\x69\x42\x71\xf2\xd7\x18\x42\xbe\xe8\x02\x93\x70\x66\xad\x35\x65\xbc\xf7\x96\x8e\x64\xf1\xc6\x92\xda\xe0\xdc\x1f\xb5\xf4", 144) != 0) if (memcmp (dk, "\xf2\xa0\x4f\xb2\xd3\xe9\xa5\xd8\x51\x0b\x5c\x06\xdf\x70\x8e\x24\xe9\xc7\xd9\x15\x3d\x22\xcd\xde\xb8\xa6\xdb\xfd\x71\x85\xc6\x99\x32\xc0\xee\x37\x27\xf7\x24\xcf\xea\xa6\xac\x73\xa1\x4c\x4e\x52\x9b\x94\xf3\x54\x06\xfc\x04\x65\xa1\x0a\x24\xfe\xf0\x98\x1d\xa6\x22\x28\xeb\x24\x55\x74\xce\x6a\x3a\x28\xe2\x04\x3a\x59\x13\xec\x3f\xf2\xdb\xcf\x58\xdd\x53\xd9\xf9\x17\xf6\xda\x74\x06\x3c\x0b\x66\xf5\x0f\xf5\x58\xa3\x27\x52\x8c\x5b\x07\x91\xd0\x81\xeb\xb6\xbc\x30\x69\x42\x71\xf2\xd7\x18\x42\xbe\xe8\x02\x93\x70\x66\xad\x35\x65\xbc\xf7\x96\x8e\x64\xf1\xc6\x92\xda\xe0\xdc\x1f\xb5\xf4", 144) != 0)
return FALSE; return FALSE;
/* PKCS-5 test 1 with HMAC-SHA-512 used as the PRF */ /* PKCS-5 test 1 with HMAC-SHA-512 used as the PRF */
derive_key_sha512 ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4); derive_key_sha512 ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4, NULL);
if (memcmp (dk, "\x13\x64\xae\xf8", 4) != 0) if (memcmp (dk, "\x13\x64\xae\xf8", 4) != 0)
return FALSE; return FALSE;
/* PKCS-5 test 2 with HMAC-SHA-512 used as the PRF (derives a key longer than the underlying /* PKCS-5 test 2 with HMAC-SHA-512 used as the PRF (derives a key longer than the underlying
hash output size and block size) */ hash output size and block size) */
derive_key_sha512 ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 144); derive_key_sha512 ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 144, NULL);
if (memcmp (dk, "\x13\x64\xae\xf8\x0d\xf5\x57\x6c\x30\xd5\x71\x4c\xa7\x75\x3f\xfd\x00\xe5\x25\x8b\x39\xc7\x44\x7f\xce\x23\x3d\x08\x75\xe0\x2f\x48\xd6\x30\xd7\x00\xb6\x24\xdb\xe0\x5a\xd7\x47\xef\x52\xca\xa6\x34\x83\x47\xe5\xcb\xe9\x87\xf1\x20\x59\x6a\xe6\xa9\xcf\x51\x78\xc6\xb6\x23\xa6\x74\x0d\xe8\x91\xbe\x1a\xd0\x28\xcc\xce\x16\x98\x9a\xbe\xfb\xdc\x78\xc9\xe1\x7d\x72\x67\xce\xe1\x61\x56\x5f\x96\x68\xe6\xe1\xdd\xf4\xbf\x1b\x80\xe0\x19\x1c\xf4\xc4\xd3\xdd\xd5\xd5\x57\x2d\x83\xc7\xa3\x37\x87\xf4\x4e\xe0\xf6\xd8\x6d\x65\xdc\xa0\x52\xa3\x13\xbe\x81\xfc\x30\xbe\x7d\x69\x58\x34\xb6\xdd\x41\xc6", 144) != 0) if (memcmp (dk, "\x13\x64\xae\xf8\x0d\xf5\x57\x6c\x30\xd5\x71\x4c\xa7\x75\x3f\xfd\x00\xe5\x25\x8b\x39\xc7\x44\x7f\xce\x23\x3d\x08\x75\xe0\x2f\x48\xd6\x30\xd7\x00\xb6\x24\xdb\xe0\x5a\xd7\x47\xef\x52\xca\xa6\x34\x83\x47\xe5\xcb\xe9\x87\xf1\x20\x59\x6a\xe6\xa9\xcf\x51\x78\xc6\xb6\x23\xa6\x74\x0d\xe8\x91\xbe\x1a\xd0\x28\xcc\xce\x16\x98\x9a\xbe\xfb\xdc\x78\xc9\xe1\x7d\x72\x67\xce\xe1\x61\x56\x5f\x96\x68\xe6\xe1\xdd\xf4\xbf\x1b\x80\xe0\x19\x1c\xf4\xc4\xd3\xdd\xd5\xd5\x57\x2d\x83\xc7\xa3\x37\x87\xf4\x4e\xe0\xf6\xd8\x6d\x65\xdc\xa0\x52\xa3\x13\xbe\x81\xfc\x30\xbe\x7d\x69\x58\x34\xb6\xdd\x41\xc6", 144) != 0)
return FALSE; return FALSE;
#ifndef WOLFCRYPT_BACKEND #ifndef WOLFCRYPT_BACKEND
/* PKCS-5 test 1 with HMAC-BLAKE2s used as the PRF */ /* PKCS-5 test 1 with HMAC-BLAKE2s used as the PRF */
derive_key_blake2s ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4); derive_key_blake2s ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4, NULL);
if (memcmp (dk, "\x8d\x51\xfa\x31", 4) != 0) if (memcmp (dk, "\x8d\x51\xfa\x31", 4) != 0)
return FALSE; return FALSE;
/* PKCS-5 test 2 with HMAC-BLAKE2s used as the PRF (derives a key longer than the underlying hash) */ /* PKCS-5 test 2 with HMAC-BLAKE2s used as the PRF (derives a key longer than the underlying hash) */
derive_key_blake2s ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 48); derive_key_blake2s ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 48, NULL);
if (memcmp (dk, "\x8d\x51\xfa\x31\x46\x25\x37\x67\xa3\x29\x6b\x3c\x6b\xc1\x5d\xb2\xee\xe1\x6c\x28\x00\x26\xea\x08\x65\x9c\x12\xf1\x07\xde\x0d\xb9\x9b\x4f\x39\xfa\xc6\x80\x26\xb1\x8f\x8e\x48\x89\x85\x2d\x24\x2d", 48) != 0) if (memcmp (dk, "\x8d\x51\xfa\x31\x46\x25\x37\x67\xa3\x29\x6b\x3c\x6b\xc1\x5d\xb2\xee\xe1\x6c\x28\x00\x26\xea\x08\x65\x9c\x12\xf1\x07\xde\x0d\xb9\x9b\x4f\x39\xfa\xc6\x80\x26\xb1\x8f\x8e\x48\x89\x85\x2d\x24\x2d", 48) != 0)
return FALSE; return FALSE;
/* PKCS-5 test 1 with HMAC-Whirlpool used as the PRF */ /* PKCS-5 test 1 with HMAC-Whirlpool used as the PRF */
derive_key_whirlpool ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4); derive_key_whirlpool ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4, NULL);
if (memcmp (dk, "\x50\x7c\x36\x6f", 4) != 0) if (memcmp (dk, "\x50\x7c\x36\x6f", 4) != 0)
return FALSE; return FALSE;
/* PKCS-5 test 2 with HMAC-Whirlpool used as the PRF (derives a key longer than the underlying hash) */ /* PKCS-5 test 2 with HMAC-Whirlpool used as the PRF (derives a key longer than the underlying hash) */
derive_key_whirlpool ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 96); derive_key_whirlpool ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 96, NULL);
if (memcmp (dk, "\x50\x7c\x36\x6f\xee\x10\x2e\x9a\xe2\x8a\xd5\x82\x72\x7d\x27\x0f\xe8\x4d\x7f\x68\x7a\xcf\xb5\xe7\x43\x67\xaa\x98\x93\x52\x2b\x09\x6e\x42\xdf\x2c\x59\x4a\x91\x6d\x7e\x10\xae\xb2\x1a\x89\x8f\xb9\x8f\xe6\x31\xa9\xd8\x9f\x98\x26\xf4\xda\xcd\x7d\x65\x65\xde\x10\x95\x91\xb4\x84\x26\xae\x43\xa1\x00\x5b\x1e\xb8\x38\x97\xa4\x1e\x4b\xd2\x65\x64\xbc\xfa\x1f\x35\x85\xdb\x4f\x97\x65\x6f\xbd\x24", 96) != 0) if (memcmp (dk, "\x50\x7c\x36\x6f\xee\x10\x2e\x9a\xe2\x8a\xd5\x82\x72\x7d\x27\x0f\xe8\x4d\x7f\x68\x7a\xcf\xb5\xe7\x43\x67\xaa\x98\x93\x52\x2b\x09\x6e\x42\xdf\x2c\x59\x4a\x91\x6d\x7e\x10\xae\xb2\x1a\x89\x8f\xb9\x8f\xe6\x31\xa9\xd8\x9f\x98\x26\xf4\xda\xcd\x7d\x65\x65\xde\x10\x95\x91\xb4\x84\x26\xae\x43\xa1\x00\x5b\x1e\xb8\x38\x97\xa4\x1e\x4b\xd2\x65\x64\xbc\xfa\x1f\x35\x85\xdb\x4f\x97\x65\x6f\xbd\x24", 96) != 0)
return FALSE; return FALSE;
/* PKCS-5 test 1 with HMAC-STREEBOG used as the PRF */ /* PKCS-5 test 1 with HMAC-STREEBOG used as the PRF */
derive_key_streebog ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4); derive_key_streebog ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4, NULL);
if (memcmp (dk, "\xd0\x53\xa2\x30", 4) != 0) if (memcmp (dk, "\xd0\x53\xa2\x30", 4) != 0)
return FALSE; return FALSE;
/* PKCS-5 test 2 with HMAC-STREEBOG used as the PRF (derives a key longer than the underlying hash) */ /* PKCS-5 test 2 with HMAC-STREEBOG used as the PRF (derives a key longer than the underlying hash) */
derive_key_streebog ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 96); derive_key_streebog ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 96, NULL);
if (memcmp (dk, "\xd0\x53\xa2\x30\x6f\x45\x81\xeb\xbc\x06\x81\xc5\xe7\x53\xa8\x5d\xc7\xf1\x23\x33\x1e\xbe\x64\x2c\x3b\x0f\x26\xd7\x00\xe1\x95\xc9\x65\x26\xb1\x85\xbe\x1e\xe2\xf4\x9b\xfc\x6b\x14\x84\xda\x24\x61\xa0\x1b\x9e\x79\x5c\xee\x69\x6e\xf9\x25\xb1\x1d\xca\xa0\x31\xba\x02\x6f\x9e\x99\x0f\xdb\x25\x01\x5b\xf1\xc7\x10\x19\x53\x3b\x29\x3f\x18\x00\xd6\xfc\x85\x03\xdc\xf2\xe5\xe9\x5a\xb1\x1e\x61\xde", 96) != 0) if (memcmp (dk, "\xd0\x53\xa2\x30\x6f\x45\x81\xeb\xbc\x06\x81\xc5\xe7\x53\xa8\x5d\xc7\xf1\x23\x33\x1e\xbe\x64\x2c\x3b\x0f\x26\xd7\x00\xe1\x95\xc9\x65\x26\xb1\x85\xbe\x1e\xe2\xf4\x9b\xfc\x6b\x14\x84\xda\x24\x61\xa0\x1b\x9e\x79\x5c\xee\x69\x6e\xf9\x25\xb1\x1d\xca\xa0\x31\xba\x02\x6f\x9e\x99\x0f\xdb\x25\x01\x5b\xf1\xc7\x10\x19\x53\x3b\x29\x3f\x18\x00\xd6\xfc\x85\x03\xdc\xf2\xe5\xe9\x5a\xb1\x1e\x61\xde", 96) != 0)
return FALSE; return FALSE;
#endif #endif

View File

@@ -194,6 +194,7 @@ int ReadVolumeHeader (BOOL bBoot, unsigned char *encryptedHeader, Password *pass
int i; int i;
int iterationsCount = 0; int iterationsCount = 0;
int memoryCost = 0; int memoryCost = 0;
LONG volatile abortKeyDerivation = 0;
#endif #endif
size_t queuedWorkItems = 0; size_t queuedWorkItems = 0;
@@ -331,7 +332,7 @@ int ReadVolumeHeader (BOOL bBoot, unsigned char *encryptedHeader, Password *pass
iterationsCount = get_pkcs5_iteration_count (enqPkcs5Prf, pim, bBoot, &memoryCost); iterationsCount = get_pkcs5_iteration_count (enqPkcs5Prf, pim, bBoot, &memoryCost);
EncryptionThreadPoolBeginKeyDerivation (keyDerivationCompletedEvent, noOutstandingWorkItemEvent, EncryptionThreadPoolBeginKeyDerivation (keyDerivationCompletedEvent, noOutstandingWorkItemEvent,
&item->KeyReady, outstandingWorkItemCount, enqPkcs5Prf, keyInfo->userKey, &item->KeyReady, outstandingWorkItemCount, enqPkcs5Prf, keyInfo->userKey,
keyInfo->keyLength, keyInfo->salt, iterationsCount, memoryCost, item->DerivedKey); keyInfo->keyLength, keyInfo->salt, iterationsCount, memoryCost, item->DerivedKey, &abortKeyDerivation);
++queuedWorkItems; ++queuedWorkItems;
break; break;
@@ -382,35 +383,35 @@ KeyReady: ;
{ {
case SHA512: case SHA512:
derive_key_sha512 (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt, derive_key_sha512 (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize()); PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize(), &abortKeyDerivation);
break; break;
case SHA256: case SHA256:
derive_key_sha256 (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt, derive_key_sha256 (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize()); PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize(), &abortKeyDerivation);
break; break;
#ifndef WOLFCRYPT_BACKEND #ifndef WOLFCRYPT_BACKEND
case BLAKE2S: case BLAKE2S:
derive_key_blake2s (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt, derive_key_blake2s (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize()); PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize(), &abortKeyDerivation);
break; break;
case WHIRLPOOL: case WHIRLPOOL:
derive_key_whirlpool (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt, derive_key_whirlpool (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize()); PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize(), &abortKeyDerivation);
break; break;
case STREEBOG: case STREEBOG:
derive_key_streebog(keyInfo->userKey, keyInfo->keyLength, keyInfo->salt, derive_key_streebog(keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize()); PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize(), &abortKeyDerivation);
break; break;
case ARGON2: case ARGON2:
derive_key_argon2(keyInfo->userKey, keyInfo->keyLength, keyInfo->salt, derive_key_argon2(keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, keyInfo->memoryCost, dk, GetMaxPkcs5OutSize()); PKCS5_SALT_SIZE, keyInfo->noIterations, keyInfo->memoryCost, dk, GetMaxPkcs5OutSize(), &abortKeyDerivation);
break; break;
#endif #endif
default: default:
@@ -615,6 +616,12 @@ KeyReady: ;
} }
status = ERR_SUCCESS; status = ERR_SUCCESS;
if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1))
{
// Signal other threads to stop
InterlockedExchange(&abortKeyDerivation, 1);
}
goto ret; goto ret;
} }
} }
@@ -622,6 +629,8 @@ KeyReady: ;
status = ERR_PASSWORD_WRONG; status = ERR_PASSWORD_WRONG;
err: err:
// Signal threads to stop
InterlockedExchange(&abortKeyDerivation, 1);
if (cryptoInfo != retHeaderCryptoInfo) if (cryptoInfo != retHeaderCryptoInfo)
{ {
crypto_close(cryptoInfo); crypto_close(cryptoInfo);
@@ -640,19 +649,33 @@ ret:
#if !defined(_UEFI) #if !defined(_UEFI)
if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1)) if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1))
{ {
EncryptionThreadPoolBeginReadVolumeHeaderFinalization (keyDerivationCompletedEvent, noOutstandingWorkItemEvent, outstandingWorkItemCount, // Wait for all outstanding threads to finish or cancel
keyInfoBuffer, keyInfoBufferSize, TC_WAIT_EVENT(*noOutstandingWorkItemEvent);
keyDerivationWorkItems, keyDerivationWorkItemsSize); // Cleanup is now synchronous because we already waited for all threads to stop.
} // The asynchronous finalization is no longer needed.
else #if !defined(DEVICE_DRIVER)
CloseHandle(*keyDerivationCompletedEvent);
CloseHandle(*noOutstandingWorkItemEvent);
#endif #endif
TCfree(keyDerivationCompletedEvent);
TCfree(noOutstandingWorkItemEvent);
TCfree(outstandingWorkItemCount);
if (keyDerivationWorkItems)
{ {
burn(keyDerivationWorkItems, keyDerivationWorkItemsSize);
#if !defined(DEVICE_DRIVER)
VirtualUnlock(keyDerivationWorkItems, keyDerivationWorkItemsSize);
#endif
TCfree(keyDerivationWorkItems);
}
}
#endif
burn (keyInfo, sizeof (KEY_INFO)); burn (keyInfo, sizeof (KEY_INFO));
#if !defined(DEVICE_DRIVER) && !defined(_UEFI) #if !defined(DEVICE_DRIVER)
VirtualUnlock (keyInfoBuffer, keyInfoBufferSize); VirtualUnlock (keyInfoBuffer, keyInfoBufferSize);
#endif #endif
TCfree(keyInfoBuffer); TCfree(keyInfoBuffer);
}
return status; return status;
} }
@@ -1018,33 +1041,33 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, unsigned char *header,
{ {
case SHA512: case SHA512:
derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt, derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize()); PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize(), NULL);
break; break;
case SHA256: case SHA256:
derive_key_sha256 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt, derive_key_sha256 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize()); PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize(), NULL);
break; break;
#ifndef WOLFCRYPT_BACKEND #ifndef WOLFCRYPT_BACKEND
case BLAKE2S: case BLAKE2S:
derive_key_blake2s (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt, derive_key_blake2s (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize()); PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize(), NULL);
break; break;
case WHIRLPOOL: case WHIRLPOOL:
derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt, derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize()); PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize(), NULL);
break; break;
case STREEBOG: case STREEBOG:
derive_key_streebog(keyInfo.userKey, keyInfo.keyLength, keyInfo.salt, derive_key_streebog(keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize()); PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize(), NULL);
break; break;
case ARGON2: case ARGON2:
derive_key_argon2(keyInfo.userKey, keyInfo.keyLength, keyInfo.salt, derive_key_argon2(keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, keyInfo.memoryCost, dk, GetMaxPkcs5OutSize()); PKCS5_SALT_SIZE, keyInfo.noIterations, keyInfo.memoryCost, dk, GetMaxPkcs5OutSize(), NULL);
break; break;
#endif #endif
default: default:

View File

@@ -165,7 +165,9 @@ typedef enum Argon2_ErrorCodes {
ARGON2_DECODING_LENGTH_FAIL = -34, ARGON2_DECODING_LENGTH_FAIL = -34,
ARGON2_VERIFY_MISMATCH = -35 ARGON2_VERIFY_MISMATCH = -35,
ARGON2_OPERATION_CANCELLED = -36
} argon2_error_codes; } argon2_error_codes;
/* Memory allocator types --- for external allocation */ /* Memory allocator types --- for external allocation */
@@ -222,6 +224,9 @@ typedef struct Argon2_Context {
uint32_t version; /* version number */ uint32_t version; /* version number */
/* Cancellation token for VeraCrypt */
long volatile *pAbortKeyDerivation;
allocate_fptr allocate_cbk; /* pointer to memory allocator */ allocate_fptr allocate_cbk; /* pointer to memory allocator */
deallocate_fptr free_cbk; /* pointer to memory deallocator */ deallocate_fptr free_cbk; /* pointer to memory deallocator */
@@ -275,20 +280,20 @@ ARGON2_PUBLIC int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd, const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt, const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash, const size_t saltlen, void *hash,
const size_t hashlen); const size_t hashlen, long volatile* pAbortKeyDerivation);
ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost, ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd, const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt, const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash, const size_t saltlen, void *hash,
const size_t hashlen); const size_t hashlen, long volatile* pAbortKeyDerivation);
ARGON2_PUBLIC int argon2id_hash_raw(const uint32_t t_cost, ARGON2_PUBLIC int argon2id_hash_raw(const uint32_t t_cost,
const uint32_t m_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd, const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt, const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash, const size_t saltlen, void *hash,
const size_t hashlen); const size_t hashlen, long volatile *pAbortKeyDerivation);
/* generic function underlying the above ones */ /* generic function underlying the above ones */
ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
@@ -296,7 +301,7 @@ ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
const size_t pwdlen, const void *salt, const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash, const size_t saltlen, void *hash,
const size_t hashlen, argon2_type type, const size_t hashlen, argon2_type type,
const uint32_t version); const uint32_t version, long volatile *pAbortKeyDerivation);
/** /**
* Argon2d: Version of Argon2 that picks memory blocks depending * Argon2d: Version of Argon2 that picks memory blocks depending

View File

@@ -24,6 +24,9 @@
#include <memory.h> #include <memory.h>
#include <stdlib.h> #include <stdlib.h>
#endif #endif
#include "Crypto/config.h"
#include "Crypto/cpu.h"
#include "Crypto/misc.h"
const char *argon2_type2string(argon2_type type, int uppercase) { const char *argon2_type2string(argon2_type type, int uppercase) {
switch (type) { switch (type) {
@@ -91,6 +94,9 @@ int argon2_ctx(argon2_context *context, argon2_type type) {
result = fill_memory_blocks(&instance); result = fill_memory_blocks(&instance);
if (ARGON2_OK != result) { if (ARGON2_OK != result) {
// If cancelled, we must still free the allocated memory!
free_memory(context, (uint8_t *)instance.memory,
instance.memory_blocks, sizeof(block));
return result; return result;
} }
/* 5. Finalization */ /* 5. Finalization */
@@ -103,7 +109,7 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd, const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt, const size_t saltlen, const size_t pwdlen, const void *salt, const size_t saltlen,
void *hash, const size_t hashlen, argon2_type type, void *hash, const size_t hashlen, argon2_type type,
const uint32_t version){ const uint32_t version, long volatile *pAbortKeyDerivation){
argon2_context context; argon2_context context;
int result; int result;
@@ -148,6 +154,7 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
context.free_cbk = NULL; context.free_cbk = NULL;
context.flags = ARGON2_DEFAULT_FLAGS; context.flags = ARGON2_DEFAULT_FLAGS;
context.version = version; context.version = version;
context.pAbortKeyDerivation = pAbortKeyDerivation;
result = argon2_ctx(&context, type); result = argon2_ctx(&context, type);
@@ -171,28 +178,28 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd, const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt, const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash, const size_t hashlen) { const size_t saltlen, void *hash, const size_t hashlen, long volatile* pAbortKeyDerivation) {
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
hash, hashlen, Argon2_i, ARGON2_VERSION_NUMBER); hash, hashlen, Argon2_i, ARGON2_VERSION_NUMBER, pAbortKeyDerivation);
} }
int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost, int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd, const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt, const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash, const size_t hashlen) { const size_t saltlen, void *hash, const size_t hashlen, long volatile* pAbortKeyDerivation) {
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
hash, hashlen, Argon2_d, ARGON2_VERSION_NUMBER); hash, hashlen, Argon2_d, ARGON2_VERSION_NUMBER, pAbortKeyDerivation);
} }
int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost, int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd, const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt, const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash, const size_t hashlen) { const size_t saltlen, void *hash, const size_t hashlen, long volatile *pAbortKeyDerivation) {
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
hash, hashlen, Argon2_id, hash, hashlen, Argon2_id,
ARGON2_VERSION_NUMBER); ARGON2_VERSION_NUMBER, pAbortKeyDerivation);
} }
int argon2d_ctx(argon2_context *context) { int argon2d_ctx(argon2_context *context) {

View File

@@ -140,6 +140,8 @@ static BLAKE2_INLINE void store48(void *dst, uint64_t w) {
*p++ = (uint8_t)w; *p++ = (uint8_t)w;
} }
/* removed since they are defined in VeraCrypt headers */
/*
static BLAKE2_INLINE uint32_t rotr32(const uint32_t w, const unsigned c) { static BLAKE2_INLINE uint32_t rotr32(const uint32_t w, const unsigned c) {
return (w >> c) | (w << (32 - c)); return (w >> c) | (w << (32 - c));
} }
@@ -147,7 +149,7 @@ static BLAKE2_INLINE uint32_t rotr32(const uint32_t w, const unsigned c) {
static BLAKE2_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) { static BLAKE2_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) {
return (w >> c) | (w << (64 - c)); return (w >> c) | (w << (64 - c));
} }
*/
void clear_internal_memory(void *v, size_t n); void clear_internal_memory(void *v, size_t n);
#endif #endif

View File

@@ -15,6 +15,9 @@
* software. If not, they may be obtained at the above URLs. * software. If not, they may be obtained at the above URLs.
*/ */
#include "Crypto/config.h"
#include "Crypto/cpu.h"
#include "Crypto/misc.h"
#include "blake2.h" #include "blake2.h"
#include "blake2-impl.h" #include "blake2-impl.h"

View File

@@ -20,13 +20,14 @@
#include "blake2-impl.h" #include "blake2-impl.h"
#include <emmintrin.h> /* remove to solve build errors under Windows Driver since */
//#include <emmintrin.h>
#if defined(__SSSE3__) #if defined(__SSSE3__)
#include <tmmintrin.h> /* for _mm_shuffle_epi8 and _mm_alignr_epi8 */ //#include <tmmintrin.h> /* for _mm_shuffle_epi8 and _mm_alignr_epi8 */
#endif #endif
#if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__)) #if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__))
#include <x86intrin.h> //#include <x86intrin.h>
#endif #endif
#if !defined(__AVX512F__) #if !defined(__AVX512F__)
@@ -180,7 +181,7 @@ static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) {
} while ((void)0, 0) } while ((void)0, 0)
#else /* __AVX2__ */ #else /* __AVX2__ */
#include <immintrin.h> //#include <immintrin.h>
#define rotr32(x) _mm256_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1)) #define rotr32(x) _mm256_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1))
#define rotr24(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) #define rotr24(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10))
@@ -329,7 +330,7 @@ static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) {
#else /* __AVX512F__ */ #else /* __AVX512F__ */
#include <immintrin.h> //#include <immintrin.h>
#define ror64(x, n) _mm512_ror_epi64((x), (n)) #define ror64(x, n) _mm512_ror_epi64((x), (n))

View File

@@ -19,6 +19,13 @@
#include "core.h" #include "core.h"
#include "Crypto/config.h"
#if !defined(_UEFI)
#include <memory.h>
#include <stdlib.h>
#endif
#include "Crypto/cpu.h"
#include "Crypto/misc.h"
#include "blake2/blake2.h" #include "blake2/blake2.h"
#include "blake2/blake2-impl.h" #include "blake2/blake2-impl.h"
@@ -206,12 +213,16 @@ uint32_t index_alpha(const argon2_instance_t *instance,
/* Single-threaded version for p=1 case */ /* Single-threaded version for p=1 case */
static int fill_memory_blocks_st(argon2_instance_t *instance) { static int fill_memory_blocks_st(argon2_instance_t *instance) {
uint32_t r, s, l; uint32_t r, s, l;
int result = ARGON2_OK;
for (r = 0; r < instance->passes; ++r) { for (r = 0; r < instance->passes; ++r) {
for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
for (l = 0; l < instance->lanes; ++l) { for (l = 0; l < instance->lanes; ++l) {
argon2_position_t position = {r, l, (uint8_t)s, 0}; argon2_position_t position = {r, l, (uint8_t)s, 0};
fill_segment(instance, position); result = fill_segment(instance, position);
if (result != ARGON2_OK) {
return result;
}
} }
} }
#ifdef GENKAT #ifdef GENKAT

View File

@@ -216,7 +216,7 @@ void finalize(const argon2_context *context, argon2_instance_t *instance);
* @param position Current position * @param position Current position
* @pre all block pointers must be valid * @pre all block pointers must be valid
*/ */
void fill_segment(const argon2_instance_t *instance, int fill_segment(const argon2_instance_t *instance,
argon2_position_t position); argon2_position_t position);
/* /*

View File

@@ -358,6 +358,8 @@ fill_block:
jne .L5 jne .L5
jmp .L4 jmp .L4
align 16
next_addresses: next_addresses:
push rdi push rdi
push rbx push rbx
@@ -386,6 +388,8 @@ next_addresses:
pop rdi pop rdi
ret ret
align 16
global fill_segment_avx2 global fill_segment_avx2
fill_segment_avx2: fill_segment_avx2:
push r15 push r15
@@ -403,7 +407,7 @@ fill_segment_avx2:
vmovdqu [rsp+48], xmm1 vmovdqu [rsp+48], xmm1
and r14, -32 and r14, -32
test rcx, rcx test rcx, rcx
je .L44 je .L37
mov edx, dword [rcx+36] mov edx, dword [rcx+36]
cmp edx, 1 cmp edx, 1
je .L18 je .L18
@@ -413,47 +417,54 @@ fill_segment_avx2:
je .L19 je .L19
mov ebp, dword [rsp+52] mov ebp, dword [rsp+52]
test r12d, r12d test r12d, r12d
jne .L37 je .L51
xor r12d, r12d
test al, al
sete r12b
xor r15d, r15d xor r15d, r15d
add r12d, r12d xor r12d, r12d
.L20: .L20:
mov r8d, dword [rbx+24] mov ecx, dword [rbx+24]
mov r9d, dword [rbx+20] mov r8d, dword [rbx+20]
xor edx, edx xor edx, edx
mov ecx, 128
mov rdi, r14 mov rdi, r14
imul ebp, r8d imul ebp, ecx
imul eax, r9d imul eax, r8d
add ebp, r12d add ebp, r12d
add ebp, eax add ebp, eax
mov eax, ebp mov eax, ebp
lea r13d, [rbp-1] lea r13d, [rbp-1]
div r8d div ecx
lea eax, [rbp+r8-1] lea eax, [rbp+rcx-1]
mov ecx, 128
test edx, edx test edx, edx
cmove r13d, eax cmove r13d, eax
lea rax, [rsp+64]
mov qword [rsp+40], rax
mov esi, r13d mov esi, r13d
sal rsi, 10 sal rsi, 10
add rsi, qword [rbx] add rsi, qword [rbx]
rep movsq rep movsq
cmp r12d, r9d cmp r12d, r8d
jnb .L44 jb .L24
lea rax, [rsp+1088] jmp .L36
mov qword [rsp+32], rax
lea rax, [rsp+64]
mov qword [rsp+40], rax
jmp .L35
align 16 align 16
align 8 align 8
.L46: .L53:
mov esi, r12d
and esi, 127
je .L52
.L29:
mov edx, dword [rsp+48]
mov eax, esi
mov ecx, dword [rsp+52]
mov r8, qword [rsp+64+rax*8]
test edx, edx
jne .L31
.L54:
cmp byte [rsp+56], 0 cmp byte [rsp+56], 0
jne .L30 jne .L31
mov rdi, rcx mov rsi, rcx
mov r9d, 1 mov r9d, 1
.L31: .L32:
lea rdx, [rsp+48] lea rdx, [rsp+48]
mov rcx, rbx mov rcx, rbx
mov dword [rsp+60], r12d mov dword [rsp+60], r12d
@@ -461,7 +472,7 @@ fill_segment_avx2:
mov edx, dword [rbx+24] mov edx, dword [rbx+24]
mov r8, qword [rbx] mov r8, qword [rbx]
mov eax, eax mov eax, eax
imul rdx, rdi imul rdx, rsi
add rdx, rax add rdx, rax
mov eax, ebp mov eax, ebp
sal rdx, 10 sal rdx, 10
@@ -469,55 +480,80 @@ fill_segment_avx2:
add rdx, r8 add rdx, r8
add r8, rax add r8, rax
cmp dword [rbx+8], 16 cmp dword [rbx+8], 16
je .L32 je .L33
mov eax, dword [rsp+48] mov eax, dword [rsp+48]
test eax, eax test eax, eax
je .L32 je .L33
mov r9d, 1 mov r9d, 1
mov rcx, r14 mov rcx, r14
call fill_block
.L34:
add r12d, 1 add r12d, 1
cmp r12d, dword [rbx+20]
jnb .L44
mov r8d, dword [rbx+24]
add ebp, 1 add ebp, 1
.L35: call fill_block
cmp r12d, dword [rbx+20]
jnb .L36
.L24:
test r12b, 63
jne .L25
mov rax, qword [rbx+48]
mov rax, qword [rax+96]
test rax, rax
je .L25
mov eax, dword [rax]
test eax, eax
jne .L41
.L25:
mov eax, ebp mov eax, ebp
xor edx, edx xor edx, edx
div r8d div dword [rbx+24]
cmp edx, 1 cmp edx, 1
je .L25 je .L26
mov eax, r13d mov eax, r13d
add r13d, 1 add r13d, 1
.L26: .L27:
test r15d, r15d test r15d, r15d
je .L27 jne .L53
mov edi, r12d
and edi, 127
je .L45
.L28:
mov eax, edi
mov r8, qword [rsp+64+rax*8]
.L29:
mov edx, dword [rsp+48] mov edx, dword [rsp+48]
sal rax, 10
add rax, qword [rbx]
mov r8, qword [rax]
mov ecx, dword [rsp+52] mov ecx, dword [rsp+52]
test edx, edx test edx, edx
je .L46 je .L54
.L30: .L31:
mov edi, dword [rbx+28] mov esi, dword [rbx+28]
mov rax, r8 mov rax, r8
xor edx, edx xor edx, edx
xor r9d, r9d xor r9d, r9d
shr rax, 32 shr rax, 32
div rdi div rsi
cmp rdx, rcx cmp rdx, rcx
mov rdi, rdx mov rsi, rdx
sete r9b sete r9b
jmp .L31 jmp .L32
align 16 align 16
align 8 align 8
.L44: .L51:
xor r12d, r12d
test al, al
sete r12b
xor r15d, r15d
add r12d, r12d
jmp .L20
align 16
align 8
.L33:
xor r9d, r9d
mov rcx, r14
add r12d, 1
add ebp, 1
call fill_block
cmp r12d, dword [rbx+20]
jb .L24
.L36:
xor eax, eax
.L16:
add rsp, 3160 add rsp, 3160
pop rbx pop rbx
pop rsi pop rsi
@@ -528,49 +564,33 @@ fill_segment_avx2:
pop r14 pop r14
pop r15 pop r15
ret ret
align 16
align 8
.L26:
lea eax, [rbp-1]
mov r13d, ebp
jmp .L27
align 16
align 8
.L52:
mov rcx, qword [rsp+40]
lea rdx, [rsp+1088]
call next_addresses
jmp .L29
align 16 align 16
align 8 align 8
.L19: .L19:
test r12d, r12d test r12d, r12d
jne .L47 jne .L55
cmp al, 1 cmp al, 1
jbe .L18 jbe .L18
mov ebp, dword [rsp+52] mov ebp, dword [rsp+52]
xor r15d, r15d xor r15d, r15d
jmp .L20 jmp .L20
align 16
align 8
.L32:
xor r9d, r9d
mov rcx, r14
call fill_block
jmp .L34
align 16
align 8
.L27:
sal rax, 10
add rax, qword [rbx]
mov r8, qword [rax]
jmp .L29
align 16
align 8
.L25:
lea eax, [rbp-1]
mov r13d, ebp
jmp .L26
align 16
align 8
.L45:
mov rdx, qword [rsp+32]
mov rcx, qword [rsp+40]
call next_addresses
jmp .L28
align 16
align 8
.L37:
xor r15d, r15d
xor r12d, r12d
jmp .L20
align 16 align 16
align 8 align 8
.L18: .L18:
@@ -583,18 +603,18 @@ fill_segment_avx2:
vpinsrd xmm0, xmm2, dword [rbx+36], 1 vpinsrd xmm0, xmm2, dword [rbx+36], 1
movzx edx, byte [rsp+56] movzx edx, byte [rsp+56]
mov qword [rsp+1088], rax mov qword [rsp+1088], rax
mov ecx, dword [rbx+16] mov edi, dword [rbx+16]
mov r12, rax mov r12, rax
mov eax, dword [rsp+52] mov eax, dword [rsp+52]
vpmovzxdq xmm0, xmm0 vpmovzxdq xmm0, xmm0
mov qword [rsp+1104], rdx mov qword [rsp+1104], rdx
mov qword [rsp+1112], rcx mov qword [rsp+1112], rdi
mov qword [rsp+1096], rax mov qword [rsp+1096], rax
mov rbp, rax mov rbp, rax
mov rax, rdx mov rax, rdx
vmovdqu [rsp+1120], xmm0 vmovdqu [rsp+1120], xmm0
test r12d, r12d test r12d, r12d
jne .L38 jne .L39
test dl, dl test dl, dl
jne .L20 jne .L20
lea rcx, [rsp+64] lea rcx, [rsp+64]
@@ -604,19 +624,28 @@ fill_segment_avx2:
mov ebp, dword [rsp+52] mov ebp, dword [rsp+52]
movzx eax, byte [rsp+56] movzx eax, byte [rsp+56]
jmp .L20 jmp .L20
align 16 align 16
align 8 align 8
.L47: .L41:
mov eax, -36
jmp .L16
.L55:
mov ebp, dword [rsp+52] mov ebp, dword [rsp+52]
xor r15d, r15d xor r15d, r15d
xor r12d, r12d xor r12d, r12d
jmp .L20 jmp .L20
align 16
align 8 .L39:
.L38:
xor r12d, r12d xor r12d, r12d
jmp .L20 jmp .L20
.L37:
mov eax, -25
jmp .L16
section .rdata align=32 section .rdata align=32
LC0: LC0:
db 3,4,5,6,7,0,1,2,11,12,13,14,15,8,9,10 db 3,4,5,6,7,0,1,2,11,12,13,14,15,8,9,10
@@ -626,8 +655,8 @@ LC1:
db 2,3,4,5,6,7,0,1,10,11,12,13,14,15,8,9 db 2,3,4,5,6,7,0,1,10,11,12,13,14,15,8,9
db 2,3,4,5,6,7,0,1,10,11,12,13,14,15,8,9 db 2,3,4,5,6,7,0,1,10,11,12,13,14,15,8,9
; External functions ; External symbols
extern index_alpha extern index_alpha
extern init_block_value extern init_block_value
; end of file ; End of file

View File

@@ -20,6 +20,9 @@
#include "argon2.h" #include "argon2.h"
#include "core.h" #include "core.h"
#include "Crypto/config.h"
#include "Crypto/cpu.h"
#include "Crypto/misc.h"
#if defined(__AVX2__) #if defined(__AVX2__)
@@ -88,7 +91,7 @@ static void next_addresses(block *address_block, block *input_block) {
fill_block(zero2_block, address_block, address_block, 0); fill_block(zero2_block, address_block, address_block, 0);
} }
void fill_segment_avx2(const argon2_instance_t *instance, int fill_segment_avx2(const argon2_instance_t *instance,
argon2_position_t position) { argon2_position_t position) {
block *ref_block = NULL, *curr_block = NULL; block *ref_block = NULL, *curr_block = NULL;
block address_block, input_block; block address_block, input_block;
@@ -99,7 +102,7 @@ void fill_segment_avx2(const argon2_instance_t *instance,
int data_independent_addressing; int data_independent_addressing;
if (instance == NULL) { if (instance == NULL) {
return; return ARGON2_INCORRECT_PARAMETER;
} }
data_independent_addressing = data_independent_addressing =
@@ -145,6 +148,12 @@ void fill_segment_avx2(const argon2_instance_t *instance,
for (i = starting_index; i < instance->segment_length; for (i = starting_index; i < instance->segment_length;
++i, ++curr_offset, ++prev_offset) { ++i, ++curr_offset, ++prev_offset) {
// Check every 64 blocks. This is a good balance for responsiveness.
if ((i & 63) == 0 && instance->context_ptr->pAbortKeyDerivation &&
*instance->context_ptr->pAbortKeyDerivation)
{
return ARGON2_OPERATION_CANCELLED; // Return cancellation code
}
/*1.1 Rotating prev_offset if needed */ /*1.1 Rotating prev_offset if needed */
if (curr_offset % instance->lane_length == 1) { if (curr_offset % instance->lane_length == 1) {
prev_offset = curr_offset - 1; prev_offset = curr_offset - 1;
@@ -191,11 +200,13 @@ void fill_segment_avx2(const argon2_instance_t *instance,
} }
} }
} }
return ARGON2_OK;
} }
#else #else
void fill_segment_avx2(const argon2_instance_t* instance, int fill_segment_avx2(const argon2_instance_t* instance,
argon2_position_t position) { argon2_position_t position) {
(void)instance; (void)instance;
(void)position; (void)position;
return ARGON2_INCORRECT_PARAMETER; /* AVX2 not available */
} }
#endif #endif

View File

@@ -19,12 +19,14 @@
#include "argon2.h" #include "argon2.h"
#include "core.h" #include "core.h"
#include "Crypto/config.h"
#include "Crypto/cpu.h"
#include "Crypto/misc.h"
#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE
#include "blake2/blake2.h" #include "blake2/blake2.h"
#include "blake2/blamka-round-opt.h" #include "blake2/blamka-round-opt.h"
#include "Crypto/config.h"
/* /*
* Function fills a new memory block and optionally XORs the old block over the new one. * Function fills a new memory block and optionally XORs the old block over the new one.
@@ -91,7 +93,7 @@ static void next_addresses(block *address_block, block *input_block) {
fill_block(zero2_block, address_block, address_block, 0); fill_block(zero2_block, address_block, address_block, 0);
} }
void fill_segment_sse2(const argon2_instance_t *instance, int fill_segment_sse2(const argon2_instance_t *instance,
argon2_position_t position) { argon2_position_t position) {
block *ref_block = NULL, *curr_block = NULL; block *ref_block = NULL, *curr_block = NULL;
block address_block, input_block; block address_block, input_block;
@@ -102,7 +104,7 @@ void fill_segment_sse2(const argon2_instance_t *instance,
int data_independent_addressing; int data_independent_addressing;
if (instance == NULL) { if (instance == NULL) {
return; return ARGON2_INCORRECT_PARAMETER;
} }
data_independent_addressing = data_independent_addressing =
@@ -148,6 +150,13 @@ void fill_segment_sse2(const argon2_instance_t *instance,
for (i = starting_index; i < instance->segment_length; for (i = starting_index; i < instance->segment_length;
++i, ++curr_offset, ++prev_offset) { ++i, ++curr_offset, ++prev_offset) {
// Check every 64 blocks. This is a good balance for responsiveness.
if ((i & 63) == 0 && instance->context_ptr->pAbortKeyDerivation &&
*instance->context_ptr->pAbortKeyDerivation)
{
return ARGON2_OPERATION_CANCELLED; // Return cancellation code
}
/*1.1 Rotating prev_offset if needed */ /*1.1 Rotating prev_offset if needed */
if (curr_offset % instance->lane_length == 1) { if (curr_offset % instance->lane_length == 1) {
prev_offset = curr_offset - 1; prev_offset = curr_offset - 1;
@@ -194,11 +203,13 @@ void fill_segment_sse2(const argon2_instance_t *instance,
} }
} }
} }
return ARGON2_OK;
} }
#else #else
void fill_segment_sse2(const argon2_instance_t* instance, int fill_segment_sse2(const argon2_instance_t* instance,
argon2_position_t position) { argon2_position_t position) {
(void)instance; (void)instance;
(void)position; (void)position;
return ARGON2_INCORRECT_PARAMETER; // SSE2 not available
} }
#endif #endif

View File

@@ -89,7 +89,7 @@ static void next_addresses(block *address_block, block *input_block,
fill_block(zero_block, address_block, address_block, 0); fill_block(zero_block, address_block, address_block, 0);
} }
void fill_segment_ref(const argon2_instance_t *instance, int fill_segment_ref(const argon2_instance_t *instance,
argon2_position_t position) { argon2_position_t position) {
block *ref_block = NULL, *curr_block = NULL; block *ref_block = NULL, *curr_block = NULL;
block address_block, input_block, zero_block; block address_block, input_block, zero_block;
@@ -100,7 +100,7 @@ void fill_segment_ref(const argon2_instance_t *instance,
int data_independent_addressing; int data_independent_addressing;
if (instance == NULL) { if (instance == NULL) {
return; return ARGON2_INCORRECT_PARAMETER;
} }
data_independent_addressing = data_independent_addressing =
@@ -145,6 +145,11 @@ void fill_segment_ref(const argon2_instance_t *instance,
for (i = starting_index; i < instance->segment_length; for (i = starting_index; i < instance->segment_length;
++i, ++curr_offset, ++prev_offset) { ++i, ++curr_offset, ++prev_offset) {
if ((i & 63) == 0 && instance->context_ptr->pAbortKeyDerivation &&
*instance->context_ptr->pAbortKeyDerivation)
{
return ARGON2_OPERATION_CANCELLED; // Return cancellation code
}
/*1.1 Rotating prev_offset if needed */ /*1.1 Rotating prev_offset if needed */
if (curr_offset % instance->lane_length == 1) { if (curr_offset % instance->lane_length == 1) {
prev_offset = curr_offset - 1; prev_offset = curr_offset - 1;
@@ -193,29 +198,30 @@ void fill_segment_ref(const argon2_instance_t *instance,
} }
} }
} }
return ARGON2_OK;
} }
#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
extern void fill_segment_sse2(const argon2_instance_t* instance, extern int fill_segment_sse2(const argon2_instance_t* instance,
argon2_position_t position); argon2_position_t position);
extern void fill_segment_avx2(const argon2_instance_t* instance, extern int fill_segment_avx2(const argon2_instance_t* instance,
argon2_position_t position); argon2_position_t position);
#endif #endif
void fill_segment(const argon2_instance_t* instance, int fill_segment(const argon2_instance_t* instance,
argon2_position_t position) { argon2_position_t position) {
#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
if (HasSAVX2()) if (HasSAVX2())
{ {
fill_segment_avx2(instance, position); return fill_segment_avx2(instance, position);
} }
else if (HasSSE2()) else if (HasSSE2())
{ {
fill_segment_sse2(instance, position); return fill_segment_sse2(instance, position);
} }
else else
#endif #endif
{ {
fill_segment_ref(instance, position); return fill_segment_ref(instance, position);
} }
} }

View File

@@ -92,6 +92,7 @@ static int argon2_selftest_ctx (void)
context.free_cbk = NULL; context.free_cbk = NULL;
context.flags = ARGON2_DEFAULT_FLAGS; context.flags = ARGON2_DEFAULT_FLAGS;
context.version = ARGON2_VERSION_13; context.version = ARGON2_VERSION_13;
context.pAbortKeyDerivation = NULL; /* No abort function */
/* Test execution for Argon2d, Argon2i, Argon2id */ /* Test execution for Argon2d, Argon2i, Argon2id */
@@ -118,7 +119,7 @@ static int hashtest (uint32_t t, uint32_t m, uint32_t p, const char *pwd,
uint8_t out[32]; uint8_t out[32];
return (argon2_hash(t, 1 << m, p, pwd, strlen (pwd), salt, strlen (salt), return (argon2_hash(t, 1 << m, p, pwd, strlen (pwd), salt, strlen (salt),
out, 32, type, ARGON2_VERSION_NUMBER) == ARGON2_OK && out, 32, type, ARGON2_VERSION_NUMBER, NULL) == ARGON2_OK &&
memcmp (out, ref, 32) == 0) ? 0 : 1; memcmp (out, ref, 32) == 0) ? 0 : 1;
} }

View File

@@ -143,6 +143,8 @@ extern __m128 _mm_shuffle_ps(__m128 _A, __m128 _B, unsigned int _Imm8);
extern __m128i _mm_srli_si128(__m128i _A, int _Imm); extern __m128i _mm_srli_si128(__m128i _A, int _Imm);
extern __m128i _mm_slli_si128(__m128i _A, int _Imm); extern __m128i _mm_slli_si128(__m128i _A, int _Imm);
extern __m128i _mm_setzero_si128(); extern __m128i _mm_setzero_si128();
extern __m128i _mm_mul_epu32(__m128i _A, __m128i _B);
extern __m128i _mm_slli_epi64(__m128i _A, int _Count);
#define _mm_xor_si64 _m_pxor #define _mm_xor_si64 _m_pxor
#define _mm_empty _m_empty #define _mm_empty _m_empty
#define _MM_SHUFFLE(fp3,fp2,fp1,fp0) (((fp3) << 6) | ((fp2) << 4) | \ #define _MM_SHUFFLE(fp3,fp2,fp1,fp0) (((fp3) << 6) | ((fp2) << 4) | \

View File

@@ -74,51 +74,51 @@ namespace VeraCrypt
void Pkcs5HmacBlake2s_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const void Pkcs5HmacBlake2s_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{ {
ValidateParameters (key, password, salt, iterationCount); ValidateParameters (key, password, salt, iterationCount);
derive_key_blake2s (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); derive_key_blake2s (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
} }
void Pkcs5HmacBlake2s::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const void Pkcs5HmacBlake2s::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{ {
ValidateParameters (key, password, salt, iterationCount); ValidateParameters (key, password, salt, iterationCount);
derive_key_blake2s (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); derive_key_blake2s (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
} }
#endif #endif
void Pkcs5HmacSha256_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const void Pkcs5HmacSha256_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{ {
ValidateParameters (key, password, salt, iterationCount); ValidateParameters (key, password, salt, iterationCount);
derive_key_sha256 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); derive_key_sha256 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
} }
void Pkcs5HmacSha256::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const void Pkcs5HmacSha256::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{ {
ValidateParameters (key, password, salt, iterationCount); ValidateParameters (key, password, salt, iterationCount);
derive_key_sha256 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); derive_key_sha256 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
} }
void Pkcs5HmacSha512::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const void Pkcs5HmacSha512::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{ {
ValidateParameters (key, password, salt, iterationCount); ValidateParameters (key, password, salt, iterationCount);
derive_key_sha512 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); derive_key_sha512 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
} }
#ifndef WOLFCRYPT_BACKEND #ifndef WOLFCRYPT_BACKEND
void Pkcs5HmacWhirlpool::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const void Pkcs5HmacWhirlpool::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{ {
ValidateParameters (key, password, salt, iterationCount); ValidateParameters (key, password, salt, iterationCount);
derive_key_whirlpool (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); derive_key_whirlpool (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
} }
void Pkcs5HmacStreebog::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const void Pkcs5HmacStreebog::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{ {
ValidateParameters (key, password, salt, iterationCount); ValidateParameters (key, password, salt, iterationCount);
derive_key_streebog (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); derive_key_streebog (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
} }
void Pkcs5HmacStreebog_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const void Pkcs5HmacStreebog_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
{ {
ValidateParameters (key, password, salt, iterationCount); ValidateParameters (key, password, salt, iterationCount);
derive_key_streebog (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); derive_key_streebog (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
} }
#endif #endif
} }