2
* $Id: gost40.c,v 1.3 2003/04/27 20:54:42 andrew_belov Exp $
3
* ---------------------------------------------------------------------------
4
* This file contains the routines that provide 40-bit GOST encryption with
5
* dependence on previously encrypted data.
11
DEBUGHDR(__FILE__) /* Debug information block */
15
static unsigned long default_key[8]={3, 10, 6, 12, 5, 9, 0, 7};
16
static int last_bytes=0; /* Number of significant bytes in the
19
static unsigned long back_code[2]={0L}; /* Recently encrypted data */
20
static unsigned long gost40_key[8]={0L};/* Automatically generated key */
21
#ifdef WORDS_BIGENDIAN
22
static const int ord[8]={3,2,1,0,7,6,5,4};
24
static void adjust_byte_order(char *p,const int len)
28
for (l4=len>>2;l4;l4--)
47
void codec(void (*fct)(unsigned char*, unsigned char*, int), unsigned char *buf, int len)
49
#ifdef WORDS_BIGENDIAN
50
if (!(len&7) && !last_bytes) adjust_byte_order(buf,len);
53
#ifdef WORDS_BIGENDIAN
54
if (!(len&7) && !last_bytes) adjust_byte_order(buf,len);
58
/* GOST encoding/decoding loop */
60
static void gost40_loop(unsigned long *src, unsigned long *dest, unsigned long *key)
62
unsigned long mod1, mod2;
69
mod2^=gost_term(mod1+key[0]);
70
mod1^=gost_term(mod2+key[1]);
71
mod2^=gost_term(mod1+key[2]);
72
mod1^=gost_term(mod2+key[3]);
73
mod2^=gost_term(mod1+key[4]);
74
mod1^=gost_term(mod2+key[5]);
75
mod2^=gost_term(mod1+key[6]);
76
mod1^=gost_term(mod2+key[7]);
78
mod2^=gost_term(mod1+key[7]);
79
mod1^=gost_term(mod2+key[6]);
80
mod2^=gost_term(mod1+key[5]);
81
mod1^=gost_term(mod2+key[4]);
82
mod2^=gost_term(mod1+key[3]);
83
mod1^=gost_term(mod2+key[2]);
84
mod2^=gost_term(mod1+key[1]);
85
mod1^=gost_term(mod2+key[0]);
90
/* Encoding sequence */
92
static void gost40_encode(unsigned char *src, unsigned char *dest, int len)
94
unsigned long *tmp_sptr; /* Pointer to source area */
95
unsigned long *tmp_dptr; /* Pointer to target area */
96
int remainder; /* Number of bytes in the last block */
97
unsigned char *bc_offset; /* Offset within back_code */
100
if(remainder==0&&last_bytes==0)
102
tmp_sptr=(unsigned long *)src;
103
tmp_dptr=(unsigned long *)dest;
107
gost40_loop(back_code, back_code, gost40_key);
108
back_code[0]=tmp_dptr[0]=tmp_sptr[0]^back_code[0];
109
back_code[1]=tmp_dptr[1]=tmp_sptr[1]^back_code[1];
116
bc_offset=(unsigned char *)back_code;
120
gost40_loop(back_code, back_code, gost40_key);
121
bc_offset[bf(last_bytes)]=*(dest++)=*(src++)^bc_offset[bf(last_bytes)];
128
/* Decoding sequence */
130
static void gost40_decode(unsigned char *src, unsigned char *dest, int len)
132
unsigned long *tmp_sptr;
133
unsigned long *tmp_dptr;
135
unsigned long d_data; /* Decoded data collector */
136
unsigned char *bc_offset; /* Offset within back_code */
137
unsigned char dec_sym; /* Currently processed symbol */
140
if(remainder==0&&last_bytes==0)
142
tmp_sptr=(unsigned long *)src;
143
tmp_dptr=(unsigned long *)dest;
147
gost40_loop(back_code, back_code, gost40_key);
149
tmp_dptr[0]=d_data^back_code[0];
152
tmp_dptr[1]=d_data^back_code[1];
160
bc_offset=(unsigned char *)back_code;
164
gost40_loop(back_code, back_code, gost40_key);
166
*(dest++)=dec_sym^bc_offset[bf(last_bytes)];
167
bc_offset[bf(last_bytes++)]=dec_sym;
173
/* Creates an unique encoding key from the given seed */
175
static void gost40_crtkey(unsigned long *seed)
177
unsigned long tmp_key[8];
180
memcpy(tmp_key, gost40_key, sizeof(tmp_key));
181
gost40_loop(seed, back_code, default_key);
182
for(i=0; i<KEYGEN_ITERATIONS; i++)
183
gost40_encode((unsigned char *)tmp_key, (unsigned char *)tmp_key, sizeof(tmp_key));
184
memcpy(gost40_key, tmp_key, sizeof(gost40_key));
187
/* Initializes the GOST 28147-89 encryption module */
189
void gost40_init(unsigned char modifier)
191
char *gp_ptr; /* Pointer to garble password */
192
char *key_ptr; /* Pointer to key field */
193
int ckey; /* Current key element */
194
unsigned long l_modifier[2]; /* Initializer for key creation loop */
196
memset(gost40_key, 0, sizeof(gost40_key));
197
key_ptr=(char *)gost40_key;
198
gp_ptr=garble_password;
199
for(ckey=0; ckey<64; ckey++)
201
key_ptr[bf(ckey%5)]+=*(gp_ptr++)<<ckey%7;
203
gp_ptr=garble_password;
205
l_modifier[0]=garble_ftime;
206
l_modifier[1]=(long)(signed char)modifier;
209
gost40_crtkey(l_modifier);
210
gost40_loop(l_modifier, back_code, gost40_key);
213
/* Encoding routine for interfacing with ARJ */
215
void gost40_encode_stub(char *data, int len)
217
codec(gost40_encode, (unsigned char *)data, len);
220
/* Decoding routine for interfacing with ARJ */
222
void gost40_decode_stub(char *data, int len)
224
codec(gost40_decode, (unsigned char *)data, len);