DESEngine.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
1package org.bouncycastle.crypto.engines; 2 3import org.bouncycastle.crypto.BlockCipher; 4import org.bouncycastle.crypto.CipherParameters; 5import org.bouncycastle.crypto.DataLengthException; 6import org.bouncycastle.crypto.params.KeyParameter; 7 8/** 9 * a class that provides a basic DES engine. 10 */ 11public class DESEngine 12 implements BlockCipher 13{ 14 protected static final int BLOCK_SIZE = 8; 15 16 private int[] workingKey = null; 17 18 /** 19 * standard constructor. 20 */ 21 public DESEngine() 22 { 23 } 24 25 /** 26 * initialise a DES cipher. 27 * 28 * @param encrypting whether or not we are for encryption. 29 * @param params the parameters required to set up the cipher. 30 * @exception IllegalArgumentException if the params argument is 31 * inappropriate. 32 */ 33 public void init( 34 boolean encrypting, 35 CipherParameters params) 36 { 37 if (params instanceof KeyParameter) 38 { 39 if (((KeyParameter)params).getKey().length > 8) 40 { 41 throw new IllegalArgumentException("DES key too long - should be 8 bytes"); 42 } 43 44 workingKey = generateWorkingKey(encrypting, 45 ((KeyParameter)params).getKey()); 46 47 return; 48 } 49 50 throw new IllegalArgumentException("invalid parameter passed to DES init - " + params.getClass().getName()); 51 } 52 53 public String getAlgorithmName() 54 { 55 return "DES"; 56 } 57 58 public int getBlockSize() 59 { 60 return BLOCK_SIZE; 61 } 62 63 public int processBlock( 64 byte[] in, 65 int inOff, 66 byte[] out, 67 int outOff) 68 { 69 if (workingKey == null) 70 { 71 throw new IllegalStateException("DES engine not initialised"); 72 } 73 74 if ((inOff + BLOCK_SIZE) > in.length) 75 { 76 throw new DataLengthException("input buffer too short"); 77 } 78 79 if ((outOff + BLOCK_SIZE) > out.length) 80 { 81 throw new DataLengthException("output buffer too short"); 82 } 83 84 desFunc(workingKey, in, inOff, out, outOff); 85 86 return BLOCK_SIZE; 87 } 88 89 public void reset() 90 { 91 } 92 93 /** 94 * what follows is mainly taken from "Applied Cryptography", by 95 * Bruce Schneier, however it also bears great resemblance to Richard 96 * Outerbridge's D3DES... 97 */ 98 99// private static final short[] Df_Key = 100// { 101// 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 102// 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, 103// 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 104// }; 105 106 private static final short[] bytebit = 107 { 108 0200, 0100, 040, 020, 010, 04, 02, 01 109 }; 110 111 private static final int[] bigbyte = 112 { 113 0x800000, 0x400000, 0x200000, 0x100000, 114 0x80000, 0x40000, 0x20000, 0x10000, 115 0x8000, 0x4000, 0x2000, 0x1000, 116 0x800, 0x400, 0x200, 0x100, 117 0x80, 0x40, 0x20, 0x10, 118 0x8, 0x4, 0x2, 0x1 119 }; 120 121 /* 122 * Use the key schedule specified in the Standard (ANSI X3.92-1981). 123 */ 124 125 private static final byte[] pc1 = 126 { 127 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 128 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 129 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 130 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 131 }; 132 133 private static final byte[] totrot = 134 { 135 1, 2, 4, 6, 8, 10, 12, 14, 136 15, 17, 19, 21, 23, 25, 27, 28 137 }; 138 139 private static final byte[] pc2 = 140 { 141 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 142 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 143 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 144 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 145 }; 146 147 private static final int[] SP1 = { 148 0x01010400, 0x00000000, 0x00010000, 0x01010404, 149 0x01010004, 0x00010404, 0x00000004, 0x00010000, 150 0x00000400, 0x01010400, 0x01010404, 0x00000400, 151 0x01000404, 0x01010004, 0x01000000, 0x00000004, 152 0x00000404, 0x01000400, 0x01000400, 0x00010400, 153 0x00010400, 0x01010000, 0x01010000, 0x01000404, 154 0x00010004, 0x01000004, 0x01000004, 0x00010004, 155 0x00000000, 0x00000404, 0x00010404, 0x01000000, 156 0x00010000, 0x01010404, 0x00000004, 0x01010000, 157 0x01010400, 0x01000000, 0x01000000, 0x00000400, 158 0x01010004, 0x00010000, 0x00010400, 0x01000004, 159 0x00000400, 0x00000004, 0x01000404, 0x00010404, 160 0x01010404, 0x00010004, 0x01010000, 0x01000404, 161 0x01000004, 0x00000404, 0x00010404, 0x01010400, 162 0x00000404, 0x01000400, 0x01000400, 0x00000000, 163 0x00010004, 0x00010400, 0x00000000, 0x01010004 164 }; 165 166 private static final int[] SP2 = { 167 0x80108020, 0x80008000, 0x00008000, 0x00108020, 168 0x00100000, 0x00000020, 0x80100020, 0x80008020, 169 0x80000020, 0x80108020, 0x80108000, 0x80000000, 170 0x80008000, 0x00100000, 0x00000020, 0x80100020, 171 0x00108000, 0x00100020, 0x80008020, 0x00000000, 172 0x80000000, 0x00008000, 0x00108020, 0x80100000, 173 0x00100020, 0x80000020, 0x00000000, 0x00108000, 174 0x00008020, 0x80108000, 0x80100000, 0x00008020, 175 0x00000000, 0x00108020, 0x80100020, 0x00100000, 176 0x80008020, 0x80100000, 0x80108000, 0x00008000, 177 0x80100000, 0x80008000, 0x00000020, 0x80108020, 178 0x00108020, 0x00000020, 0x00008000, 0x80000000, 179 0x00008020, 0x80108000, 0x00100000, 0x80000020, 180 0x00100020, 0x80008020, 0x80000020, 0x00100020, 181 0x00108000, 0x00000000, 0x80008000, 0x00008020, 182 0x80000000, 0x80100020, 0x80108020, 0x00108000 183 }; 184 185 private static final int[] SP3 = { 186 0x00000208, 0x08020200, 0x00000000, 0x08020008, 187 0x08000200, 0x00000000, 0x00020208, 0x08000200, 188 0x00020008, 0x08000008, 0x08000008, 0x00020000, 189 0x08020208, 0x00020008, 0x08020000, 0x00000208, 190 0x08000000, 0x00000008, 0x08020200, 0x00000200, 191 0x00020200, 0x08020000, 0x08020008, 0x00020208, 192 0x08000208, 0x00020200, 0x00020000, 0x08000208, 193 0x00000008, 0x08020208, 0x00000200, 0x08000000, 194 0x08020200, 0x08000000, 0x00020008, 0x00000208, 195 0x00020000, 0x08020200, 0x08000200, 0x00000000, 196 0x00000200, 0x00020008, 0x08020208, 0x08000200, 197 0x08000008, 0x00000200, 0x00000000, 0x08020008, 198 0x08000208, 0x00020000, 0x08000000, 0x08020208, 199 0x00000008, 0x00020208, 0x00020200, 0x08000008, 200 0x08020000, 0x08000208, 0x00000208, 0x08020000, 201 0x00020208, 0x00000008, 0x08020008, 0x00020200 202 }; 203 204 private static final int[] SP4 = { 205 0x00802001, 0x00002081, 0x00002081, 0x00000080, 206 0x00802080, 0x00800081, 0x00800001, 0x00002001, 207 0x00000000, 0x00802000, 0x00802000, 0x00802081, 208 0x00000081, 0x00000000, 0x00800080, 0x00800001, 209 0x00000001, 0x00002000, 0x00800000, 0x00802001, 210 0x00000080, 0x00800000, 0x00002001, 0x00002080, 211 0x00800081, 0x00000001, 0x00002080, 0x00800080, 212 0x00002000, 0x00802080, 0x00802081, 0x00000081, 213 0x00800080, 0x00800001, 0x00802000, 0x00802081, 214 0x00000081, 0x00000000, 0x00000000, 0x00802000, 215 0x00002080, 0x00800080, 0x00800081, 0x00000001, 216 0x00802001, 0x00002081, 0x00002081, 0x00000080, 217 0x00802081, 0x00000081, 0x00000001, 0x00002000, 218 0x00800001, 0x00002001, 0x00802080, 0x00800081, 219 0x00002001, 0x00002080, 0x00800000, 0x00802001, 220 0x00000080, 0x00800000, 0x00002000, 0x00802080 221 }; 222 223 private static final int[] SP5 = { 224 0x00000100, 0x02080100, 0x02080000, 0x42000100, 225 0x00080000, 0x00000100, 0x40000000, 0x02080000, 226 0x40080100, 0x00080000, 0x02000100, 0x40080100, 227 0x42000100, 0x42080000, 0x00080100, 0x40000000, 228 0x02000000, 0x40080000, 0x40080000, 0x00000000, 229 0x40000100, 0x42080100, 0x42080100, 0x02000100, 230 0x42080000, 0x40000100, 0x00000000, 0x42000000, 231 0x02080100, 0x02000000, 0x42000000, 0x00080100, 232 0x00080000, 0x42000100, 0x00000100, 0x02000000, 233 0x40000000, 0x02080000, 0x42000100, 0x40080100, 234 0x02000100, 0x40000000, 0x42080000, 0x02080100, 235 0x40080100, 0x00000100, 0x02000000, 0x42080000, 236 0x42080100, 0x00080100, 0x42000000, 0x42080100, 237 0x02080000, 0x00000000, 0x40080000, 0x42000000, 238 0x00080100, 0x02000100, 0x40000100, 0x00080000, 239 0x00000000, 0x40080000, 0x02080100, 0x40000100 240 }; 241 242 private static final int[] SP6 = { 243 0x20000010, 0x20400000, 0x00004000, 0x20404010, 244 0x20400000, 0x00000010, 0x20404010, 0x00400000, 245 0x20004000, 0x00404010, 0x00400000, 0x20000010, 246 0x00400010, 0x20004000, 0x20000000, 0x00004010, 247 0x00000000, 0x00400010, 0x20004010, 0x00004000, 248 0x00404000, 0x20004010, 0x00000010, 0x20400010, 249 0x20400010, 0x00000000, 0x00404010, 0x20404000, 250 0x00004010, 0x00404000, 0x20404000, 0x20000000, 251 0x20004000, 0x00000010, 0x20400010, 0x00404000, 252 0x20404010, 0x00400000, 0x00004010, 0x20000010, 253 0x00400000, 0x20004000, 0x20000000, 0x00004010, 254 0x20000010, 0x20404010, 0x00404000, 0x20400000, 255 0x00404010, 0x20404000, 0x00000000, 0x20400010, 256 0x00000010, 0x00004000, 0x20400000, 0x00404010, 257 0x00004000, 0x00400010, 0x20004010, 0x00000000, 258 0x20404000, 0x20000000, 0x00400010, 0x20004010 259 }; 260 261 private static final int[] SP7 = { 262 0x00200000, 0x04200002, 0x04000802, 0x00000000, 263 0x00000800, 0x04000802, 0x00200802, 0x04200800, 264 0x04200802, 0x00200000, 0x00000000, 0x04000002, 265 0x00000002, 0x04000000, 0x04200002, 0x00000802, 266 0x04000800, 0x00200802, 0x00200002, 0x04000800, 267 0x04000002, 0x04200000, 0x04200800, 0x00200002, 268 0x04200000, 0x00000800, 0x00000802, 0x04200802, 269 0x00200800, 0x00000002, 0x04000000, 0x00200800, 270 0x04000000, 0x00200800, 0x00200000, 0x04000802, 271 0x04000802, 0x04200002, 0x04200002, 0x00000002, 272 0x00200002, 0x04000000, 0x04000800, 0x00200000, 273 0x04200800, 0x00000802, 0x00200802, 0x04200800, 274 0x00000802, 0x04000002, 0x04200802, 0x04200000, 275 0x00200800, 0x00000000, 0x00000002, 0x04200802, 276 0x00000000, 0x00200802, 0x04200000, 0x00000800, 277 0x04000002, 0x04000800, 0x00000800, 0x00200002 278 }; 279 280 private static final int[] SP8 = { 281 0x10001040, 0x00001000, 0x00040000, 0x10041040, 282 0x10000000, 0x10001040, 0x00000040, 0x10000000, 283 0x00040040, 0x10040000, 0x10041040, 0x00041000, 284 0x10041000, 0x00041040, 0x00001000, 0x00000040, 285 0x10040000, 0x10000040, 0x10001000, 0x00001040, 286 0x00041000, 0x00040040, 0x10040040, 0x10041000, 287 0x00001040, 0x00000000, 0x00000000, 0x10040040, 288 0x10000040, 0x10001000, 0x00041040, 0x00040000, 289 0x00041040, 0x00040000, 0x10041000, 0x00001000, 290 0x00000040, 0x10040040, 0x00001000, 0x00041040, 291 0x10001000, 0x00000040, 0x10000040, 0x10040000, 292 0x10040040, 0x10000000, 0x00040000, 0x10001040, 293 0x00000000, 0x10041040, 0x00040040, 0x10000040, 294 0x10040000, 0x10001000, 0x10001040, 0x00000000, 295 0x10041040, 0x00041000, 0x00041000, 0x00001040, 296 0x00001040, 0x00040040, 0x10000000, 0x10041000 297 }; 298 299 /** 300 * generate an integer based working key based on our secret key 301 * and what we processing we are planning to do. 302 * 303 * Acknowledgements for this routine go to James Gillogly & Phil Karn. 304 * (whoever, and wherever they are!). 305 */ 306 protected int[] generateWorkingKey( 307 boolean encrypting, 308 byte[] key) 309 { 310 int[] newKey = new int[32]; 311 boolean[] pc1m = new boolean[56], 312 pcr = new boolean[56]; 313 314 for (int j = 0; j < 56; j++) 315 { 316 int l = pc1[j]; 317 318 pc1m[j] = ((key[l >>> 3] & bytebit[l & 07]) != 0); 319 } 320 321 for (int i = 0; i < 16; i++) 322 { 323 int l, m, n; 324 325 if (encrypting) 326 { 327 m = i << 1; 328 } 329 else 330 { 331 m = (15 - i) << 1; 332 } 333 334 n = m + 1; 335 newKey[m] = newKey[n] = 0; 336 337 for (int j = 0; j < 28; j++) 338 { 339 l = j + totrot[i]; 340 if (l < 28) 341 { 342 pcr[j] = pc1m[l]; 343 } 344 else 345 { 346 pcr[j] = pc1m[l - 28]; 347 } 348 } 349 350 for (int j = 28; j < 56; j++) 351 { 352 l = j + totrot[i]; 353 if (l < 56) 354 { 355 pcr[j] = pc1m[l]; 356 } 357 else 358 { 359 pcr[j] = pc1m[l - 28]; 360 } 361 } 362 363 for (int j = 0; j < 24; j++) 364 { 365 if (pcr[pc2[j]]) 366 { 367 newKey[m] |= bigbyte[j]; 368 } 369 370 if (pcr[pc2[j + 24]]) 371 { 372 newKey[n] |= bigbyte[j]; 373 } 374 } 375 } 376 377 // 378 // store the processed key 379 // 380 for (int i = 0; i != 32; i += 2) 381 { 382 int i1, i2; 383 384 i1 = newKey[i]; 385 i2 = newKey[i + 1]; 386 387 newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10) 388 | ((i2 & 0x00fc0000) >>> 10) | ((i2 & 0x00000fc0) >>> 6); 389 390 newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16) 391 | ((i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f); 392 } 393 394 return newKey; 395 } 396 397 /** 398 * the DES engine. 399 */ 400 protected void desFunc( 401 int[] wKey, 402 byte[] in, 403 int inOff, 404 byte[] out, 405 int outOff) 406 { 407 int work, right, left; 408 409 left = (in[inOff + 0] & 0xff) << 24; 410 left |= (in[inOff + 1] & 0xff) << 16; 411 left |= (in[inOff + 2] & 0xff) << 8; 412 left |= (in[inOff + 3] & 0xff); 413 414 right = (in[inOff + 4] & 0xff) << 24; 415 right |= (in[inOff + 5] & 0xff) << 16; 416 right |= (in[inOff + 6] & 0xff) << 8; 417 right |= (in[inOff + 7] & 0xff); 418 419 work = ((left >>> 4) ^ right) & 0x0f0f0f0f; 420 right ^= work; 421 left ^= (work << 4); 422 work = ((left >>> 16) ^ right) & 0x0000ffff; 423 right ^= work; 424 left ^= (work << 16); 425 work = ((right >>> 2) ^ left) & 0x33333333; 426 left ^= work; 427 right ^= (work << 2); 428 work = ((right >>> 8) ^ left) & 0x00ff00ff; 429 left ^= work; 430 right ^= (work << 8); 431 right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff; 432 work = (left ^ right) & 0xaaaaaaaa; 433 left ^= work; 434 right ^= work; 435 left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff; 436 437 for (int round = 0; round < 8; round++) 438 { 439 int fval; 440 441 work = (right << 28) | (right >>> 4); 442 work ^= wKey[round * 4 + 0]; 443 fval = SP7[ work & 0x3f]; 444 fval |= SP5[(work >>> 8) & 0x3f]; 445 fval |= SP3[(work >>> 16) & 0x3f]; 446 fval |= SP1[(work >>> 24) & 0x3f]; 447 work = right ^ wKey[round * 4 + 1]; 448 fval |= SP8[ work & 0x3f]; 449 fval |= SP6[(work >>> 8) & 0x3f]; 450 fval |= SP4[(work >>> 16) & 0x3f]; 451 fval |= SP2[(work >>> 24) & 0x3f]; 452 left ^= fval; 453 work = (left << 28) | (left >>> 4); 454 work ^= wKey[round * 4 + 2]; 455 fval = SP7[ work & 0x3f]; 456 fval |= SP5[(work >>> 8) & 0x3f]; 457 fval |= SP3[(work >>> 16) & 0x3f]; 458 fval |= SP1[(work >>> 24) & 0x3f]; 459 work = left ^ wKey[round * 4 + 3]; 460 fval |= SP8[ work & 0x3f]; 461 fval |= SP6[(work >>> 8) & 0x3f]; 462 fval |= SP4[(work >>> 16) & 0x3f]; 463 fval |= SP2[(work >>> 24) & 0x3f]; 464 right ^= fval; 465 } 466 467 right = (right << 31) | (right >>> 1); 468 work = (left ^ right) & 0xaaaaaaaa; 469 left ^= work; 470 right ^= work; 471 left = (left << 31) | (left >>> 1); 472 work = ((left >>> 8) ^ right) & 0x00ff00ff; 473 right ^= work; 474 left ^= (work << 8); 475 work = ((left >>> 2) ^ right) & 0x33333333; 476 right ^= work; 477 left ^= (work << 2); 478 work = ((right >>> 16) ^ left) & 0x0000ffff; 479 left ^= work; 480 right ^= (work << 16); 481 work = ((right >>> 4) ^ left) & 0x0f0f0f0f; 482 left ^= work; 483 right ^= (work << 4); 484 485 out[outOff + 0] = (byte)((right >>> 24) & 0xff); 486 out[outOff + 1] = (byte)((right >>> 16) & 0xff); 487 out[outOff + 2] = (byte)((right >>> 8) & 0xff); 488 out[outOff + 3] = (byte)(right & 0xff); 489 out[outOff + 4] = (byte)((left >>> 24) & 0xff); 490 out[outOff + 5] = (byte)((left >>> 16) & 0xff); 491 out[outOff + 6] = (byte)((left >>> 8) & 0xff); 492 out[outOff + 7] = (byte)(left & 0xff); 493 } 494} 495