comparison src/com/trilead/ssh2/crypto/cipher/DES.java @ 0:0ce5cc452d02

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