From c1378f781aaaa4d9e57c0a383cded7173bde7663 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sun, 26 Oct 2014 00:33:18 +0200 Subject: Bootloader: optimize code size in single cipher mode by manually inlining EAInit, EAGetFirst and EAGetKeySize, and by removing the loop in ReadVolumeHeader that tests for encryption algorithms. --- src/Common/Crypto.c | 27 +++---------------------- src/Common/Crypto.h | 4 ++++ src/Common/Volumes.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 61 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/Common/Crypto.c b/src/Common/Crypto.c index 9fc69022..e47f9565 100644 --- a/src/Common/Crypto.c +++ b/src/Common/Crypto.c @@ -965,20 +965,11 @@ void DecipherBlock(int cipher, void *data, void *ks) #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 +int EAInit (unsigned char *key, unsigned __int8 *ks) +{ aes_init(); if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS) @@ -986,23 +977,11 @@ int EAInit (int ea, unsigned char *key, unsigned __int8 *ks) 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, ks); -#elif defined (TC_WINDOWS_BOOT_TWOFISH) - twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key); -#endif return ERR_SUCCESS; } -int EAGetKeySize (int ea) -{ - return 32; -} +#endif -int EAGetFirstCipher (int ea) -{ - return 1; -} void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo) { diff --git a/src/Common/Crypto.h b/src/Common/Crypto.h index 7875e1a5..a6ed56d2 100644 --- a/src/Common/Crypto.h +++ b/src/Common/Crypto.h @@ -259,7 +259,11 @@ const char * CipherGetName (int cipher); int CipherInit (int cipher, unsigned char *key, unsigned char *ks); +#ifndef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE int EAInit (int ea, unsigned char *key, unsigned char *ks); +#else +int EAInit (unsigned char *key, unsigned char *ks); +#endif BOOL EAInitMode (PCRYPTO_INFO ci); void EncipherBlock(int cipher, void *data, void *ks); void DecipherBlock(int cipher, void *data, void *ks); diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c index 2b7b01ab..ef00728b 100644 --- a/src/Common/Volumes.c +++ b/src/Common/Volumes.c @@ -558,7 +558,7 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, PCRYPTO_INFO #endif PCRYPTO_INFO cryptoInfo; - int status; + int status = ERR_SUCCESS; if (retHeaderCryptoInfo != NULL) cryptoInfo = retHeaderCryptoInfo; @@ -577,15 +577,40 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, PCRYPTO_INFO // Mode of operation cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID; +#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE + cryptoInfo->ea = 1; +#else // Test all available encryption algorithms for (cryptoInfo->ea = EAGetFirst (); cryptoInfo->ea != 0; cryptoInfo->ea = EAGetNext (cryptoInfo->ea)) +#endif { +#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE + #if defined (TC_WINDOWS_BOOT_SERPENT) + serpent_set_key (dk, cryptoInfo->ks); + #elif defined (TC_WINDOWS_BOOT_TWOFISH) + twofish_set_key ((TwofishInstance *) cryptoInfo->ks, (const u4byte *) dk); + #else + status = EAInit (dk, cryptoInfo->ks); + if (status == ERR_CIPHER_INIT_FAILURE) + goto err; + #endif +#else status = EAInit (cryptoInfo->ea, dk, cryptoInfo->ks); if (status == ERR_CIPHER_INIT_FAILURE) goto err; - +#endif // Secondary key schedule +#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE + #if defined (TC_WINDOWS_BOOT_SERPENT) + serpent_set_key (dk + 32, cryptoInfo->ks2); + #elif defined (TC_WINDOWS_BOOT_TWOFISH) + twofish_set_key ((TwofishInstance *)cryptoInfo->ks2, (const u4byte *) (dk + 32)); + #else + EAInit (dk + 32, cryptoInfo->ks2); + #endif +#else EAInit (cryptoInfo->ea, dk + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2); +#endif // Try to decrypt header DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo); @@ -596,7 +621,12 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, PCRYPTO_INFO || GetHeaderField32 (header, TC_HEADER_OFFSET_KEY_AREA_CRC) != GetCrc32 (header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE)) { EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo); +#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE + status = ERR_PASSWORD_WRONG; + goto err; +#else continue; +#endif } // Header decrypted @@ -629,12 +659,34 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, PCRYPTO_INFO goto ret; // Init the encryption algorithm with the decrypted master key +#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE + #if defined (TC_WINDOWS_BOOT_SERPENT) + serpent_set_key (masterKey, cryptoInfo->ks); + #elif defined (TC_WINDOWS_BOOT_TWOFISH) + twofish_set_key ((TwofishInstance *) cryptoInfo->ks, (const u4byte *) masterKey); + #else + status = EAInit (masterKey, cryptoInfo->ks); + if (status == ERR_CIPHER_INIT_FAILURE) + goto err; + #endif +#else status = EAInit (cryptoInfo->ea, masterKey, cryptoInfo->ks); if (status == ERR_CIPHER_INIT_FAILURE) goto err; +#endif // The secondary master key (if cascade, multiple concatenated) +#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE + #if defined (TC_WINDOWS_BOOT_SERPENT) + serpent_set_key (masterKey + 32, cryptoInfo->ks2); + #elif defined (TC_WINDOWS_BOOT_TWOFISH) + twofish_set_key ((TwofishInstance *)cryptoInfo->ks2, (const u4byte *) (masterKey + 32)); + #else + EAInit (masterKey + 32, cryptoInfo->ks2); + #endif +#else EAInit (cryptoInfo->ea, masterKey + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2); +#endif goto ret; } -- cgit v1.2.3