From 36795a688fd1d5bb9f497970938d9fcb08cfc330 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Mon, 7 Mar 2022 00:45:30 +0100 Subject: Implement support of Blake2s-256 hash algorithm and remove deprecated algorithms RIPEMD-160 and GOST89. --- src/Common/BootEncryption.cpp | 18 +-- src/Common/Crypto.c | 26 +--- src/Common/Crypto.h | 14 +- src/Common/Dlgcode.c | 19 ++- src/Common/EncryptionThreadPool.c | 4 +- src/Common/Pkcs5.c | 294 ++++++++++++++++++++++---------------- src/Common/Pkcs5.h | 6 +- src/Common/Random.c | 18 +-- src/Common/Random.h | 2 +- src/Common/Tcdefs.h | 6 + src/Common/Tests.c | 186 ++++++++++-------------- src/Common/Tests.h | 2 +- src/Common/Volumes.c | 34 +++-- 13 files changed, 313 insertions(+), 316 deletions(-) (limited to 'src/Common') 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 #include #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; ik; 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 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 +#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; -- cgit v1.2.3