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