Mon, 17 Sep 2012 19:10:10 +0200
Update to new version of vendor software although Oracle fails to deliver.
More specifically, newer db(3) patch revisions exist but Oracle has
removed them from the canonical download server URI for Berkely DB.
1 #include <config.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h> /* for memcmp() */
5 #include <assert.h>
7 #include "types.h" /* for byte and u32 typedefs */
8 #include "g10lib.h"
9 #include "cipher.h"
11 /* configuration stuff */
12 #ifdef __alpha__
13 #define SIZEOF_UNSIGNED_LONG 8
14 #else
15 #define SIZEOF_UNSIGNED_LONG 4
16 #endif
18 #if defined(__mc68000__) || defined (__sparc__) || defined (__PPC__) \
19 || (defined(__mips__) && (defined(MIPSEB) || defined (__MIPSEB__)) ) \
20 || defined(__powerpc__) \
21 || defined(__hpux__) /* should be replaced by the Macro for the PA */
22 #define BIG_ENDIAN_HOST 1
23 #else
24 #define LITTLE_ENDIAN_HOST 1
25 #endif
27 #ifndef DIM
28 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
29 #define DIMof(type,member) DIM(((type *)0)->member)
30 #endif
32 /* imports */
33 void g10_log_fatal( const char *fmt, ... );
36 /* local stuff */
38 #define FNCCAST_SETKEY(f) ((int(*)(void*, byte*, unsigned))(f))
39 #define FNCCAST_CRYPT(f) ((void(*)(void*, byte*, byte*))(f))
41 #define IDEA_KEYSIZE 16
42 #define IDEA_BLOCKSIZE 8
43 #define IDEA_ROUNDS 8
44 #define IDEA_KEYLEN (6*IDEA_ROUNDS+4)
46 typedef struct {
47 u16 ek[IDEA_KEYLEN];
48 u16 dk[IDEA_KEYLEN];
49 int have_dk;
50 } IDEA_context;
52 static u16
53 mul_inv( u16 x )
54 {
55 u16 t0, t1;
56 u16 q, y;
58 if( x < 2 )
59 return x;
60 t1 = 0x10001L / x;
61 y = 0x10001L % x;
62 if( y == 1 )
63 return (1-t1) & 0xffff;
65 t0 = 1;
66 do {
67 q = x / y;
68 x = x % y;
69 t0 += q * t1;
70 if( x == 1 )
71 return t0;
72 q = y / x;
73 y = y % x;
74 t1 += q * t0;
75 } while( y != 1 );
76 return (1-t1) & 0xffff;
77 }
79 static void
80 cipher( byte *outbuf, const byte *inbuf, u16 *key )
81 {
82 u16 x1, x2, x3,x4, s2, s3;
83 u16 *in, *out;
84 int r = IDEA_ROUNDS;
85 #define MUL(x,y) \
86 do {u16 _t16; u32 _t32; \
87 if( (_t16 = (y)) ) { \
88 if( (x = (x)&0xffff) ) { \
89 _t32 = (u32)x * _t16; \
90 x = _t32 & 0xffff; \
91 _t16 = _t32 >> 16; \
92 x = ((x)-_t16) + (x<_t16?1:0); \
93 } \
94 else { \
95 x = 1 - _t16; \
96 } \
97 } \
98 else { \
99 x = 1 - x; \
100 } \
101 } while(0)
103 in = (u16*)inbuf;
104 x1 = *in++;
105 x2 = *in++;
106 x3 = *in++;
107 x4 = *in;
108 #ifdef LITTLE_ENDIAN_HOST
109 x1 = (x1>>8) | (x1<<8);
110 x2 = (x2>>8) | (x2<<8);
111 x3 = (x3>>8) | (x3<<8);
112 x4 = (x4>>8) | (x4<<8);
113 #endif
114 do {
115 MUL(x1, *key++);
116 x2 += *key++;
117 x3 += *key++;
118 MUL(x4, *key++ );
120 s3 = x3;
121 x3 ^= x1;
122 MUL(x3, *key++);
123 s2 = x2;
124 x2 ^=x4;
125 x2 += x3;
126 MUL(x2, *key++);
127 x3 += x2;
129 x1 ^= x2;
130 x4 ^= x3;
132 x2 ^= s3;
133 x3 ^= s2;
134 } while( --r );
135 MUL(x1, *key++);
136 x3 += *key++;
137 x2 += *key++;
138 MUL(x4, *key);
140 out = (u16*)outbuf;
141 #ifdef LITTLE_ENDIAN_HOST
142 *out++ = (x1>>8) | (x1<<8);
143 *out++ = (x3>>8) | (x3<<8);
144 *out++ = (x2>>8) | (x2<<8);
145 *out = (x4>>8) | (x4<<8);
146 #else
147 *out++ = x1;
148 *out++ = x3;
149 *out++ = x2;
150 *out = x4;
151 #endif
152 #undef MUL
153 }
155 static void
156 expand_key( const byte *userkey, u16 *ek )
157 {
158 int i,j;
160 for(j=0; j < 8; j++ ) {
161 ek[j] = (*userkey << 8) + userkey[1];
162 userkey += 2;
163 }
164 for(i=0; j < IDEA_KEYLEN; j++ ) {
165 i++;
166 ek[i+7] = ek[i&7] << 9 | ek[(i+1)&7] >> 7;
167 ek += i & 8;
168 i &= 7;
169 }
170 }
172 static void
173 invert_key( u16 *ek, u16 dk[IDEA_KEYLEN] )
174 {
175 int i;
176 u16 t1, t2, t3;
177 u16 temp[IDEA_KEYLEN];
178 u16 *p = temp + IDEA_KEYLEN;
180 t1 = mul_inv( *ek++ );
181 t2 = -*ek++;
182 t3 = -*ek++;
183 *--p = mul_inv( *ek++ );
184 *--p = t3;
185 *--p = t2;
186 *--p = t1;
188 for(i=0; i < IDEA_ROUNDS-1; i++ ) {
189 t1 = *ek++;
190 *--p = *ek++;
191 *--p = t1;
193 t1 = mul_inv( *ek++ );
194 t2 = -*ek++;
195 t3 = -*ek++;
196 *--p = mul_inv( *ek++ );
197 *--p = t2;
198 *--p = t3;
199 *--p = t1;
200 }
201 t1 = *ek++;
202 *--p = *ek++;
203 *--p = t1;
205 t1 = mul_inv( *ek++ );
206 t2 = -*ek++;
207 t3 = -*ek++;
208 *--p = mul_inv( *ek++ );
209 *--p = t3;
210 *--p = t2;
211 *--p = t1;
212 memcpy(dk, temp, sizeof(temp) );
213 memset(temp, 0, sizeof(temp) ); /* burn temp */
214 }
216 static int
217 do_idea_setkey( IDEA_context *c, const byte *key, unsigned int keylen )
218 {
219 assert(keylen == 16);
220 c->have_dk = 0;
221 expand_key( key, c->ek );
222 invert_key( c->ek, c->dk );
223 return 0;
224 }
226 static gcry_err_code_t
227 idea_setkey (void *context, const byte *key, unsigned int keylen)
228 {
229 IDEA_context *ctx = context;
230 int rc = do_idea_setkey (ctx, key, keylen);
231 _gcry_burn_stack (23+6*sizeof(void*));
232 return rc;
233 }
235 static void
236 do_idea_encrypt( IDEA_context *c, byte *outbuf, const byte *inbuf )
237 {
238 cipher( outbuf, inbuf, c->ek );
239 }
241 static void
242 idea_encrypt (void *context, byte *out, const byte *in)
243 {
244 IDEA_context *ctx = context;
245 do_idea_encrypt (ctx, out, in);
246 _gcry_burn_stack (24+3*sizeof (void*));
247 }
249 static void
250 do_idea_decrypt( IDEA_context *c, byte *outbuf, const byte *inbuf )
251 {
252 if( !c->have_dk ) {
253 c->have_dk = 1;
254 invert_key( c->ek, c->dk );
255 }
256 cipher( outbuf, inbuf, c->dk );
257 }
259 static void
260 idea_decrypt (void *context, byte *out, const byte *in)
261 {
262 IDEA_context *ctx = context;
264 do_idea_decrypt (ctx, out, in);
265 _gcry_burn_stack (24+3*sizeof (void*));
266 }
268 gcry_cipher_spec_t _gcry_cipher_spec_idea =
269 {
270 "IDEA", NULL, NULL, IDEA_BLOCKSIZE, 128, sizeof (IDEA_context),
271 idea_setkey, idea_encrypt, idea_decrypt,
272 };