--- truecrypt/common/crypto.c 2018/04/24 16:43:52 1.1.1.8 +++ truecrypt/common/crypto.c 2018/04/24 16:46:33 1.1.1.11 @@ -1,20 +1,23 @@ -/* Legal Notice: The source code contained in this file has been derived from - the source code of Encryption for the Masses 2.02a, which is Copyright (c) - 1998-99 Paul Le Roux and which is covered by the 'License Agreement for - Encryption for the Masses'. Modifications and additions to that source code - contained in this file are Copyright (c) 2004-2005 TrueCrypt Foundation and - Copyright (c) 2004 TrueCrypt Team, and are covered by TrueCrypt License 2.0 - the full text of which is contained in the file License.txt included in - TrueCrypt binary and source code distribution archives. */ +/* + Legal Notice: The source code contained in this file has been derived from + the source code of Encryption for the Masses 2.02a, which is Copyright (c) + Paul Le Roux and which is covered by the 'License Agreement for Encryption + for the Masses'. Modifications and additions to that source code contained + in this file are Copyright (c) TrueCrypt Foundation and are covered by the + TrueCrypt License 2.2 the full text of which is contained in the file + License.txt included in TrueCrypt binary and source code distribution + packages. */ #include "Tcdefs.h" #include "Crypto.h" #include "Crc.h" -#include "Endian.h" +#include "Common/Endian.h" #ifdef LINUX_DRIVER #include #include +#else +#include #endif /* Update the following when adding a new cipher or EA: @@ -52,28 +55,36 @@ static Cipher Ciphers[] = static EncryptionAlgorithm EncryptionAlgorithms[] = { // Cipher(s) Modes - { { 0, 0 } , { 0, 0, 0 } }, // Must be all-zero - { { AES, 0 } , { LRW, CBC, 0 } }, - { { BLOWFISH, 0 } , { LRW, CBC, 0 } }, - { { CAST, 0 } , { LRW, CBC, 0 } }, - { { SERPENT, 0 } , { LRW, CBC, 0 } }, - { { TRIPLEDES, 0 } , { LRW, CBC, 0 } }, - { { TWOFISH, 0 } , { LRW, CBC, 0 } }, - { { BLOWFISH, AES, 0 } , { INNER_CBC, 0, 0 } }, - { { SERPENT, BLOWFISH, AES, 0 } , { INNER_CBC, 0, 0 } }, - { { TWOFISH, AES, 0 } , { LRW, OUTER_CBC, 0 } }, - { { SERPENT, TWOFISH, AES, 0 } , { LRW, OUTER_CBC, 0 } }, - { { AES, SERPENT, 0 } , { LRW, OUTER_CBC, 0 } }, - { { AES, TWOFISH, SERPENT, 0 } , { LRW, OUTER_CBC, 0 } }, - { { SERPENT, TWOFISH, 0 } , { LRW, OUTER_CBC, 0 } }, - { { 0, 0 } , { 0, 0, 0 } } // Must be all-zero + { { 0, 0 }, { 0, 0, 0 }, 0 }, // Must be all-zero + { { AES, 0 }, { LRW, CBC, 0 }, 1 }, + { { BLOWFISH, 0 }, { LRW, CBC, 0 }, 0 }, + { { CAST, 0 }, { LRW, CBC, 0 }, 0 }, + { { SERPENT, 0 }, { LRW, CBC, 0 }, 1 }, + { { TRIPLEDES, 0 }, { LRW, CBC, 0 }, 0 }, + { { TWOFISH, 0 }, { LRW, CBC, 0 }, 1 }, + { { TWOFISH, AES, 0 }, { LRW, OUTER_CBC, 0 }, 1 }, + { { SERPENT, TWOFISH, AES, 0 }, { LRW, OUTER_CBC, 0 }, 1 }, + { { AES, SERPENT, 0 }, { LRW, OUTER_CBC, 0 }, 1 }, + { { AES, TWOFISH, SERPENT, 0 }, { LRW, OUTER_CBC, 0 }, 1 }, + { { SERPENT, TWOFISH, 0 }, { LRW, OUTER_CBC, 0 }, 1 }, + { { BLOWFISH, AES, 0 }, { INNER_CBC, 0, 0 }, 0 }, + { { SERPENT, BLOWFISH, AES, 0 }, { INNER_CBC, 0, 0 }, 0 }, + { { 0, 0 }, { 0, 0, 0 }, 0 } // Must be all-zero }; +// Hash algorithms +static Hash Hashes[] = +{ + { RIPEMD160, "RIPEMD-160" }, + { SHA1, "SHA-1" }, + { WHIRLPOOL, "Whirlpool" }, + { 0, 0 } +}; /* Return values: 0 = success, ERR_CIPHER_INIT_FAILURE (fatal), ERR_CIPHER_INIT_WEAK_KEY (non-fatal) */ int CipherInit (int cipher, unsigned char *key, unsigned __int8 *ks) { - int retVal = 0; + int retVal = ERR_SUCCESS; switch (cipher) { @@ -135,6 +146,13 @@ int CipherInit (int cipher, unsigned cha retVal = ERR_CIPHER_INIT_WEAK_KEY; // Non-fatal error break; } + + // Verify whether all three DES keys are mutually different + if (((*((__int64 *) key) ^ *((__int64 *) key+1)) & 0xFEFEFEFEFEFEFEFEULL) == 0 + || ((*((__int64 *) key+1) ^ *((__int64 *) key+2)) & 0xFEFEFEFEFEFEFEFEULL) == 0 + || ((*((__int64 *) key) ^ *((__int64 *) key+2)) & 0xFEFEFEFEFEFEFEFEULL) == 0) + retVal = ERR_CIPHER_INIT_WEAK_KEY; // Non-fatal error + break; case TWOFISH: @@ -239,7 +257,10 @@ int EAGetNext (int previousEA) // Return values: 0 = success, ERR_CIPHER_INIT_FAILURE (fatal), ERR_CIPHER_INIT_WEAK_KEY (non-fatal) int EAInit (int ea, unsigned char *key, unsigned __int8 *ks) { - int c, retVal = 0; + int c, retVal = ERR_SUCCESS; + + if (ea == 0) + return ERR_CIPHER_INIT_FAILURE; for (c = EAGetFirstCipher (ea); c != 0; c = EAGetNextCipher (ea, c)) { @@ -286,7 +307,7 @@ int EAInitMode (PCRYPTO_INFO ci) char *EAGetName (char *buf, int ea) { int i = EAGetLastCipher(ea); - strcpy (buf, CipherGetName (i)); + strcpy (buf, (i != 0) ? CipherGetName (i) : "?"); while (i = EAGetPreviousCipher(ea, i)) { @@ -473,15 +494,37 @@ int EAGetPreviousCipher (int ea, int pre } -char *get_hash_algo_name (int hash_algo_id) +int EAIsFormatEnabled (int ea) { - switch (hash_algo_id) - { - case SHA1: return "SHA-1"; - case RIPEMD160: return "RIPEMD-160"; - case WHIRLPOOL: return "Whirlpool"; - default: return "Unknown"; - } + return EncryptionAlgorithms[ea].FormatEnabled; +} + + +Hash *HashGet (int id) +{ + int i; + for (i = 0; Hashes[i].Id != 0; i++) + if (Hashes[i].Id == id) + return &Hashes[i]; + + return 0; +} + + +int HashGetIdByName (char *name) +{ + int i; + for (i = 0; Hashes[i].Id != 0; i++) + if (strcmp (Hashes[i].Name, name) == 0) + return Hashes[i].Id; + + return 0; +} + + +char *HashGetName (int hashId) +{ + return HashGet (hashId) -> Name; } @@ -489,7 +532,9 @@ PCRYPTO_INFO crypto_open () { /* Do the crt allocation */ - PCRYPTO_INFO cryptoInfo = TCalloc (sizeof (CRYPTO_INFO)); + PCRYPTO_INFO cryptoInfo = (PCRYPTO_INFO) TCalloc (sizeof (CRYPTO_INFO)); + memset (cryptoInfo, 0, sizeof (CRYPTO_INFO)); + #ifndef DEVICE_DRIVER #ifdef _WIN32 VirtualLock (cryptoInfo, sizeof (CRYPTO_INFO)); @@ -525,7 +570,49 @@ crypto_close (PCRYPTO_INFO cryptoInfo) TCfree (cryptoInfo); } } - + + +// Detect weak and potentially weak secondary LRW keys. +// Remark: These tests reduce the key search space by approximately 0.001% +BOOL DetectWeakSecondaryKey (unsigned char *key, int len) +{ +#define LRW_MAX_SUCCESSIVE_IDENTICAL_BITS 24 +#define LRW_MIN_HAMMING_WEIGHT_16 39 +#define LRW_MIN_HAMMING_WEIGHT_8 15 + + int minWeight = (len == 16 ? LRW_MIN_HAMMING_WEIGHT_16 : LRW_MIN_HAMMING_WEIGHT_8); + int i, b, zero = 0, one = 0, zeroTotal = 0, oneTotal = 0; + + for (i = 0; i < len; i++) + { + for (b = 7; b >= 0; b--) + { + if ((key[i] & (1 << b)) == 0) + { + zeroTotal++; + zero++; + one = 0; + } + else + { + oneTotal++; + one++; + zero = 0; + } + + // Maximum number of consecutive identical bit values + if (one >= LRW_MAX_SUCCESSIVE_IDENTICAL_BITS || zero >= LRW_MAX_SUCCESSIVE_IDENTICAL_BITS) + return TRUE; + } + } + + // Minimum and maximum Hamming weight + if (zeroTotal < minWeight || oneTotal < minWeight) + return TRUE; + + return FALSE; +} + // Initializes IV and whitening values for sector encryption/decryption in CBC mode. // IMPORTANT: This function has been deprecated (legacy). @@ -1030,7 +1117,7 @@ unsigned __int64 LRWSector2Index (unsign // iv: IV // ea: encryption algorithm -void _cdecl +void EncryptSectors (unsigned __int32 *buf, unsigned __int64 secNo, unsigned __int64 noSectors, @@ -1192,7 +1279,7 @@ DecryptBuffer (unsigned __int32 *buf, // iv: IV // ea: encryption algorithm -void _cdecl +void DecryptSectors (unsigned __int32 *buf, unsigned __int64 secNo, unsigned __int64 noSectors,