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