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.

This commit is contained in:
Mounir IDRASSI 2014-10-26 00:33:18 +02:00
parent c61f8c70de
commit c1378f781a
3 changed files with 61 additions and 26 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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;
}