comparison src/ch/ethz/ssh2/crypto/cipher/DES.java @ 273:91a31873c42a ganymed

start conversion from trilead to ganymed
author Carl Byington <carl@five-ten-sg.com>
date Fri, 18 Jul 2014 11:21:46 -0700
parents
children 071eccdff8ea
comparison
equal deleted inserted replaced
272:ce2f4e397703 273:91a31873c42a
1 package ch.ethz.ssh2.crypto.cipher;
2
3 /*
4 This file is based on the 3DES implementation from the Bouncy Castle Crypto package.
5 Their licence file states the following:
6
7 Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
8 (http://www.bouncycastle.org)
9
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 THE SOFTWARE.
27 */
28
29 /**
30 * DES.
31 *
32 * @author See comments in the source file
33 * @version 2.50, 03/15/10
34 *
35 */
36 public class DES implements BlockCipher
37 {
38 private int[] workingKey = null;
39
40 /**
41 * standard constructor.
42 */
43 public DES()
44 {
45 }
46
47 /**
48 * initialise a DES cipher.
49 *
50 * @param encrypting
51 * whether or not we are for encryption.
52 * @param key
53 * the parameters required to set up the cipher.
54 * @exception IllegalArgumentException
55 * if the params argument is inappropriate.
56 */
57 public void init(boolean encrypting, byte[] key)
58 {
59 this.workingKey = generateWorkingKey(encrypting, key, 0);
60 }
61
62 public String getAlgorithmName()
63 {
64 return "DES";
65 }
66
67 public int getBlockSize()
68 {
69 return 8;
70 }
71
72 public void transformBlock(byte[] in, int inOff, byte[] out, int outOff)
73 {
74 if (workingKey == null)
75 {
76 throw new IllegalStateException("DES engine not initialised!");
77 }
78
79 desFunc(workingKey, in, inOff, out, outOff);
80 }
81
82 public void reset()
83 {
84 }
85
86 /**
87 * what follows is mainly taken from "Applied Cryptography", by Bruce
88 * Schneier, however it also bears great resemblance to Richard
89 * Outerbridge's D3DES...
90 */
91
92 static short[] Df_Key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32,
93 0x10, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 };
94
95 static short[] bytebit = { 0200, 0100, 040, 020, 010, 04, 02, 01 };
96
97 static int[] bigbyte = { 0x800000, 0x400000, 0x200000, 0x100000, 0x80000, 0x40000, 0x20000, 0x10000, 0x8000,
98 0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };
99
100 /*
101 * Use the key schedule specified in the Standard (ANSI X3.92-1981).
102 */
103
104 static byte[] pc1 = { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2,
105 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12,
106 4, 27, 19, 11, 3 };
107
108 static byte[] totrot = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 };
109
110 static byte[] pc2 = { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40,
111 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
112
113 static int[] SP1 = { 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004,
114 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
115 0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004,
116 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404,
117 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400,
118 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404,
119 0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004,
120 0x00010400, 0x00000000, 0x01010004 };
121
122 static int[] SP2 = { 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020,
123 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
124 0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020,
125 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020,
126 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020,
127 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020,
128 0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000,
129 0x80100020, 0x80108020, 0x00108000 };
130
131 static int[] SP3 = { 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208,
132 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
133 0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208,
134 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000,
135 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208,
136 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208,
137 0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208,
138 0x00000008, 0x08020008, 0x00020200 };
139
140 static int[] SP4 = { 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001,
141 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
142 0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081,
143 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001,
144 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081,
145 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000,
146 0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080,
147 0x00800000, 0x00002000, 0x00802080 };
148
149 static int[] SP5 = { 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000,
150 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
151 0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, 0x42080000,
152 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100,
153 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000,
154 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, 0x42080100, 0x00080100, 0x42000000, 0x42080100,
155 0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000,
156 0x40080000, 0x02080100, 0x40000100 };
157
158 static int[] SP6 = { 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010,
159 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
160 0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010,
161 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010,
162 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000,
163 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010,
164 0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000,
165 0x20000000, 0x00400010, 0x20004010 };
166
167 static int[] SP7 = { 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802,
168 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
169 0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000,
170 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800,
171 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800,
172 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000,
173 0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002,
174 0x04000800, 0x00000800, 0x00200002 };
175
176 static int[] SP8 = { 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040,
177 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
178 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040,
179 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000,
180 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040,
181 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040,
182 0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040,
183 0x00040040, 0x10000000, 0x10041000 };
184
185 /**
186 * generate an integer based working key based on our secret key and what we
187 * processing we are planning to do.
188 *
189 * Acknowledgements for this routine go to James Gillogly & Phil Karn.
190 * (whoever, and wherever they are!).
191 */
192 protected int[] generateWorkingKey(boolean encrypting, byte[] key, int off)
193 {
194 int[] newKey = new int[32];
195 boolean[] pc1m = new boolean[56], pcr = new boolean[56];
196
197 for (int j = 0; j < 56; j++)
198 {
199 int l = pc1[j];
200
201 pc1m[j] = ((key[off + (l >>> 3)] & bytebit[l & 07]) != 0);
202 }
203
204 for (int i = 0; i < 16; i++)
205 {
206 int l, m, n;
207
208 if (encrypting)
209 {
210 m = i << 1;
211 }
212 else
213 {
214 m = (15 - i) << 1;
215 }
216
217 n = m + 1;
218 newKey[m] = newKey[n] = 0;
219
220 for (int j = 0; j < 28; j++)
221 {
222 l = j + totrot[i];
223 if (l < 28)
224 {
225 pcr[j] = pc1m[l];
226 }
227 else
228 {
229 pcr[j] = pc1m[l - 28];
230 }
231 }
232
233 for (int j = 28; j < 56; j++)
234 {
235 l = j + totrot[i];
236 if (l < 56)
237 {
238 pcr[j] = pc1m[l];
239 }
240 else
241 {
242 pcr[j] = pc1m[l - 28];
243 }
244 }
245
246 for (int j = 0; j < 24; j++)
247 {
248 if (pcr[pc2[j]])
249 {
250 newKey[m] |= bigbyte[j];
251 }
252
253 if (pcr[pc2[j + 24]])
254 {
255 newKey[n] |= bigbyte[j];
256 }
257 }
258 }
259
260 //
261 // store the processed key
262 //
263 for (int i = 0; i != 32; i += 2)
264 {
265 int i1, i2;
266
267 i1 = newKey[i];
268 i2 = newKey[i + 1];
269
270 newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10) | ((i2 & 0x00fc0000) >>> 10)
271 | ((i2 & 0x00000fc0) >>> 6);
272
273 newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16) | ((i2 & 0x0003f000) >>> 4)
274 | (i2 & 0x0000003f);
275 }
276
277 return newKey;
278 }
279
280 /**
281 * the DES engine.
282 */
283 protected void desFunc(int[] wKey, byte[] in, int inOff, byte[] out, int outOff)
284 {
285 int work, right, left;
286
287 left = (in[inOff + 0] & 0xff) << 24;
288 left |= (in[inOff + 1] & 0xff) << 16;
289 left |= (in[inOff + 2] & 0xff) << 8;
290 left |= (in[inOff + 3] & 0xff);
291
292 right = (in[inOff + 4] & 0xff) << 24;
293 right |= (in[inOff + 5] & 0xff) << 16;
294 right |= (in[inOff + 6] & 0xff) << 8;
295 right |= (in[inOff + 7] & 0xff);
296
297 work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
298 right ^= work;
299 left ^= (work << 4);
300 work = ((left >>> 16) ^ right) & 0x0000ffff;
301 right ^= work;
302 left ^= (work << 16);
303 work = ((right >>> 2) ^ left) & 0x33333333;
304 left ^= work;
305 right ^= (work << 2);
306 work = ((right >>> 8) ^ left) & 0x00ff00ff;
307 left ^= work;
308 right ^= (work << 8);
309 right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
310 work = (left ^ right) & 0xaaaaaaaa;
311 left ^= work;
312 right ^= work;
313 left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
314
315 for (int round = 0; round < 8; round++)
316 {
317 int fval;
318
319 work = (right << 28) | (right >>> 4);
320 work ^= wKey[round * 4 + 0];
321 fval = SP7[work & 0x3f];
322 fval |= SP5[(work >>> 8) & 0x3f];
323 fval |= SP3[(work >>> 16) & 0x3f];
324 fval |= SP1[(work >>> 24) & 0x3f];
325 work = right ^ wKey[round * 4 + 1];
326 fval |= SP8[work & 0x3f];
327 fval |= SP6[(work >>> 8) & 0x3f];
328 fval |= SP4[(work >>> 16) & 0x3f];
329 fval |= SP2[(work >>> 24) & 0x3f];
330 left ^= fval;
331 work = (left << 28) | (left >>> 4);
332 work ^= wKey[round * 4 + 2];
333 fval = SP7[work & 0x3f];
334 fval |= SP5[(work >>> 8) & 0x3f];
335 fval |= SP3[(work >>> 16) & 0x3f];
336 fval |= SP1[(work >>> 24) & 0x3f];
337 work = left ^ wKey[round * 4 + 3];
338 fval |= SP8[work & 0x3f];
339 fval |= SP6[(work >>> 8) & 0x3f];
340 fval |= SP4[(work >>> 16) & 0x3f];
341 fval |= SP2[(work >>> 24) & 0x3f];
342 right ^= fval;
343 }
344
345 right = (right << 31) | (right >>> 1);
346 work = (left ^ right) & 0xaaaaaaaa;
347 left ^= work;
348 right ^= work;
349 left = (left << 31) | (left >>> 1);
350 work = ((left >>> 8) ^ right) & 0x00ff00ff;
351 right ^= work;
352 left ^= (work << 8);
353 work = ((left >>> 2) ^ right) & 0x33333333;
354 right ^= work;
355 left ^= (work << 2);
356 work = ((right >>> 16) ^ left) & 0x0000ffff;
357 left ^= work;
358 right ^= (work << 16);
359 work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
360 left ^= work;
361 right ^= (work << 4);
362
363 out[outOff + 0] = (byte) ((right >>> 24) & 0xff);
364 out[outOff + 1] = (byte) ((right >>> 16) & 0xff);
365 out[outOff + 2] = (byte) ((right >>> 8) & 0xff);
366 out[outOff + 3] = (byte) (right & 0xff);
367 out[outOff + 4] = (byte) ((left >>> 24) & 0xff);
368 out[outOff + 5] = (byte) ((left >>> 16) & 0xff);
369 out[outOff + 6] = (byte) ((left >>> 8) & 0xff);
370 out[outOff + 7] = (byte) (left & 0xff);
371 }
372 }