2 // This DES class has been extracted from package Acme.Crypto for use in VNC.
3 // The bytebit[] array has been reversed so that the most significant bit
4 // in each byte of the key is ignored, not the least significant. Also the
5 // unnecessary odd parity code has been removed.
8 // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
10 // This software is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 // DesCipher - the DES encryption method
17 // The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is:
19 // Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
21 // Permission to use, copy, modify, and distribute this software
22 // and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
23 // without fee is hereby granted, provided that this copyright notice is kept
26 // WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
27 // OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
28 // TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
29 // PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
30 // FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
31 // DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
33 // THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
34 // CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
35 // PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
36 // NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
37 // SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
38 // SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
39 // PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP
40 // SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
41 // HIGH RISK ACTIVITIES.
46 // Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
48 // Redistribution and use in source and binary forms, with or without
49 // modification, are permitted provided that the following conditions
51 // 1. Redistributions of source code must retain the above copyright
52 // notice, this list of conditions and the following disclaimer.
53 // 2. Redistributions in binary form must reproduce the above copyright
54 // notice, this list of conditions and the following disclaimer in the
55 // documentation and/or other materials provided with the distribution.
57 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
58 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
59 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
60 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
61 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
62 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
63 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
65 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
66 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 // Visit the ACME Labs Java page for up-to-date versions of this and other
70 // fine Java utilities: http://www.acme.com/java/
75 /// The DES encryption method.
77 // This is surprisingly fast, for pure Java. On a SPARC 20, wrapped
78 // in Acme.Crypto.EncryptedOutputStream or Acme.Crypto.EncryptedInputStream,
79 // it does around 7000 bytes/second.
81 // Most of this code is by Dave Zimmerman <dzimm@widget.com>, and is
82 // Copyright (c) 1996 Widget Workshop, Inc. See the source file for details.
84 // <A HREF="/resources/classes/Acme/Crypto/DesCipher.java">Fetch the software.</A><BR>
85 // <A HREF="/resources/classes/Acme.tar.Z">Fetch the entire Acme package.</A>
88 // @see EncryptedOutputStream
89 // @see EncryptedInputStream
91 public class DesCipher
94 // Constructor, byte-array key.
95 public DesCipher( byte[] key )
102 private int[] encryptKeys = new int[32];
103 private int[] decryptKeys = new int[32];
106 public void setKey( byte[] key )
108 deskey( key, true, encryptKeys );
109 deskey( key, false, decryptKeys );
112 // Turn an 8-byte key into internal keys.
113 private void deskey( byte[] keyBlock, boolean encrypting, int[] KnL )
116 int[] pc1m = new int[56];
117 int[] pcr = new int[56];
118 int[] kn = new int[32];
120 for ( j = 0; j < 56; ++j )
124 pc1m[j] = ( (keyBlock[l >>> 3] & bytebit[m]) != 0 )? 1: 0;
127 for ( i = 0; i < 16; ++i )
135 for ( j = 0; j < 28; ++j )
143 for ( j=28; j < 56; ++j )
151 for ( j = 0; j < 24; ++j )
153 if ( pcr[pc2[j]] != 0 )
155 if ( pcr[pc2[j+24]] != 0 )
162 private void cookey( int[] raw, int KnL[] )
168 for ( i = 0, rawi = 0, KnLi = 0; i < 16; ++i )
172 KnL[KnLi] = (raw0 & 0x00fc0000) << 6;
173 KnL[KnLi] |= (raw0 & 0x00000fc0) << 10;
174 KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
175 KnL[KnLi] |= (raw1 & 0x00000fc0) >>> 6;
177 KnL[KnLi] = (raw0 & 0x0003f000) << 12;
178 KnL[KnLi] |= (raw0 & 0x0000003f) << 16;
179 KnL[KnLi] |= (raw1 & 0x0003f000) >>> 4;
180 KnL[KnLi] |= (raw1 & 0x0000003f);
186 // Block encryption routines.
188 private int[] tempInts = new int[2];
190 /// Encrypt a block of eight bytes.
191 public void encrypt( byte[] clearText, int clearOff, byte[] cipherText, int cipherOff )
193 squashBytesToInts( clearText, clearOff, tempInts, 0, 2 );
194 des( tempInts, tempInts, encryptKeys );
195 spreadIntsToBytes( tempInts, 0, cipherText, cipherOff, 2 );
198 /// Decrypt a block of eight bytes.
199 public void decrypt( byte[] cipherText, int cipherOff, byte[] clearText, int clearOff )
201 squashBytesToInts( cipherText, cipherOff, tempInts, 0, 2 );
202 des( tempInts, tempInts, decryptKeys );
203 spreadIntsToBytes( tempInts, 0, clearText, clearOff, 2 );
207 private void des( int[] inInts, int[] outInts, int[] keys )
209 int fval, work, right, leftt;
216 work = ((leftt >>> 4) ^ right) & 0x0f0f0f0f;
218 leftt ^= (work << 4);
220 work = ((leftt >>> 16) ^ right) & 0x0000ffff;
222 leftt ^= (work << 16);
224 work = ((right >>> 2) ^ leftt) & 0x33333333;
226 right ^= (work << 2);
228 work = ((right >>> 8) ^ leftt) & 0x00ff00ff;
230 right ^= (work << 8);
231 right = (right << 1) | ((right >>> 31) & 1);
233 work = (leftt ^ right) & 0xaaaaaaaa;
236 leftt = (leftt << 1) | ((leftt >>> 31) & 1);
238 for ( round = 0; round < 8; ++round )
240 work = (right << 28) | (right >>> 4);
241 work ^= keys[keysi++];
242 fval = SP7[ work & 0x0000003f ];
243 fval |= SP5[(work >>> 8) & 0x0000003f ];
244 fval |= SP3[(work >>> 16) & 0x0000003f ];
245 fval |= SP1[(work >>> 24) & 0x0000003f ];
246 work = right ^ keys[keysi++];
247 fval |= SP8[ work & 0x0000003f ];
248 fval |= SP6[(work >>> 8) & 0x0000003f ];
249 fval |= SP4[(work >>> 16) & 0x0000003f ];
250 fval |= SP2[(work >>> 24) & 0x0000003f ];
252 work = (leftt << 28) | (leftt >>> 4);
253 work ^= keys[keysi++];
254 fval = SP7[ work & 0x0000003f ];
255 fval |= SP5[(work >>> 8) & 0x0000003f ];
256 fval |= SP3[(work >>> 16) & 0x0000003f ];
257 fval |= SP1[(work >>> 24) & 0x0000003f ];
258 work = leftt ^ keys[keysi++];
259 fval |= SP8[ work & 0x0000003f ];
260 fval |= SP6[(work >>> 8) & 0x0000003f ];
261 fval |= SP4[(work >>> 16) & 0x0000003f ];
262 fval |= SP2[(work >>> 24) & 0x0000003f ];
266 right = (right << 31) | (right >>> 1);
267 work = (leftt ^ right) & 0xaaaaaaaa;
270 leftt = (leftt << 31) | (leftt >>> 1);
271 work = ((leftt >>> 8) ^ right) & 0x00ff00ff;
273 leftt ^= (work << 8);
274 work = ((leftt >>> 2) ^ right) & 0x33333333;
276 leftt ^= (work << 2);
277 work = ((right >>> 16) ^ leftt) & 0x0000ffff;
279 right ^= (work << 16);
280 work = ((right >>> 4) ^ leftt) & 0x0f0f0f0f;
282 right ^= (work << 4);
288 // Tables, permutations, S-boxes, etc.
290 private static byte[] bytebit = {
291 (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x08,
292 (byte)0x10, (byte)0x20, (byte)0x40, (byte)0x80
294 private static int[] bigbyte = {
295 0x800000, 0x400000, 0x200000, 0x100000,
296 0x080000, 0x040000, 0x020000, 0x010000,
297 0x008000, 0x004000, 0x002000, 0x001000,
298 0x000800, 0x000400, 0x000200, 0x000100,
299 0x000080, 0x000040, 0x000020, 0x000010,
300 0x000008, 0x000004, 0x000002, 0x000001
302 private static byte[] pc1 = {
303 (byte)56, (byte)48, (byte)40, (byte)32, (byte)24, (byte)16, (byte) 8,
304 (byte) 0, (byte)57, (byte)49, (byte)41, (byte)33, (byte)25, (byte)17,
305 (byte) 9, (byte) 1, (byte)58, (byte)50, (byte)42, (byte)34, (byte)26,
306 (byte)18, (byte)10, (byte) 2, (byte)59, (byte)51, (byte)43, (byte)35,
307 (byte)62, (byte)54, (byte)46, (byte)38, (byte)30, (byte)22, (byte)14,
308 (byte) 6, (byte)61, (byte)53, (byte)45, (byte)37, (byte)29, (byte)21,
309 (byte)13, (byte) 5, (byte)60, (byte)52, (byte)44, (byte)36, (byte)28,
310 (byte)20, (byte)12, (byte) 4, (byte)27, (byte)19, (byte)11, (byte)3
312 private static int[] totrot = {
313 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
316 private static byte[] pc2 = {
317 (byte)13, (byte)16, (byte)10, (byte)23, (byte) 0, (byte) 4,
318 (byte) 2, (byte)27, (byte)14, (byte) 5, (byte)20, (byte) 9,
319 (byte)22, (byte)18, (byte)11, (byte)3 , (byte)25, (byte) 7,
320 (byte)15, (byte) 6, (byte)26, (byte)19, (byte)12, (byte) 1,
321 (byte)40, (byte)51, (byte)30, (byte)36, (byte)46, (byte)54,
322 (byte)29, (byte)39, (byte)50, (byte)44, (byte)32, (byte)47,
323 (byte)43, (byte)48, (byte)38, (byte)55, (byte)33, (byte)52,
324 (byte)45, (byte)41, (byte)49, (byte)35, (byte)28, (byte)31,
327 private static int[] SP1 = {
328 0x01010400, 0x00000000, 0x00010000, 0x01010404,
329 0x01010004, 0x00010404, 0x00000004, 0x00010000,
330 0x00000400, 0x01010400, 0x01010404, 0x00000400,
331 0x01000404, 0x01010004, 0x01000000, 0x00000004,
332 0x00000404, 0x01000400, 0x01000400, 0x00010400,
333 0x00010400, 0x01010000, 0x01010000, 0x01000404,
334 0x00010004, 0x01000004, 0x01000004, 0x00010004,
335 0x00000000, 0x00000404, 0x00010404, 0x01000000,
336 0x00010000, 0x01010404, 0x00000004, 0x01010000,
337 0x01010400, 0x01000000, 0x01000000, 0x00000400,
338 0x01010004, 0x00010000, 0x00010400, 0x01000004,
339 0x00000400, 0x00000004, 0x01000404, 0x00010404,
340 0x01010404, 0x00010004, 0x01010000, 0x01000404,
341 0x01000004, 0x00000404, 0x00010404, 0x01010400,
342 0x00000404, 0x01000400, 0x01000400, 0x00000000,
343 0x00010004, 0x00010400, 0x00000000, 0x01010004
345 private static int[] SP2 = {
346 0x80108020, 0x80008000, 0x00008000, 0x00108020,
347 0x00100000, 0x00000020, 0x80100020, 0x80008020,
348 0x80000020, 0x80108020, 0x80108000, 0x80000000,
349 0x80008000, 0x00100000, 0x00000020, 0x80100020,
350 0x00108000, 0x00100020, 0x80008020, 0x00000000,
351 0x80000000, 0x00008000, 0x00108020, 0x80100000,
352 0x00100020, 0x80000020, 0x00000000, 0x00108000,
353 0x00008020, 0x80108000, 0x80100000, 0x00008020,
354 0x00000000, 0x00108020, 0x80100020, 0x00100000,
355 0x80008020, 0x80100000, 0x80108000, 0x00008000,
356 0x80100000, 0x80008000, 0x00000020, 0x80108020,
357 0x00108020, 0x00000020, 0x00008000, 0x80000000,
358 0x00008020, 0x80108000, 0x00100000, 0x80000020,
359 0x00100020, 0x80008020, 0x80000020, 0x00100020,
360 0x00108000, 0x00000000, 0x80008000, 0x00008020,
361 0x80000000, 0x80100020, 0x80108020, 0x00108000
363 private static int[] SP3 = {
364 0x00000208, 0x08020200, 0x00000000, 0x08020008,
365 0x08000200, 0x00000000, 0x00020208, 0x08000200,
366 0x00020008, 0x08000008, 0x08000008, 0x00020000,
367 0x08020208, 0x00020008, 0x08020000, 0x00000208,
368 0x08000000, 0x00000008, 0x08020200, 0x00000200,
369 0x00020200, 0x08020000, 0x08020008, 0x00020208,
370 0x08000208, 0x00020200, 0x00020000, 0x08000208,
371 0x00000008, 0x08020208, 0x00000200, 0x08000000,
372 0x08020200, 0x08000000, 0x00020008, 0x00000208,
373 0x00020000, 0x08020200, 0x08000200, 0x00000000,
374 0x00000200, 0x00020008, 0x08020208, 0x08000200,
375 0x08000008, 0x00000200, 0x00000000, 0x08020008,
376 0x08000208, 0x00020000, 0x08000000, 0x08020208,
377 0x00000008, 0x00020208, 0x00020200, 0x08000008,
378 0x08020000, 0x08000208, 0x00000208, 0x08020000,
379 0x00020208, 0x00000008, 0x08020008, 0x00020200
381 private static int[] SP4 = {
382 0x00802001, 0x00002081, 0x00002081, 0x00000080,
383 0x00802080, 0x00800081, 0x00800001, 0x00002001,
384 0x00000000, 0x00802000, 0x00802000, 0x00802081,
385 0x00000081, 0x00000000, 0x00800080, 0x00800001,
386 0x00000001, 0x00002000, 0x00800000, 0x00802001,
387 0x00000080, 0x00800000, 0x00002001, 0x00002080,
388 0x00800081, 0x00000001, 0x00002080, 0x00800080,
389 0x00002000, 0x00802080, 0x00802081, 0x00000081,
390 0x00800080, 0x00800001, 0x00802000, 0x00802081,
391 0x00000081, 0x00000000, 0x00000000, 0x00802000,
392 0x00002080, 0x00800080, 0x00800081, 0x00000001,
393 0x00802001, 0x00002081, 0x00002081, 0x00000080,
394 0x00802081, 0x00000081, 0x00000001, 0x00002000,
395 0x00800001, 0x00002001, 0x00802080, 0x00800081,
396 0x00002001, 0x00002080, 0x00800000, 0x00802001,
397 0x00000080, 0x00800000, 0x00002000, 0x00802080
399 private static int[] SP5 = {
400 0x00000100, 0x02080100, 0x02080000, 0x42000100,
401 0x00080000, 0x00000100, 0x40000000, 0x02080000,
402 0x40080100, 0x00080000, 0x02000100, 0x40080100,
403 0x42000100, 0x42080000, 0x00080100, 0x40000000,
404 0x02000000, 0x40080000, 0x40080000, 0x00000000,
405 0x40000100, 0x42080100, 0x42080100, 0x02000100,
406 0x42080000, 0x40000100, 0x00000000, 0x42000000,
407 0x02080100, 0x02000000, 0x42000000, 0x00080100,
408 0x00080000, 0x42000100, 0x00000100, 0x02000000,
409 0x40000000, 0x02080000, 0x42000100, 0x40080100,
410 0x02000100, 0x40000000, 0x42080000, 0x02080100,
411 0x40080100, 0x00000100, 0x02000000, 0x42080000,
412 0x42080100, 0x00080100, 0x42000000, 0x42080100,
413 0x02080000, 0x00000000, 0x40080000, 0x42000000,
414 0x00080100, 0x02000100, 0x40000100, 0x00080000,
415 0x00000000, 0x40080000, 0x02080100, 0x40000100
417 private static int[] SP6 = {
418 0x20000010, 0x20400000, 0x00004000, 0x20404010,
419 0x20400000, 0x00000010, 0x20404010, 0x00400000,
420 0x20004000, 0x00404010, 0x00400000, 0x20000010,
421 0x00400010, 0x20004000, 0x20000000, 0x00004010,
422 0x00000000, 0x00400010, 0x20004010, 0x00004000,
423 0x00404000, 0x20004010, 0x00000010, 0x20400010,
424 0x20400010, 0x00000000, 0x00404010, 0x20404000,
425 0x00004010, 0x00404000, 0x20404000, 0x20000000,
426 0x20004000, 0x00000010, 0x20400010, 0x00404000,
427 0x20404010, 0x00400000, 0x00004010, 0x20000010,
428 0x00400000, 0x20004000, 0x20000000, 0x00004010,
429 0x20000010, 0x20404010, 0x00404000, 0x20400000,
430 0x00404010, 0x20404000, 0x00000000, 0x20400010,
431 0x00000010, 0x00004000, 0x20400000, 0x00404010,
432 0x00004000, 0x00400010, 0x20004010, 0x00000000,
433 0x20404000, 0x20000000, 0x00400010, 0x20004010
435 private static int[] SP7 = {
436 0x00200000, 0x04200002, 0x04000802, 0x00000000,
437 0x00000800, 0x04000802, 0x00200802, 0x04200800,
438 0x04200802, 0x00200000, 0x00000000, 0x04000002,
439 0x00000002, 0x04000000, 0x04200002, 0x00000802,
440 0x04000800, 0x00200802, 0x00200002, 0x04000800,
441 0x04000002, 0x04200000, 0x04200800, 0x00200002,
442 0x04200000, 0x00000800, 0x00000802, 0x04200802,
443 0x00200800, 0x00000002, 0x04000000, 0x00200800,
444 0x04000000, 0x00200800, 0x00200000, 0x04000802,
445 0x04000802, 0x04200002, 0x04200002, 0x00000002,
446 0x00200002, 0x04000000, 0x04000800, 0x00200000,
447 0x04200800, 0x00000802, 0x00200802, 0x04200800,
448 0x00000802, 0x04000002, 0x04200802, 0x04200000,
449 0x00200800, 0x00000000, 0x00000002, 0x04200802,
450 0x00000000, 0x00200802, 0x04200000, 0x00000800,
451 0x04000002, 0x04000800, 0x00000800, 0x00200002
453 private static int[] SP8 = {
454 0x10001040, 0x00001000, 0x00040000, 0x10041040,
455 0x10000000, 0x10001040, 0x00000040, 0x10000000,
456 0x00040040, 0x10040000, 0x10041040, 0x00041000,
457 0x10041000, 0x00041040, 0x00001000, 0x00000040,
458 0x10040000, 0x10000040, 0x10001000, 0x00001040,
459 0x00041000, 0x00040040, 0x10040040, 0x10041000,
460 0x00001040, 0x00000000, 0x00000000, 0x10040040,
461 0x10000040, 0x10001000, 0x00041040, 0x00040000,
462 0x00041040, 0x00040000, 0x10041000, 0x00001000,
463 0x00000040, 0x10040040, 0x00001000, 0x00041040,
464 0x10001000, 0x00000040, 0x10000040, 0x10040000,
465 0x10040040, 0x10000000, 0x00040000, 0x10001040,
466 0x00000000, 0x10041040, 0x00040040, 0x10000040,
467 0x10040000, 0x10001000, 0x10001040, 0x00000000,
468 0x10041040, 0x00041000, 0x00041000, 0x00001040,
469 0x00001040, 0x00040040, 0x10000000, 0x10041000
472 // Routines taken from other parts of the Acme utilities.
474 /// Squash bytes down to ints.
475 public static void squashBytesToInts( byte[] inBytes, int inOff, int[] outInts, int outOff, int intLen )
477 for ( int i = 0; i < intLen; ++i )
478 outInts[outOff + i] =
479 ( ( inBytes[inOff + i * 4 ] & 0xff ) << 24 ) |
480 ( ( inBytes[inOff + i * 4 + 1] & 0xff ) << 16 ) |
481 ( ( inBytes[inOff + i * 4 + 2] & 0xff ) << 8 ) |
482 ( inBytes[inOff + i * 4 + 3] & 0xff );
485 /// Spread ints into bytes.
486 public static void spreadIntsToBytes( int[] inInts, int inOff, byte[] outBytes, int outOff, int intLen )
488 for ( int i = 0; i < intLen; ++i )
490 outBytes[outOff + i * 4 ] = (byte) ( inInts[inOff + i] >>> 24 );
491 outBytes[outOff + i * 4 + 1] = (byte) ( inInts[inOff + i] >>> 16 );
492 outBytes[outOff + i * 4 + 2] = (byte) ( inInts[inOff + i] >>> 8 );
493 outBytes[outOff + i * 4 + 3] = (byte) inInts[inOff + i];