1 /* DES.java --
2    Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
3 
4 This file is a part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or (at
9 your option) any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19 USA
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version.  */
37 
38 
39 package gnu.javax.crypto.cipher;
40 
41 import gnu.java.security.Registry;
42 import gnu.java.security.Properties;
43 import gnu.java.security.util.Util;
44 
45 import java.security.InvalidKeyException;
46 import java.util.Arrays;
47 import java.util.Collections;
48 import java.util.Iterator;
49 
50 /**
51  * The Data Encryption Standard. DES is a 64-bit block cipher with a 56-bit
52  * key, developed by IBM in the 1970's for the standardization process begun by
53  * the National Bureau of Standards (now NIST).
54  * <p>
55  * New applications should not use DES except for compatibility.
56  * <p>
57  * This version is based upon the description and sample implementation in
58  * [1].
59  * <p>
60  * References:
61  * <ol>
62  *    <li>Bruce Schneier, <i>Applied Cryptography: Protocols, Algorithms, and
63  *    Source Code in C, Second Edition</i>. (1996 John Wiley and Sons) ISBN
64  *    0-471-11709-9. Pages 265--301, 623--632.</li>
65  * </ol>
66  */
67 public class DES
68     extends BaseCipher
69 {
70   /** DES operates on 64 bit blocks. */
71   public static final int BLOCK_SIZE = 8;
72   /** DES uses 56 bits of a 64 bit parity-adjusted key. */
73   public static final int KEY_SIZE = 8;
74   // S-Boxes 1 through 8.
75   private static final int[] SP1 = new int[] {
76       0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404,
77       0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400,
78       0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400,
79       0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
80       0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404,
81       0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000,
82       0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000,
83       0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
84       0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404,
85       0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000,
86       0x00010004, 0x00010400, 0x00000000, 0x01010004 };
87   private static final int[] SP2 = new int[] {
88       0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020,
89       0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000,
90       0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020,
91       0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
92       0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000,
93       0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000,
94       0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000,
95       0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
96       0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020,
97       0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020,
98       0x80000000, 0x80100020, 0x80108020, 0x00108000 };
99   private static final int[] SP3 = new int[] {
100       0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000,
101       0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000,
102       0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008,
103       0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
104       0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208,
105       0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208,
106       0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008,
107       0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
108       0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208,
109       0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000,
110       0x00020208, 0x00000008, 0x08020008, 0x00020200 };
111   private static final int[] SP4 = new int[] {
112       0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081,
113       0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081,
114       0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000,
115       0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
116       0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080,
117       0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081,
118       0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080,
119       0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
120       0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001,
121       0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001,
122       0x00000080, 0x00800000, 0x00002000, 0x00802080 };
123   private static final int[] SP5 = new int[] {
124       0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100,
125       0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100,
126       0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000,
127       0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
128       0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000,
129       0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000,
130       0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000,
131       0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
132       0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000,
133       0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000,
134       0x00000000, 0x40080000, 0x02080100, 0x40000100 };
135   private static final int[] SP6 = new int[] {
136       0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010,
137       0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010,
138       0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010,
139       0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
140       0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000,
141       0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000,
142       0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000,
143       0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
144       0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000,
145       0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000,
146       0x20404000, 0x20000000, 0x00400010, 0x20004010 };
147   private static final int[] SP7 = new int[] {
148       0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802,
149       0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002,
150       0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802,
151       0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
152       0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002,
153       0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802,
154       0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000,
155       0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
156       0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000,
157       0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800,
158       0x04000002, 0x04000800, 0x00000800, 0x00200002 };
159   private static final int[] SP8 = new int[] {
160       0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040,
161       0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000,
162       0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040,
163       0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
164       0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000,
165       0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000,
166       0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040,
167       0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
168       0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000,
169       0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040,
170       0x00001040, 0x00040040, 0x10000000, 0x10041000 };
171   /**
172    * Constants that help in determining whether or not a byte array is parity
173    * adjusted.
174    */
175   private static final byte[] PARITY = {
176       8, 1, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 2, 8,
177       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 3,
178       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
179       8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
180       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
181       8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
182       8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
183       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
184       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
185       8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
186       8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
187       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
188       8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
189       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
190       4, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
191       8, 5, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 6, 8 };
192   // Key schedule constants.
193   private static final byte[] ROTARS = {
194       1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 };
195   private static final byte[] PC1 = {
196       56, 48, 40, 32, 24, 16,  8,  0, 57, 49, 41, 33, 25, 17,  9,  1,
197       58, 50, 42, 34, 26, 18, 10,  2, 59, 51, 43, 35, 62, 54, 46, 38,
198       30, 22, 14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 60, 52, 44, 36,
199       28, 20, 12,  4, 27, 19, 11,  3 };
200   private static final byte[] PC2 = {
201       13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9, 22, 18, 11,  3,
202       25,  7, 15,  6, 26, 19, 12,  1, 40, 51, 30, 36, 46, 54, 29, 39,
203       50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
204   /**
205    * Weak keys (parity adjusted): If all the bits in each half are either 0
206    * or 1, then the key used for any cycle of the algorithm is the same as
207    * all other cycles.
208    */
209   public static final byte[][] WEAK_KEYS = {
210       Util.toBytesFromString("0101010101010101"),
211       Util.toBytesFromString("01010101FEFEFEFE"),
212       Util.toBytesFromString("FEFEFEFE01010101"),
213       Util.toBytesFromString("FEFEFEFEFEFEFEFE") };
214   /**
215    * Semi-weak keys (parity adjusted):  Some pairs of keys encrypt plain text
216    * to identical cipher text. In other words, one key in the pair can decrypt
217    * messages that were encrypted with the other key. These keys are called
218    * semi-weak keys. This occurs because instead of 16 different sub-keys being
219    * generated, these semi-weak keys produce only two different sub-keys.
220    */
221   public static final byte[][] SEMIWEAK_KEYS = {
222       Util.toBytesFromString("01FE01FE01FE01FE"),
223       Util.toBytesFromString("FE01FE01FE01FE01"),
224       Util.toBytesFromString("1FE01FE00EF10EF1"),
225       Util.toBytesFromString("E01FE01FF10EF10E"),
226       Util.toBytesFromString("01E001E001F101F1"),
227       Util.toBytesFromString("E001E001F101F101"),
228       Util.toBytesFromString("1FFE1FFE0EFE0EFE"),
229       Util.toBytesFromString("FE1FFE1FFE0EFE0E"),
230       Util.toBytesFromString("011F011F010E010E"),
231       Util.toBytesFromString("1F011F010E010E01"),
232       Util.toBytesFromString("E0FEE0FEF1FEF1FE"),
233       Util.toBytesFromString("FEE0FEE0FEF1FEF1") };
234   /** Possible weak keys (parity adjusted) --produce 4 instead of 16 subkeys. */
235   public static final byte[][] POSSIBLE_WEAK_KEYS = {
236       Util.toBytesFromString("1F1F01010E0E0101"),
237       Util.toBytesFromString("011F1F01010E0E01"),
238       Util.toBytesFromString("1F01011F0E01010E"),
239       Util.toBytesFromString("01011F1F01010E0E"),
240       Util.toBytesFromString("E0E00101F1F10101"),
241       Util.toBytesFromString("FEFE0101FEFE0101"),
242       Util.toBytesFromString("FEE01F01FEF10E01"),
243       Util.toBytesFromString("E0FE1F01F1FE0E01"),
244       Util.toBytesFromString("FEE0011FFEF1010E"),
245       Util.toBytesFromString("E0FE011FF1FE010E"),
246       Util.toBytesFromString("E0E01F1FF1F10E0E"),
247       Util.toBytesFromString("FEFE1F1FFEFE0E0E"),
248       Util.toBytesFromString("1F1F01010E0E0101"),
249       Util.toBytesFromString("011F1F01010E0E01"),
250       Util.toBytesFromString("1F01011F0E01010E"),
251       Util.toBytesFromString("01011F1F01010E0E"),
252       Util.toBytesFromString("01E0E00101F1F101"),
253       Util.toBytesFromString("1FFEE0010EFEF001"),
254       Util.toBytesFromString("1FE0FE010EF1FE01"),
255       Util.toBytesFromString("01FEFE0101FEFE01"),
256       Util.toBytesFromString("1FE0E01F0EF1F10E"),
257       Util.toBytesFromString("01FEE01F01FEF10E"),
258       Util.toBytesFromString("01E0FE1F01F1FE0E"),
259       Util.toBytesFromString("1FFEFE1F0EFEFE0E"),
260 
261       Util.toBytesFromString("E00101E0F10101F1"),
262       Util.toBytesFromString("FE1F01E0FE0E0EF1"),
263       Util.toBytesFromString("FE011FE0FE010EF1"),
264       Util.toBytesFromString("E01F1FE0F10E0EF1"),
265       Util.toBytesFromString("FE0101FEFE0101FE"),
266       Util.toBytesFromString("E01F01FEF10E01FE"),
267       Util.toBytesFromString("E0011FFEF1010EFE"),
268       Util.toBytesFromString("FE1F1FFEFE0E0EFE"),
269       Util.toBytesFromString("1FFE01E00EFE01F1"),
270       Util.toBytesFromString("01FE1FE001FE0EF1"),
271       Util.toBytesFromString("1FE001FE0EF101FE"),
272       Util.toBytesFromString("01E01FFE01F10EFE"),
273       Util.toBytesFromString("0101E0E00101F1F1"),
274       Util.toBytesFromString("1F1FE0E00E0EF1F1"),
275       Util.toBytesFromString("1F01FEE00E01FEF1"),
276       Util.toBytesFromString("011FFEE0010EFEF1"),
277       Util.toBytesFromString("1F01E0FE0E01F1FE"),
278       Util.toBytesFromString("011FE0FE010EF1FE"),
279       Util.toBytesFromString("0101FEFE0001FEFE"),
280       Util.toBytesFromString("1F1FFEFE0E0EFEFE"),
281       Util.toBytesFromString("FEFEE0E0FEFEF1F1"),
282       Util.toBytesFromString("E0FEFEE0F1FEFEF1"),
283       Util.toBytesFromString("FEE0E0FEFEF1F1FE"),
284       Util.toBytesFromString("E0E0FEFEF1F1FEFE") };
285 
286   /** Default 0-argument constructor. */
DES()287   public DES()
288   {
289     super(Registry.DES_CIPHER, BLOCK_SIZE, KEY_SIZE);
290   }
291 
292   /**
293    * Adjust the parity for a raw key array. This essentially means that each
294    * byte in the array will have an odd number of '1' bits (the last bit in
295    * each byte is unused.
296    *
297    * @param kb The key array, to be parity-adjusted.
298    * @param offset The starting index into the key bytes.
299    */
adjustParity(byte[] kb, int offset)300   public static void adjustParity(byte[] kb, int offset)
301   {
302     for (int i = offset; i < offset + KEY_SIZE; i++)
303       kb[i] ^= (PARITY[kb[i] & 0xff] == 8) ? 1 : 0;
304   }
305 
306   /**
307    * Test if a byte array, which must be at least 8 bytes long, is parity
308    * adjusted.
309    *
310    * @param kb The key bytes.
311    * @param offset The starting index into the key bytes.
312    * @return <code>true</code> if the first 8 bytes of <i>kb</i> have been
313    * parity adjusted. <code>false</code> otherwise.
314    */
isParityAdjusted(byte[] kb, int offset)315   public static boolean isParityAdjusted(byte[] kb, int offset)
316   {
317     int w = 0x88888888;
318     int n = PARITY[kb[offset + 0] & 0xff];
319     n <<= 4;
320     n |= PARITY[kb[offset + 1] & 0xff];
321     n <<= 4;
322     n |= PARITY[kb[offset + 2] & 0xff];
323     n <<= 4;
324     n |= PARITY[kb[offset + 3] & 0xff];
325     n <<= 4;
326     n |= PARITY[kb[offset + 4] & 0xff];
327     n <<= 4;
328     n |= PARITY[kb[offset + 5] & 0xff];
329     n <<= 4;
330     n |= PARITY[kb[offset + 6] & 0xff];
331     n <<= 4;
332     n |= PARITY[kb[offset + 7] & 0xff];
333     return (n & w) == 0;
334   }
335 
336   /**
337    * Test if a key is a weak key.
338    *
339    * @param kb The key to test.
340    * @return <code>true</code> if the key is weak.
341    */
isWeak(byte[] kb)342   public static boolean isWeak(byte[] kb)
343   {
344     for (int i = 0; i < WEAK_KEYS.length; i++)
345       if (Arrays.equals(WEAK_KEYS[i], kb))
346         return true;
347     return false;
348   }
349 
350   /**
351    * Test if a key is a semi-weak key.
352    *
353    * @param kb The key to test.
354    * @return <code>true</code> if this key is semi-weak.
355    */
isSemiWeak(byte[] kb)356   public static boolean isSemiWeak(byte[] kb)
357   {
358     for (int i = 0; i < SEMIWEAK_KEYS.length; i++)
359       if (Arrays.equals(SEMIWEAK_KEYS[i], kb))
360         return true;
361     return false;
362   }
363 
364   /**
365    * Test if the designated byte array represents a possibly weak key.
366    *
367    * @param kb the byte array to test.
368    * @return <code>true</code> if <code>kb</code>represents a possibly weak key.
369    * Returns <code>false</code> otherwise.
370    */
isPossibleWeak(byte[] kb)371   public static boolean isPossibleWeak(byte[] kb)
372   {
373     for (int i = 0; i < POSSIBLE_WEAK_KEYS.length; i++)
374       if (Arrays.equals(POSSIBLE_WEAK_KEYS[i], kb))
375         return true;
376     return false;
377   }
378 
379   /**
380    * The core DES function. This is used for both encryption and decryption,
381    * the only difference being the key.
382    *
383    * @param in The input bytes.
384    * @param i The starting offset into the input bytes.
385    * @param out The output bytes.
386    * @param o The starting offset into the output bytes.
387    * @param key The working key.
388    */
desFunc(byte[] in, int i, byte[] out, int o, int[] key)389   private static void desFunc(byte[] in, int i, byte[] out, int o, int[] key)
390   {
391     int right, left, work;
392     // Load.
393     left =  (in[i++] & 0xff) << 24
394           | (in[i++] & 0xff) << 16
395           | (in[i++] & 0xff) << 8
396           |  in[i++] & 0xff;
397     right = (in[i++] & 0xff) << 24
398           | (in[i++] & 0xff) << 16
399           | (in[i++] & 0xff) << 8
400           |  in[i  ] & 0xff;
401     // Initial permutation.
402     work = ((left >>> 4) ^ right) & 0x0F0F0F0F;
403     left ^= work << 4;
404     right ^= work;
405 
406     work = ((left >>> 16) ^ right) & 0x0000FFFF;
407     left ^= work << 16;
408     right ^= work;
409 
410     work = ((right >>> 2) ^ left) & 0x33333333;
411     right ^= work << 2;
412     left ^= work;
413 
414     work = ((right >>> 8) ^ left) & 0x00FF00FF;
415     right ^= work << 8;
416     left ^= work;
417 
418     right = ((right << 1) | ((right >>> 31) & 1)) & 0xFFFFFFFF;
419     work = (left ^ right) & 0xAAAAAAAA;
420     left ^= work;
421     right ^= work;
422     left = ((left << 1) | ((left >>> 31) & 1)) & 0xFFFFFFFF;
423 
424     int k = 0, t;
425     for (int round = 0; round < 8; round++)
426       {
427         work = right >>> 4 | right << 28;
428         work ^= key[k++];
429         t = SP7[work & 0x3F];
430         work >>>= 8;
431         t |= SP5[work & 0x3F];
432         work >>>= 8;
433         t |= SP3[work & 0x3F];
434         work >>>= 8;
435         t |= SP1[work & 0x3F];
436         work = right ^ key[k++];
437         t |= SP8[work & 0x3F];
438         work >>>= 8;
439         t |= SP6[work & 0x3F];
440         work >>>= 8;
441         t |= SP4[work & 0x3F];
442         work >>>= 8;
443         t |= SP2[work & 0x3F];
444         left ^= t;
445 
446         work = left >>> 4 | left << 28;
447         work ^= key[k++];
448         t = SP7[work & 0x3F];
449         work >>>= 8;
450         t |= SP5[work & 0x3F];
451         work >>>= 8;
452         t |= SP3[work & 0x3F];
453         work >>>= 8;
454         t |= SP1[work & 0x3F];
455         work = left ^ key[k++];
456         t |= SP8[work & 0x3F];
457         work >>>= 8;
458         t |= SP6[work & 0x3F];
459         work >>>= 8;
460         t |= SP4[work & 0x3F];
461         work >>>= 8;
462         t |= SP2[work & 0x3F];
463         right ^= t;
464       }
465     // The final permutation.
466     right = (right << 31) | (right >>> 1);
467     work = (left ^ right) & 0xAAAAAAAA;
468     left ^= work;
469     right ^= work;
470     left = (left << 31) | (left >>> 1);
471 
472     work = ((left >>> 8) ^ right) & 0x00FF00FF;
473     left ^= work << 8;
474     right ^= work;
475 
476     work = ((left >>> 2) ^ right) & 0x33333333;
477     left ^= work << 2;
478     right ^= work;
479 
480     work = ((right >>> 16) ^ left) & 0x0000FFFF;
481     right ^= work << 16;
482     left ^= work;
483 
484     work = ((right >>> 4) ^ left) & 0x0F0F0F0F;
485     right ^= work << 4;
486     left ^= work;
487 
488     out[o++] = (byte)(right >>> 24);
489     out[o++] = (byte)(right >>> 16);
490     out[o++] = (byte)(right >>> 8);
491     out[o++] = (byte) right;
492     out[o++] = (byte)(left >>> 24);
493     out[o++] = (byte)(left >>> 16);
494     out[o++] = (byte)(left >>> 8);
495     out[o  ] = (byte) left;
496   }
497 
clone()498   public Object clone()
499   {
500     return new DES();
501   }
502 
blockSizes()503   public Iterator blockSizes()
504   {
505     return Collections.singleton(Integer.valueOf(BLOCK_SIZE)).iterator();
506   }
507 
keySizes()508   public Iterator keySizes()
509   {
510     return Collections.singleton(Integer.valueOf(KEY_SIZE)).iterator();
511   }
512 
makeKey(byte[] kb, int bs)513   public Object makeKey(byte[] kb, int bs) throws InvalidKeyException
514   {
515     if (kb == null || kb.length != KEY_SIZE)
516       throw new InvalidKeyException("DES keys must be 8 bytes long");
517 
518     if (Properties.checkForWeakKeys()
519         && (isWeak(kb) || isSemiWeak(kb) || isPossibleWeak(kb)))
520       throw new WeakKeyException();
521 
522     int i, j, l, m, n;
523     long pc1m = 0, pcr = 0;
524 
525     for (i = 0; i < 56; i++)
526       {
527         l = PC1[i];
528         pc1m |= ((kb[l >>> 3] & (0x80 >>> (l & 7))) != 0) ? (1L << (55 - i))
529                                                           : 0;
530       }
531     Context ctx = new Context();
532     // Encryption key first.
533     for (i = 0; i < 16; i++)
534       {
535         pcr = 0;
536         m = i << 1;
537         n = m + 1;
538         for (j = 0; j < 28; j++)
539           {
540             l = j + ROTARS[i];
541             if (l < 28)
542               pcr |= ((pc1m & 1L << (55 - l)) != 0) ? (1L << (55 - j)) : 0;
543             else
544               pcr |= ((pc1m & 1L << (55 - (l - 28))) != 0) ? (1L << (55 - j))
545                                                            : 0;
546           }
547         for (j = 28; j < 56; j++)
548           {
549             l = j + ROTARS[i];
550             if (l < 56)
551               pcr |= ((pc1m & 1L << (55 - l)) != 0) ? (1L << (55 - j)) : 0;
552             else
553               pcr |= ((pc1m & 1L << (55 - (l - 28))) != 0) ? (1L << (55 - j))
554                                                            : 0;
555           }
556         for (j = 0; j < 24; j++)
557           {
558             if ((pcr & 1L << (55 - PC2[j])) != 0)
559               ctx.ek[m] |= 1 << (23 - j);
560             if ((pcr & 1L << (55 - PC2[j + 24])) != 0)
561               ctx.ek[n] |= 1 << (23 - j);
562           }
563       }
564     // The decryption key is the same, but in reversed order.
565     for (i = 0; i < Context.EXPANDED_KEY_SIZE; i += 2)
566       {
567         ctx.dk[30 - i] = ctx.ek[i];
568         ctx.dk[31 - i] = ctx.ek[i + 1];
569       }
570     // "Cook" the keys.
571     for (i = 0; i < 32; i += 2)
572       {
573         int x, y;
574         x = ctx.ek[i];
575         y = ctx.ek[i + 1];
576         ctx.ek[i    ] = ((x & 0x00FC0000)  <<  6)
577                       | ((x & 0x00000FC0)  << 10)
578                       | ((y & 0x00FC0000) >>> 10)
579                       | ((y & 0x00000FC0) >>>  6);
580         ctx.ek[i + 1] = ((x & 0x0003F000)  << 12)
581                       | ((x & 0x0000003F)  << 16)
582                       | ((y & 0x0003F000) >>>  4)
583                       |  (y & 0x0000003F);
584         x = ctx.dk[i];
585         y = ctx.dk[i + 1];
586         ctx.dk[i    ] = ((x & 0x00FC0000)  <<  6)
587                       | ((x & 0x00000FC0)  << 10)
588                       | ((y & 0x00FC0000) >>> 10)
589                       | ((y & 0x00000FC0) >>>  6);
590         ctx.dk[i + 1] = ((x & 0x0003F000)  << 12)
591                       | ((x & 0x0000003F)  << 16)
592                       | ((y & 0x0003F000) >>>  4)
593                       |  (y & 0x0000003F);
594       }
595     return ctx;
596   }
597 
encrypt(byte[] in, int i, byte[] out, int o, Object K, int bs)598   public void encrypt(byte[] in, int i, byte[] out, int o, Object K, int bs)
599   {
600     desFunc(in, i, out, o, ((Context) K).ek);
601   }
602 
decrypt(byte[] in, int i, byte[] out, int o, Object K, int bs)603   public void decrypt(byte[] in, int i, byte[] out, int o, Object K, int bs)
604   {
605     desFunc(in, i, out, o, ((Context) K).dk);
606   }
607 
608   /**
609    * Simple wrapper class around the session keys. Package-private so TripleDES
610    * can see it.
611    */
612   final class Context
613   {
614     private static final int EXPANDED_KEY_SIZE = 32;
615 
616     /** The encryption key. */
617     int[] ek;
618 
619     /** The decryption key. */
620     int[] dk;
621 
622     /** Default 0-arguments constructor. */
Context()623     Context()
624     {
625       ek = new int[EXPANDED_KEY_SIZE];
626       dk = new int[EXPANDED_KEY_SIZE];
627     }
628 
getEncryptionKeyBytes()629     byte[] getEncryptionKeyBytes()
630     {
631       return toByteArray(ek);
632     }
633 
getDecryptionKeyBytes()634     byte[] getDecryptionKeyBytes()
635     {
636       return toByteArray(dk);
637     }
638 
toByteArray(int[] k)639     byte[] toByteArray(int[] k)
640     {
641       byte[] result = new byte[4 * k.length];
642       for (int i = 0, j = 0; i < k.length; i++)
643         {
644           result[j++] = (byte)(k[i] >>> 24);
645           result[j++] = (byte)(k[i] >>> 16);
646           result[j++] = (byte)(k[i] >>> 8);
647           result[j++] = (byte) k[i];
648         }
649       return result;
650     }
651   }
652 }
653