DCT4 Crypt - Firmware Encryption - another approach
g3gg0 and nok5rev created a DCT4 crypter to encrypt and decrypt mobile phone flashfiles of a widly known company some time ago. This algorithm is also used in Trix. They use a table with 65535 entries (each 16 bit) for both directions. This table is build from a small table with 16 entries. Now, since this is originally done in an ASIC there must be another way, because storing those big tables is not effective and a waste of everything
On PC this is perfect since the code to code translation is only a table lookup which is quite fast. But how this was done in the ASIC?
I analysed the 16 bit 16 entries table… I counted the bits set in every entry and found that the count of bits increase (shuffled) through the table. Nearly every count was there two times. If you xor the current entry with the result for that code you get a value which you find again in this table. So in generally we have two ‘chains’ with a start value. The start value includes the bits for the chain. Sounds easy but took me around 2 days
Unfortunately it’s not working 100% yet - but most of the results are correct.
Here’s the table from g3gg0 and nok5rev (for understanding), if you’re interested on the algo take a look into Trix source code.
unsigned short mbit[] = {
0×1221, 0xA91A, 0×52A5, 0×0908, // 0001 0002 0004 0008
0xa918, 0×1020, 0xFFFF, 0×52A1, // 0010 0020 0040 0080
0×0100, 0×1220, 0xAD1A, 0×0900, // 0100 0200 0400 0800
0×1000, 0×2908, 0×5221, 0xa908, // 1000 2000 4000 8000
};
the following is what I produced from it to replace the big table:
void k_dct4_code_to_code_part ( unsigned short *enc, unsigned short *dec, unsigned short bit, unsigned short *xorval )
{
if ( *enc & bit )
{
*enc ^= *xorval;
*dec ^= bit;
}
*xorval ^= bit;
}unsigned short k_dct4_code_to_code_chain_1 ( unsigned short enc )
{
unsigned short dec = 0;
unsigned char c;
unsigned short xorval = 0×52A5;
//order is important!
//we can break if enc equals zerounsigned short bits[7] = { 0×4, 0×80, 0×4000, 0×1, 0×200, 0×20, 0×1000 };
enc &= xorval;
for ( c = 0; c < 7; c++ )
{
k_dct4_code_to_code_part ( &enc, &dec, bits[c], &xorval );
}if ( enc )
printf ( “decrypting err in chain 1, wrong algo)” );
return enc;
}
For chain two the xorvalue is 0xad5a and the bits array is { 0×40, 0×400, 0×2, 0×10, 0×8000, 0×2000, 0×8, 0×800, 0×100 } (9 entries!).
Remember this is only code to code translation/scrambling and somehow some values are wrong. I think this is ’cause of a wrong order, start value or maybe one or two values in wrong chain. If you find the bug, let me know. Address scrambling is little bit different and not covered here.
Update: Instead of using 0×400 as value, try 0×404, this could solve the bug in theory.
g3gg0 also did some brainstorming on this and found an easier way - wow, never thought it could be that small and easy ![]()
Am 1. August 2008 um 23:21 Uhr
Hello Krisha. Greets from Poland!
Ekhm, I just want to let you know that some spamming bots are devastating TriX wiki.