//================= Global Functions ================================
BYTE key_n[96];
//---------------------- ExpandTo64 -----------------------------------
/*!
*\brief PURPOSE: Get 64 byte data expanded from 8-byte array.
*
*\par Description
Change 8-byte array into 64-byte array, each bit stored as byte.
*\param[in] Array8 - 8-byte array
*\param[in] bits - count of bits
*\param[out] Array64 - 64-byte array
*\return
no
*\note
*\see
*\bug
None
*\test
No test
*\todo
NO
*/
/*-------------------------------------------------------------*/
void ExpandTo64(BYTE *Array8, BYTE *Array64, BYTE bits)
{
BYTE i;
for(i=0; i<bits; i++)
Array64[i] = (Array8[i>>3] >> (7-(i& 0x7))) & 1;
}
/*---------------------- ContractTo8 -----------------------------------*/
/*!
*\brief PURPOSE: Get 8 byte data compress from 64-byte array.
*
*\par Description
Change 64-byte array into 8-byte array, each 8 -byte store as 1-byte .
*\bug
None
*\test
No test
*\todo
NO
*/
/*-------------------------------------------------------------*/
void ContractTo8(BYTE *Array64, BYTE *Array8, BYTE bits)
{
BYTE i,j;
for(i = 0; i < bits/8; i++)
{
Array8[i]=0;
for (j=0;j<8;j++)
if (Array64[i*8 +j])
Array8[i]|=(0x01<<(7-j));
}
}
/*---------------------- GenSubKey -----------------------------------*/
/*!
*\brief PURPOSE: Process 16 sub key from 8-byte key.
*
*\par Description
1. Calculate the key schedule, reducing 8-byte key to 56 bits
2. Split the permuted key into two halves.
3. Calculate the 16 subkeys, Get 16-group 48-bit sub key from 8-byte key.
*\param[in] oldkey - 8-byte key array
*\param[out] newkey - 16 group sub key array
*\return
*\note
*\see
*\bug
None
*\test
No test
*\todo
NO
*/
/*-------------------------------------------------------------*/
void GenSubKey(const BYTE oldkey[8], BYTE newkey[96])
{
BYTE i, k, rol = 0;
BYTE oldkey_c[28];
BYTE oldkey_d[28];
BYTE newkey_byte[64];
BYTE *p;
signed char tmp;
for(i = 0; i < 16; i++)
{
rol += ccmovebit1[i];
for(k = 0; k < 48; k++)
{
tmp = pc_2[k];
p = (tmp<28) ? (oldkey_c+rol) : (tmp-=28, oldkey_d+rol);
if (tmp+rol>=28)
tmp-=28;
newkey_byte[k] =*(p+tmp);
}
ContractTo8(newkey_byte, newkey+i*6, 48);
}
}
/*---------------------- sReplace -----------------------------------*/
/*!
*\brief PURPOSE: Change 48-bits into 32-bits and replace.
*
*\par Description
Substitute the values in the S-boxes for 48-bits.
*\param[in,out] s_byte - 48-bits data array for input and 32-bits data array for output
/*---------------------- endeDes -----------------------------------*/
/*!
*\brief PURPOSE: Process of Des arithmetic.
*
*\par Description
1. Get 16 subkey form inkey.
2. Replace indata and Divide into Letf 32-bits and Right 32-bits
3. 16 iterative operation, use subkey.
4. Left 32-bits and Right 32-bits compose 64 bits, and Replace.
5. Change 64-bits into 8-byte as output.
*\param[in] indata - data which input for encrypt or decrypt
*\param[in] len - length of data
*\param[in] inkey - key
*\param[in] enflag - flag of encrypt, 0--decrypt, 1--encrypt
*\param[out] outdata - output data which get cryptograph or proclaimed in writing
*\return
*\note
*\see
*\bug
None
*\test
No test
*\todo
NO
*/
/*-------------------------------------------------------------*/
BOOL endeDesC(BYTE *indata, int len, BYTE inkey[8], BYTE *outdata, BOOL enflag)
{
#define BPOLY 0x1b /* !< Lower 8 bits of (x^8+x^4+x^3+x+1), ie. (x^4+x^3+x+1). */
#define BLOCKSIZE 16 /* !< Block size in number of UINT8s. */
#if KEY_COUNT == 1
#define KEYBITS 128 /* !< Use AES128. */
#elif KEY_COUNT == 2
#define KEYBITS 192 /* !< Use AES196. */
#elif KEY_COUNT == 3
#define KEYBITS 256 /* !< Use AES256. */
#else
#error Use 1, 2 or 3 keys!
#endif
#if KEYBITS == 128
#define ROUNDS 10 /* !< Number of rounds. */
#define KEYLENGTH 16 /* !< Key length in number of UINT8s. */
#elif KEYBITS == 192
#define ROUNDS 12 /* !< Number of rounds. */
#define KEYLENGTH 24 /* !< Key length in number of UINT8s. */
#elif KEYBITS == 256
#define ROUNDS 14 /* !< Number of rounds. */
#define KEYLENGTH 32 /* !< Key length in number of UINT8s. */
#else
#error Key must be 128, 192 or 256 bits!
#endif
UINT8 *powTbl = NULL; /* !< Final location of exponentiation lookup table.*/
UINT8 *logTbl = NULL; /* !< Final location of logarithm lookup table. */
UINT8 *sBox = NULL; /* !< Final location of s-box. */
UINT8 *sBoxInv = NULL; /* !< Final location of inverse s-box. */
UINT8 *expandedKey = NULL; /* !< Final location of expanded key. */
void CalcPowLog(UINT8 * powTbl, UINT8 * logTbl )
{
UINT8 i = 0;
UINT8 t = 1;
do
{ /* Use 0x03 as root for exponentiation and logarithms. */
powTbl[i] = t;
logTbl[t] = i;
i++; /* Muliply t by 3 in GF(2^8). */
t ^= (t << 1) ^ (t & 0x80 ? BPOLY : 0);
} while( t != 1 ); /* Cyclic properties ensure that i < 255. */
powTbl[255] = powTbl[0]; /* 255 = '-0', 254 = -1, etc. */
}
void CalcSBox( UINT8 * sBox )
{
UINT8 i, rot;
UINT8 temp;
UINT8 result;
i = 0;
do
{ /* Inverse in GF(2^8). */
if( i > 0 )
{ temp = powTbl[ 255 - logTbl[i] ]; }
else
{ temp = 0; }
/* Affine transformation in GF(2). */
result = temp ^ 0x63; /* Start with adding a vector in GF(2). */
for( rot = 0; rot < 4; rot++ )
{ // Rotate left.
temp = (temp<<1) | (temp>>7);
// Add rotated UINT8 in GF(2).
result ^= temp;
}
// Put result in table.
sBox[i] = result;
}while( ++i != 0 );
}
void CalcSBoxInv( UINT8 * sBox, UINT8 * sBoxInv )
{
UINT8 i = 0;
UINT8 j = 0;
// Iterate through all elements in sBoxInv using i.
do
{ // Search through sBox using j.
do
{ // Check if current j is the inverse of current i.
if( sBox[ j ] == i )
{ // If so, set sBoxInc and indicate search finished.
sBoxInv[ i ] = j;
j = 255;
}
}while( ++j != 0 );
}while( ++i != 0 );
}
// Copy key to start of expanded key.
i = KEYLENGTH;
do
{
*expandedKey = *key;
expandedKey++;
key++;
} while( --i );
// Prepare last 4 bytes of key in temp.
CopyBytes(temp, expandedKey-4, 4);
// Expand key.
i = KEYLENGTH;
//j = BLOCKSIZE*(ROUNDS+1) - KEYLENGTH;
while( i < BLOCKSIZE*(ROUNDS+1) )
{
// Are we at the start of a multiple of the key size?
if( (i % KEYLENGTH) == 0 )
{
CycleLeft( temp ); // Cycle left once.
SubBytes( temp, 4 ); // Substitute each byte.
XORBytes( temp, Rcon, 4 ); // Add constant in GF(2).
*Rcon = (*Rcon << 1) ^ (*Rcon & 0x80 ? BPOLY : 0);
}
// Keysize larger than 24 bytes, ie. larger that 192 bits?
#if KEYLENGTH > 24
// Are we right past a block size?
else if( (i % KEYLENGTH) == BLOCKSIZE ) {
SubBytes( temp, 4 ); // Substitute each byte.
}
#endif
// Add bytes in GF(2) one KEYLENGTH away.
XORBytes( temp, expandedKey - KEYLENGTH, 4 );