1 package org.bouncycastle.crypto.engines;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import org.bouncycastle.crypto.BlockCipher;
26 import org.bouncycastle.crypto.CipherParameters;
27 import org.bouncycastle.crypto.DataLengthException;
28 import org.bouncycastle.crypto.params.KeyParameter;
29
30
31
32
33 public class DESEngine
34 implements BlockCipher
35 {
36 protected static final int BLOCK_SIZE = 8;
37
38 private int[] workingKey = null;
39
40
41
42
43 public DESEngine()
44 {
45 }
46
47
48
49
50
51
52
53
54
55 public void init(
56 boolean encrypting,
57 CipherParameters params)
58 {
59 if (params instanceof KeyParameter)
60 {
61 workingKey = generateWorkingKey(encrypting,
62 ((KeyParameter)params).getKey());
63
64 return;
65 }
66
67 throw new IllegalArgumentException("invalid parameter passed to DES init - " + params.getClass().getName());
68 }
69
70 public String getAlgorithmName()
71 {
72 return "DES";
73 }
74
75 public int getBlockSize()
76 {
77 return BLOCK_SIZE;
78 }
79
80 public int processBlock(
81 byte[] in,
82 int inOff,
83 byte[] out,
84 int outOff)
85 {
86 if (workingKey == null)
87 {
88 throw new IllegalStateException("DES engine not initialised");
89 }
90
91 if ((inOff + BLOCK_SIZE) > in.length)
92 {
93 throw new DataLengthException("input buffer too short");
94 }
95
96 if ((outOff + BLOCK_SIZE) > out.length)
97 {
98 throw new DataLengthException("output buffer too short");
99 }
100
101 desFunc(workingKey, in, inOff, out, outOff);
102
103 return BLOCK_SIZE;
104 }
105
106 public void reset()
107 {
108 }
109
110
111
112
113
114
115
116 static short[] Df_Key =
117 {
118 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
119 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
120 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
121 };
122
123 static short[] bytebit =
124 {
125 0200, 0100, 040, 020, 010, 04, 02, 01
126 };
127
128 static int[] bigbyte =
129 {
130 0x800000, 0x400000, 0x200000, 0x100000,
131 0x80000, 0x40000, 0x20000, 0x10000,
132 0x8000, 0x4000, 0x2000, 0x1000,
133 0x800, 0x400, 0x200, 0x100,
134 0x80, 0x40, 0x20, 0x10,
135 0x8, 0x4, 0x2, 0x1
136 };
137
138
139
140
141
142 static byte[] pc1 =
143 {
144 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
145 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
146 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
147 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
148 };
149
150 static byte[] totrot =
151 {
152 1, 2, 4, 6, 8, 10, 12, 14,
153 15, 17, 19, 21, 23, 25, 27, 28
154 };
155
156 static byte[] pc2 =
157 {
158 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
159 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
160 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
161 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
162 };
163
164 static int[] SP1 = {
165 0x01010400, 0x00000000, 0x00010000, 0x01010404,
166 0x01010004, 0x00010404, 0x00000004, 0x00010000,
167 0x00000400, 0x01010400, 0x01010404, 0x00000400,
168 0x01000404, 0x01010004, 0x01000000, 0x00000004,
169 0x00000404, 0x01000400, 0x01000400, 0x00010400,
170 0x00010400, 0x01010000, 0x01010000, 0x01000404,
171 0x00010004, 0x01000004, 0x01000004, 0x00010004,
172 0x00000000, 0x00000404, 0x00010404, 0x01000000,
173 0x00010000, 0x01010404, 0x00000004, 0x01010000,
174 0x01010400, 0x01000000, 0x01000000, 0x00000400,
175 0x01010004, 0x00010000, 0x00010400, 0x01000004,
176 0x00000400, 0x00000004, 0x01000404, 0x00010404,
177 0x01010404, 0x00010004, 0x01010000, 0x01000404,
178 0x01000004, 0x00000404, 0x00010404, 0x01010400,
179 0x00000404, 0x01000400, 0x01000400, 0x00000000,
180 0x00010004, 0x00010400, 0x00000000, 0x01010004
181 };
182
183 static int[] SP2 = {
184 0x80108020, 0x80008000, 0x00008000, 0x00108020,
185 0x00100000, 0x00000020, 0x80100020, 0x80008020,
186 0x80000020, 0x80108020, 0x80108000, 0x80000000,
187 0x80008000, 0x00100000, 0x00000020, 0x80100020,
188 0x00108000, 0x00100020, 0x80008020, 0x00000000,
189 0x80000000, 0x00008000, 0x00108020, 0x80100000,
190 0x00100020, 0x80000020, 0x00000000, 0x00108000,
191 0x00008020, 0x80108000, 0x80100000, 0x00008020,
192 0x00000000, 0x00108020, 0x80100020, 0x00100000,
193 0x80008020, 0x80100000, 0x80108000, 0x00008000,
194 0x80100000, 0x80008000, 0x00000020, 0x80108020,
195 0x00108020, 0x00000020, 0x00008000, 0x80000000,
196 0x00008020, 0x80108000, 0x00100000, 0x80000020,
197 0x00100020, 0x80008020, 0x80000020, 0x00100020,
198 0x00108000, 0x00000000, 0x80008000, 0x00008020,
199 0x80000000, 0x80100020, 0x80108020, 0x00108000
200 };
201
202 static int[] SP3 = {
203 0x00000208, 0x08020200, 0x00000000, 0x08020008,
204 0x08000200, 0x00000000, 0x00020208, 0x08000200,
205 0x00020008, 0x08000008, 0x08000008, 0x00020000,
206 0x08020208, 0x00020008, 0x08020000, 0x00000208,
207 0x08000000, 0x00000008, 0x08020200, 0x00000200,
208 0x00020200, 0x08020000, 0x08020008, 0x00020208,
209 0x08000208, 0x00020200, 0x00020000, 0x08000208,
210 0x00000008, 0x08020208, 0x00000200, 0x08000000,
211 0x08020200, 0x08000000, 0x00020008, 0x00000208,
212 0x00020000, 0x08020200, 0x08000200, 0x00000000,
213 0x00000200, 0x00020008, 0x08020208, 0x08000200,
214 0x08000008, 0x00000200, 0x00000000, 0x08020008,
215 0x08000208, 0x00020000, 0x08000000, 0x08020208,
216 0x00000008, 0x00020208, 0x00020200, 0x08000008,
217 0x08020000, 0x08000208, 0x00000208, 0x08020000,
218 0x00020208, 0x00000008, 0x08020008, 0x00020200
219 };
220
221 static int[] SP4 = {
222 0x00802001, 0x00002081, 0x00002081, 0x00000080,
223 0x00802080, 0x00800081, 0x00800001, 0x00002001,
224 0x00000000, 0x00802000, 0x00802000, 0x00802081,
225 0x00000081, 0x00000000, 0x00800080, 0x00800001,
226 0x00000001, 0x00002000, 0x00800000, 0x00802001,
227 0x00000080, 0x00800000, 0x00002001, 0x00002080,
228 0x00800081, 0x00000001, 0x00002080, 0x00800080,
229 0x00002000, 0x00802080, 0x00802081, 0x00000081,
230 0x00800080, 0x00800001, 0x00802000, 0x00802081,
231 0x00000081, 0x00000000, 0x00000000, 0x00802000,
232 0x00002080, 0x00800080, 0x00800081, 0x00000001,
233 0x00802001, 0x00002081, 0x00002081, 0x00000080,
234 0x00802081, 0x00000081, 0x00000001, 0x00002000,
235 0x00800001, 0x00002001, 0x00802080, 0x00800081,
236 0x00002001, 0x00002080, 0x00800000, 0x00802001,
237 0x00000080, 0x00800000, 0x00002000, 0x00802080
238 };
239
240 static int[] SP5 = {
241 0x00000100, 0x02080100, 0x02080000, 0x42000100,
242 0x00080000, 0x00000100, 0x40000000, 0x02080000,
243 0x40080100, 0x00080000, 0x02000100, 0x40080100,
244 0x42000100, 0x42080000, 0x00080100, 0x40000000,
245 0x02000000, 0x40080000, 0x40080000, 0x00000000,
246 0x40000100, 0x42080100, 0x42080100, 0x02000100,
247 0x42080000, 0x40000100, 0x00000000, 0x42000000,
248 0x02080100, 0x02000000, 0x42000000, 0x00080100,
249 0x00080000, 0x42000100, 0x00000100, 0x02000000,
250 0x40000000, 0x02080000, 0x42000100, 0x40080100,
251 0x02000100, 0x40000000, 0x42080000, 0x02080100,
252 0x40080100, 0x00000100, 0x02000000, 0x42080000,
253 0x42080100, 0x00080100, 0x42000000, 0x42080100,
254 0x02080000, 0x00000000, 0x40080000, 0x42000000,
255 0x00080100, 0x02000100, 0x40000100, 0x00080000,
256 0x00000000, 0x40080000, 0x02080100, 0x40000100
257 };
258
259 static int[] SP6 = {
260 0x20000010, 0x20400000, 0x00004000, 0x20404010,
261 0x20400000, 0x00000010, 0x20404010, 0x00400000,
262 0x20004000, 0x00404010, 0x00400000, 0x20000010,
263 0x00400010, 0x20004000, 0x20000000, 0x00004010,
264 0x00000000, 0x00400010, 0x20004010, 0x00004000,
265 0x00404000, 0x20004010, 0x00000010, 0x20400010,
266 0x20400010, 0x00000000, 0x00404010, 0x20404000,
267 0x00004010, 0x00404000, 0x20404000, 0x20000000,
268 0x20004000, 0x00000010, 0x20400010, 0x00404000,
269 0x20404010, 0x00400000, 0x00004010, 0x20000010,
270 0x00400000, 0x20004000, 0x20000000, 0x00004010,
271 0x20000010, 0x20404010, 0x00404000, 0x20400000,
272 0x00404010, 0x20404000, 0x00000000, 0x20400010,
273 0x00000010, 0x00004000, 0x20400000, 0x00404010,
274 0x00004000, 0x00400010, 0x20004010, 0x00000000,
275 0x20404000, 0x20000000, 0x00400010, 0x20004010
276 };
277
278 static int[] SP7 = {
279 0x00200000, 0x04200002, 0x04000802, 0x00000000,
280 0x00000800, 0x04000802, 0x00200802, 0x04200800,
281 0x04200802, 0x00200000, 0x00000000, 0x04000002,
282 0x00000002, 0x04000000, 0x04200002, 0x00000802,
283 0x04000800, 0x00200802, 0x00200002, 0x04000800,
284 0x04000002, 0x04200000, 0x04200800, 0x00200002,
285 0x04200000, 0x00000800, 0x00000802, 0x04200802,
286 0x00200800, 0x00000002, 0x04000000, 0x00200800,
287 0x04000000, 0x00200800, 0x00200000, 0x04000802,
288 0x04000802, 0x04200002, 0x04200002, 0x00000002,
289 0x00200002, 0x04000000, 0x04000800, 0x00200000,
290 0x04200800, 0x00000802, 0x00200802, 0x04200800,
291 0x00000802, 0x04000002, 0x04200802, 0x04200000,
292 0x00200800, 0x00000000, 0x00000002, 0x04200802,
293 0x00000000, 0x00200802, 0x04200000, 0x00000800,
294 0x04000002, 0x04000800, 0x00000800, 0x00200002
295 };
296
297 static int[] SP8 = {
298 0x10001040, 0x00001000, 0x00040000, 0x10041040,
299 0x10000000, 0x10001040, 0x00000040, 0x10000000,
300 0x00040040, 0x10040000, 0x10041040, 0x00041000,
301 0x10041000, 0x00041040, 0x00001000, 0x00000040,
302 0x10040000, 0x10000040, 0x10001000, 0x00001040,
303 0x00041000, 0x00040040, 0x10040040, 0x10041000,
304 0x00001040, 0x00000000, 0x00000000, 0x10040040,
305 0x10000040, 0x10001000, 0x00041040, 0x00040000,
306 0x00041040, 0x00040000, 0x10041000, 0x00001000,
307 0x00000040, 0x10040040, 0x00001000, 0x00041040,
308 0x10001000, 0x00000040, 0x10000040, 0x10040000,
309 0x10040040, 0x10000000, 0x00040000, 0x10001040,
310 0x00000000, 0x10041040, 0x00040040, 0x10000040,
311 0x10040000, 0x10001000, 0x10001040, 0x00000000,
312 0x10041040, 0x00041000, 0x00041000, 0x00001040,
313 0x00001040, 0x00040040, 0x10000000, 0x10041000
314 };
315
316
317
318
319
320
321
322
323 protected int[] generateWorkingKey(
324 boolean encrypting,
325 byte[] key)
326 {
327 int[] newKey = new int[32];
328 boolean[] pc1m = new boolean[56],
329 pcr = new boolean[56];
330
331 for (int j = 0; j < 56; j++ )
332 {
333 int l = pc1[j];
334
335 pc1m[j] = ((key[l >>> 3] & bytebit[l & 07]) != 0);
336 }
337
338 for (int i = 0; i < 16; i++)
339 {
340 int l, m, n;
341
342 if (encrypting)
343 {
344 m = i << 1;
345 }
346 else
347 {
348 m = (15 - i) << 1;
349 }
350
351 n = m + 1;
352 newKey[m] = newKey[n] = 0;
353
354 for (int j = 0; j < 28; j++)
355 {
356 l = j + totrot[i];
357 if ( l < 28 )
358 {
359 pcr[j] = pc1m[l];
360 }
361 else
362 {
363 pcr[j] = pc1m[l - 28];
364 }
365 }
366
367 for (int j = 28; j < 56; j++)
368 {
369 l = j + totrot[i];
370 if (l < 56 )
371 {
372 pcr[j] = pc1m[l];
373 }
374 else
375 {
376 pcr[j] = pc1m[l - 28];
377 }
378 }
379
380 for (int j = 0; j < 24; j++)
381 {
382 if (pcr[pc2[j]])
383 {
384 newKey[m] |= bigbyte[j];
385 }
386
387 if (pcr[pc2[j + 24]])
388 {
389 newKey[n] |= bigbyte[j];
390 }
391 }
392 }
393
394
395
396
397 for (int i = 0; i != 32; i += 2)
398 {
399 int i1, i2;
400
401 i1 = newKey[i];
402 i2 = newKey[i + 1];
403
404 newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10)
405 | ((i2 & 0x00fc0000) >>> 10) | ((i2 & 0x00000fc0) >>> 6);
406
407 newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16)
408 | ((i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f);
409 }
410
411 return newKey;
412 }
413
414
415
416
417 protected void desFunc(
418 int[] wKey,
419 byte[] in,
420 int inOff,
421 byte[] out,
422 int outOff)
423 {
424 int work, right, left;
425
426 left = (in[inOff + 0] & 0xff) << 24;
427 left |= (in[inOff + 1] & 0xff) << 16;
428 left |= (in[inOff + 2] & 0xff) << 8;
429 left |= (in[inOff + 3] & 0xff);
430
431 right = (in[inOff + 4] & 0xff) << 24;
432 right |= (in[inOff + 5] & 0xff) << 16;
433 right |= (in[inOff + 6] & 0xff) << 8;
434 right |= (in[inOff + 7] & 0xff);
435
436 work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
437 right ^= work;
438 left ^= (work << 4);
439 work = ((left >>> 16) ^ right) & 0x0000ffff;
440 right ^= work;
441 left ^= (work << 16);
442 work = ((right >>> 2) ^ left) & 0x33333333;
443 left ^= work;
444 right ^= (work << 2);
445 work = ((right >>> 8) ^ left) & 0x00ff00ff;
446 left ^= work;
447 right ^= (work << 8);
448 right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
449 work = (left ^ right) & 0xaaaaaaaa;
450 left ^= work;
451 right ^= work;
452 left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
453
454 for (int round = 0; round < 8; round++)
455 {
456 int fval;
457
458 work = (right << 28) | (right >>> 4);
459 work ^= wKey[round * 4 + 0];
460 fval = SP7[ work & 0x3f];
461 fval |= SP5[(work >>> 8) & 0x3f];
462 fval |= SP3[(work >>> 16) & 0x3f];
463 fval |= SP1[(work >>> 24) & 0x3f];
464 work = right ^ wKey[round * 4 + 1];
465 fval |= SP8[ work & 0x3f];
466 fval |= SP6[(work >>> 8) & 0x3f];
467 fval |= SP4[(work >>> 16) & 0x3f];
468 fval |= SP2[(work >>> 24) & 0x3f];
469 left ^= fval;
470 work = (left << 28) | (left >>> 4);
471 work ^= wKey[round * 4 + 2];
472 fval = SP7[ work & 0x3f];
473 fval |= SP5[(work >>> 8) & 0x3f];
474 fval |= SP3[(work >>> 16) & 0x3f];
475 fval |= SP1[(work >>> 24) & 0x3f];
476 work = left ^ wKey[round * 4 + 3];
477 fval |= SP8[ work & 0x3f];
478 fval |= SP6[(work >>> 8) & 0x3f];
479 fval |= SP4[(work >>> 16) & 0x3f];
480 fval |= SP2[(work >>> 24) & 0x3f];
481 right ^= fval;
482 }
483
484 right = (right << 31) | (right >>> 1);
485 work = (left ^ right) & 0xaaaaaaaa;
486 left ^= work;
487 right ^= work;
488 left = (left << 31) | (left >>> 1);
489 work = ((left >>> 8) ^ right) & 0x00ff00ff;
490 right ^= work;
491 left ^= (work << 8);
492 work = ((left >>> 2) ^ right) & 0x33333333;
493 right ^= work;
494 left ^= (work << 2);
495 work = ((right >>> 16) ^ left) & 0x0000ffff;
496 left ^= work;
497 right ^= (work << 16);
498 work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
499 left ^= work;
500 right ^= (work << 4);
501
502 out[outOff + 0] = (byte)((right >>> 24) & 0xff);
503 out[outOff + 1] = (byte)((right >>> 16) & 0xff);
504 out[outOff + 2] = (byte)((right >>> 8) & 0xff);
505 out[outOff + 3] = (byte)( right & 0xff);
506 out[outOff + 4] = (byte)((left >>> 24) & 0xff);
507 out[outOff + 5] = (byte)((left >>> 16) & 0xff);
508 out[outOff + 6] = (byte)((left >>> 8) & 0xff);
509 out[outOff + 7] = (byte)( left & 0xff);
510 }
511 }