comparison app/src/main/java/ch/ethz/ssh2/crypto/cipher/DES.java @ 438:d29cce60f393

migrate from Eclipse to Android Studio
author Carl Byington <carl@five-ten-sg.com>
date Thu, 03 Dec 2015 11:23:55 -0800
parents src/ch/ethz/ssh2/crypto/cipher/DES.java@071eccdff8ea
children
comparison
equal deleted inserted replaced
437:208b31032318 438:d29cce60f393
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 private int[] workingKey = null;
38
39 /**
40 * standard constructor.
41 */
42 public DES() {
43 }
44
45 /**
46 * initialise a DES cipher.
47 *
48 * @param encrypting
49 * whether or not we are for encryption.
50 * @param key
51 * the parameters required to set up the cipher.
52 * @exception IllegalArgumentException
53 * if the params argument is inappropriate.
54 */
55 public void init(boolean encrypting, byte[] key) {
56 this.workingKey = generateWorkingKey(encrypting, key, 0);
57 }
58
59 public String getAlgorithmName() {
60 return "DES";
61 }
62
63 public int getBlockSize() {
64 return 8;
65 }
66
67 public void transformBlock(byte[] in, int inOff, byte[] out, int outOff) {
68 if (workingKey == null) {
69 throw new IllegalStateException("DES engine not initialised!");
70 }
71
72 desFunc(workingKey, in, inOff, out, outOff);
73 }
74
75 public void reset() {
76 }
77
78 /**
79 * what follows is mainly taken from "Applied Cryptography", by Bruce
80 * Schneier, however it also bears great resemblance to Richard
81 * Outerbridge's D3DES...
82 */
83
84 static short[] Df_Key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32,
85 0x10, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67
86 };
87
88 static short[] bytebit = { 0200, 0100, 040, 020, 010, 04, 02, 01 };
89
90 static int[] bigbyte = { 0x800000, 0x400000, 0x200000, 0x100000, 0x80000, 0x40000, 0x20000, 0x10000, 0x8000,
91 0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1
92 };
93
94 /*
95 * Use the key schedule specified in the Standard (ANSI X3.92-1981).
96 */
97
98 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,
99 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,
100 4, 27, 19, 11, 3
101 };
102
103 static byte[] totrot = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 };
104
105 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,
106 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
107 };
108
109 static int[] SP1 = { 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004,
110 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
111 0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004,
112 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404,
113 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400,
114 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404,
115 0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004,
116 0x00010400, 0x00000000, 0x01010004
117 };
118
119 static int[] SP2 = { 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020,
120 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
121 0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020,
122 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020,
123 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020,
124 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020,
125 0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000,
126 0x80100020, 0x80108020, 0x00108000
127 };
128
129 static int[] SP3 = { 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208,
130 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
131 0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208,
132 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000,
133 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208,
134 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208,
135 0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208,
136 0x00000008, 0x08020008, 0x00020200
137 };
138
139 static int[] SP4 = { 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001,
140 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
141 0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081,
142 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001,
143 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081,
144 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000,
145 0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080,
146 0x00800000, 0x00002000, 0x00802080
147 };
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
159 static int[] SP6 = { 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010,
160 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
161 0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010,
162 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010,
163 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000,
164 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010,
165 0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000,
166 0x20000000, 0x00400010, 0x20004010
167 };
168
169 static int[] SP7 = { 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802,
170 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
171 0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000,
172 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800,
173 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800,
174 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000,
175 0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002,
176 0x04000800, 0x00000800, 0x00200002
177 };
178
179 static int[] SP8 = { 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040,
180 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
181 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040,
182 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000,
183 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040,
184 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040,
185 0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040,
186 0x00040040, 0x10000000, 0x10041000
187 };
188
189 /**
190 * generate an integer based working key based on our secret key and what we
191 * processing we are planning to do.
192 *
193 * Acknowledgements for this routine go to James Gillogly & Phil Karn.
194 * (whoever, and wherever they are!).
195 */
196 protected int[] generateWorkingKey(boolean encrypting, byte[] key, int off) {
197 int[] newKey = new int[32];
198 boolean[] pc1m = new boolean[56], pcr = new boolean[56];
199
200 for (int j = 0; j < 56; j++) {
201 int l = pc1[j];
202 pc1m[j] = ((key[off + (l >>> 3)] & bytebit[l & 07]) != 0);
203 }
204
205 for (int i = 0; i < 16; i++) {
206 int l, m, n;
207
208 if (encrypting) {
209 m = i << 1;
210 }
211 else {
212 m = (15 - i) << 1;
213 }
214
215 n = m + 1;
216 newKey[m] = newKey[n] = 0;
217
218 for (int j = 0; j < 28; j++) {
219 l = j + totrot[i];
220
221 if (l < 28) {
222 pcr[j] = pc1m[l];
223 }
224 else {
225 pcr[j] = pc1m[l - 28];
226 }
227 }
228
229 for (int j = 28; j < 56; j++) {
230 l = j + totrot[i];
231
232 if (l < 56) {
233 pcr[j] = pc1m[l];
234 }
235 else {
236 pcr[j] = pc1m[l - 28];
237 }
238 }
239
240 for (int j = 0; j < 24; j++) {
241 if (pcr[pc2[j]]) {
242 newKey[m] |= bigbyte[j];
243 }
244
245 if (pcr[pc2[j + 24]]) {
246 newKey[n] |= bigbyte[j];
247 }
248 }
249 }
250
251 //
252 // store the processed key
253 //
254 for (int i = 0; i != 32; i += 2) {
255 int i1, i2;
256 i1 = newKey[i];
257 i2 = newKey[i + 1];
258 newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10) | ((i2 & 0x00fc0000) >>> 10)
259 | ((i2 & 0x00000fc0) >>> 6);
260 newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16) | ((i2 & 0x0003f000) >>> 4)
261 | (i2 & 0x0000003f);
262 }
263
264 return newKey;
265 }
266
267 /**
268 * the DES engine.
269 */
270 protected void desFunc(int[] wKey, byte[] in, int inOff, byte[] out, int outOff) {
271 int work, right, left;
272 left = (in[inOff + 0] & 0xff) << 24;
273 left |= (in[inOff + 1] & 0xff) << 16;
274 left |= (in[inOff + 2] & 0xff) << 8;
275 left |= (in[inOff + 3] & 0xff);
276 right = (in[inOff + 4] & 0xff) << 24;
277 right |= (in[inOff + 5] & 0xff) << 16;
278 right |= (in[inOff + 6] & 0xff) << 8;
279 right |= (in[inOff + 7] & 0xff);
280 work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
281 right ^= work;
282 left ^= (work << 4);
283 work = ((left >>> 16) ^ right) & 0x0000ffff;
284 right ^= work;
285 left ^= (work << 16);
286 work = ((right >>> 2) ^ left) & 0x33333333;
287 left ^= work;
288 right ^= (work << 2);
289 work = ((right >>> 8) ^ left) & 0x00ff00ff;
290 left ^= work;
291 right ^= (work << 8);
292 right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
293 work = (left ^ right) & 0xaaaaaaaa;
294 left ^= work;
295 right ^= work;
296 left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
297
298 for (int round = 0; round < 8; round++) {
299 int fval;
300 work = (right << 28) | (right >>> 4);
301 work ^= wKey[round * 4 + 0];
302 fval = SP7[work & 0x3f];
303 fval |= SP5[(work >>> 8) & 0x3f];
304 fval |= SP3[(work >>> 16) & 0x3f];
305 fval |= SP1[(work >>> 24) & 0x3f];
306 work = right ^ wKey[round * 4 + 1];
307 fval |= SP8[work & 0x3f];
308 fval |= SP6[(work >>> 8) & 0x3f];
309 fval |= SP4[(work >>> 16) & 0x3f];
310 fval |= SP2[(work >>> 24) & 0x3f];
311 left ^= fval;
312 work = (left << 28) | (left >>> 4);
313 work ^= wKey[round * 4 + 2];
314 fval = SP7[work & 0x3f];
315 fval |= SP5[(work >>> 8) & 0x3f];
316 fval |= SP3[(work >>> 16) & 0x3f];
317 fval |= SP1[(work >>> 24) & 0x3f];
318 work = left ^ wKey[round * 4 + 3];
319 fval |= SP8[work & 0x3f];
320 fval |= SP6[(work >>> 8) & 0x3f];
321 fval |= SP4[(work >>> 16) & 0x3f];
322 fval |= SP2[(work >>> 24) & 0x3f];
323 right ^= fval;
324 }
325
326 right = (right << 31) | (right >>> 1);
327 work = (left ^ right) & 0xaaaaaaaa;
328 left ^= work;
329 right ^= work;
330 left = (left << 31) | (left >>> 1);
331 work = ((left >>> 8) ^ right) & 0x00ff00ff;
332 right ^= work;
333 left ^= (work << 8);
334 work = ((left >>> 2) ^ right) & 0x33333333;
335 right ^= work;
336 left ^= (work << 2);
337 work = ((right >>> 16) ^ left) & 0x0000ffff;
338 left ^= work;
339 right ^= (work << 16);
340 work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
341 left ^= work;
342 right ^= (work << 4);
343 out[outOff + 0] = (byte)((right >>> 24) & 0xff);
344 out[outOff + 1] = (byte)((right >>> 16) & 0xff);
345 out[outOff + 2] = (byte)((right >>> 8) & 0xff);
346 out[outOff + 3] = (byte)(right & 0xff);
347 out[outOff + 4] = (byte)((left >>> 24) & 0xff);
348 out[outOff + 5] = (byte)((left >>> 16) & 0xff);
349 out[outOff + 6] = (byte)((left >>> 8) & 0xff);
350 out[outOff + 7] = (byte)(left & 0xff);
351 }
352 }