VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2022-03-07 00:45:30 +0100
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2022-03-08 00:29:26 +0100
commit36795a688fd1d5bb9f497970938d9fcb08cfc330 (patch)
tree24ffb2320c1f72c16b96c13fa4dddda4267065ee /src/Common
parent2dee49d3c8422aa1aa11c8630823aab3028cccd5 (diff)
downloadVeraCrypt-36795a688fd1d5bb9f497970938d9fcb08cfc330.tar.gz
VeraCrypt-36795a688fd1d5bb9f497970938d9fcb08cfc330.zip
Implement support of Blake2s-256 hash algorithm and remove deprecated algorithms RIPEMD-160 and GOST89.
Diffstat (limited to 'src/Common')
-rw-r--r--src/Common/BootEncryption.cpp18
-rw-r--r--src/Common/Crypto.c26
-rw-r--r--src/Common/Crypto.h14
-rw-r--r--src/Common/Dlgcode.c19
-rw-r--r--src/Common/EncryptionThreadPool.c4
-rw-r--r--src/Common/Pkcs5.c294
-rw-r--r--src/Common/Pkcs5.h6
-rw-r--r--src/Common/Random.c18
-rw-r--r--src/Common/Random.h2
-rw-r--r--src/Common/Tcdefs.h6
-rw-r--r--src/Common/Tests.c186
-rw-r--r--src/Common/Tests.h2
-rw-r--r--src/Common/Volumes.c34
13 files changed, 313 insertions, 316 deletions
diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp
index c3ce07ab..9a16db53 100644
--- a/src/Common/BootEncryption.cpp
+++ b/src/Common/BootEncryption.cpp
@@ -1705,15 +1705,11 @@ namespace VeraCrypt
ea = TWOFISH;
else if (_stricmp (request.BootEncryptionAlgorithmName, "Camellia") == 0)
ea = CAMELLIA;
-#if defined(CIPHER_GOST89)
- else if (_stricmp (request.BootEncryptionAlgorithmName, "GOST89") == 0)
- ea = GOST89;
-#endif
if (_stricmp(request.BootPrfAlgorithmName, "SHA-256") == 0)
pkcs5_prf = SHA256;
- else if (_stricmp(request.BootPrfAlgorithmName, "RIPEMD-160") == 0)
- pkcs5_prf = RIPEMD160;
+ else if (_stricmp(request.BootPrfAlgorithmName, "BLAKE2s-256") == 0)
+ pkcs5_prf = BLAKE2S;
else if (_stricmp(request.BootPrfAlgorithmName, "SHA-512") == 0)
pkcs5_prf = SHA512;
else if (_stricmp(request.BootPrfAlgorithmName, "Whirlpool") == 0)
@@ -1721,7 +1717,7 @@ namespace VeraCrypt
else if (_stricmp(request.BootPrfAlgorithmName, "Streebog") == 0)
pkcs5_prf = STREEBOG;
else if (strlen(request.BootPrfAlgorithmName) == 0) // case of version < 1.0f
- pkcs5_prf = RIPEMD160;
+ pkcs5_prf = BLAKE2S;
}
catch (...)
{
@@ -1747,8 +1743,8 @@ namespace VeraCrypt
pkcs5_prf = SelectedPrfAlgorithmId;
}
- // Only RIPEMD160 and SHA-256 are supported for MBR boot loader
- if (!bIsGPT && pkcs5_prf != RIPEMD160 && pkcs5_prf != SHA256)
+ // Only BLAKE2s and SHA-256 are supported for MBR boot loader
+ if (!bIsGPT && pkcs5_prf != BLAKE2S && pkcs5_prf != SHA256)
throw ParameterIncorrect (SRC_POS);
int bootSectorId = 0;
@@ -2222,7 +2218,7 @@ namespace VeraCrypt
EfiBootConf::EfiBootConf() : passwordType (0),
passwordMsg ("Password: "),
passwordPicture ("login.bmp"),
- hashMsg ("(0) TEST ALL (1) SHA512 (2) WHIRLPOOL (3) SHA256 (4) RIPEMD160 (5) STREEBOG\nHash: "),
+ hashMsg ("(0) TEST ALL (1) SHA512 (2) WHIRLPOOL (3) SHA256 (4) BLAKE2S (5) STREEBOG\nHash: "),
hashAlgo (0),
requestHash (0),
pimMsg ("PIM (Leave empty for default): "),
@@ -2339,7 +2335,7 @@ namespace VeraCrypt
passwordType = ReadConfigInteger (configContent, "PasswordType", 0);
passwordMsg = ReadConfigString (configContent, "PasswordMsg", "Password: ", buffer, sizeof (buffer));
passwordPicture = ReadConfigString (configContent, "PasswordPicture", "\\EFI\\VeraCrypt\\login.bmp", buffer, sizeof (buffer));
- //hashMsg = ReadConfigString (configContent, "HashMsg", "(0) TEST ALL (1) SHA512 (2) WHIRLPOOL (3) SHA256 (4) RIPEMD160 (5) STREEBOG\nHash: ", buffer, sizeof (buffer));
+ //hashMsg = ReadConfigString (configContent, "HashMsg", "(0) TEST ALL (1) SHA512 (2) WHIRLPOOL (3) SHA256 (4) BLAKE2S (5) STREEBOG\nHash: ", buffer, sizeof (buffer));
hashAlgo = ReadConfigInteger (configContent, "Hash", 0);
requestHash = ReadConfigInteger (configContent, "HashRqt", 1);
pimMsg = ReadConfigString (configContent, "PimMsg", "PIM: ", buffer, sizeof (buffer));
diff --git a/src/Common/Crypto.c b/src/Common/Crypto.c
index da233090..10c97e98 100644
--- a/src/Common/Crypto.c
+++ b/src/Common/Crypto.c
@@ -64,9 +64,6 @@ static Cipher Ciphers[] =
{ SERPENT, L"Serpent", 16, 32, 140*4 },
{ TWOFISH, L"Twofish", 16, 32, TWOFISH_KS },
{ CAMELLIA, L"Camellia", 16, 32, CAMELLIA_KS },
-#if defined(CIPHER_GOST89)
- { GOST89, L"GOST89", 16, 32, GOST_KS },
-#endif // defined(CIPHER_GOST89)
{ KUZNYECHIK, L"Kuznyechik",16, 32, KUZNYECHIK_KS },
#endif
{ 0, 0, 0, 0, 0 }
@@ -85,9 +82,6 @@ static EncryptionAlgorithm EncryptionAlgorithms[] =
{ { SERPENT, 0 }, { XTS, 0 }, 1, 1 },
{ { TWOFISH, 0 }, { XTS, 0 }, 1, 1 },
{ { CAMELLIA, 0 }, { XTS, 0 }, 1, 1 },
-#if defined(CIPHER_GOST89)
- { { GOST89, 0 }, { XTS, 0 }, 0, 0 },
-#endif // defined(CIPHER_GOST89)
{ { KUZNYECHIK, 0 }, { XTS, 0 }, 0, 1 },
{ { TWOFISH, AES, 0 }, { XTS, 0 }, 1, 1 },
{ { SERPENT, TWOFISH, AES, 0 }, { XTS, 0 }, 1, 1 },
@@ -126,8 +120,8 @@ static Hash Hashes[] =
{ // ID Name Deprecated System Encryption
{ SHA512, L"SHA-512", FALSE, FALSE },
{ WHIRLPOOL, L"Whirlpool", FALSE, FALSE },
+ { BLAKE2S, L"BLAKE2s-256", FALSE, TRUE },
{ SHA256, L"SHA-256", FALSE, TRUE },
- { RIPEMD160, L"RIPEMD-160", TRUE, TRUE },
{ STREEBOG, L"Streebog", FALSE, FALSE },
{ 0, 0, 0 }
};
@@ -168,11 +162,6 @@ int CipherInit (int cipher, unsigned char *key, unsigned __int8 *ks)
#endif
#if !defined(TC_WINDOWS_BOOT)
-#if defined(CIPHER_GOST89)
- case GOST89:
- gost_set_key(key, (gost_kds*)ks, 1);
- break;
-#endif // && defined(CIPHER_GOST89)
case KUZNYECHIK:
kuznyechik_set_key(key, (kuznyechik_kds*)ks);
break;
@@ -206,9 +195,6 @@ void EncipherBlock(int cipher, void *data, void *ks)
case CAMELLIA: camellia_encrypt (data, data, ks); break;
#endif
#if !defined(TC_WINDOWS_BOOT)
-#if defined(CIPHER_GOST89)
- case GOST89: gost_encrypt(data, data, ks, 1); break;
-#endif // defined(CIPHER_GOST89)
case KUZNYECHIK: kuznyechik_encrypt_block(data, data, ks); break;
#endif // !defined(TC_WINDOWS_BOOT)
default: TC_THROW_FATAL_EXCEPTION; // Unknown/wrong ID
@@ -281,9 +267,6 @@ void EncipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
#endif
}
#endif
- else if (cipher == GOST89) {
- gost_encrypt(data, data, ks, (int)blockCount);
- }
else
{
size_t blockSize = CipherGetBlockSize (cipher);
@@ -307,9 +290,6 @@ void DecipherBlock(int cipher, void *data, void *ks)
case CAMELLIA: camellia_decrypt (data, data, ks); break;
#endif
#if !defined(TC_WINDOWS_BOOT)
-#if defined(CIPHER_GOST89)
- case GOST89: gost_decrypt(data, data, ks, 1); break;
-#endif // defined(CIPHER_GOST89)
case KUZNYECHIK: kuznyechik_decrypt_block(data, data, ks); break;
#endif // !defined(TC_WINDOWS_BOOT)
@@ -398,9 +378,6 @@ void DecipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
#endif
}
#endif
- else if (cipher == GOST89) {
- gost_decrypt(data, data, ks, (int)blockCount);
- }
else
{
size_t blockSize = CipherGetBlockSize (cipher);
@@ -466,7 +443,6 @@ int CipherGetKeyScheduleSize (int cipherId)
BOOL CipherSupportsIntraDataUnitParallelization (int cipher)
{
return (cipher == AES && IsAesHwCpuSupported())
- || (cipher == GOST89)
#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && !defined (_UEFI)
|| (cipher == SERPENT && HasSSE2())
|| (cipher == KUZNYECHIK && HasSSE2())
diff --git a/src/Common/Crypto.h b/src/Common/Crypto.h
index 95222ba6..b9600cf9 100644
--- a/src/Common/Crypto.h
+++ b/src/Common/Crypto.h
@@ -53,7 +53,7 @@ enum
SHA512 = FIRST_PRF_ID,
WHIRLPOOL,
SHA256,
- RIPEMD160,
+ BLAKE2S,
STREEBOG,
HASH_ENUM_END_ID
};
@@ -61,8 +61,8 @@ enum
// The last PRF to try when mounting and also the number of implemented PRFs
#define LAST_PRF_ID (HASH_ENUM_END_ID - 1)
-#define RIPEMD160_BLOCKSIZE 64
-#define RIPEMD160_DIGESTSIZE 20
+#define BLAKE2S_BLOCKSIZE 64
+#define BLAKE2S_DIGESTSIZE 32
#define SHA256_BLOCKSIZE 64
#define SHA256_DIGESTSIZE 32
@@ -112,7 +112,6 @@ enum
SERPENT,
TWOFISH,
CAMELLIA,
- GOST89,
KUZNYECHIK
};
@@ -173,7 +172,7 @@ typedef struct
#ifdef TC_WINDOWS_BOOT
#define MAX_EXPANDED_KEY VC_MAX((AES_KS + SERPENT_KS + TWOFISH_KS), CAMELLIA_KS)
#else
-#define MAX_EXPANDED_KEY VC_MAX(VC_MAX(VC_MAX(VC_MAX((AES_KS + SERPENT_KS + TWOFISH_KS), GOST_KS), CAMELLIA_KS + KUZNYECHIK_KS + SERPENT_KS), KUZNYECHIK_KS + TWOFISH_KS), AES_KS + KUZNYECHIK_KS)
+#define MAX_EXPANDED_KEY VC_MAX(VC_MAX(VC_MAX((AES_KS + SERPENT_KS + TWOFISH_KS), CAMELLIA_KS + KUZNYECHIK_KS + SERPENT_KS), KUZNYECHIK_KS + TWOFISH_KS), AES_KS + KUZNYECHIK_KS)
#endif
#endif
@@ -200,12 +199,11 @@ typedef struct
#endif
#include "Twofish.h"
-#include "Rmd160.h"
+#include "blake2.h"
#ifndef TC_WINDOWS_BOOT
# include "Sha2.h"
# include "Whirlpool.h"
# include "Streebog.h"
-# include "GostCipher.h"
# include "kuznyechik.h"
# include "Camellia.h"
#if !defined (_UEFI)
@@ -252,7 +250,7 @@ typedef struct CRYPTO_INFO_t
uint16 HeaderVersion;
#ifdef TC_WINDOWS_DRIVER
- unsigned __int8 master_keydata_hash[RIPEMD160_DIGESTSIZE];
+ unsigned __int8 master_keydata_hash[BLAKE2S_DIGESTSIZE];
#else
CRYPTOPP_ALIGN_DATA(16) unsigned __int8 master_keydata[MASTER_KEYDATA_SIZE]; /* This holds the volume header area containing concatenated master key(s) and secondary key(s) (XTS mode). For LRW (deprecated/legacy), it contains the tweak key before the master key(s). For CBC (deprecated/legacy), it contains the IV seed before the master key(s). */
CRYPTOPP_ALIGN_DATA(16) unsigned __int8 k2[MASTER_KEYDATA_SIZE]; /* For XTS, this contains the secondary key (if cascade, multiple concatenated). For LRW (deprecated/legacy), it contains the tweak key. For CBC (deprecated/legacy), it contains the IV seed. */
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index f26ae38c..9d5c0d06 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -6412,7 +6412,7 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg)
{
BYTE digest [MAX_DIGESTSIZE];
WHIRLPOOL_CTX wctx;
- RMD160_CTX rctx;
+ blake2s_state bctx;
sha512_ctx s2ctx;
sha256_ctx s256ctx;
STREEBOG_CTX stctx;
@@ -6441,10 +6441,10 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg)
sha256_end ((unsigned char *) digest, &s256ctx);
break;
- case RIPEMD160:
- RMD160Init(&rctx);
- RMD160Update(&rctx, lpTestBuffer, benchmarkBufferSize);
- RMD160Final((unsigned char *) digest, &rctx);
+ case BLAKE2S:
+ blake2s_init(&bctx);
+ blake2s_update(&bctx, lpTestBuffer, benchmarkBufferSize);
+ blake2s_final(&bctx, (unsigned char *) digest);
break;
case WHIRLPOOL:
@@ -6509,9 +6509,9 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg)
derive_key_sha256 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, FALSE, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE);
break;
- case RIPEMD160:
- /* PKCS-5 test with HMAC-RIPEMD-160 used as the PRF */
- derive_key_ripemd160 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, FALSE, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE);
+ case BLAKE2S:
+ /* PKCS-5 test with HMAC-BLAKE2s used as the PRF */
+ derive_key_blake2s ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, FALSE, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE);
break;
case WHIRLPOOL:
@@ -7895,9 +7895,6 @@ ResetCipherTest(HWND hwndDlg, int idTestCipher)
SetWindowText(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), L"0000000000000000");
if (idTestCipher == AES || idTestCipher == SERPENT || idTestCipher == TWOFISH || idTestCipher == CAMELLIA
-#if defined(CIPHER_GOST89)
- || idTestCipher == GOST89
-#endif
|| idTestCipher == KUZNYECHIK
)
{
diff --git a/src/Common/EncryptionThreadPool.c b/src/Common/EncryptionThreadPool.c
index 1401e8a0..62b2cae8 100644
--- a/src/Common/EncryptionThreadPool.c
+++ b/src/Common/EncryptionThreadPool.c
@@ -248,8 +248,8 @@ static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
case DeriveKeyWork:
switch (workItem->KeyDerivation.Pkcs5Prf)
{
- case RIPEMD160:
- derive_key_ripemd160 (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
+ case BLAKE2S:
+ derive_key_blake2s (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize());
break;
diff --git a/src/Common/Pkcs5.c b/src/Common/Pkcs5.c
index 3ac3cc2c..10d33ff0 100644
--- a/src/Common/Pkcs5.c
+++ b/src/Common/Pkcs5.c
@@ -16,7 +16,7 @@
#include <memory.h>
#include <stdlib.h>
#endif
-#include "Rmd160.h"
+#include "blake2.h"
#ifndef TC_WINDOWS_BOOT
#include "Sha2.h"
#include "Whirlpool.h"
@@ -550,100 +550,131 @@ void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, uint32
#endif // TC_WINDOWS_BOOT
-#if !defined(TC_WINDOWS_BOOT) || defined(TC_WINDOWS_BOOT_RIPEMD160)
+#if !defined(TC_WINDOWS_BOOT) || defined(TC_WINDOWS_BOOT_BLAKE2S)
-typedef struct hmac_ripemd160_ctx_struct
+typedef struct hmac_blake2s_ctx_struct
{
- RMD160_CTX context;
- RMD160_CTX inner_digest_ctx; /*pre-computed inner digest context */
- RMD160_CTX outer_digest_ctx; /*pre-computed outer digest context */
- char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the RIPEMD-160 hash */
- char u[RIPEMD160_DIGESTSIZE];
-} hmac_ripemd160_ctx;
-
-void hmac_ripemd160_internal (char *input_digest, int len, hmac_ripemd160_ctx* hmac)
+ blake2s_state ctx;
+ blake2s_state inner_digest_ctx; /*pre-computed inner digest context */
+ blake2s_state outer_digest_ctx; /*pre-computed outer digest context */
+ char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the SHA256 hash */
+ char u[BLAKE2S_DIGESTSIZE];
+} hmac_blake2s_ctx;
+
+void hmac_blake2s_internal
+(
+ char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */
+ int ld, /* length of input data in bytes */
+ hmac_blake2s_ctx* hmac /* HMAC-SHA256 context which holds temporary variables */
+)
{
- RMD160_CTX* context = &(hmac->context);
+ blake2s_state* ctx = &(hmac->ctx);
/**** Restore Precomputed Inner Digest Context ****/
- memcpy (context, &(hmac->inner_digest_ctx), sizeof (RMD160_CTX));
+ memcpy (ctx, &(hmac->inner_digest_ctx), sizeof (blake2s_state));
- RMD160Update(context, (const unsigned char *) input_digest, len); /* then text of datagram */
- RMD160Final((unsigned char *) input_digest, context); /* finish up 1st pass */
+ blake2s_update (ctx, d, ld);
+
+ blake2s_final (ctx, (unsigned char*) d); /* d = inner digest */
/**** Restore Precomputed Outer Digest Context ****/
- memcpy (context, &(hmac->outer_digest_ctx), sizeof (RMD160_CTX));
+ memcpy (ctx, &(hmac->outer_digest_ctx), sizeof (blake2s_state));
+
+ blake2s_update (ctx, d, SHA256_DIGESTSIZE);
- /* results of 1st hash */
- RMD160Update(context, (const unsigned char *) input_digest, RIPEMD160_DIGESTSIZE);
- RMD160Final((unsigned char *) input_digest, context); /* finish up 2nd pass */
+ blake2s_final (ctx, (unsigned char *) d); /* d = outer digest */
}
#ifndef TC_WINDOWS_BOOT
-void hmac_ripemd160 (char *key, int keylen, char *input_digest, int len)
+void hmac_blake2s
+(
+ char *k, /* secret key */
+ int lk, /* length of the key in bytes */
+ char *d, /* data */
+ int ld /* length of data in bytes */
+)
{
- hmac_ripemd160_ctx hmac;
- RMD160_CTX* ctx;
- unsigned char* k_pad = (unsigned char*) hmac.k; /* inner/outer padding - key XORd with ipad */
- unsigned char tk[RIPEMD160_DIGESTSIZE];
- int i;
-
- /* If the key is longer than the hash algorithm block size,
- let key = ripemd160(key), as per HMAC specifications. */
- if (keylen > RIPEMD160_BLOCKSIZE)
+ hmac_blake2s_ctx hmac;
+ blake2s_state* ctx;
+ char* buf = hmac.k;
+ int b;
+ char key[BLAKE2S_DIGESTSIZE];
+#if defined (DEVICE_DRIVER)
+ NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
+#ifdef _WIN64
+ XSTATE_SAVE SaveState;
+ if (IsCpuIntel() && HasSAVX())
+ saveStatus = KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState);
+#else
+ KFLOATING_SAVE floatingPointState;
+ if (HasSSE2())
+ saveStatus = KeSaveFloatingPointState (&floatingPointState);
+#endif
+#endif
+ /* If the key is longer than the hash algorithm block size,
+ let key = blake2s(key), as per HMAC specifications. */
+ if (lk > BLAKE2S_BLOCKSIZE)
{
- RMD160_CTX tctx;
+ blake2s_state tctx;
- RMD160Init(&tctx);
- RMD160Update(&tctx, (const unsigned char *) key, keylen);
- RMD160Final(tk, &tctx);
+ blake2s_init (&tctx);
+ blake2s_update (&tctx, k, lk);
+ blake2s_final (&tctx, (unsigned char *) key);
- key = (char *) tk;
- keylen = RIPEMD160_DIGESTSIZE;
+ k = key;
+ lk = BLAKE2S_DIGESTSIZE;
- burn (&tctx, sizeof(tctx)); // Prevent leaks
- }
+ burn (&tctx, sizeof(tctx)); // Prevent leaks
+ }
+
+ /**** Precompute HMAC Inner Digest ****/
- /* perform inner RIPEMD-160 */
ctx = &(hmac.inner_digest_ctx);
- /* start out by storing key in pads */
- memset(k_pad, 0x36, 64);
- /* XOR key with ipad and opad values */
- for (i=0; i<keylen; i++)
- {
- k_pad[i] ^= key[i];
- }
+ blake2s_init (ctx);
- RMD160Init(ctx); /* init context for 1st pass */
- RMD160Update(ctx, k_pad, RIPEMD160_BLOCKSIZE); /* start with inner pad */
+ /* Pad the key for inner digest */
+ for (b = 0; b < lk; ++b)
+ buf[b] = (char) (k[b] ^ 0x36);
+ memset (&buf[lk], 0x36, BLAKE2S_BLOCKSIZE - lk);
+
+ blake2s_update (ctx, (unsigned char *) buf, BLAKE2S_BLOCKSIZE);
+
+ /**** Precompute HMAC Outer Digest ****/
- /* perform outer RIPEMD-160 */
ctx = &(hmac.outer_digest_ctx);
- memset(k_pad, 0x5c, 64);
- for (i=0; i<keylen; i++)
- {
- k_pad[i] ^= key[i];
- }
+ blake2s_init (ctx);
- RMD160Init(ctx); /* init context for 2nd pass */
- RMD160Update(ctx, k_pad, RIPEMD160_BLOCKSIZE); /* start with outer pad */
+ for (b = 0; b < lk; ++b)
+ buf[b] = (char) (k[b] ^ 0x5C);
+ memset (&buf[lk], 0x5C, SHA256_BLOCKSIZE - lk);
- hmac_ripemd160_internal (input_digest, len, &hmac);
+ blake2s_update (ctx, (unsigned char *) buf, BLAKE2S_BLOCKSIZE);
- burn (&hmac, sizeof(hmac));
- burn (tk, sizeof(tk));
-}
+ hmac_blake2s_internal(d, ld, &hmac);
+
+#if defined (DEVICE_DRIVER)
+ if (NT_SUCCESS (saveStatus))
+#ifdef _WIN64
+ KeRestoreExtendedProcessorStateVC(&SaveState);
+#else
+ KeRestoreFloatingPointState (&floatingPointState);
+#endif
#endif
+ /* Prevent leaks */
+ burn(&hmac, sizeof(hmac));
+ burn(key, sizeof(key));
+}
+#endif
-static void derive_u_ripemd160 (char *salt, int salt_len, uint32 iterations, int b, hmac_ripemd160_ctx* hmac)
+static void derive_u_blake2s (char *salt, int salt_len, uint32 iterations, int b, hmac_blake2s_ctx* hmac)
{
char* k = hmac->k;
char* u = hmac->u;
uint32 c;
- int i;
+ int i;
#ifdef TC_WINDOWS_BOOT
/* In bootloader mode, least significant bit of iterations is a boolean (TRUE for boot derivation mode, FALSE otherwise)
@@ -653,11 +684,11 @@ static void derive_u_ripemd160 (char *salt, int salt_len, uint32 iterations, int
c = iterations >> 16;
i = ((int) iterations) & 0x01;
if (i)
- c = (c == 0)? 327661 : c << 11;
+ c = (c == 0)? 200000 : c << 11;
else
- c = (c == 0)? 655331 : 15000 + c * 1000;
+ c = (c == 0)? 500000 : 15000 + c * 1000;
#else
- c = iterations;
+ c = iterations;
#endif
/* iteration 1 */
@@ -665,7 +696,7 @@ static void derive_u_ripemd160 (char *salt, int salt_len, uint32 iterations, int
/* big-endian block number */
#ifdef TC_WINDOWS_BOOT
- /* specific case of 16-bit bootloader: b is a 16-bit integer that is always < 256*/
+ /* specific case of 16-bit bootloader: b is a 16-bit integer that is always < 256 */
memset (&k[salt_len], 0, 3);
k[salt_len + 3] = (char) b;
#else
@@ -673,14 +704,14 @@ static void derive_u_ripemd160 (char *salt, int salt_len, uint32 iterations, int
memcpy (&k[salt_len], &b, 4);
#endif
- hmac_ripemd160_internal (k, salt_len + 4, hmac);
- memcpy (u, k, RIPEMD160_DIGESTSIZE);
+ hmac_blake2s_internal (k, salt_len + 4, hmac);
+ memcpy (u, k, BLAKE2S_DIGESTSIZE);
/* remaining iterations */
- while ( c > 1)
+ while (c > 1)
{
- hmac_ripemd160_internal (k, RIPEMD160_DIGESTSIZE, hmac);
- for (i = 0; i < RIPEMD160_DIGESTSIZE; i++)
+ hmac_blake2s_internal (k, BLAKE2S_DIGESTSIZE, hmac);
+ for (i = 0; i < BLAKE2S_DIGESTSIZE; i++)
{
u[i] ^= k[i];
}
@@ -688,86 +719,107 @@ static void derive_u_ripemd160 (char *salt, int salt_len, uint32 iterations, int
}
}
-void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen)
+
+void derive_key_blake2s (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen)
{
+ hmac_blake2s_ctx hmac;
+ blake2s_state* ctx;
+ char* buf = hmac.k;
int b, l, r;
- hmac_ripemd160_ctx hmac;
- RMD160_CTX* ctx;
- unsigned char* k_pad = (unsigned char*) hmac.k;
#ifndef TC_WINDOWS_BOOT
- unsigned char tk[RIPEMD160_DIGESTSIZE];
+ char key[BLAKE2S_DIGESTSIZE];
+#if defined (DEVICE_DRIVER)
+ NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
+#ifdef _WIN64
+ XSTATE_SAVE SaveState;
+ if (IsCpuIntel() && HasSAVX())
+ saveStatus = KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState);
+#else
+ KFLOATING_SAVE floatingPointState;
+ if (HasSSE2())
+ saveStatus = KeSaveFloatingPointState (&floatingPointState);
+#endif
+#endif
/* If the password is longer than the hash algorithm block size,
- let password = ripemd160(password), as per HMAC specifications. */
- if (pwd_len > RIPEMD160_BLOCKSIZE)
+ let pwd = blake2s(pwd), as per HMAC specifications. */
+ if (pwd_len > BLAKE2S_BLOCKSIZE)
{
- RMD160_CTX tctx;
+ blake2s_state tctx;
- RMD160Init(&tctx);
- RMD160Update(&tctx, (const unsigned char *) pwd, pwd_len);
- RMD160Final(tk, &tctx);
+ blake2s_init (&tctx);
+ blake2s_update (&tctx, pwd, pwd_len);
+ blake2s_final (&tctx, (unsigned char *) key);
- pwd = (char *) tk;
- pwd_len = RIPEMD160_DIGESTSIZE;
+ pwd = key;
+ pwd_len = SHA256_DIGESTSIZE;
- burn (&tctx, sizeof(tctx)); // Prevent leaks
- }
+ burn (&tctx, sizeof(tctx)); // Prevent leaks
+ }
#endif
- if (dklen % RIPEMD160_DIGESTSIZE)
+ if (dklen % BLAKE2S_DIGESTSIZE)
{
- l = 1 + dklen / RIPEMD160_DIGESTSIZE;
+ l = 1 + dklen / BLAKE2S_DIGESTSIZE;
}
else
{
- l = dklen / RIPEMD160_DIGESTSIZE;
+ l = dklen / BLAKE2S_DIGESTSIZE;
}
- r = dklen - (l - 1) * RIPEMD160_DIGESTSIZE;
+ r = dklen - (l - 1) * BLAKE2S_DIGESTSIZE;
+
+ /**** Precompute HMAC Inner Digest ****/
- /* perform inner RIPEMD-160 */
ctx = &(hmac.inner_digest_ctx);
- /* start out by storing key in pads */
- memset(k_pad, 0x36, 64);
- /* XOR key with ipad and opad values */
- for (b=0; b<pwd_len; b++)
- {
- k_pad[b] ^= pwd[b];
- }
+ blake2s_init (ctx);
+
+ /* Pad the key for inner digest */
+ for (b = 0; b < pwd_len; ++b)
+ buf[b] = (char) (pwd[b] ^ 0x36);
+ memset (&buf[pwd_len], 0x36, BLAKE2S_BLOCKSIZE - pwd_len);
+
+ blake2s_update (ctx, buf, BLAKE2S_BLOCKSIZE);
- RMD160Init(ctx); /* init context for 1st pass */
- RMD160Update(ctx, k_pad, RIPEMD160_BLOCKSIZE); /* start with inner pad */
+ /**** Precompute HMAC Outer Digest ****/
- /* perform outer RIPEMD-160 */
ctx = &(hmac.outer_digest_ctx);
- memset(k_pad, 0x5c, 64);
- for (b=0; b<pwd_len; b++)
- {
- k_pad[b] ^= pwd[b];
- }
+ blake2s_init (ctx);
+
+ for (b = 0; b < pwd_len; ++b)
+ buf[b] = (char) (pwd[b] ^ 0x5C);
+ memset (&buf[pwd_len], 0x5C, BLAKE2S_BLOCKSIZE - pwd_len);
- RMD160Init(ctx); /* init context for 2nd pass */
- RMD160Update(ctx, k_pad, RIPEMD160_BLOCKSIZE); /* start with outer pad */
+ blake2s_update (ctx, buf, BLAKE2S_BLOCKSIZE);
/* first l - 1 blocks */
for (b = 1; b < l; b++)
{
- derive_u_ripemd160 (salt, salt_len, iterations, b, &hmac);
- memcpy (dk, hmac.u, RIPEMD160_DIGESTSIZE);
- dk += RIPEMD160_DIGESTSIZE;
+ derive_u_blake2s (salt, salt_len, iterations, b, &hmac);
+ memcpy (dk, hmac.u, BLAKE2S_DIGESTSIZE);
+ dk += BLAKE2S_DIGESTSIZE;
}
/* last block */
- derive_u_ripemd160 (salt, salt_len, iterations, b, &hmac);
+ derive_u_blake2s (salt, salt_len, iterations, b, &hmac);
memcpy (dk, hmac.u, r);
+#if defined (DEVICE_DRIVER)
+ if (NT_SUCCESS (saveStatus))
+#ifdef _WIN64
+ KeRestoreExtendedProcessorStateVC(&SaveState);
+#else
+ KeRestoreFloatingPointState (&floatingPointState);
+#endif
+#endif
/* Prevent possible leaks. */
burn (&hmac, sizeof(hmac));
#ifndef TC_WINDOWS_BOOT
- burn (tk, sizeof(tk));
+ burn (key, sizeof(key));
#endif
}
-#endif // TC_WINDOWS_BOOT
+
+#endif
#ifndef TC_WINDOWS_BOOT
@@ -1210,8 +1262,8 @@ wchar_t *get_pkcs5_prf_name (int pkcs5_prf_id)
case SHA256:
return L"HMAC-SHA-256";
- case RIPEMD160:
- return L"HMAC-RIPEMD-160";
+ case BLAKE2S:
+ return L"HMAC-BLAKE2s";
case WHIRLPOOL:
return L"HMAC-Whirlpool";
@@ -1238,11 +1290,11 @@ int get_pkcs5_iteration_count (int pkcs5_prf_id, int pim, BOOL truecryptMode, BO
switch (pkcs5_prf_id)
{
- case RIPEMD160:
+ case BLAKE2S:
if (truecryptMode)
- return bBoot ? 1000 : 2000;
+ return 0; // BLAKE2s not supported by TrueCrypt
else if (pim == 0)
- return bBoot? 327661 : 655331;
+ return bBoot? 200000 : 500000;
else
{
return bBoot? pim * 2048 : 15000 + pim * 1000;
@@ -1290,14 +1342,14 @@ int is_pkcs5_prf_supported (int pkcs5_prf_id, BOOL truecryptMode, PRF_BOOT_TYPE
if (truecryptMode)
{
if ( (bootType == PRF_BOOT_GPT)
- || (bootType == PRF_BOOT_MBR && pkcs5_prf_id != RIPEMD160)
- || (bootType == PRF_BOOT_NO && pkcs5_prf_id != SHA512 && pkcs5_prf_id != WHIRLPOOL && pkcs5_prf_id != RIPEMD160)
+ || (bootType == PRF_BOOT_MBR)
+ || (bootType == PRF_BOOT_NO && pkcs5_prf_id != SHA512 && pkcs5_prf_id != WHIRLPOOL)
)
return 0;
}
else
{
- if ( (bootType == PRF_BOOT_MBR && pkcs5_prf_id != RIPEMD160 && pkcs5_prf_id != SHA256)
+ if ( (bootType == PRF_BOOT_MBR && pkcs5_prf_id != BLAKE2S && pkcs5_prf_id != SHA256)
|| (bootType != PRF_BOOT_MBR && (pkcs5_prf_id < FIRST_PRF_ID || pkcs5_prf_id > LAST_PRF_ID))
)
return 0;
diff --git a/src/Common/Pkcs5.h b/src/Common/Pkcs5.h
index 98d8bf74..4a6b6882 100644
--- a/src/Common/Pkcs5.h
+++ b/src/Common/Pkcs5.h
@@ -20,9 +20,9 @@
extern "C"
{
#endif
-/* output written to input_digest which must be at lease 20 bytes long */
-void hmac_ripemd160 (char *key, int keylen, char *input_digest, int len);
-void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen);
+/* output written to input_digest which must be at lease 32 bytes long */
+void hmac_blake2s (char *key, int keylen, char *input_digest, int len);
+void derive_key_blake2s (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen);
/* output written to d which must be at lease 32 bytes long */
void hmac_sha256 (char *k, int lk, char *d, int ld);
diff --git a/src/Common/Random.c b/src/Common/Random.c
index 1080ce7e..c44c69d7 100644
--- a/src/Common/Random.c
+++ b/src/Common/Random.c
@@ -263,7 +263,7 @@ BOOL Randmix ()
{
unsigned char hashOutputBuffer [MAX_DIGESTSIZE];
WHIRLPOOL_CTX wctx;
- RMD160_CTX rctx;
+ blake2s_state bctx;
sha512_ctx sctx;
sha256_ctx s256ctx;
STREEBOG_CTX stctx;
@@ -271,8 +271,8 @@ BOOL Randmix ()
switch (HashFunction)
{
- case RIPEMD160:
- digestSize = RIPEMD160_DIGESTSIZE;
+ case BLAKE2S:
+ digestSize = BLAKE2S_DIGESTSIZE;
break;
case SHA512:
@@ -303,10 +303,10 @@ BOOL Randmix ()
/* Compute the message digest of the entire pool using the selected hash function. */
switch (HashFunction)
{
- case RIPEMD160:
- RMD160Init(&rctx);
- RMD160Update(&rctx, pRandPool, RNG_POOL_SIZE);
- RMD160Final(hashOutputBuffer, &rctx);
+ case BLAKE2S:
+ blake2s_init(&bctx);
+ blake2s_update(&bctx, pRandPool, RNG_POOL_SIZE);
+ blake2s_final(&bctx, hashOutputBuffer);
break;
case SHA512:
@@ -349,8 +349,8 @@ BOOL Randmix ()
burn (hashOutputBuffer, MAX_DIGESTSIZE);
switch (HashFunction)
{
- case RIPEMD160:
- burn (&rctx, sizeof(rctx));
+ case BLAKE2S:
+ burn (&bctx, sizeof(bctx));
break;
case SHA512:
diff --git a/src/Common/Random.h b/src/Common/Random.h
index 88dd041b..68758782 100644
--- a/src/Common/Random.h
+++ b/src/Common/Random.h
@@ -21,7 +21,7 @@ extern "C" {
/* RNG defines & pool pointers */
#define RNG_POOL_SIZE 320 // Must be divisible by the size of the output of each of the implemented hash functions. (in bytes)
-#if RNG_POOL_SIZE % SHA512_DIGESTSIZE || RNG_POOL_SIZE % WHIRLPOOL_DIGESTSIZE || RNG_POOL_SIZE % RIPEMD160_DIGESTSIZE
+#if RNG_POOL_SIZE % SHA512_DIGESTSIZE || RNG_POOL_SIZE % WHIRLPOOL_DIGESTSIZE || RNG_POOL_SIZE % BLAKE2S_DIGESTSIZE
#error RNG_POOL_SIZE must be divisible by the size of the output of each of the implemented hash functions.
#endif
diff --git a/src/Common/Tcdefs.h b/src/Common/Tcdefs.h
index 0b3025ed..8a0a1e2f 100644
--- a/src/Common/Tcdefs.h
+++ b/src/Common/Tcdefs.h
@@ -52,6 +52,10 @@ extern unsigned short _rotl16(unsigned short value, unsigned char shift);
#endif // defined(_UEFI)
+#ifdef TC_WINDOWS_BOOT
+#include <stddef.h>
+#endif
+
#define TC_APP_NAME "VeraCrypt"
// Version displayed to user
@@ -92,6 +96,7 @@ typedef __int8 int8;
typedef __int16 int16;
typedef __int32 int32;
typedef unsigned __int8 byte;
+typedef unsigned __int8 uint8;
typedef unsigned __int16 uint16;
typedef unsigned __int32 uint32;
@@ -118,6 +123,7 @@ typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
typedef uint8_t byte;
+typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;
diff --git a/src/Common/Tests.c b/src/Common/Tests.c
index a66c7b54..0fcd93ce 100644
--- a/src/Common/Tests.c
+++ b/src/Common/Tests.c
@@ -374,27 +374,6 @@ CAMELLIA_TEST camellia_vectors[CAMELLIA_TEST_COUNT] = {
0xAD, 0x5C, 0x4D, 0x84
}
};
-#if defined(CIPHER_GOST89)
-// GOST89 ECB test vectors
-#define GOST89_TEST_COUNT 1
-
-typedef struct {
- unsigned char key[32];
- unsigned char plaintext[16];
- unsigned char ciphertext[16];
- } GOST89_TEST;
-
-GOST89_TEST gost89_vectors[GOST89_TEST_COUNT] = {
-{
- 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44,
- 0x33, 0x22, 0x11, 0x00, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFE, 0xDC, 0xBA, 0x98,
- 0x76, 0x54, 0x32, 0x10, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88,
- 0x8F, 0xC6, 0xFE, 0xB8, 0x91, 0x51, 0x4C, 0x37, 0x4D, 0x51, 0x46, 0xEF,
- 0x02, 0x9D, 0xBD, 0x9F
-}
-};
-#endif
// Kuznyechik ECB test vectors
#define KUZNYECHIK_TEST_COUNT 4
@@ -503,22 +482,34 @@ char *hmac_sha512_test_vectors[] =
"\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd\xde\xbd\x71\xf8\x86\x72\x89\x86\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44\xb6\x02\x2c\xac\x3c\x49\x82\xb1\x0d\x5e\xeb\x55\xc3\xe4\xde\x15\x13\x46\x76\xfb\x6d\xe0\x44\x60\x65\xc9\x74\x40\xfa\x8c\x6a\x58",
};
-char *hmac_ripemd160_test_keys[] =
+char *hmac_blake2s_test_keys[] =
{
- "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x01\x23\x45\x67",
- "\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10\x00\x11\x22\x33",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ "Jefe",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
};
-char *hmac_ripemd160_test_data[] =
+char *hmac_blake2s_test_data[] =
{
- "message digest",
- "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ "Hi There",
+ "what do ya want for nothing?",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.",
};
-char *hmac_ripemd160_test_vectors[] =
+char *hmac_blake2s_test_vectors[] =
{
- "\xf8\x36\x62\xcc\x8d\x33\x9c\x22\x7e\x60\x0f\xcd\x63\x6c\x57\xd2\x57\x1b\x1c\x34",
- "\x85\xf1\x64\x70\x3e\x61\xa6\x31\x31\xbe\x7e\x45\x95\x8e\x07\x94\x12\x39\x04\xf9",
+ "\x65\xa8\xb7\xc5\xcc\x91\x36\xd4\x24\xe8\x2c\x37\xe2\x70\x7e\x74\xe9\x13\xc0\x65\x5b\x99\xc7\x5f\x40\xed\xf3\x87\x45\x3a\x32\x60",
+ "\x90\xb6\x28\x1e\x2f\x30\x38\xc9\x05\x6a\xf0\xb4\xa7\xe7\x63\xca\xe6\xfe\x5d\x9e\xb4\x38\x6a\x0e\xc9\x52\x37\x89\x0c\x10\x4f\xf0",
+ "\xfc\xc4\xf5\x95\x29\x50\x2e\x34\xc3\xd8\xda\x3f\xfd\xab\x82\x96\x6a\x2c\xb6\x37\xff\x5e\x9b\xd7\x01\x13\x5c\x2e\x94\x69\xe7\x90",
+ "\x46\x44\x34\xdc\xbe\xce\x09\x5d\x45\x6a\x1d\x62\xd6\xec\x56\xf8\x98\xe6\x25\xa3\x9e\x5c\x52\xbd\xf9\x4d\xaf\x11\x1b\xad\x83\xaa",
+ "\xd2\x3d\x79\x39\x4f\x53\xd5\x36\xa0\x96\xe6\x51\x44\x47\xee\xaa\xbb\x05\xde\xd0\x1b\xe3\x2c\x19\x37\xda\x6a\x8f\x71\x03\xbc\x4e",
+ "\xcb\x60\xf6\xa7\x91\xf1\x40\xbf\x8a\xa2\xe5\x1f\xf3\x58\xcd\xb2\xcc\x5c\x03\x33\x04\x5b\x7f\xb7\x7a\xba\x7a\xb3\xb0\xcf\xb2\x37",
};
char *hmac_whirlpool_test_key =
@@ -628,6 +619,32 @@ HashTestVector Streebog512TestVectors[] = {
{NULL, NULL}
};
+/* https://github.com/openssl/openssl/blob/2d0b44126763f989a4cbffbffe9d0c7518158bb7/test/evptests.txt */
+HashTestVector Blake2sTestVectors[] = {
+ {"",
+ "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9"
+ },
+ {"61",
+ "4a0d129873403037c2cd9b9048203687f6233fb6738956e0349bd4320fec3e90"
+ },
+ {"616263",
+ "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982"
+ },
+ {"6d65737361676520646967657374",
+ "fa10ab775acf89b7d3c8a6e823d586f6b67bdbac4ce207fe145b7d3ac25cd28c"
+ },
+ {"6162636465666768696a6b6c6d6e6f707172737475767778797a",
+ "bdf88eb1f86a0cdf0e840ba88fa118508369df186c7355b4b16cf79fa2710a12"
+ },
+ {"4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a30313233343536373839",
+ "c75439ea17e1de6fa4510c335dc3d3f343e6f9e1ce2773e25b4174f1df8b119b"
+ },
+ {"3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930",
+ "fdaedb290a0d5af9870864fec2e090200989dc9cd53a3c092129e8535e8b4f66"
+ },
+ {NULL, NULL}
+};
+
unsigned char ks_tmp[MAX_EXPANDED_KEY];
void CipherInit2(int cipher, void* key, void* ks, int key_len)
@@ -650,11 +667,6 @@ void CipherInit2(int cipher, void* key, void* ks, int key_len)
case CAMELLIA:
CipherInit(cipher,key,ks);
break;
-#if defined(CIPHER_GOST89)
- case GOST89:
- CipherInit(cipher,key,ks);
- break;
-#endif // defined(CIPHER_GOST89)
case KUZNYECHIK:
CipherInit(cipher, key, ks);
break;
@@ -850,34 +862,6 @@ BOOL TestSectorBufEncryption (PCRYPTO_INFO ci)
break;
}
}
-#if defined(CIPHER_GOST89)
- else if (wcscmp (name, L"GOST89") == 0)
- {
- switch (testCase)
- {
- case 0:
- if (crc != 0x12194ef5)
- return FALSE;
- nTestsPerformed++;
- break;
- case 1:
- if (crc != 0xda8d429b)
- return FALSE;
- nTestsPerformed++;
- break;
- case 2:
- if (crc != 0xdbf0b12e)
- return FALSE;
- nTestsPerformed++;
- break;
- case 3:
- if (crc != 0xb986eb4a)
- return FALSE;
- nTestsPerformed++;
- break;
- }
- }
-#endif
else if (wcscmp (name, L"Kuznyechik") == 0)
{
switch (testCase)
@@ -1234,14 +1218,6 @@ BOOL TestSectorBufEncryption (PCRYPTO_INFO ci)
return FALSE;
nTestsPerformed++;
}
-#if defined(CIPHER_GOST89)
- else if (wcscmp (name, L"GOST89") == 0)
- {
- if (crc != 0x9e8653cb)
- return FALSE;
- nTestsPerformed++;
- }
-#endif
else if (wcscmp (name, L"Kuznyechik") == 0)
{
if (crc != 0xd6d39cdb)
@@ -1319,11 +1295,7 @@ BOOL TestSectorBufEncryption (PCRYPTO_INFO ci)
nTestsPerformed++;
}
-#if defined(CIPHER_GOST89)
- return (nTestsPerformed == 160);
-#else
- return (nTestsPerformed == 155);
-#endif
+ return (nTestsPerformed == 150);
}
static BOOL DoAutoTestAlgorithms (void)
@@ -1466,28 +1438,6 @@ static BOOL DoAutoTestAlgorithms (void)
if (i != KUZNYECHIK_TEST_COUNT)
bFailed = TRUE;
-#if defined(CIPHER_GOST89)
- /* GOST89 */
-
- for (i = 0; i < GOST89_TEST_COUNT; i++)
- {
- int cipher = GOST89;
- memcpy(key, gost89_vectors[i].key, 32);
- memcpy(tmp, gost89_vectors[i].plaintext, 16);
- gost_set_key(key, (gost_kds*)ks_tmp, 0);
-
- EncipherBlock(cipher, tmp, ks_tmp);
- if (memcmp(gost89_vectors[i].ciphertext, tmp, 16) != 0)
- break;
-
- DecipherBlock(cipher, tmp, ks_tmp);
- if (memcmp(gost89_vectors[i].plaintext, tmp, 16) != 0)
- break;
- }
- if (i != GOST89_TEST_COUNT)
- bFailed = TRUE;
-#endif
-
/* PKCS #5 and HMACs */
if (!test_pkcs5 ())
bFailed = TRUE;
@@ -1599,23 +1549,29 @@ BOOL test_hmac_sha512 ()
return (nTestsPerformed == 6);
}
-BOOL test_hmac_ripemd160 ()
+BOOL test_hmac_blake2s ()
{
- int nTestsPerformed = 0;
unsigned int i;
+ int nTestsPerformed = 0;
- for (i = 0; i < sizeof (hmac_ripemd160_test_data) / sizeof(char *); i++)
+ for (i = 0; i < sizeof (hmac_blake2s_test_data) / sizeof(char *); i++)
{
char digest[1024]; /* large enough to hold digets and test vector inputs */
- memcpy (digest, hmac_ripemd160_test_data[i], strlen (hmac_ripemd160_test_data[i]));
- hmac_ripemd160 (hmac_ripemd160_test_keys[i], RIPEMD160_DIGESTSIZE, digest, (int) strlen (hmac_ripemd160_test_data[i]));
- if (memcmp (digest, hmac_ripemd160_test_vectors[i], RIPEMD160_DIGESTSIZE) != 0)
+ memcpy (digest, hmac_blake2s_test_data[i], strlen (hmac_blake2s_test_data[i]));
+ hmac_blake2s (hmac_blake2s_test_keys[i], (int) strlen (hmac_blake2s_test_keys[i]), digest, (int) strlen (hmac_blake2s_test_data[i]));
+ if (memcmp (digest, hmac_blake2s_test_vectors[i], BLAKE2S_DIGESTSIZE) != 0)
return FALSE;
else
nTestsPerformed++;
}
- return (nTestsPerformed == 2);
+ return (nTestsPerformed == 6);
+}
+
+int __cdecl Blake2sHash (unsigned char* input, unsigned long inputLen, unsigned char* output)
+{
+ blake2s(output, input, (size_t) inputLen);
+ return BLAKE2S_DIGESTSIZE;
}
BOOL test_hmac_whirlpool ()
@@ -1686,8 +1642,12 @@ BOOL test_pkcs5 ()
if (!test_hmac_sha512())
return FALSE;
- /* HMAC-RIPEMD-160 tests */
- if (test_hmac_ripemd160() == FALSE)
+ /* HMAC-BLAKE2s tests */
+ if (test_hmac_blake2s() == FALSE)
+ return FALSE;
+
+ /* Blake2s hash tests */
+ if (RunHashTest (Blake2sHash, Blake2sTestVectors, (HasSSE2())? TRUE : FALSE) == FALSE)
return FALSE;
/* HMAC-Whirlpool tests */
@@ -1733,14 +1693,14 @@ BOOL test_pkcs5 ()
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;
- /* PKCS-5 test 1 with HMAC-RIPEMD-160 used as the PRF */
- derive_key_ripemd160 ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 4);
- if (memcmp (dk, "\x7a\x3d\x7c\x03", 4) != 0)
+ /* PKCS-5 test 1 with HMAC-BLAKE2s used as the PRF */
+ derive_key_blake2s ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 4);
+ if (memcmp (dk, "\x8d\x51\xfa\x31", 4) != 0)
return FALSE;
- /* PKCS-5 test 2 with HMAC-RIPEMD-160 used as the PRF (derives a key longer than the underlying hash) */
- derive_key_ripemd160 ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 48);
- if (memcmp (dk, "\x7a\x3d\x7c\x03\xe7\x26\x6b\xf8\x3d\x78\xfb\x29\xd2\x64\x1f\x56\xea\xf0\xe5\xf5\xcc\xc4\x3a\x31\xa8\x84\x70\xbf\xbd\x6f\x8e\x78\x24\x5a\xc0\x0a\xf6\xfa\xf0\xf6\xe9\x00\x47\x5f\x73\xce\xe1\x43", 48) != 0)
+ /* PKCS-5 test 2 with HMAC-BLAKE2s used as the PRF (derives a key longer than the underlying hash) */
+ derive_key_blake2s ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 48);
+ 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;
/* PKCS-5 test 1 with HMAC-Whirlpool used as the PRF */
diff --git a/src/Common/Tests.h b/src/Common/Tests.h
index 6aff505f..356d54f4 100644
--- a/src/Common/Tests.h
+++ b/src/Common/Tests.h
@@ -19,7 +19,7 @@ extern unsigned char ks_tmp[MAX_EXPANDED_KEY];
void CipherInit2(int cipher, void* key, void* ks, int key_len);
BOOL test_hmac_sha512 (void);
-BOOL test_hmac_ripemd160 (void);
+BOOL test_hmac_blake2s (void);
BOOL test_hmac_whirlpool (void);
BOOL test_pkcs5 (void);
BOOL TestSectorBufEncryption ();
diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c
index 7bfb8ec2..902c1699 100644
--- a/src/Common/Volumes.c
+++ b/src/Common/Volumes.c
@@ -27,6 +27,8 @@
#ifndef DEVICE_DRIVER
#include "Random.h"
+#else
+#include "cpu.h"
#endif
#endif // !defined(_UEFI)
@@ -378,8 +380,8 @@ KeyReady: ;
switch (pkcs5_prf)
{
- case RIPEMD160:
- derive_key_ripemd160 (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
+ case BLAKE2S:
+ derive_key_blake2s (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize());
break;
@@ -577,12 +579,22 @@ KeyReady: ;
memcpy (keyInfo->master_keydata, header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE);
#ifdef TC_WINDOWS_DRIVER
{
- RMD160_CTX ctx;
- RMD160Init (&ctx);
- RMD160Update (&ctx, keyInfo->master_keydata, MASTER_KEYDATA_SIZE);
- RMD160Update (&ctx, header, sizeof(header));
- RMD160Final (cryptoInfo->master_keydata_hash, &ctx);
+ blake2s_state ctx;
+#ifndef _WIN64
+ NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
+ KFLOATING_SAVE floatingPointState;
+ if (HasSSE2())
+ saveStatus = KeSaveFloatingPointState (&floatingPointState);
+#endif
+ blake2s_init (&ctx);
+ blake2s_update (&ctx, keyInfo->master_keydata, MASTER_KEYDATA_SIZE);
+ blake2s_update (&ctx, header, sizeof(header));
+ blake2s_final (&ctx, cryptoInfo->master_keydata_hash);
burn(&ctx, sizeof (ctx));
+#ifndef _WIN64
+ if (NT_SUCCESS (saveStatus))
+ KeRestoreFloatingPointState (&floatingPointState);
+#endif
}
#else
memcpy (cryptoInfo->master_keydata, keyInfo->master_keydata, MASTER_KEYDATA_SIZE);
@@ -709,7 +721,7 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCR
derive_key_sha256 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
PKCS5_SALT_SIZE, iterations, dk, sizeof (dk));
#else
- derive_key_ripemd160 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
+ derive_key_blake2s (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
PKCS5_SALT_SIZE, iterations, dk, sizeof (dk));
#endif
@@ -792,7 +804,7 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCR
#ifdef TC_WINDOWS_BOOT_SHA2
cryptoInfo->pkcs5 = SHA256;
#else
- cryptoInfo->pkcs5 = RIPEMD160;
+ cryptoInfo->pkcs5 = BLAKE2S;
#endif
memcpy (dk, header + HEADER_MASTER_KEYDATA_OFFSET, sizeof (dk));
@@ -981,8 +993,8 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
break;
- case RIPEMD160:
- derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
+ case BLAKE2S:
+ derive_key_blake2s (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
break;