-
ivan.fedorov authored
some fixes
4049bb05
/** @file
* @brief 28147-89
*
* @copyright InfoTeCS. All rights reserved.
*/
#include "28147_89.h"
/** @brief int32
*
* @param[in] input 4
* @return int32
*/
static unsigned int uint8ToUint32(unsigned char* input)
{
unsigned int r = ( (input[3]) | (input[2]<<8) | (input[1]<<16) | (input[0]<<24));
return r;
}
/** @brief int32
*
* @param[in] input int32
* @param[out] output 4
*/
static void uint32ToUint8(unsigned int input, unsigned char* output)
{
int i;
for(i = 0; i < 4; ++i)
{
output[3-i] = ( ( input >> (8*i) ) & 0x000000ff );
}
}
/** @brief id-tc26-gost-28147-param-Z OID: 1.2.643.7.1.2.5.1.1 */
unsigned char p[8][16] =
{
{0xc, 0x4, 0x6, 0x2, 0xa, 0x5, 0xb, 0x9, 0xe, 0x8, 0xd, 0x7, 0x0, 0x3, 0xf, 0x1},
{0x6, 0x8, 0x2, 0x3, 0x9, 0xa, 0x5, 0xc, 0x1, 0xe, 0x4, 0x7, 0xb, 0xd, 0x0, 0xf},
{0xb, 0x3, 0x5, 0x8, 0x2, 0xf, 0xa, 0xd, 0xe, 0x1, 0x7, 0x4, 0xc, 0x9, 0x6, 0x0},
{0xc, 0x8, 0x2, 0x1, 0xd, 0x4, 0xf, 0x6, 0x7, 0x0, 0xa, 0x5, 0x3, 0xe, 0x9, 0xb},
{0x7, 0xf, 0x5, 0xa, 0x8, 0x1, 0x6, 0xd, 0x0, 0x9, 0x3, 0xe, 0xb, 0x4, 0x2, 0xc},
{0x5, 0xd, 0xf, 0x6, 0x9, 0x2, 0xc, 0xa, 0xb, 0x7, 0x8, 0x1, 0x4, 0x3, 0xe, 0x0},
{0x8, 0xe, 0x2, 0x5, 0x6, 0x9, 0x1, 0xc, 0xf, 0x4, 0xb, 0x0, 0xd, 0xa, 0x3, 0x7},
{0x1, 0x7, 0xe, 0xd, 0x0, 0x5, 0x8, 0x3, 0x4, 0xf, 0xa, 0x6, 0x9, 0xc, 0xb, 0x2}
};
/** @brief */
unsigned char kEncRoundKey[32] =
{
0, 4, 8, 12, 16, 20, 24, 28, 0, 4, 8, 12, 16, 20, 24, 28, 0, 4, 8, 12, 16, 20, 24, 28, 28, 24, 20, 16, 12, 8, 4, 0
};
/** @brief */
unsigned char kDecRoundKey[32] =
{
0, 4, 8, 12, 16, 20, 24, 28, 28, 24, 20, 16, 12, 8, 4, 0, 28, 24, 20, 16, 12, 8, 4, 0, 28, 24, 20, 16, 12, 8, 4, 0
};
unsigned int DLL_IMPORT funcT(unsigned int a, printout_uint_array print)
{
unsigned int res = 0;
res ^= p[ 0 ][ a & 0x0000000f ];
res ^= ( p[ 1 ][ ( ( a & 0x000000f0 ) >> 4 ) ] << 4 );
res ^= ( p[ 2 ][ ( ( a & 0x00000f00 ) >> 8 ) ] << 8 );
res ^= ( p[ 3 ][ ( ( a & 0x0000f000 ) >> 12 ) ] << 12 );
res ^= ( p[ 4 ][ ( ( a & 0x000f0000 ) >> 16 ) ] << 16 );
res ^= ( p[ 5 ][ ( ( a & 0x00f00000 ) >> 20 ) ] << 20 );
res ^= ( p[ 6 ][ ( ( a & 0x0f000000 ) >> 24 ) ] << 24 );
res ^= ( p[ 7 ][ ( ( a & 0xf0000000 ) >> 28 ) ] << 28 );
if(print)
{
print("funcT: a: ", &a, 1);
print("funcT: output: ", &res, 1);
}
return res;
}
unsigned int DLL_IMPORT funcG(unsigned int a, unsigned int k, printout_uint_array print)
{
unsigned int c = a + k;
unsigned int tmp = funcT(c, print);
unsigned int r = (tmp<<11) | (tmp >> 21);
if(print)
{
print("funcG: a: ", &a, 1);
print("funcG: k: ", &k, 1);
print("funcG: output: ", &r, 1);
}
return r;
}
void DLL_IMPORT Round(unsigned int* a1, unsigned int* a0, unsigned int k, printout_uint_array print)
{
unsigned int a;
unsigned int tmp;
if(print)
{
print("Round: input a1: ", a1, 1);
print("Round: input a0: ", a0, 1);
print("Round: k: ", &k, 1);
}
a = *a0;
tmp = funcG(*a0, k, print);
*a0 = *a1 ^ tmp;
*a1 = a;
if(print)
{
print("Round: output a1: ", a1, 1);
print("Round: output a0: ", a0, 1);
}
}
void DLL_IMPORT RoundShtrih(unsigned int* a1, unsigned int* a0, unsigned int k, printout_uint_array print)
{
unsigned int tmp;
if(print)
{
print("RoundShtrih: input a1: ", a1, 1);
print("RoundShtrih: input a0: ", a0, 1);
print("RoundShtrih: k: ", &k, 1);
}
tmp = funcG(*a0, k, print);
*a1 ^= tmp;
if(print)
{
print("RoundShtrih: output a1: ", a1, 1);
print("RoundShtrih: output a0: ", a0, 1);
}
}
int DLL_IMPORT CryptBlock(unsigned char* input, unsigned char* output, unsigned char* key, unsigned char* keyIndex, printout_uint_array print)
{
unsigned int a1 = uint8ToUint32(input);
unsigned int a0 = uint8ToUint32(input + 4);
int i;
if(print)
{
print("CryptBlock: input a1:", &a1, 1);
print("CryptBlock: input a0:", &a0, 1);
}
for(i = 0; i < 31; ++i)
{
Round(&a1, &a0, uint8ToUint32(key + keyIndex[i]), print);
}
RoundShtrih(&a1, &a0, uint8ToUint32(key + keyIndex[31]), print);
if(print)
{
print("CryptBlock: output a1:", &a1, 1);
print("CryptBlock: output a0:", &a0, 1);
}
uint32ToUint8(a1, output);
uint32ToUint8(a0, output+4);
return 0;
}
int DLL_IMPORT EncryptBlock(unsigned char* input, unsigned char* output, unsigned char* key, printout_uint_array print)
{
return CryptBlock(input, output, key, kEncRoundKey, print);
}
int DLL_IMPORT DecryptBlock(unsigned char* input, unsigned char* output, unsigned char* key, printout_uint_array print)
{
return CryptBlock(input, output, key, kDecRoundKey, print);
}
int DLL_IMPORT Encrypt_89(unsigned char* input, unsigned char* output, unsigned char* key, printout_byte_array print, printout_uint_array print_uint)
{
if( !input || !output || !key )
{
if(print)
print("Encrypt_89: internal error!", 0, 0);
return -1;
}
if(EncryptBlock(input, output, key, print_uint))
return -1;
if(print)
{
print("Encrypt_89: plain text: ", input, 8);
print("Encrypt_89: chipher text: ", output, 8);
}
return 0;
}
int DLL_IMPORT Decrypt_89(unsigned char* input, unsigned char* output, unsigned char* key, printout_byte_array print, printout_uint_array print_uint)
{
if( !input || !output || !key )
{
if(print)
print("Decrypt_89: internal error!", 0, 0);
return -1;
}
if(DecryptBlock(input, output, key, print_uint))
return -1;
if(print)
{
print("Encrypt_89: chipher text: ", input, 8);
print("Encrypt_89: plain text: ", output, 8);
}
return 0;
}