--- truecrypt/common/crypto.c 2018/04/24 16:48:33 1.1.1.13 +++ truecrypt/common/crypto.c 2018/04/24 17:02:28 1.1.1.18 @@ -4,8 +4,8 @@ Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License Agreement for Encryption for the Masses'. Modifications and additions to the original source code (contained in this file) and all other portions of - this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed - by the TrueCrypt License 2.4 the full text of which is contained in the + this file are Copyright (c) 2003-2009 TrueCrypt Foundation and are governed + by the TrueCrypt License 2.7 the full text of which is contained in the file License.txt included in TrueCrypt binary and source code distribution packages. */ @@ -14,13 +14,11 @@ #include "Xts.h" #include "Crc.h" #include "Common/Endian.h" - -#ifdef LINUX_DRIVER -#include -#include -#else #include +#ifndef TC_WINDOWS_BOOT +#include "EncryptionThreadPool.h" #endif +#include "Volumes.h" /* Update the following when adding a new cipher or EA: @@ -37,6 +35,8 @@ */ +#ifndef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE + // Cipher configuration static Cipher Ciphers[] = { @@ -46,10 +46,9 @@ static Cipher Ciphers[] = { SERPENT, "Serpent", 16, 32, 140*4 }, { TWOFISH, "Twofish", 16, 32, TWOFISH_KS }, #ifndef TC_WINDOWS_BOOT - { BLOWFISH, "Blowfish", 8, 56, 4168 }, // Deprecated/legacy - { CAST, "CAST5", 8, 16, 128 }, // Deprecated/legacy - { DES56, "DES", 8, 7, 128 }, // Deprecated/legacy - { TRIPLEDES,"Triple DES", 8, 8*3, 128*3 }, // Deprecated/legacy + { BLOWFISH, "Blowfish", 8, 56, sizeof (BF_KEY) }, // Deprecated/legacy + { CAST, "CAST5", 8, 16, sizeof (CAST_KEY) }, // Deprecated/legacy + { TRIPLEDES,"Triple DES", 8, 8*3, sizeof (TDES_KEY) }, // Deprecated/legacy #endif { 0, 0, 0, 0, 0 } }; @@ -120,16 +119,15 @@ int CipherInit (int cipher, unsigned cha { case AES: #ifndef TC_WINDOWS_BOOT - if (aes_encrypt_key(key, CipherGetKeySize(AES), (aes_encrypt_ctx *) ks) != EXIT_SUCCESS) + if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS) return ERR_CIPHER_INIT_FAILURE; - if (aes_decrypt_key(key, CipherGetKeySize(AES), (aes_decrypt_ctx *) (ks + sizeof(aes_encrypt_ctx))) != EXIT_SUCCESS) + if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof(aes_encrypt_ctx))) != EXIT_SUCCESS) return ERR_CIPHER_INIT_FAILURE; #else if (aes_set_key (key, (length_type) CipherGetKeySize(AES), (aes_context *) ks) != 0) return ERR_CIPHER_INIT_FAILURE; #endif - break; case SERPENT: @@ -144,52 +142,17 @@ int CipherInit (int cipher, unsigned cha case BLOWFISH: /* Deprecated/legacy */ - BF_set_key ((BF_KEY *)ks, CipherGetKeySize(BLOWFISH), key); - break; - - case DES56: - /* Deprecated/legacy */ - switch (des_key_sched ((des_cblock *) key, (struct des_ks_struct *) ks)) - { - case -1: - return ERR_CIPHER_INIT_FAILURE; - case -2: - retVal = ERR_CIPHER_INIT_WEAK_KEY; // Non-fatal error - break; - } + BlowfishSetKey ((BF_KEY *)ks, CipherGetKeySize(BLOWFISH), key); break; case CAST: /* Deprecated/legacy */ - CAST_set_key((CAST_KEY *) ks, CipherGetKeySize(CAST), key); + Cast5SetKey ((CAST_KEY *) ks, CipherGetKeySize(CAST), key); break; case TRIPLEDES: /* Deprecated/legacy */ - switch (des_key_sched ((des_cblock *) key, (struct des_ks_struct *) ks)) - { - case -1: - return ERR_CIPHER_INIT_FAILURE; - case -2: - retVal = ERR_CIPHER_INIT_WEAK_KEY; // Non-fatal error - break; - } - switch (des_key_sched ((des_cblock *) ((char*)(key)+8), (struct des_ks_struct *) (ks + CipherGetKeyScheduleSize (DES56)))) - { - case -1: - return ERR_CIPHER_INIT_FAILURE; - case -2: - retVal = ERR_CIPHER_INIT_WEAK_KEY; // Non-fatal error - break; - } - switch (des_key_sched ((des_cblock *) ((char*)(key)+16), (struct des_ks_struct *) (ks + CipherGetKeyScheduleSize (DES56) * 2))) - { - case -1: - return ERR_CIPHER_INIT_FAILURE; - case -2: - retVal = ERR_CIPHER_INIT_WEAK_KEY; // Non-fatal error - break; - } + TripleDesSetKey (key, CipherGetKeySize (TRIPLEDES), (TDES_KEY *) ks); // Verify whether all three DES keys are mutually different if (((*((__int64 *) key) ^ *((__int64 *) key+1)) & 0xFEFEFEFEFEFEFEFEULL) == 0 @@ -217,11 +180,9 @@ void EncipherBlock(int cipher, void *dat case TWOFISH: twofish_encrypt (ks, data, data); break; case SERPENT: serpent_encrypt (data, data, ks); break; #ifndef TC_WINDOWS_BOOT - case BLOWFISH: BF_ecb_le_encrypt (data, data, ks, 1); break; // Deprecated/legacy - case DES56: des_encrypt (data, ks, 1); break; // Deprecated/legacy - case CAST: CAST_ecb_encrypt (data, data, ks, 1); break; // Deprecated/legacy - case TRIPLEDES: des_ecb3_encrypt (data, data, ks, // Deprecated/legacy - (void*)((char*) ks + CipherGetKeyScheduleSize (DES56)), (void*)((char*) ks + CipherGetKeyScheduleSize (DES56) * 2), 1); break; + case BLOWFISH: BlowfishEncryptLE (data, data, ks, 1); break; // Deprecated/legacy + case CAST: Cast5Encrypt (data, data, ks); break; // Deprecated/legacy + case TRIPLEDES: TripleDesEncrypt (data, data, ks, 1); break; // Deprecated/legacy #endif default: TC_THROW_FATAL_EXCEPTION; // Unknown/wrong ID } @@ -235,12 +196,9 @@ void DecipherBlock(int cipher, void *dat case TWOFISH: twofish_decrypt (ks, data, data); break; #ifndef TC_WINDOWS_BOOT case AES: aes_decrypt (data, data, (void *) ((char *) ks + sizeof(aes_encrypt_ctx))); break; - case BLOWFISH: BF_ecb_le_encrypt (data, data, ks, 0); break; // Deprecated/legacy - case DES56: des_encrypt (data, ks, 0); break; // Deprecated/legacy - case CAST: CAST_ecb_encrypt (data, data, ks,0); break; // Deprecated/legacy - case TRIPLEDES: des_ecb3_encrypt (data, data, ks, // Deprecated/legacy - (void*)((char*) ks + CipherGetKeyScheduleSize (DES56)), - (void*)((char*) ks + CipherGetKeyScheduleSize (DES56) * 2), 0); break; + case BLOWFISH: BlowfishEncryptLE (data, data, ks, 0); break; // Deprecated/legacy + case CAST: Cast5Decrypt (data, data, ks); break; // Deprecated/legacy + case TRIPLEDES: TripleDesEncrypt (data, data, ks, 0); break; // Deprecated/legacy #else case AES: aes_decrypt (data, data, ks); break; #endif @@ -335,7 +293,9 @@ int EAInit (int ea, unsigned char *key, } -int EAInitMode (PCRYPTO_INFO ci) +#ifndef TC_WINDOWS_BOOT + +BOOL EAInitMode (PCRYPTO_INFO ci) { switch (ci->mode) { @@ -351,7 +311,6 @@ int EAInitMode (PCRYPTO_INFO ci) that the size of each of the volumes is 1024 terabytes). */ break; -#ifndef TC_WINDOWS_BOOT case LRW: switch (CipherGetBlockSize (EAGetFirstCipher (ci->ea))) { @@ -373,7 +332,6 @@ int EAInitMode (PCRYPTO_INFO ci) case OUTER_CBC: // The mode does not need to be initialized or is initialized elsewhere return TRUE; -#endif // TC_WINDOWS_BOOT default: // Unknown/wrong ID @@ -382,7 +340,6 @@ int EAInitMode (PCRYPTO_INFO ci) return TRUE; } -#ifndef TC_WINDOWS_BOOT // Returns name of EA, cascaded cipher names are separated by hyphens char *EAGetName (char *buf, int ea) @@ -658,6 +615,9 @@ BOOL HashIsDeprecated (int hashId) } +#endif // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE + + #ifdef TC_WINDOWS_BOOT static byte CryptoInfoBufferInUse = 0; @@ -674,10 +634,8 @@ PCRYPTO_INFO crypto_open () memset (cryptoInfo, 0, sizeof (CRYPTO_INFO)); #ifndef DEVICE_DRIVER -#ifdef _WIN32 VirtualLock (cryptoInfo, sizeof (CRYPTO_INFO)); #endif -#endif if (cryptoInfo == NULL) return NULL; @@ -712,10 +670,8 @@ void crypto_close (PCRYPTO_INFO cryptoIn { burn (cryptoInfo, sizeof (CRYPTO_INFO)); #ifndef DEVICE_DRIVER -#ifdef _WIN32 VirtualUnlock (cryptoInfo, sizeof (CRYPTO_INFO)); #endif -#endif TCfree (cryptoInfo); } @@ -728,6 +684,9 @@ void crypto_close (PCRYPTO_INFO cryptoIn } +#ifndef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE + + #ifndef TC_NO_COMPILER_INT64 void Xor128 (unsigned __int64 *a, unsigned __int64 *b) { @@ -742,7 +701,7 @@ void Xor64 (unsigned __int64 *a, unsigne } -void EncryptBufferLRW128 (unsigned __int8 *buffer, unsigned __int64 length, unsigned __int64 blockIndex, PCRYPTO_INFO cryptoInfo) +void EncryptBufferLRW128 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo) { /* Deprecated/legacy */ @@ -797,7 +756,7 @@ void EncryptBufferLRW128 (unsigned __int } -void EncryptBufferLRW64 (unsigned __int8 *buffer, unsigned __int64 length, unsigned __int64 blockIndex, PCRYPTO_INFO cryptoInfo) +void EncryptBufferLRW64 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo) { /* Deprecated/legacy */ @@ -834,7 +793,7 @@ void EncryptBufferLRW64 (unsigned __int8 } -void DecryptBufferLRW128 (unsigned __int8 *buffer, unsigned __int64 length, unsigned __int64 blockIndex, PCRYPTO_INFO cryptoInfo) +void DecryptBufferLRW128 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo) { /* Deprecated/legacy */ @@ -891,7 +850,7 @@ void DecryptBufferLRW128 (unsigned __int -void DecryptBufferLRW64 (unsigned __int8 *buffer, unsigned __int64 length, unsigned __int64 blockIndex, PCRYPTO_INFO cryptoInfo) +void DecryptBufferLRW64 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo) { /* Deprecated/legacy */ @@ -1166,12 +1125,10 @@ DecryptBufferCBC (unsigned __int32 *data // EncryptBuffer // -// buf: data to be encrypted -// len: number of bytes to encrypt; must be divisible by the block size (for cascaded -// ciphers divisible by the largest block size used within the cascade) -void EncryptBuffer (unsigned __int8 *buf, - TC_LARGEST_COMPILER_UINT len, - PCRYPTO_INFO cryptoInfo) +// buf: data to be encrypted; the start of the buffer is assumed to be aligned with the start of a data unit. +// len: number of bytes to encrypt; must be divisible by the block size (for cascaded ciphers, divisible +// by the largest block size used within the cascade) +void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo) { switch (cryptoInfo->mode) { @@ -1184,7 +1141,7 @@ void EncryptBuffer (unsigned __int8 *buf // When encrypting/decrypting a buffer (typically a volume header) the sequential number // of the first XTS data unit in the buffer is always 0 and the start of the buffer is - // always considered aligned with the start of a data unit. + // always assumed to be aligned with the start of a data unit. dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0; @@ -1269,14 +1226,14 @@ void EncryptBuffer (unsigned __int8 *buf #ifndef TC_NO_COMPILER_INT64 // Converts a data unit number to the index of the first LRW block in the data unit. // Note that the maximum supported volume size is 8589934592 GB (i.e., 2^63 bytes). -unsigned __int64 DataUnit2LRWIndex (unsigned __int64 dataUnit, int blockSize, PCRYPTO_INFO ci) +uint64 DataUnit2LRWIndex (uint64 dataUnit, int blockSize, PCRYPTO_INFO ci) { /* Deprecated/legacy */ if (ci->hiddenVolume) dataUnit -= ci->hiddenVolumeOffset / ENCRYPTION_DATA_UNIT_SIZE; else - dataUnit -= HEADER_SIZE / ENCRYPTION_DATA_UNIT_SIZE; // Compensate for the volume header size + dataUnit -= TC_VOLUME_HEADER_SIZE_LEGACY / ENCRYPTION_DATA_UNIT_SIZE; // Compensate for the volume header size switch (blockSize) { @@ -1299,6 +1256,13 @@ unsigned __int64 DataUnit2LRWIndex (unsi // unitNo: sequential number of the data unit with which the buffer starts // nbrUnits: number of data units in the buffer void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci) +#ifndef TC_WINDOWS_BOOT +{ + EncryptionThreadPoolDoWork (EncryptDataUnitsWork, buf, structUnitNo, nbrUnits, ci); +} + +void EncryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci) +#endif // !TC_WINDOWS_BOOT { int ea = ci->ea; unsigned __int8 *ks = ci->ks; @@ -1414,12 +1378,10 @@ void EncryptDataUnits (unsigned __int8 * // DecryptBuffer // -// buf: data to be decrypted -// len: number of bytes to decrypt; must be divisible by the block size (for cascaded -// ciphers divisible by the largest block size used within the cascade) -void DecryptBuffer (unsigned __int8 *buf, - TC_LARGEST_COMPILER_UINT len, - PCRYPTO_INFO cryptoInfo) +// buf: data to be decrypted; the start of the buffer is assumed to be aligned with the start of a data unit. +// len: number of bytes to decrypt; must be divisible by the block size (for cascaded ciphers, divisible +// by the largest block size used within the cascade) +void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo) { switch (cryptoInfo->mode) { @@ -1432,7 +1394,7 @@ void DecryptBuffer (unsigned __int8 *buf // When encrypting/decrypting a buffer (typically a volume header) the sequential number // of the first XTS data unit in the buffer is always 0 and the start of the buffer is - // always considered aligned with the start of the data unit 0. + // always assumed to be aligned with the start of the data unit 0. dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0; @@ -1517,6 +1479,13 @@ void DecryptBuffer (unsigned __int8 *buf // unitNo: sequential number of the data unit with which the buffer starts // nbrUnits: number of data units in the buffer void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci) +#ifndef TC_WINDOWS_BOOT +{ + EncryptionThreadPoolDoWork (DecryptDataUnitsWork, buf, structUnitNo, nbrUnits, ci); +} + +void DecryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci) +#endif // !TC_WINDOWS_BOOT { int ea = ci->ea; unsigned __int8 *ks = ci->ks; @@ -1640,10 +1609,6 @@ int GetMaxPkcs5OutSize (void) { int size = 32; -#ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif - size = max (size, EAGetLargestKeyForMode (XTS) * 2); // Sizes of primary + secondary keys #ifndef TC_WINDOWS_BOOT @@ -1655,3 +1620,98 @@ int GetMaxPkcs5OutSize (void) return size; } + + +#else // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE + + +#if !defined (TC_WINDOWS_BOOT_AES) && !defined (TC_WINDOWS_BOOT_SERPENT) && !defined (TC_WINDOWS_BOOT_TWOFISH) +#error No cipher defined +#endif + +void EncipherBlock(int cipher, void *data, void *ks) +{ +#ifdef TC_WINDOWS_BOOT_AES + aes_encrypt (data, data, ks); +#elif defined (TC_WINDOWS_BOOT_SERPENT) + serpent_encrypt (data, data, ks); +#elif defined (TC_WINDOWS_BOOT_TWOFISH) + twofish_encrypt (ks, data, data); +#endif +} + +void DecipherBlock(int cipher, void *data, void *ks) +{ +#ifdef TC_WINDOWS_BOOT_AES + aes_decrypt (data, data, (aes_decrypt_ctx *) ((byte *) ks + sizeof(aes_encrypt_ctx))); +#elif defined (TC_WINDOWS_BOOT_SERPENT) + serpent_decrypt (data, data, ks); +#elif defined (TC_WINDOWS_BOOT_TWOFISH) + twofish_decrypt (ks, data, data); +#endif +} + +int EAGetFirst () +{ + return 1; +} + +int EAGetNext (int previousEA) +{ + return 0; +} + +int EAInit (int ea, unsigned char *key, unsigned __int8 *ks) +{ +#ifdef TC_WINDOWS_BOOT_AES + + aes_init(); + + if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS) + return ERR_CIPHER_INIT_FAILURE; + if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS) + return ERR_CIPHER_INIT_FAILURE; + +#elif defined (TC_WINDOWS_BOOT_SERPENT) + serpent_set_key (key, 32 * 8, ks); +#elif defined (TC_WINDOWS_BOOT_TWOFISH) + twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key, 32 * 8); +#endif + return ERR_SUCCESS; +} + +int EAGetKeySize (int ea) +{ + return 32; +} + +int EAGetFirstCipher (int ea) +{ + return 1; +} + +void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo) +{ + UINT64_STRUCT dataUnitNo; + dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0; + EncryptBufferXTS (buf, len, &dataUnitNo, 0, cryptoInfo->ks, cryptoInfo->ks2, 1); +} + +void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci) +{ + EncryptBufferXTS (buf, nbrUnits * ENCRYPTION_DATA_UNIT_SIZE, structUnitNo, 0, ci->ks, ci->ks2, 1); +} + +void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo) +{ + UINT64_STRUCT dataUnitNo; + dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0; + DecryptBufferXTS (buf, len, &dataUnitNo, 0, cryptoInfo->ks, cryptoInfo->ks2, 1); +} + +void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci) +{ + DecryptBufferXTS (buf, nbrUnits * ENCRYPTION_DATA_UNIT_SIZE, structUnitNo, 0, ci->ks, ci->ks2, 1); +} + +#endif // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE