KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > maverick > crypto > engines > DESEngine


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.maverick.crypto.engines;
21
22 import java.io.IOException JavaDoc;
23
24 /**
25  * a class that provides a basic DES engine.
26  */

27 public class DESEngine
28     implements CipherEngine {
29   protected static final int BLOCK_SIZE = 8;
30
31   private int[] workingKey = null;
32
33   /**
34    * standard constructor.
35    */

36   public DESEngine() {
37   }
38
39   /**
40    * initialise a DES cipher.
41    *
42    * @param forEncryption whether or not we are for encryption.
43    * @param params the parameters required to set up the cipher.
44    * @exception IllegalArgumentException if the params argument is
45    * inappropriate.
46    */

47   public void init(
48       boolean encrypting,
49       byte[] key) {
50     workingKey = generateWorkingKey(encrypting,
51                                     key);
52
53   }
54
55   public String JavaDoc getAlgorithmName() {
56     return "DES";
57   }
58
59   public byte[] doFinal(byte[] input) throws IOException JavaDoc {
60
61       if(input.length % BLOCK_SIZE != 0)
62           throw new IOException JavaDoc("Invalid block size on input data");
63
64       byte[] output = new byte[input.length];
65       for(int i=0;i<input.length;i+=BLOCK_SIZE)
66           processBlock(input, i, output, i);
67
68       return output;
69   }
70
71   public int getBlockSize() {
72     return BLOCK_SIZE;
73   }
74
75   public int processBlock(
76       byte[] in,
77       int inOff,
78       byte[] out,
79       int outOff) throws IOException JavaDoc {
80     if (workingKey == null) {
81       throw new IllegalStateException JavaDoc("DES engine not initialised");
82     }
83
84     if ( (inOff + BLOCK_SIZE) > in.length) {
85       throw new IOException JavaDoc("input buffer too short");
86     }
87
88     if ( (outOff + BLOCK_SIZE) > out.length) {
89       throw new IOException JavaDoc("output buffer too short");
90     }
91
92     desFunc(workingKey, in, inOff, out, outOff);
93
94     return BLOCK_SIZE;
95   }
96
97   public void reset() {
98   }
99
100   /**
101    * what follows is mainly taken from "Applied Cryptography", by
102    * Bruce Schneier, however it also bears great resemblance to Richard
103    * Outerbridge's D3DES...
104    */

105
106   static short[] Df_Key = {
107       0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
108       0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
109       0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67
110   };
111
112   static short[] bytebit = {
113       0200, 0100, 040, 020, 010, 04, 02, 01
114   };
115
116   static int[] bigbyte = {
117       0x800000, 0x400000, 0x200000, 0x100000,
118       0x80000, 0x40000, 0x20000, 0x10000,
119       0x8000, 0x4000, 0x2000, 0x1000,
120       0x800, 0x400, 0x200, 0x100,
121       0x80, 0x40, 0x20, 0x10,
122       0x8, 0x4, 0x2, 0x1
123   };
124
125   /*
126    * Use the key schedule specified in the Standard (ANSI X3.92-1981).
127    */

128
129   static byte[] pc1 = {
130       56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
131       9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
132       62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
133       13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
134   };
135
136   static byte[] totrot = {
137       1, 2, 4, 6, 8, 10, 12, 14,
138       15, 17, 19, 21, 23, 25, 27, 28
139   };
140
141   static byte[] pc2 = {
142       13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
143       22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
144       40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
145       43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
146   };
147
148   static int[] SP1 = {
149       0x01010400, 0x00000000, 0x00010000, 0x01010404,
150       0x01010004, 0x00010404, 0x00000004, 0x00010000,
151       0x00000400, 0x01010400, 0x01010404, 0x00000400,
152       0x01000404, 0x01010004, 0x01000000, 0x00000004,
153       0x00000404, 0x01000400, 0x01000400, 0x00010400,
154       0x00010400, 0x01010000, 0x01010000, 0x01000404,
155       0x00010004, 0x01000004, 0x01000004, 0x00010004,
156       0x00000000, 0x00000404, 0x00010404, 0x01000000,
157       0x00010000, 0x01010404, 0x00000004, 0x01010000,
158       0x01010400, 0x01000000, 0x01000000, 0x00000400,
159       0x01010004, 0x00010000, 0x00010400, 0x01000004,
160       0x00000400, 0x00000004, 0x01000404, 0x00010404,
161       0x01010404, 0x00010004, 0x01010000, 0x01000404,
162       0x01000004, 0x00000404, 0x00010404, 0x01010400,
163       0x00000404, 0x01000400, 0x01000400, 0x00000000,
164       0x00010004, 0x00010400, 0x00000000, 0x01010004
165   };
166
167   static int[] SP2 = {
168       0x80108020, 0x80008000, 0x00008000, 0x00108020,
169       0x00100000, 0x00000020, 0x80100020, 0x80008020,
170       0x80000020, 0x80108020, 0x80108000, 0x80000000,
171       0x80008000, 0x00100000, 0x00000020, 0x80100020,
172       0x00108000, 0x00100020, 0x80008020, 0x00000000,
173       0x80000000, 0x00008000, 0x00108020, 0x80100000,
174       0x00100020, 0x80000020, 0x00000000, 0x00108000,
175       0x00008020, 0x80108000, 0x80100000, 0x00008020,
176       0x00000000, 0x00108020, 0x80100020, 0x00100000,
177       0x80008020, 0x80100000, 0x80108000, 0x00008000,
178       0x80100000, 0x80008000, 0x00000020, 0x80108020,
179       0x00108020, 0x00000020, 0x00008000, 0x80000000,
180       0x00008020, 0x80108000, 0x00100000, 0x80000020,
181       0x00100020, 0x80008020, 0x80000020, 0x00100020,
182       0x00108000, 0x00000000, 0x80008000, 0x00008020,
183       0x80000000, 0x80100020, 0x80108020, 0x00108000
184   };
185
186   static int[] SP3 = {
187       0x00000208, 0x08020200, 0x00000000, 0x08020008,
188       0x08000200, 0x00000000, 0x00020208, 0x08000200,
189       0x00020008, 0x08000008, 0x08000008, 0x00020000,
190       0x08020208, 0x00020008, 0x08020000, 0x00000208,
191       0x08000000, 0x00000008, 0x08020200, 0x00000200,
192       0x00020200, 0x08020000, 0x08020008, 0x00020208,
193       0x08000208, 0x00020200, 0x00020000, 0x08000208,
194       0x00000008, 0x08020208, 0x00000200, 0x08000000,
195       0x08020200, 0x08000000, 0x00020008, 0x00000208,
196       0x00020000, 0x08020200, 0x08000200, 0x00000000,
197       0x00000200, 0x00020008, 0x08020208, 0x08000200,
198       0x08000008, 0x00000200, 0x00000000, 0x08020008,
199       0x08000208, 0x00020000, 0x08000000, 0x08020208,
200       0x00000008, 0x00020208, 0x00020200, 0x08000008,
201       0x08020000, 0x08000208, 0x00000208, 0x08020000,
202       0x00020208, 0x00000008, 0x08020008, 0x00020200
203   };
204
205   static int[] SP4 = {
206       0x00802001, 0x00002081, 0x00002081, 0x00000080,
207       0x00802080, 0x00800081, 0x00800001, 0x00002001,
208       0x00000000, 0x00802000, 0x00802000, 0x00802081,
209       0x00000081, 0x00000000, 0x00800080, 0x00800001,
210       0x00000001, 0x00002000, 0x00800000, 0x00802001,
211       0x00000080, 0x00800000, 0x00002001, 0x00002080,
212       0x00800081, 0x00000001, 0x00002080, 0x00800080,
213       0x00002000, 0x00802080, 0x00802081, 0x00000081,
214       0x00800080, 0x00800001, 0x00802000, 0x00802081,
215       0x00000081, 0x00000000, 0x00000000, 0x00802000,
216       0x00002080, 0x00800080, 0x00800081, 0x00000001,
217       0x00802001, 0x00002081, 0x00002081, 0x00000080,
218       0x00802081, 0x00000081, 0x00000001, 0x00002000,
219       0x00800001, 0x00002001, 0x00802080, 0x00800081,
220       0x00002001, 0x00002080, 0x00800000, 0x00802001,
221       0x00000080, 0x00800000, 0x00002000, 0x00802080
222   };
223
224   static int[] SP5 = {
225       0x00000100, 0x02080100, 0x02080000, 0x42000100,
226       0x00080000, 0x00000100, 0x40000000, 0x02080000,
227       0x40080100, 0x00080000, 0x02000100, 0x40080100,
228       0x42000100, 0x42080000, 0x00080100, 0x40000000,
229       0x02000000, 0x40080000, 0x40080000, 0x00000000,
230       0x40000100, 0x42080100, 0x42080100, 0x02000100,
231       0x42080000, 0x40000100, 0x00000000, 0x42000000,
232       0x02080100, 0x02000000, 0x42000000, 0x00080100,
233       0x00080000, 0x42000100, 0x00000100, 0x02000000,
234       0x40000000, 0x02080000, 0x42000100, 0x40080100,
235       0x02000100, 0x40000000, 0x42080000, 0x02080100,
236       0x40080100, 0x00000100, 0x02000000, 0x42080000,
237       0x42080100, 0x00080100, 0x42000000, 0x42080100,
238       0x02080000, 0x00000000, 0x40080000, 0x42000000,
239       0x00080100, 0x02000100, 0x40000100, 0x00080000,
240       0x00000000, 0x40080000, 0x02080100, 0x40000100
241   };
242
243   static int[] SP6 = {
244       0x20000010, 0x20400000, 0x00004000, 0x20404010,
245       0x20400000, 0x00000010, 0x20404010, 0x00400000,
246       0x20004000, 0x00404010, 0x00400000, 0x20000010,
247       0x00400010, 0x20004000, 0x20000000, 0x00004010,
248       0x00000000, 0x00400010, 0x20004010, 0x00004000,
249       0x00404000, 0x20004010, 0x00000010, 0x20400010,
250       0x20400010, 0x00000000, 0x00404010, 0x20404000,
251       0x00004010, 0x00404000, 0x20404000, 0x20000000,
252       0x20004000, 0x00000010, 0x20400010, 0x00404000,
253       0x20404010, 0x00400000, 0x00004010, 0x20000010,
254       0x00400000, 0x20004000, 0x20000000, 0x00004010,
255       0x20000010, 0x20404010, 0x00404000, 0x20400000,
256       0x00404010, 0x20404000, 0x00000000, 0x20400010,
257       0x00000010, 0x00004000, 0x20400000, 0x00404010,
258       0x00004000, 0x00400010, 0x20004010, 0x00000000,
259       0x20404000, 0x20000000, 0x00400010, 0x20004010
260   };
261
262   static int[] SP7 = {
263       0x00200000, 0x04200002, 0x04000802, 0x00000000,
264       0x00000800, 0x04000802, 0x00200802, 0x04200800,
265       0x04200802, 0x00200000, 0x00000000, 0x04000002,
266       0x00000002, 0x04000000, 0x04200002, 0x00000802,
267       0x04000800, 0x00200802, 0x00200002, 0x04000800,
268       0x04000002, 0x04200000, 0x04200800, 0x00200002,
269       0x04200000, 0x00000800, 0x00000802, 0x04200802,
270       0x00200800, 0x00000002, 0x04000000, 0x00200800,
271       0x04000000, 0x00200800, 0x00200000, 0x04000802,
272       0x04000802, 0x04200002, 0x04200002, 0x00000002,
273       0x00200002, 0x04000000, 0x04000800, 0x00200000,
274       0x04200800, 0x00000802, 0x00200802, 0x04200800,
275       0x00000802, 0x04000002, 0x04200802, 0x04200000,
276       0x00200800, 0x00000000, 0x00000002, 0x04200802,
277       0x00000000, 0x00200802, 0x04200000, 0x00000800,
278       0x04000002, 0x04000800, 0x00000800, 0x00200002
279   };
280
281   static int[] SP8 = {
282       0x10001040, 0x00001000, 0x00040000, 0x10041040,
283       0x10000000, 0x10001040, 0x00000040, 0x10000000,
284       0x00040040, 0x10040000, 0x10041040, 0x00041000,
285       0x10041000, 0x00041040, 0x00001000, 0x00000040,
286       0x10040000, 0x10000040, 0x10001000, 0x00001040,
287       0x00041000, 0x00040040, 0x10040040, 0x10041000,
288       0x00001040, 0x00000000, 0x00000000, 0x10040040,
289       0x10000040, 0x10001000, 0x00041040, 0x00040000,
290       0x00041040, 0x00040000, 0x10041000, 0x00001000,
291       0x00000040, 0x10040040, 0x00001000, 0x00041040,
292       0x10001000, 0x00000040, 0x10000040, 0x10040000,
293       0x10040040, 0x10000000, 0x00040000, 0x10001040,
294       0x00000000, 0x10041040, 0x00040040, 0x10000040,
295       0x10040000, 0x10001000, 0x10001040, 0x00000000,
296       0x10041040, 0x00041000, 0x00041000, 0x00001040,
297       0x00001040, 0x00040040, 0x10000000, 0x10041000
298   };
299
300   /**
301    * generate an integer based working key based on our secret key
302    * and what we processing we are planning to do.
303    *
304    * Acknowledgements for this routine go to James Gillogly & Phil Karn.
305    * (whoever, and wherever they are!).
306    */

307   protected int[] generateWorkingKey(
308       boolean encrypting,
309       byte[] key) {
310     int[] newKey = new int[32];
311     boolean[] pc1m = new boolean[56],
312         pcr = new boolean[56];
313
314     for (int j = 0; j < 56; j++) {
315       int l = pc1[j];
316
317       pc1m[j] = ( (key[l >>> 3] & bytebit[l & 07]) != 0);
318     }
319
320     for (int i = 0; i < 16; i++) {
321       int l, m, n;
322
323       if (encrypting) {
324         m = i << 1;
325       }
326       else {
327         m = (15 - i) << 1;
328       }
329
330       n = m + 1;
331       newKey[m] = newKey[n] = 0;
332
333       for (int j = 0; j < 28; j++) {
334         l = j + totrot[i];
335         if (l < 28) {
336           pcr[j] = pc1m[l];
337         }
338         else {
339           pcr[j] = pc1m[l - 28];
340         }
341       }
342
343       for (int j = 28; j < 56; j++) {
344         l = j + totrot[i];
345         if (l < 56) {
346           pcr[j] = pc1m[l];
347         }
348         else {
349           pcr[j] = pc1m[l - 28];
350         }
351       }
352
353       for (int j = 0; j < 24; j++) {
354         if (pcr[pc2[j]]) {
355           newKey[m] |= bigbyte[j];
356         }
357
358         if (pcr[pc2[j + 24]]) {
359           newKey[n] |= bigbyte[j];
360         }
361       }
362     }
363
364     //
365
// store the processed key
366
//
367
for (int i = 0; i != 32; i += 2) {
368       int i1, i2;
369
370       i1 = newKey[i];
371       i2 = newKey[i + 1];
372
373       newKey[i] = ( (i1 & 0x00fc0000) << 6) | ( (i1 & 0x00000fc0) << 10)
374           | ( (i2 & 0x00fc0000) >>> 10) | ( (i2 & 0x00000fc0) >>> 6);
375
376       newKey[i + 1] = ( (i1 & 0x0003f000) << 12) | ( (i1 & 0x0000003f) << 16)
377           | ( (i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f);
378     }
379
380     return newKey;
381   }
382
383   /**
384    * the DES engine.
385    */

386   protected void desFunc(
387       int[] wKey,
388       byte[] in,
389       int inOff,
390       byte[] out,
391       int outOff) {
392     int work, right, left;
393
394     left = (in[inOff + 0] & 0xff) << 24;
395     left |= (in[inOff + 1] & 0xff) << 16;
396     left |= (in[inOff + 2] & 0xff) << 8;
397     left |= (in[inOff + 3] & 0xff);
398
399     right = (in[inOff + 4] & 0xff) << 24;
400     right |= (in[inOff + 5] & 0xff) << 16;
401     right |= (in[inOff + 6] & 0xff) << 8;
402     right |= (in[inOff + 7] & 0xff);
403
404     work = ( (left >>> 4) ^ right) & 0x0f0f0f0f;
405     right ^= work;
406     left ^= (work << 4);
407     work = ( (left >>> 16) ^ right) & 0x0000ffff;
408     right ^= work;
409     left ^= (work << 16);
410     work = ( (right >>> 2) ^ left) & 0x33333333;
411     left ^= work;
412     right ^= (work << 2);
413     work = ( (right >>> 8) ^ left) & 0x00ff00ff;
414     left ^= work;
415     right ^= (work << 8);
416     right = ( (right << 1) | ( (right >>> 31) & 1)) & 0xffffffff;
417     work = (left ^ right) & 0xaaaaaaaa;
418     left ^= work;
419     right ^= work;
420     left = ( (left << 1) | ( (left >>> 31) & 1)) & 0xffffffff;
421
422     for (int round = 0; round < 8; round++) {
423       int fval;
424
425       work = (right << 28) | (right >>> 4);
426       work ^= wKey[round * 4 + 0];
427       fval = SP7[work & 0x3f];
428       fval |= SP5[ (work >>> 8) & 0x3f];
429       fval |= SP3[ (work >>> 16) & 0x3f];
430       fval |= SP1[ (work >>> 24) & 0x3f];
431       work = right ^ wKey[round * 4 + 1];
432       fval |= SP8[work & 0x3f];
433       fval |= SP6[ (work >>> 8) & 0x3f];
434       fval |= SP4[ (work >>> 16) & 0x3f];
435       fval |= SP2[ (work >>> 24) & 0x3f];
436       left ^= fval;
437       work = (left << 28) | (left >>> 4);
438       work ^= wKey[round * 4 + 2];
439       fval = SP7[work & 0x3f];
440       fval |= SP5[ (work >>> 8) & 0x3f];
441       fval |= SP3[ (work >>> 16) & 0x3f];
442       fval |= SP1[ (work >>> 24) & 0x3f];
443       work = left ^ wKey[round * 4 + 3];
444       fval |= SP8[work & 0x3f];
445       fval |= SP6[ (work >>> 8) & 0x3f];
446       fval |= SP4[ (work >>> 16) & 0x3f];
447       fval |= SP2[ (work >>> 24) & 0x3f];
448       right ^= fval;
449     }
450
451     right = (right << 31) | (right >>> 1);
452     work = (left ^ right) & 0xaaaaaaaa;
453     left ^= work;
454     right ^= work;
455     left = (left << 31) | (left >>> 1);
456     work = ( (left >>> 8) ^ right) & 0x00ff00ff;
457     right ^= work;
458     left ^= (work << 8);
459     work = ( (left >>> 2) ^ right) & 0x33333333;
460     right ^= work;
461     left ^= (work << 2);
462     work = ( (right >>> 16) ^ left) & 0x0000ffff;
463     left ^= work;
464     right ^= (work << 16);
465     work = ( (right >>> 4) ^ left) & 0x0f0f0f0f;
466     left ^= work;
467     right ^= (work << 4);
468
469     out[outOff + 0] = (byte) ( (right >>> 24) & 0xff);
470     out[outOff + 1] = (byte) ( (right >>> 16) & 0xff);
471     out[outOff + 2] = (byte) ( (right >>> 8) & 0xff);
472     out[outOff + 3] = (byte) (right & 0xff);
473     out[outOff + 4] = (byte) ( (left >>> 24) & 0xff);
474     out[outOff + 5] = (byte) ( (left >>> 16) & 0xff);
475     out[outOff + 6] = (byte) ( (left >>> 8) & 0xff);
476     out[outOff + 7] = (byte) (left & 0xff);
477   }
478 }
479
Popular Tags