1 package org.bouncycastle.crypto.engines;
3 import java.lang.IllegalStateException;
5 import org.bouncycastle.crypto.BlockCipher;
6 import org.bouncycastle.crypto.CipherParameters;
7 import org.bouncycastle.crypto.DataLengthException;
8 import org.bouncycastle.crypto.params.KeyParameter;
11 * a class that provides a basic DES engine.
13 public class DESEngine
14 implements BlockCipher
16 protected static final int BLOCK_SIZE = 8;
18 private int[] workingKey = null;
21 * standard constructor.
28 * initialise a DES cipher.
30 * @param forEncryption whether or not we are for encryption.
31 * @param params the parameters required to set up the cipher.
32 * @exception IllegalArgumentException if the params argument is
37 CipherParameters params)
39 if (params instanceof KeyParameter)
41 workingKey = generateWorkingKey(encrypting,
42 ((KeyParameter)params).getKey());
47 throw new IllegalArgumentException("invalid parameter passed to DES init - " + params.getClass().getName());
50 public String getAlgorithmName()
55 public int getBlockSize()
60 public int processBlock(
66 if (workingKey == null)
68 throw new IllegalStateException("DES engine not initialised");
71 if ((inOff + BLOCK_SIZE) > in.length)
73 throw new DataLengthException("input buffer too short");
76 if ((outOff + BLOCK_SIZE) > out.length)
78 throw new DataLengthException("output buffer too short");
81 desFunc(workingKey, in, inOff, out, outOff);
91 * what follows is mainly taken from "Applied Cryptography", by
92 * Bruce Schneier, however it also bears great resemblance to Richard
93 * Outerbridge's D3DES...
96 static short[] Df_Key =
98 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
99 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
100 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
103 static short[] bytebit =
105 0200, 0100, 040, 020, 010, 04, 02, 01
108 static int[] bigbyte =
110 0x800000, 0x400000, 0x200000, 0x100000,
111 0x80000, 0x40000, 0x20000, 0x10000,
112 0x8000, 0x4000, 0x2000, 0x1000,
113 0x800, 0x400, 0x200, 0x100,
114 0x80, 0x40, 0x20, 0x10,
119 * Use the key schedule specified in the Standard (ANSI X3.92-1981).
124 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
125 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
126 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
127 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
130 static byte[] totrot =
132 1, 2, 4, 6, 8, 10, 12, 14,
133 15, 17, 19, 21, 23, 25, 27, 28
138 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
139 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
140 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
141 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
145 0x01010400, 0x00000000, 0x00010000, 0x01010404,
146 0x01010004, 0x00010404, 0x00000004, 0x00010000,
147 0x00000400, 0x01010400, 0x01010404, 0x00000400,
148 0x01000404, 0x01010004, 0x01000000, 0x00000004,
149 0x00000404, 0x01000400, 0x01000400, 0x00010400,
150 0x00010400, 0x01010000, 0x01010000, 0x01000404,
151 0x00010004, 0x01000004, 0x01000004, 0x00010004,
152 0x00000000, 0x00000404, 0x00010404, 0x01000000,
153 0x00010000, 0x01010404, 0x00000004, 0x01010000,
154 0x01010400, 0x01000000, 0x01000000, 0x00000400,
155 0x01010004, 0x00010000, 0x00010400, 0x01000004,
156 0x00000400, 0x00000004, 0x01000404, 0x00010404,
157 0x01010404, 0x00010004, 0x01010000, 0x01000404,
158 0x01000004, 0x00000404, 0x00010404, 0x01010400,
159 0x00000404, 0x01000400, 0x01000400, 0x00000000,
160 0x00010004, 0x00010400, 0x00000000, 0x01010004
164 0x80108020, 0x80008000, 0x00008000, 0x00108020,
165 0x00100000, 0x00000020, 0x80100020, 0x80008020,
166 0x80000020, 0x80108020, 0x80108000, 0x80000000,
167 0x80008000, 0x00100000, 0x00000020, 0x80100020,
168 0x00108000, 0x00100020, 0x80008020, 0x00000000,
169 0x80000000, 0x00008000, 0x00108020, 0x80100000,
170 0x00100020, 0x80000020, 0x00000000, 0x00108000,
171 0x00008020, 0x80108000, 0x80100000, 0x00008020,
172 0x00000000, 0x00108020, 0x80100020, 0x00100000,
173 0x80008020, 0x80100000, 0x80108000, 0x00008000,
174 0x80100000, 0x80008000, 0x00000020, 0x80108020,
175 0x00108020, 0x00000020, 0x00008000, 0x80000000,
176 0x00008020, 0x80108000, 0x00100000, 0x80000020,
177 0x00100020, 0x80008020, 0x80000020, 0x00100020,
178 0x00108000, 0x00000000, 0x80008000, 0x00008020,
179 0x80000000, 0x80100020, 0x80108020, 0x00108000
183 0x00000208, 0x08020200, 0x00000000, 0x08020008,
184 0x08000200, 0x00000000, 0x00020208, 0x08000200,
185 0x00020008, 0x08000008, 0x08000008, 0x00020000,
186 0x08020208, 0x00020008, 0x08020000, 0x00000208,
187 0x08000000, 0x00000008, 0x08020200, 0x00000200,
188 0x00020200, 0x08020000, 0x08020008, 0x00020208,
189 0x08000208, 0x00020200, 0x00020000, 0x08000208,
190 0x00000008, 0x08020208, 0x00000200, 0x08000000,
191 0x08020200, 0x08000000, 0x00020008, 0x00000208,
192 0x00020000, 0x08020200, 0x08000200, 0x00000000,
193 0x00000200, 0x00020008, 0x08020208, 0x08000200,
194 0x08000008, 0x00000200, 0x00000000, 0x08020008,
195 0x08000208, 0x00020000, 0x08000000, 0x08020208,
196 0x00000008, 0x00020208, 0x00020200, 0x08000008,
197 0x08020000, 0x08000208, 0x00000208, 0x08020000,
198 0x00020208, 0x00000008, 0x08020008, 0x00020200
202 0x00802001, 0x00002081, 0x00002081, 0x00000080,
203 0x00802080, 0x00800081, 0x00800001, 0x00002001,
204 0x00000000, 0x00802000, 0x00802000, 0x00802081,
205 0x00000081, 0x00000000, 0x00800080, 0x00800001,
206 0x00000001, 0x00002000, 0x00800000, 0x00802001,
207 0x00000080, 0x00800000, 0x00002001, 0x00002080,
208 0x00800081, 0x00000001, 0x00002080, 0x00800080,
209 0x00002000, 0x00802080, 0x00802081, 0x00000081,
210 0x00800080, 0x00800001, 0x00802000, 0x00802081,
211 0x00000081, 0x00000000, 0x00000000, 0x00802000,
212 0x00002080, 0x00800080, 0x00800081, 0x00000001,
213 0x00802001, 0x00002081, 0x00002081, 0x00000080,
214 0x00802081, 0x00000081, 0x00000001, 0x00002000,
215 0x00800001, 0x00002001, 0x00802080, 0x00800081,
216 0x00002001, 0x00002080, 0x00800000, 0x00802001,
217 0x00000080, 0x00800000, 0x00002000, 0x00802080
221 0x00000100, 0x02080100, 0x02080000, 0x42000100,
222 0x00080000, 0x00000100, 0x40000000, 0x02080000,
223 0x40080100, 0x00080000, 0x02000100, 0x40080100,
224 0x42000100, 0x42080000, 0x00080100, 0x40000000,
225 0x02000000, 0x40080000, 0x40080000, 0x00000000,
226 0x40000100, 0x42080100, 0x42080100, 0x02000100,
227 0x42080000, 0x40000100, 0x00000000, 0x42000000,
228 0x02080100, 0x02000000, 0x42000000, 0x00080100,
229 0x00080000, 0x42000100, 0x00000100, 0x02000000,
230 0x40000000, 0x02080000, 0x42000100, 0x40080100,
231 0x02000100, 0x40000000, 0x42080000, 0x02080100,
232 0x40080100, 0x00000100, 0x02000000, 0x42080000,
233 0x42080100, 0x00080100, 0x42000000, 0x42080100,
234 0x02080000, 0x00000000, 0x40080000, 0x42000000,
235 0x00080100, 0x02000100, 0x40000100, 0x00080000,
236 0x00000000, 0x40080000, 0x02080100, 0x40000100
240 0x20000010, 0x20400000, 0x00004000, 0x20404010,
241 0x20400000, 0x00000010, 0x20404010, 0x00400000,
242 0x20004000, 0x00404010, 0x00400000, 0x20000010,
243 0x00400010, 0x20004000, 0x20000000, 0x00004010,
244 0x00000000, 0x00400010, 0x20004010, 0x00004000,
245 0x00404000, 0x20004010, 0x00000010, 0x20400010,
246 0x20400010, 0x00000000, 0x00404010, 0x20404000,
247 0x00004010, 0x00404000, 0x20404000, 0x20000000,
248 0x20004000, 0x00000010, 0x20400010, 0x00404000,
249 0x20404010, 0x00400000, 0x00004010, 0x20000010,
250 0x00400000, 0x20004000, 0x20000000, 0x00004010,
251 0x20000010, 0x20404010, 0x00404000, 0x20400000,
252 0x00404010, 0x20404000, 0x00000000, 0x20400010,
253 0x00000010, 0x00004000, 0x20400000, 0x00404010,
254 0x00004000, 0x00400010, 0x20004010, 0x00000000,
255 0x20404000, 0x20000000, 0x00400010, 0x20004010
259 0x00200000, 0x04200002, 0x04000802, 0x00000000,
260 0x00000800, 0x04000802, 0x00200802, 0x04200800,
261 0x04200802, 0x00200000, 0x00000000, 0x04000002,
262 0x00000002, 0x04000000, 0x04200002, 0x00000802,
263 0x04000800, 0x00200802, 0x00200002, 0x04000800,
264 0x04000002, 0x04200000, 0x04200800, 0x00200002,
265 0x04200000, 0x00000800, 0x00000802, 0x04200802,
266 0x00200800, 0x00000002, 0x04000000, 0x00200800,
267 0x04000000, 0x00200800, 0x00200000, 0x04000802,
268 0x04000802, 0x04200002, 0x04200002, 0x00000002,
269 0x00200002, 0x04000000, 0x04000800, 0x00200000,
270 0x04200800, 0x00000802, 0x00200802, 0x04200800,
271 0x00000802, 0x04000002, 0x04200802, 0x04200000,
272 0x00200800, 0x00000000, 0x00000002, 0x04200802,
273 0x00000000, 0x00200802, 0x04200000, 0x00000800,
274 0x04000002, 0x04000800, 0x00000800, 0x00200002
278 0x10001040, 0x00001000, 0x00040000, 0x10041040,
279 0x10000000, 0x10001040, 0x00000040, 0x10000000,
280 0x00040040, 0x10040000, 0x10041040, 0x00041000,
281 0x10041000, 0x00041040, 0x00001000, 0x00000040,
282 0x10040000, 0x10000040, 0x10001000, 0x00001040,
283 0x00041000, 0x00040040, 0x10040040, 0x10041000,
284 0x00001040, 0x00000000, 0x00000000, 0x10040040,
285 0x10000040, 0x10001000, 0x00041040, 0x00040000,
286 0x00041040, 0x00040000, 0x10041000, 0x00001000,
287 0x00000040, 0x10040040, 0x00001000, 0x00041040,
288 0x10001000, 0x00000040, 0x10000040, 0x10040000,
289 0x10040040, 0x10000000, 0x00040000, 0x10001040,
290 0x00000000, 0x10041040, 0x00040040, 0x10000040,
291 0x10040000, 0x10001000, 0x10001040, 0x00000000,
292 0x10041040, 0x00041000, 0x00041000, 0x00001040,
293 0x00001040, 0x00040040, 0x10000000, 0x10041000
297 * generate an integer based working key based on our secret key
298 * and what we processing we are planning to do.
300 * Acknowledgements for this routine go to James Gillogly & Phil Karn.
301 * (whoever, and wherever they are!).
303 protected int[] generateWorkingKey(
307 int[] newKey = new int[32];
308 boolean[] pc1m = new boolean[56],
309 pcr = new boolean[56];
311 for (int j = 0; j < 56; j++ )
315 pc1m[j] = ((key[l >>> 3] & bytebit[l & 07]) != 0);
318 for (int i = 0; i < 16; i++)
332 newKey[m] = newKey[n] = 0;
334 for (int j = 0; j < 28; j++)
343 pcr[j] = pc1m[l - 28];
347 for (int j = 28; j < 56; j++)
356 pcr[j] = pc1m[l - 28];
360 for (int j = 0; j < 24; j++)
364 newKey[m] |= bigbyte[j];
367 if (pcr[pc2[j + 24]])
369 newKey[n] |= bigbyte[j];
375 // store the processed key
377 for (int i = 0; i != 32; i += 2)
384 newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10)
385 | ((i2 & 0x00fc0000) >>> 10) | ((i2 & 0x00000fc0) >>> 6);
387 newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16)
388 | ((i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f);
397 protected void desFunc(
404 int work, right, left;
406 left = (in[inOff + 0] & 0xff) << 24;
407 left |= (in[inOff + 1] & 0xff) << 16;
408 left |= (in[inOff + 2] & 0xff) << 8;
409 left |= (in[inOff + 3] & 0xff);
411 right = (in[inOff + 4] & 0xff) << 24;
412 right |= (in[inOff + 5] & 0xff) << 16;
413 right |= (in[inOff + 6] & 0xff) << 8;
414 right |= (in[inOff + 7] & 0xff);
416 work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
419 work = ((left >>> 16) ^ right) & 0x0000ffff;
421 left ^= (work << 16);
422 work = ((right >>> 2) ^ left) & 0x33333333;
424 right ^= (work << 2);
425 work = ((right >>> 8) ^ left) & 0x00ff00ff;
427 right ^= (work << 8);
428 right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
429 work = (left ^ right) & 0xaaaaaaaa;
432 left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
434 for (int round = 0; round < 8; round++)
438 work = (right << 28) | (right >>> 4);
439 work ^= wKey[round * 4 + 0];
440 fval = SP7[ work & 0x3f];
441 fval |= SP5[(work >>> 8) & 0x3f];
442 fval |= SP3[(work >>> 16) & 0x3f];
443 fval |= SP1[(work >>> 24) & 0x3f];
444 work = right ^ wKey[round * 4 + 1];
445 fval |= SP8[ work & 0x3f];
446 fval |= SP6[(work >>> 8) & 0x3f];
447 fval |= SP4[(work >>> 16) & 0x3f];
448 fval |= SP2[(work >>> 24) & 0x3f];
450 work = (left << 28) | (left >>> 4);
451 work ^= wKey[round * 4 + 2];
452 fval = SP7[ work & 0x3f];
453 fval |= SP5[(work >>> 8) & 0x3f];
454 fval |= SP3[(work >>> 16) & 0x3f];
455 fval |= SP1[(work >>> 24) & 0x3f];
456 work = left ^ wKey[round * 4 + 3];
457 fval |= SP8[ work & 0x3f];
458 fval |= SP6[(work >>> 8) & 0x3f];
459 fval |= SP4[(work >>> 16) & 0x3f];
460 fval |= SP2[(work >>> 24) & 0x3f];
464 right = (right << 31) | (right >>> 1);
465 work = (left ^ right) & 0xaaaaaaaa;
468 left = (left << 31) | (left >>> 1);
469 work = ((left >>> 8) ^ right) & 0x00ff00ff;
472 work = ((left >>> 2) ^ right) & 0x33333333;
475 work = ((right >>> 16) ^ left) & 0x0000ffff;
477 right ^= (work << 16);
478 work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
480 right ^= (work << 4);
482 out[outOff + 0] = (byte)((right >>> 24) & 0xff);
483 out[outOff + 1] = (byte)((right >>> 16) & 0xff);
484 out[outOff + 2] = (byte)((right >>> 8) & 0xff);
485 out[outOff + 3] = (byte)( right & 0xff);
486 out[outOff + 4] = (byte)((left >>> 24) & 0xff);
487 out[outOff + 5] = (byte)((left >>> 16) & 0xff);
488 out[outOff + 6] = (byte)((left >>> 8) & 0xff);
489 out[outOff + 7] = (byte)( left & 0xff);