]> git.sesse.net Git - shamaz/blob - ice.c
Split XML parsing out in a separate program.
[shamaz] / ice.c
1 /*
2  * Implementation of the ICE encryption algorithm.
3  *
4  * Written by Matthew Kwan - July 1996
5  */
6
7 #include "ice.h"
8 #include <stdio.h>
9 #include <stdlib.h>
10
11
12         /* Structure of a single round subkey */
13 typedef unsigned long   ICE_SUBKEY[3];
14
15
16         /* Internal structure of the ICE_KEY structure */
17 struct ice_key_struct {
18         int             ik_size;
19         int             ik_rounds;
20         ICE_SUBKEY      *ik_keysched;
21 };
22
23         /* The S-boxes */
24 static unsigned long    ice_sbox[4][1024];
25 static int              ice_sboxes_initialised = 0;
26
27
28         /* Modulo values for the S-boxes */
29 static const int        ice_smod[4][4] = {
30                                 {333, 313, 505, 369},
31                                 {379, 375, 319, 391},
32                                 {361, 445, 451, 397},
33                                 {397, 425, 395, 505}};
34
35         /* XOR values for the S-boxes */
36 static const int        ice_sxor[4][4] = {
37                                 {0x83, 0x85, 0x9b, 0xcd},
38                                 {0xcc, 0xa7, 0xad, 0x41},
39                                 {0x4b, 0x2e, 0xd4, 0x33},
40                                 {0xea, 0xcb, 0x2e, 0x04}};
41
42         /* Expanded permutation values for the P-box */
43 static const unsigned long      ice_pbox[32] = {
44                 0x00000001, 0x00000080, 0x00000400, 0x00002000,
45                 0x00080000, 0x00200000, 0x01000000, 0x40000000,
46                 0x00000008, 0x00000020, 0x00000100, 0x00004000,
47                 0x00010000, 0x00800000, 0x04000000, 0x20000000,
48                 0x00000004, 0x00000010, 0x00000200, 0x00008000,
49                 0x00020000, 0x00400000, 0x08000000, 0x10000000,
50                 0x00000002, 0x00000040, 0x00000800, 0x00001000,
51                 0x00040000, 0x00100000, 0x02000000, 0x80000000};
52
53         /* The key rotation schedule */
54 static const int        ice_keyrot[16] = {
55                                 0, 1, 2, 3, 2, 1, 3, 0,
56                                 1, 3, 2, 0, 3, 1, 0, 2};
57
58
59 /*
60  * Galois Field multiplication of a by b, modulo m.
61  * Just like arithmetic multiplication, except that additions and
62  * subtractions are replaced by XOR.
63  */
64
65 static unsigned int
66 gf_mult (
67         register unsigned int   a,
68         register unsigned int   b,
69         register unsigned int   m
70 ) {
71         register unsigned int   res = 0;
72
73         while (b) {
74             if (b & 1)
75                 res ^= a;
76
77             a <<= 1;
78             b >>= 1;
79
80             if (a >= 256)
81                 a ^= m;
82         }
83
84         return (res);
85 }
86
87
88 /*
89  * Galois Field exponentiation.
90  * Raise the base to the power of 7, modulo m.
91  */
92
93 static unsigned long
94 gf_exp7 (
95         register unsigned int   b,
96         unsigned int            m
97 ) {
98         register unsigned int   x;
99
100         if (b == 0)
101             return (0);
102
103         x = gf_mult (b, b, m);
104         x = gf_mult (b, x, m);
105         x = gf_mult (x, x, m);
106         return (gf_mult (b, x, m));
107 }
108
109
110 /*
111  * Carry out the ICE 32-bit P-box permutation.
112  */
113
114 static unsigned long
115 ice_perm32 (
116         register unsigned long  x
117 ) {
118         register unsigned long          res = 0;
119         register const unsigned long    *pbox = ice_pbox;
120
121         while (x) {
122             if (x & 1)
123                 res |= *pbox;
124             pbox++;
125             x >>= 1;
126         }
127
128         return (res);
129 }
130
131
132 /*
133  * Initialise the ICE S-boxes.
134  * This only has to be done once.
135  */
136
137 static void
138 ice_sboxes_init (void)
139 {
140         register int    i;
141
142         for (i=0; i<1024; i++) {
143             int                 col = (i >> 1) & 0xff;
144             int                 row = (i & 0x1) | ((i & 0x200) >> 8);
145             unsigned long       x;
146
147             x = gf_exp7 (col ^ ice_sxor[0][row], ice_smod[0][row]) << 24;
148             ice_sbox[0][i] = ice_perm32 (x);
149
150             x = gf_exp7 (col ^ ice_sxor[1][row], ice_smod[1][row]) << 16;
151             ice_sbox[1][i] = ice_perm32 (x);
152
153             x = gf_exp7 (col ^ ice_sxor[2][row], ice_smod[2][row]) << 8;
154             ice_sbox[2][i] = ice_perm32 (x);
155
156             x = gf_exp7 (col ^ ice_sxor[3][row], ice_smod[3][row]);
157             ice_sbox[3][i] = ice_perm32 (x);
158         }
159 }
160
161
162 /*
163  * Create a new ICE key.
164  */
165
166 ICE_KEY *
167 ice_key_create (
168         int             n
169 ) {
170         ICE_KEY         *ik;
171
172         if (!ice_sboxes_initialised) {
173             ice_sboxes_init ();
174             ice_sboxes_initialised = 1;
175         }
176
177         if ((ik = (ICE_KEY *) malloc (sizeof (ICE_KEY))) == NULL)
178             return (NULL);
179
180         if (n < 1) {
181             ik->ik_size = 1;
182             ik->ik_rounds = 8;
183         } else {
184             ik->ik_size = n;
185             ik->ik_rounds = n * 16;
186         }
187
188         if ((ik->ik_keysched = (ICE_SUBKEY *) malloc (ik->ik_rounds
189                                         * sizeof (ICE_SUBKEY))) == NULL) {
190             free (ik);
191             return (NULL);
192         }
193
194         return (ik);
195 }
196
197
198 /*
199  * Destroy an ICE key.
200  * Zero out the memory to prevent snooping.
201  */
202
203 void
204 ice_key_destroy (
205         ICE_KEY         *ik
206 ) {
207         int             i, j;
208
209         if (ik == NULL)
210             return;
211
212         for (i=0; i<ik->ik_rounds; i++)
213             for (j=0; j<3; j++)
214                 ik->ik_keysched[i][j] = 0;
215
216         ik->ik_rounds = ik->ik_size = 0;
217
218         if (ik->ik_keysched != NULL)
219             free (ik->ik_keysched);
220
221         free (ik);
222 }
223
224
225 /*
226  * The single round ICE f function.
227  */
228
229 static unsigned long
230 ice_f (
231         register unsigned long  p,
232         const ICE_SUBKEY        sk
233 ) {
234         unsigned long   tl, tr;         /* Expanded 40-bit values */
235         unsigned long   al, ar;         /* Salted expanded 40-bit values */
236
237                                         /* Left half expansion */
238         tl = ((p >> 16) & 0x3ff) | (((p >> 14) | (p << 18)) & 0xffc00);
239
240                                         /* Right half expansion */
241         tr = (p & 0x3ff) | ((p << 2) & 0xffc00);
242
243                                         /* Perform the salt permutation */
244                                 /* al = (tr & sk[2]) | (tl & ~sk[2]); */
245                                 /* ar = (tl & sk[2]) | (tr & ~sk[2]); */
246         al = sk[2] & (tl ^ tr);
247         ar = al ^ tr;
248         al ^= tl;
249
250         al ^= sk[0];                    /* XOR with the subkey */
251         ar ^= sk[1];
252
253                                         /* S-box lookup and permutation */
254         return (ice_sbox[0][al >> 10] | ice_sbox[1][al & 0x3ff]
255                 | ice_sbox[2][ar >> 10] | ice_sbox[3][ar & 0x3ff]);
256 }
257
258
259 /*
260  * Encrypt a block of 8 bytes of data with the given ICE key.
261  */
262
263 void
264 ice_key_encrypt (
265         const ICE_KEY           *ik,
266         const unsigned char     *ptext,
267         unsigned char           *ctext
268 ) {
269         register int            i;
270         register unsigned long  l, r;
271
272         l = (((unsigned long) ptext[0]) << 24)
273                                 | (((unsigned long) ptext[1]) << 16)
274                                 | (((unsigned long) ptext[2]) << 8) | ptext[3];
275         r = (((unsigned long) ptext[4]) << 24)
276                                 | (((unsigned long) ptext[5]) << 16)
277                                 | (((unsigned long) ptext[6]) << 8) | ptext[7];
278
279         for (i = 0; i < ik->ik_rounds; i += 2) {
280             l ^= ice_f (r, ik->ik_keysched[i]);
281             r ^= ice_f (l, ik->ik_keysched[i + 1]);
282         }
283
284         for (i = 0; i < 4; i++) {
285             ctext[3 - i] = r & 0xff;
286             ctext[7 - i] = l & 0xff;
287
288             r >>= 8;
289             l >>= 8;
290         }
291 }
292
293
294 /*
295  * Decrypt a block of 8 bytes of data with the given ICE key.
296  */
297
298 void
299 ice_key_decrypt (
300         const ICE_KEY           *ik,
301         const unsigned char     *ctext,
302         unsigned char           *ptext
303 ) {
304         register int            i;
305         register unsigned long  l, r;
306
307         l = (((unsigned long) ctext[0]) << 24)
308                                 | (((unsigned long) ctext[1]) << 16)
309                                 | (((unsigned long) ctext[2]) << 8) | ctext[3];
310         r = (((unsigned long) ctext[4]) << 24)
311                                 | (((unsigned long) ctext[5]) << 16)
312                                 | (((unsigned long) ctext[6]) << 8) | ctext[7];
313
314         for (i = ik->ik_rounds - 1; i > 0; i -= 2) {
315             l ^= ice_f (r, ik->ik_keysched[i]);
316             r ^= ice_f (l, ik->ik_keysched[i - 1]);
317         }
318
319         for (i = 0; i < 4; i++) {
320             ptext[3 - i] = r & 0xff;
321             ptext[7 - i] = l & 0xff;
322
323             r >>= 8;
324             l >>= 8;
325         }
326 }
327
328
329 /*
330  * Set 8 rounds [n, n+7] of the key schedule of an ICE key.
331  */
332
333 static void
334 ice_key_sched_build (
335         ICE_KEY         *ik,
336         unsigned short  *kb,
337         int             n,
338         const int       *keyrot
339 ) {
340         int             i;
341
342         for (i=0; i<8; i++) {
343             register int        j;
344             register int        kr = keyrot[i];
345             ICE_SUBKEY          *isk = &ik->ik_keysched[n + i];
346
347             for (j=0; j<3; j++)
348                 (*isk)[j] = 0;
349
350             for (j=0; j<15; j++) {
351                 register int    k;
352                 unsigned long   *curr_sk = &(*isk)[j % 3];
353
354                 for (k=0; k<4; k++) {
355                     unsigned short      *curr_kb = &kb[(kr + k) & 3];
356                     register int        bit = *curr_kb & 1;
357
358                     *curr_sk = (*curr_sk << 1) | bit;
359                     *curr_kb = (*curr_kb >> 1) | ((bit ^ 1) << 15);
360                 }
361             }
362         }
363 }
364
365
366 /*
367  * Set the key schedule of an ICE key.
368  */
369
370 void
371 ice_key_set (
372         ICE_KEY                 *ik,
373         const unsigned char     *key
374 ) {
375         int             i;
376
377         if (ik->ik_rounds == 8) {
378             unsigned short      kb[4];
379
380             for (i=0; i<4; i++)
381                 kb[3 - i] = (key[i*2] << 8) | key[i*2 + 1];
382
383             ice_key_sched_build (ik, kb, 0, ice_keyrot);
384             return;
385         }
386
387         for (i = 0; i < ik->ik_size; i++) {
388             int                 j;
389             unsigned short      kb[4];
390
391             for (j=0; j<4; j++)
392                 kb[3 - j] = (key[i*8 + j*2] << 8) | key[i*8 + j*2 + 1];
393
394             ice_key_sched_build (ik, kb, i*8, ice_keyrot);
395             ice_key_sched_build (ik, kb, ik->ik_rounds - 8 - i*8,
396                                                         &ice_keyrot[8]);
397         }
398 }
399
400
401 /*
402  * Return the key size, in bytes.
403  */
404
405 int
406 ice_key_key_size (
407         const ICE_KEY   *ik
408 ) {
409         return (ik->ik_size * 8);
410 }
411
412
413 /*
414  * Return the block size, in bytes.
415  */
416
417 int
418 ice_key_block_size (
419         const ICE_KEY   *ik
420 ) {
421         return (8);
422 }