~ubuntu-branches/ubuntu/precise/arj/precise-security

« back to all changes in this revision

Viewing changes to gost40.c

  • Committer: Bazaar Package Importer
  • Author(s): Guillem Jover
  • Date: 2004-06-27 08:07:09 UTC
  • Revision ID: james.westby@ubuntu.com-20040627080709-1gkxm72ex66gkwe4
Tags: upstream-3.10.21
ImportĀ upstreamĀ versionĀ 3.10.21

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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.
 
6
 *
 
7
 */
 
8
 
 
9
#include "arj.h"
 
10
 
 
11
DEBUGHDR(__FILE__)                      /* Debug information block */
 
12
 
 
13
/* Local variables */
 
14
 
 
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
 
17
                                           last block */
 
18
 
 
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};
 
23
#define bf(x) ord[x]
 
24
static void adjust_byte_order(char *p,const int len)
 
25
{
 
26
int l4;
 
27
 
 
28
for (l4=len>>2;l4;l4--)
 
29
  {
 
30
  char tmp,*p1,*p2;
 
31
 
 
32
   p1   =  p +1;
 
33
   p2   =  p1+1;
 
34
   tmp  = *p2;
 
35
  *p2++ = *p1;
 
36
  *p1-- =  tmp;
 
37
   tmp  = *p1;
 
38
  *p1   = *p2;
 
39
  *p2   =  tmp;
 
40
   p    =  p2+1;
 
41
  }
 
42
}
 
43
#else
 
44
#define bf(x) (x)
 
45
#endif
 
46
 
 
47
void codec(void (*fct)(unsigned char*, unsigned char*, int), unsigned char *buf, int len)
 
48
{
 
49
#ifdef WORDS_BIGENDIAN
 
50
if (!(len&7) && !last_bytes) adjust_byte_order(buf,len);
 
51
#endif
 
52
(*fct)(buf,buf,len);
 
53
#ifdef WORDS_BIGENDIAN
 
54
if (!(len&7) && !last_bytes) adjust_byte_order(buf,len);
 
55
#endif
 
56
}
 
57
 
 
58
/* GOST encoding/decoding loop */
 
59
 
 
60
static void gost40_loop(unsigned long *src, unsigned long *dest, unsigned long *key)
 
61
{
 
62
 unsigned long mod1, mod2;
 
63
 int i;
 
64
 
 
65
 mod1=src[0];
 
66
 mod2=src[1];
 
67
 for(i=0; i<3; i++)
 
68
 {
 
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]);
 
77
 }
 
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]);
 
86
 dest[0]=mod2;
 
87
 dest[1]=mod1;
 
88
}
 
89
 
 
90
/* Encoding sequence */
 
91
 
 
92
static void gost40_encode(unsigned char *src, unsigned char *dest, int len)
 
93
{
 
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 */
 
98
 
 
99
 remainder=len%8;
 
100
 if(remainder==0&&last_bytes==0)
 
101
 {
 
102
  tmp_sptr=(unsigned long *)src;
 
103
  tmp_dptr=(unsigned long *)dest;
 
104
  len>>=3;
 
105
  while(len--!=0)
 
106
  {
 
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];
 
110
   tmp_sptr+=2;
 
111
   tmp_dptr+=2;
 
112
  }
 
113
 }
 
114
 else
 
115
 {
 
116
  bc_offset=(unsigned char *)back_code;
 
117
  while(len--!=0)
 
118
  {
 
119
   if(last_bytes==0)
 
120
    gost40_loop(back_code, back_code, gost40_key);
 
121
   bc_offset[bf(last_bytes)]=*(dest++)=*(src++)^bc_offset[bf(last_bytes)];
 
122
   last_bytes++;
 
123
   last_bytes%=8;
 
124
  }
 
125
 }
 
126
}
 
127
 
 
128
/* Decoding sequence */
 
129
 
 
130
static void gost40_decode(unsigned char *src, unsigned char *dest, int len)
 
131
{
 
132
 unsigned long *tmp_sptr;
 
133
 unsigned long *tmp_dptr;
 
134
 int remainder;
 
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 */
 
138
 
 
139
 remainder=len%8;
 
140
 if(remainder==0&&last_bytes==0)
 
141
 {
 
142
  tmp_sptr=(unsigned long *)src;
 
143
  tmp_dptr=(unsigned long *)dest;
 
144
  len>>=3;
 
145
  while(len--!=0)
 
146
  {
 
147
   gost40_loop(back_code, back_code, gost40_key);
 
148
   d_data=tmp_sptr[0];
 
149
   tmp_dptr[0]=d_data^back_code[0];
 
150
   back_code[0]=d_data;
 
151
   d_data=tmp_sptr[1];
 
152
   tmp_dptr[1]=d_data^back_code[1];
 
153
   back_code[1]=d_data;
 
154
   tmp_sptr+=2;
 
155
   tmp_dptr+=2;
 
156
  }
 
157
 }
 
158
 else
 
159
 {
 
160
  bc_offset=(unsigned char *)back_code;
 
161
  while(len--!=0)
 
162
  {
 
163
   if(last_bytes==0)
 
164
    gost40_loop(back_code, back_code, gost40_key);
 
165
   dec_sym=*(src++);
 
166
   *(dest++)=dec_sym^bc_offset[bf(last_bytes)];
 
167
   bc_offset[bf(last_bytes++)]=dec_sym;
 
168
   last_bytes%=8;
 
169
  }
 
170
 }
 
171
}
 
172
 
 
173
/* Creates an unique encoding key from the given seed */
 
174
 
 
175
static void gost40_crtkey(unsigned long *seed)
 
176
{
 
177
 unsigned long tmp_key[8];
 
178
 int i;
 
179
 
 
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));
 
185
}
 
186
 
 
187
/* Initializes the GOST 28147-89 encryption module */
 
188
 
 
189
void gost40_init(unsigned char modifier)
 
190
{
 
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 */
 
195
 
 
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++)
 
200
 {
 
201
  key_ptr[bf(ckey%5)]+=*(gp_ptr++)<<ckey%7;
 
202
  if(*gp_ptr=='\0')
 
203
   gp_ptr=garble_password;
 
204
 }
 
205
 l_modifier[0]=garble_ftime;
 
206
 l_modifier[1]=(long)(signed char)modifier;
 
207
 last_bytes=0;
 
208
 calc_gost_pattern();
 
209
 gost40_crtkey(l_modifier);
 
210
 gost40_loop(l_modifier, back_code, gost40_key);
 
211
}
 
212
 
 
213
/* Encoding routine for interfacing with ARJ */
 
214
 
 
215
void gost40_encode_stub(char *data, int len)
 
216
{
 
217
 codec(gost40_encode, (unsigned char *)data, len);
 
218
}
 
219
 
 
220
/* Decoding routine for interfacing with ARJ */
 
221
 
 
222
void gost40_decode_stub(char *data, int len)
 
223
{
 
224
 codec(gost40_decode, (unsigned char *)data, len);
 
225
}
 
226