1 package org.bouncycastle.crypto.engines; 2 3 import org.bouncycastle.crypto.BlockCipher; 4 import org.bouncycastle.crypto.CipherParameters; 5 import org.bouncycastle.crypto.DataLengthException; 6 import org.bouncycastle.crypto.OutputLengthException; 7 import org.bouncycastle.crypto.params.KeyParameter; 8 9 /** 10 * A class that provides Twofish encryption operations. 11 * 12 * This Java implementation is based on the Java reference 13 * implementation provided by Bruce Schneier and developed 14 * by Raif S. Naffah. 15 */ 16 public final class TwofishEngine 17 implements BlockCipher 18 { 19 private static final byte[][] P = { 20 { // p0 21 (byte) 0xA9, (byte) 0x67, (byte) 0xB3, (byte) 0xE8, 22 (byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76, 23 (byte) 0x9A, (byte) 0x92, (byte) 0x80, (byte) 0x78, 24 (byte) 0xE4, (byte) 0xDD, (byte) 0xD1, (byte) 0x38, 25 (byte) 0x0D, (byte) 0xC6, (byte) 0x35, (byte) 0x98, 26 (byte) 0x18, (byte) 0xF7, (byte) 0xEC, (byte) 0x6C, 27 (byte) 0x43, (byte) 0x75, (byte) 0x37, (byte) 0x26, 28 (byte) 0xFA, (byte) 0x13, (byte) 0x94, (byte) 0x48, 29 (byte) 0xF2, (byte) 0xD0, (byte) 0x8B, (byte) 0x30, 30 (byte) 0x84, (byte) 0x54, (byte) 0xDF, (byte) 0x23, 31 (byte) 0x19, (byte) 0x5B, (byte) 0x3D, (byte) 0x59, 32 (byte) 0xF3, (byte) 0xAE, (byte) 0xA2, (byte) 0x82, 33 (byte) 0x63, (byte) 0x01, (byte) 0x83, (byte) 0x2E, 34 (byte) 0xD9, (byte) 0x51, (byte) 0x9B, (byte) 0x7C, 35 (byte) 0xA6, (byte) 0xEB, (byte) 0xA5, (byte) 0xBE, 36 (byte) 0x16, (byte) 0x0C, (byte) 0xE3, (byte) 0x61, 37 (byte) 0xC0, (byte) 0x8C, (byte) 0x3A, (byte) 0xF5, 38 (byte) 0x73, (byte) 0x2C, (byte) 0x25, (byte) 0x0B, 39 (byte) 0xBB, (byte) 0x4E, (byte) 0x89, (byte) 0x6B, 40 (byte) 0x53, (byte) 0x6A, (byte) 0xB4, (byte) 0xF1, 41 (byte) 0xE1, (byte) 0xE6, (byte) 0xBD, (byte) 0x45, 42 (byte) 0xE2, (byte) 0xF4, (byte) 0xB6, (byte) 0x66, 43 (byte) 0xCC, (byte) 0x95, (byte) 0x03, (byte) 0x56, 44 (byte) 0xD4, (byte) 0x1C, (byte) 0x1E, (byte) 0xD7, 45 (byte) 0xFB, (byte) 0xC3, (byte) 0x8E, (byte) 0xB5, 46 (byte) 0xE9, (byte) 0xCF, (byte) 0xBF, (byte) 0xBA, 47 (byte) 0xEA, (byte) 0x77, (byte) 0x39, (byte) 0xAF, 48 (byte) 0x33, (byte) 0xC9, (byte) 0x62, (byte) 0x71, 49 (byte) 0x81, (byte) 0x79, (byte) 0x09, (byte) 0xAD, 50 (byte) 0x24, (byte) 0xCD, (byte) 0xF9, (byte) 0xD8, 51 (byte) 0xE5, (byte) 0xC5, (byte) 0xB9, (byte) 0x4D, 52 (byte) 0x44, (byte) 0x08, (byte) 0x86, (byte) 0xE7, 53 (byte) 0xA1, (byte) 0x1D, (byte) 0xAA, (byte) 0xED, 54 (byte) 0x06, (byte) 0x70, (byte) 0xB2, (byte) 0xD2, 55 (byte) 0x41, (byte) 0x7B, (byte) 0xA0, (byte) 0x11, 56 (byte) 0x31, (byte) 0xC2, (byte) 0x27, (byte) 0x90, 57 (byte) 0x20, (byte) 0xF6, (byte) 0x60, (byte) 0xFF, 58 (byte) 0x96, (byte) 0x5C, (byte) 0xB1, (byte) 0xAB, 59 (byte) 0x9E, (byte) 0x9C, (byte) 0x52, (byte) 0x1B, 60 (byte) 0x5F, (byte) 0x93, (byte) 0x0A, (byte) 0xEF, 61 (byte) 0x91, (byte) 0x85, (byte) 0x49, (byte) 0xEE, 62 (byte) 0x2D, (byte) 0x4F, (byte) 0x8F, (byte) 0x3B, 63 (byte) 0x47, (byte) 0x87, (byte) 0x6D, (byte) 0x46, 64 (byte) 0xD6, (byte) 0x3E, (byte) 0x69, (byte) 0x64, 65 (byte) 0x2A, (byte) 0xCE, (byte) 0xCB, (byte) 0x2F, 66 (byte) 0xFC, (byte) 0x97, (byte) 0x05, (byte) 0x7A, 67 (byte) 0xAC, (byte) 0x7F, (byte) 0xD5, (byte) 0x1A, 68 (byte) 0x4B, (byte) 0x0E, (byte) 0xA7, (byte) 0x5A, 69 (byte) 0x28, (byte) 0x14, (byte) 0x3F, (byte) 0x29, 70 (byte) 0x88, (byte) 0x3C, (byte) 0x4C, (byte) 0x02, 71 (byte) 0xB8, (byte) 0xDA, (byte) 0xB0, (byte) 0x17, 72 (byte) 0x55, (byte) 0x1F, (byte) 0x8A, (byte) 0x7D, 73 (byte) 0x57, (byte) 0xC7, (byte) 0x8D, (byte) 0x74, 74 (byte) 0xB7, (byte) 0xC4, (byte) 0x9F, (byte) 0x72, 75 (byte) 0x7E, (byte) 0x15, (byte) 0x22, (byte) 0x12, 76 (byte) 0x58, (byte) 0x07, (byte) 0x99, (byte) 0x34, 77 (byte) 0x6E, (byte) 0x50, (byte) 0xDE, (byte) 0x68, 78 (byte) 0x65, (byte) 0xBC, (byte) 0xDB, (byte) 0xF8, 79 (byte) 0xC8, (byte) 0xA8, (byte) 0x2B, (byte) 0x40, 80 (byte) 0xDC, (byte) 0xFE, (byte) 0x32, (byte) 0xA4, 81 (byte) 0xCA, (byte) 0x10, (byte) 0x21, (byte) 0xF0, 82 (byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00, 83 (byte) 0x6F, (byte) 0x9D, (byte) 0x36, (byte) 0x42, 84 (byte) 0x4A, (byte) 0x5E, (byte) 0xC1, (byte) 0xE0 }, 85 { // p1 86 (byte) 0x75, (byte) 0xF3, (byte) 0xC6, (byte) 0xF4, 87 (byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8, 88 (byte) 0x4A, (byte) 0xD3, (byte) 0xE6, (byte) 0x6B, 89 (byte) 0x45, (byte) 0x7D, (byte) 0xE8, (byte) 0x4B, 90 (byte) 0xD6, (byte) 0x32, (byte) 0xD8, (byte) 0xFD, 91 (byte) 0x37, (byte) 0x71, (byte) 0xF1, (byte) 0xE1, 92 (byte) 0x30, (byte) 0x0F, (byte) 0xF8, (byte) 0x1B, 93 (byte) 0x87, (byte) 0xFA, (byte) 0x06, (byte) 0x3F, 94 (byte) 0x5E, (byte) 0xBA, (byte) 0xAE, (byte) 0x5B, 95 (byte) 0x8A, (byte) 0x00, (byte) 0xBC, (byte) 0x9D, 96 (byte) 0x6D, (byte) 0xC1, (byte) 0xB1, (byte) 0x0E, 97 (byte) 0x80, (byte) 0x5D, (byte) 0xD2, (byte) 0xD5, 98 (byte) 0xA0, (byte) 0x84, (byte) 0x07, (byte) 0x14, 99 (byte) 0xB5, (byte) 0x90, (byte) 0x2C, (byte) 0xA3, 100 (byte) 0xB2, (byte) 0x73, (byte) 0x4C, (byte) 0x54, 101 (byte) 0x92, (byte) 0x74, (byte) 0x36, (byte) 0x51, 102 (byte) 0x38, (byte) 0xB0, (byte) 0xBD, (byte) 0x5A, 103 (byte) 0xFC, (byte) 0x60, (byte) 0x62, (byte) 0x96, 104 (byte) 0x6C, (byte) 0x42, (byte) 0xF7, (byte) 0x10, 105 (byte) 0x7C, (byte) 0x28, (byte) 0x27, (byte) 0x8C, 106 (byte) 0x13, (byte) 0x95, (byte) 0x9C, (byte) 0xC7, 107 (byte) 0x24, (byte) 0x46, (byte) 0x3B, (byte) 0x70, 108 (byte) 0xCA, (byte) 0xE3, (byte) 0x85, (byte) 0xCB, 109 (byte) 0x11, (byte) 0xD0, (byte) 0x93, (byte) 0xB8, 110 (byte) 0xA6, (byte) 0x83, (byte) 0x20, (byte) 0xFF, 111 (byte) 0x9F, (byte) 0x77, (byte) 0xC3, (byte) 0xCC, 112 (byte) 0x03, (byte) 0x6F, (byte) 0x08, (byte) 0xBF, 113 (byte) 0x40, (byte) 0xE7, (byte) 0x2B, (byte) 0xE2, 114 (byte) 0x79, (byte) 0x0C, (byte) 0xAA, (byte) 0x82, 115 (byte) 0x41, (byte) 0x3A, (byte) 0xEA, (byte) 0xB9, 116 (byte) 0xE4, (byte) 0x9A, (byte) 0xA4, (byte) 0x97, 117 (byte) 0x7E, (byte) 0xDA, (byte) 0x7A, (byte) 0x17, 118 (byte) 0x66, (byte) 0x94, (byte) 0xA1, (byte) 0x1D, 119 (byte) 0x3D, (byte) 0xF0, (byte) 0xDE, (byte) 0xB3, 120 (byte) 0x0B, (byte) 0x72, (byte) 0xA7, (byte) 0x1C, 121 (byte) 0xEF, (byte) 0xD1, (byte) 0x53, (byte) 0x3E, 122 (byte) 0x8F, (byte) 0x33, (byte) 0x26, (byte) 0x5F, 123 (byte) 0xEC, (byte) 0x76, (byte) 0x2A, (byte) 0x49, 124 (byte) 0x81, (byte) 0x88, (byte) 0xEE, (byte) 0x21, 125 (byte) 0xC4, (byte) 0x1A, (byte) 0xEB, (byte) 0xD9, 126 (byte) 0xC5, (byte) 0x39, (byte) 0x99, (byte) 0xCD, 127 (byte) 0xAD, (byte) 0x31, (byte) 0x8B, (byte) 0x01, 128 (byte) 0x18, (byte) 0x23, (byte) 0xDD, (byte) 0x1F, 129 (byte) 0x4E, (byte) 0x2D, (byte) 0xF9, (byte) 0x48, 130 (byte) 0x4F, (byte) 0xF2, (byte) 0x65, (byte) 0x8E, 131 (byte) 0x78, (byte) 0x5C, (byte) 0x58, (byte) 0x19, 132 (byte) 0x8D, (byte) 0xE5, (byte) 0x98, (byte) 0x57, 133 (byte) 0x67, (byte) 0x7F, (byte) 0x05, (byte) 0x64, 134 (byte) 0xAF, (byte) 0x63, (byte) 0xB6, (byte) 0xFE, 135 (byte) 0xF5, (byte) 0xB7, (byte) 0x3C, (byte) 0xA5, 136 (byte) 0xCE, (byte) 0xE9, (byte) 0x68, (byte) 0x44, 137 (byte) 0xE0, (byte) 0x4D, (byte) 0x43, (byte) 0x69, 138 (byte) 0x29, (byte) 0x2E, (byte) 0xAC, (byte) 0x15, 139 (byte) 0x59, (byte) 0xA8, (byte) 0x0A, (byte) 0x9E, 140 (byte) 0x6E, (byte) 0x47, (byte) 0xDF, (byte) 0x34, 141 (byte) 0x35, (byte) 0x6A, (byte) 0xCF, (byte) 0xDC, 142 (byte) 0x22, (byte) 0xC9, (byte) 0xC0, (byte) 0x9B, 143 (byte) 0x89, (byte) 0xD4, (byte) 0xED, (byte) 0xAB, 144 (byte) 0x12, (byte) 0xA2, (byte) 0x0D, (byte) 0x52, 145 (byte) 0xBB, (byte) 0x02, (byte) 0x2F, (byte) 0xA9, 146 (byte) 0xD7, (byte) 0x61, (byte) 0x1E, (byte) 0xB4, 147 (byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2, 148 (byte) 0x16, (byte) 0x25, (byte) 0x86, (byte) 0x56, 149 (byte) 0x55, (byte) 0x09, (byte) 0xBE, (byte) 0x91 } 150 }; 151 152 /** 153 * Define the fixed p0/p1 permutations used in keyed S-box lookup. 154 * By changing the following constant definitions, the S-boxes will 155 * automatically get changed in the Twofish engine. 156 */ 157 private static final int P_00 = 1; 158 private static final int P_01 = 0; 159 private static final int P_02 = 0; 160 private static final int P_03 = P_01 ^ 1; 161 private static final int P_04 = 1; 162 163 private static final int P_10 = 0; 164 private static final int P_11 = 0; 165 private static final int P_12 = 1; 166 private static final int P_13 = P_11 ^ 1; 167 private static final int P_14 = 0; 168 169 private static final int P_20 = 1; 170 private static final int P_21 = 1; 171 private static final int P_22 = 0; 172 private static final int P_23 = P_21 ^ 1; 173 private static final int P_24 = 0; 174 175 private static final int P_30 = 0; 176 private static final int P_31 = 1; 177 private static final int P_32 = 1; 178 private static final int P_33 = P_31 ^ 1; 179 private static final int P_34 = 1; 180 181 /* Primitive polynomial for GF(256) */ 182 private static final int GF256_FDBK = 0x169; 183 private static final int GF256_FDBK_2 = GF256_FDBK / 2; 184 private static final int GF256_FDBK_4 = GF256_FDBK / 4; 185 186 private static final int RS_GF_FDBK = 0x14D; // field generator 187 188 //==================================== 189 // Useful constants 190 //==================================== 191 192 private static final int ROUNDS = 16; 193 private static final int MAX_ROUNDS = 16; // bytes = 128 bits 194 private static final int BLOCK_SIZE = 16; // bytes = 128 bits 195 private static final int MAX_KEY_BITS = 256; 196 197 private static final int INPUT_WHITEN=0; 198 private static final int OUTPUT_WHITEN=INPUT_WHITEN+BLOCK_SIZE/4; // 4 199 private static final int ROUND_SUBKEYS=OUTPUT_WHITEN+BLOCK_SIZE/4;// 8 200 201 private static final int TOTAL_SUBKEYS=ROUND_SUBKEYS+2*MAX_ROUNDS;// 40 202 203 private static final int SK_STEP = 0x02020202; 204 private static final int SK_BUMP = 0x01010101; 205 private static final int SK_ROTL = 9; 206 207 private boolean encrypting = false; 208 209 private int[] gMDS0 = new int[MAX_KEY_BITS]; 210 private int[] gMDS1 = new int[MAX_KEY_BITS]; 211 private int[] gMDS2 = new int[MAX_KEY_BITS]; 212 private int[] gMDS3 = new int[MAX_KEY_BITS]; 213 214 /** 215 * gSubKeys[] and gSBox[] are eventually used in the 216 * encryption and decryption methods. 217 */ 218 private int[] gSubKeys; 219 private int[] gSBox; 220 221 private int k64Cnt = 0; 222 223 private byte[] workingKey = null; 224 TwofishEngine()225 public TwofishEngine() 226 { 227 // calculate the MDS matrix 228 int[] m1 = new int[2]; 229 int[] mX = new int[2]; 230 int[] mY = new int[2]; 231 int j; 232 233 for (int i=0; i< MAX_KEY_BITS ; i++) 234 { 235 j = P[0][i] & 0xff; 236 m1[0] = j; 237 mX[0] = Mx_X(j) & 0xff; 238 mY[0] = Mx_Y(j) & 0xff; 239 240 j = P[1][i] & 0xff; 241 m1[1] = j; 242 mX[1] = Mx_X(j) & 0xff; 243 mY[1] = Mx_Y(j) & 0xff; 244 245 gMDS0[i] = m1[P_00] | mX[P_00] << 8 | 246 mY[P_00] << 16 | mY[P_00] << 24; 247 248 gMDS1[i] = mY[P_10] | mY[P_10] << 8 | 249 mX[P_10] << 16 | m1[P_10] << 24; 250 251 gMDS2[i] = mX[P_20] | mY[P_20] << 8 | 252 m1[P_20] << 16 | mY[P_20] << 24; 253 254 gMDS3[i] = mX[P_30] | m1[P_30] << 8 | 255 mY[P_30] << 16 | mX[P_30] << 24; 256 } 257 } 258 259 /** 260 * initialise a Twofish cipher. 261 * 262 * @param encrypting whether or not we are for encryption. 263 * @param params the parameters required to set up the cipher. 264 * @exception IllegalArgumentException if the params argument is 265 * inappropriate. 266 */ init( boolean encrypting, CipherParameters params)267 public void init( 268 boolean encrypting, 269 CipherParameters params) 270 { 271 if (params instanceof KeyParameter) 272 { 273 this.encrypting = encrypting; 274 this.workingKey = ((KeyParameter)params).getKey(); 275 this.k64Cnt = (this.workingKey.length / 8); // pre-padded ? 276 setKey(this.workingKey); 277 278 return; 279 } 280 281 throw new IllegalArgumentException("invalid parameter passed to Twofish init - " + params.getClass().getName()); 282 } 283 getAlgorithmName()284 public String getAlgorithmName() 285 { 286 return "Twofish"; 287 } 288 processBlock( byte[] in, int inOff, byte[] out, int outOff)289 public int processBlock( 290 byte[] in, 291 int inOff, 292 byte[] out, 293 int outOff) 294 { 295 if (workingKey == null) 296 { 297 throw new IllegalStateException("Twofish not initialised"); 298 } 299 300 if ((inOff + BLOCK_SIZE) > in.length) 301 { 302 throw new DataLengthException("input buffer too short"); 303 } 304 305 if ((outOff + BLOCK_SIZE) > out.length) 306 { 307 throw new OutputLengthException("output buffer too short"); 308 } 309 310 if (encrypting) 311 { 312 encryptBlock(in, inOff, out, outOff); 313 } 314 else 315 { 316 decryptBlock(in, inOff, out, outOff); 317 } 318 319 return BLOCK_SIZE; 320 } 321 reset()322 public void reset() 323 { 324 if (this.workingKey != null) 325 { 326 setKey(this.workingKey); 327 } 328 } 329 getBlockSize()330 public int getBlockSize() 331 { 332 return BLOCK_SIZE; 333 } 334 335 //================================== 336 // Private Implementation 337 //================================== 338 setKey(byte[] key)339 private void setKey(byte[] key) 340 { 341 int[] k32e = new int[MAX_KEY_BITS/64]; // 4 342 int[] k32o = new int[MAX_KEY_BITS/64]; // 4 343 344 int[] sBoxKeys = new int[MAX_KEY_BITS/64]; // 4 345 gSubKeys = new int[TOTAL_SUBKEYS]; 346 347 if (k64Cnt < 1) 348 { 349 throw new IllegalArgumentException("Key size less than 64 bits"); 350 } 351 352 if (k64Cnt > 4) 353 { 354 throw new IllegalArgumentException("Key size larger than 256 bits"); 355 } 356 357 /* 358 * k64Cnt is the number of 8 byte blocks (64 chunks) 359 * that are in the input key. The input key is a 360 * maximum of 32 bytes (256 bits), so the range 361 * for k64Cnt is 1..4 362 */ 363 for (int i=0; i<k64Cnt ; i++) 364 { 365 int p = i* 8; 366 367 k32e[i] = BytesTo32Bits(key, p); 368 k32o[i] = BytesTo32Bits(key, p+4); 369 370 sBoxKeys[k64Cnt-1-i] = RS_MDS_Encode(k32e[i], k32o[i]); 371 } 372 373 int q,A,B; 374 for (int i=0; i < TOTAL_SUBKEYS / 2 ; i++) 375 { 376 q = i*SK_STEP; 377 A = F32(q, k32e); 378 B = F32(q+SK_BUMP, k32o); 379 B = B << 8 | B >>> 24; 380 A += B; 381 gSubKeys[i*2] = A; 382 A += B; 383 gSubKeys[i*2 + 1] = A << SK_ROTL | A >>> (32-SK_ROTL); 384 } 385 386 /* 387 * fully expand the table for speed 388 */ 389 int k0 = sBoxKeys[0]; 390 int k1 = sBoxKeys[1]; 391 int k2 = sBoxKeys[2]; 392 int k3 = sBoxKeys[3]; 393 int b0, b1, b2, b3; 394 gSBox = new int[4*MAX_KEY_BITS]; 395 for (int i=0; i<MAX_KEY_BITS; i++) 396 { 397 b0 = b1 = b2 = b3 = i; 398 switch (k64Cnt & 3) 399 { 400 case 1: 401 gSBox[i*2] = gMDS0[(P[P_01][b0] & 0xff) ^ b0(k0)]; 402 gSBox[i*2+1] = gMDS1[(P[P_11][b1] & 0xff) ^ b1(k0)]; 403 gSBox[i*2+0x200] = gMDS2[(P[P_21][b2] & 0xff) ^ b2(k0)]; 404 gSBox[i*2+0x201] = gMDS3[(P[P_31][b3] & 0xff) ^ b3(k0)]; 405 break; 406 case 0: // 256 bits of key 407 b0 = (P[P_04][b0] & 0xff) ^ b0(k3); 408 b1 = (P[P_14][b1] & 0xff) ^ b1(k3); 409 b2 = (P[P_24][b2] & 0xff) ^ b2(k3); 410 b3 = (P[P_34][b3] & 0xff) ^ b3(k3); 411 // fall through, having pre-processed b[0]..b[3] with k32[3] 412 case 3: // 192 bits of key 413 b0 = (P[P_03][b0] & 0xff) ^ b0(k2); 414 b1 = (P[P_13][b1] & 0xff) ^ b1(k2); 415 b2 = (P[P_23][b2] & 0xff) ^ b2(k2); 416 b3 = (P[P_33][b3] & 0xff) ^ b3(k2); 417 // fall through, having pre-processed b[0]..b[3] with k32[2] 418 case 2: // 128 bits of key 419 gSBox[i*2] = gMDS0[(P[P_01] 420 [(P[P_02][b0] & 0xff) ^ b0(k1)] & 0xff) ^ b0(k0)]; 421 gSBox[i*2+1] = gMDS1[(P[P_11] 422 [(P[P_12][b1] & 0xff) ^ b1(k1)] & 0xff) ^ b1(k0)]; 423 gSBox[i*2+0x200] = gMDS2[(P[P_21] 424 [(P[P_22][b2] & 0xff) ^ b2(k1)] & 0xff) ^ b2(k0)]; 425 gSBox[i*2+0x201] = gMDS3[(P[P_31] 426 [(P[P_32][b3] & 0xff) ^ b3(k1)] & 0xff) ^ b3(k0)]; 427 break; 428 } 429 } 430 431 /* 432 * the function exits having setup the gSBox with the 433 * input key material. 434 */ 435 } 436 437 /** 438 * Encrypt the given input starting at the given offset and place 439 * the result in the provided buffer starting at the given offset. 440 * The input will be an exact multiple of our blocksize. 441 * 442 * encryptBlock uses the pre-calculated gSBox[] and subKey[] 443 * arrays. 444 */ encryptBlock( byte[] src, int srcIndex, byte[] dst, int dstIndex)445 private void encryptBlock( 446 byte[] src, 447 int srcIndex, 448 byte[] dst, 449 int dstIndex) 450 { 451 int x0 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[INPUT_WHITEN]; 452 int x1 = BytesTo32Bits(src, srcIndex + 4) ^ gSubKeys[INPUT_WHITEN + 1]; 453 int x2 = BytesTo32Bits(src, srcIndex + 8) ^ gSubKeys[INPUT_WHITEN + 2]; 454 int x3 = BytesTo32Bits(src, srcIndex + 12) ^ gSubKeys[INPUT_WHITEN + 3]; 455 456 int k = ROUND_SUBKEYS; 457 int t0, t1; 458 for (int r = 0; r < ROUNDS; r +=2) 459 { 460 t0 = Fe32_0(x0); 461 t1 = Fe32_3(x1); 462 x2 ^= t0 + t1 + gSubKeys[k++]; 463 x2 = x2 >>>1 | x2 << 31; 464 x3 = (x3 << 1 | x3 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]); 465 466 t0 = Fe32_0(x2); 467 t1 = Fe32_3(x3); 468 x0 ^= t0 + t1 + gSubKeys[k++]; 469 x0 = x0 >>>1 | x0 << 31; 470 x1 = (x1 << 1 | x1 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]); 471 } 472 473 Bits32ToBytes(x2 ^ gSubKeys[OUTPUT_WHITEN], dst, dstIndex); 474 Bits32ToBytes(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], dst, dstIndex + 4); 475 Bits32ToBytes(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], dst, dstIndex + 8); 476 Bits32ToBytes(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], dst, dstIndex + 12); 477 } 478 479 /** 480 * Decrypt the given input starting at the given offset and place 481 * the result in the provided buffer starting at the given offset. 482 * The input will be an exact multiple of our blocksize. 483 */ decryptBlock( byte[] src, int srcIndex, byte[] dst, int dstIndex)484 private void decryptBlock( 485 byte[] src, 486 int srcIndex, 487 byte[] dst, 488 int dstIndex) 489 { 490 int x2 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[OUTPUT_WHITEN]; 491 int x3 = BytesTo32Bits(src, srcIndex+4) ^ gSubKeys[OUTPUT_WHITEN + 1]; 492 int x0 = BytesTo32Bits(src, srcIndex+8) ^ gSubKeys[OUTPUT_WHITEN + 2]; 493 int x1 = BytesTo32Bits(src, srcIndex+12) ^ gSubKeys[OUTPUT_WHITEN + 3]; 494 495 int k = ROUND_SUBKEYS + 2 * ROUNDS -1 ; 496 int t0, t1; 497 for (int r = 0; r< ROUNDS ; r +=2) 498 { 499 t0 = Fe32_0(x2); 500 t1 = Fe32_3(x3); 501 x1 ^= t0 + 2*t1 + gSubKeys[k--]; 502 x0 = (x0 << 1 | x0 >>> 31) ^ (t0 + t1 + gSubKeys[k--]); 503 x1 = x1 >>>1 | x1 << 31; 504 505 t0 = Fe32_0(x0); 506 t1 = Fe32_3(x1); 507 x3 ^= t0 + 2*t1 + gSubKeys[k--]; 508 x2 = (x2 << 1 | x2 >>> 31) ^ (t0 + t1 + gSubKeys[k--]); 509 x3 = x3 >>>1 | x3 << 31; 510 } 511 512 Bits32ToBytes(x0 ^ gSubKeys[INPUT_WHITEN], dst, dstIndex); 513 Bits32ToBytes(x1 ^ gSubKeys[INPUT_WHITEN + 1], dst, dstIndex + 4); 514 Bits32ToBytes(x2 ^ gSubKeys[INPUT_WHITEN + 2], dst, dstIndex + 8); 515 Bits32ToBytes(x3 ^ gSubKeys[INPUT_WHITEN + 3], dst, dstIndex + 12); 516 } 517 518 /* 519 * TODO: This can be optimised and made cleaner by combining 520 * the functionality in this function and applying it appropriately 521 * to the creation of the subkeys during key setup. 522 */ F32(int x, int[] k32)523 private int F32(int x, int[] k32) 524 { 525 int b0 = b0(x); 526 int b1 = b1(x); 527 int b2 = b2(x); 528 int b3 = b3(x); 529 int k0 = k32[0]; 530 int k1 = k32[1]; 531 int k2 = k32[2]; 532 int k3 = k32[3]; 533 534 int result = 0; 535 switch (k64Cnt & 3) 536 { 537 case 1: 538 result = gMDS0[(P[P_01][b0] & 0xff) ^ b0(k0)] ^ 539 gMDS1[(P[P_11][b1] & 0xff) ^ b1(k0)] ^ 540 gMDS2[(P[P_21][b2] & 0xff) ^ b2(k0)] ^ 541 gMDS3[(P[P_31][b3] & 0xff) ^ b3(k0)]; 542 break; 543 case 0: /* 256 bits of key */ 544 b0 = (P[P_04][b0] & 0xff) ^ b0(k3); 545 b1 = (P[P_14][b1] & 0xff) ^ b1(k3); 546 b2 = (P[P_24][b2] & 0xff) ^ b2(k3); 547 b3 = (P[P_34][b3] & 0xff) ^ b3(k3); 548 case 3: 549 b0 = (P[P_03][b0] & 0xff) ^ b0(k2); 550 b1 = (P[P_13][b1] & 0xff) ^ b1(k2); 551 b2 = (P[P_23][b2] & 0xff) ^ b2(k2); 552 b3 = (P[P_33][b3] & 0xff) ^ b3(k2); 553 case 2: 554 result = 555 gMDS0[(P[P_01][(P[P_02][b0]&0xff)^b0(k1)]&0xff)^b0(k0)] ^ 556 gMDS1[(P[P_11][(P[P_12][b1]&0xff)^b1(k1)]&0xff)^b1(k0)] ^ 557 gMDS2[(P[P_21][(P[P_22][b2]&0xff)^b2(k1)]&0xff)^b2(k0)] ^ 558 gMDS3[(P[P_31][(P[P_32][b3]&0xff)^b3(k1)]&0xff)^b3(k0)]; 559 break; 560 } 561 return result; 562 } 563 564 /** 565 * Use (12, 8) Reed-Solomon code over GF(256) to produce 566 * a key S-box 32-bit entity from 2 key material 32-bit 567 * entities. 568 * 569 * @param k0 first 32-bit entity 570 * @param k1 second 32-bit entity 571 * @return Remainder polynomial generated using RS code 572 */ RS_MDS_Encode(int k0, int k1)573 private int RS_MDS_Encode(int k0, int k1) 574 { 575 int r = k1; 576 for (int i = 0 ; i < 4 ; i++) // shift 1 byte at a time 577 { 578 r = RS_rem(r); 579 } 580 r ^= k0; 581 for (int i=0 ; i < 4 ; i++) 582 { 583 r = RS_rem(r); 584 } 585 586 return r; 587 } 588 589 /** 590 * Reed-Solomon code parameters: (12,8) reversible code:<p> 591 * <pre> 592 * g(x) = x^4 + (a+1/a)x^3 + ax^2 + (a+1/a)x + 1 593 * </pre> 594 * where a = primitive root of field generator 0x14D 595 */ RS_rem(int x)596 private int RS_rem(int x) 597 { 598 int b = (x >>> 24) & 0xff; 599 int g2 = ((b << 1) ^ 600 ((b & 0x80) != 0 ? RS_GF_FDBK : 0)) & 0xff; 601 int g3 = ((b >>> 1) ^ 602 ((b & 0x01) != 0 ? (RS_GF_FDBK >>> 1) : 0)) ^ g2 ; 603 return ((x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b); 604 } 605 LFSR1(int x)606 private int LFSR1(int x) 607 { 608 return (x >> 1) ^ 609 (((x & 0x01) != 0) ? GF256_FDBK_2 : 0); 610 } 611 LFSR2(int x)612 private int LFSR2(int x) 613 { 614 return (x >> 2) ^ 615 (((x & 0x02) != 0) ? GF256_FDBK_2 : 0) ^ 616 (((x & 0x01) != 0) ? GF256_FDBK_4 : 0); 617 } 618 Mx_X(int x)619 private int Mx_X(int x) 620 { 621 return x ^ LFSR2(x); 622 } // 5B 623 Mx_Y(int x)624 private int Mx_Y(int x) 625 { 626 return x ^ LFSR1(x) ^ LFSR2(x); 627 } // EF 628 b0(int x)629 private int b0(int x) 630 { 631 return x & 0xff; 632 } 633 b1(int x)634 private int b1(int x) 635 { 636 return (x >>> 8) & 0xff; 637 } 638 b2(int x)639 private int b2(int x) 640 { 641 return (x >>> 16) & 0xff; 642 } 643 b3(int x)644 private int b3(int x) 645 { 646 return (x >>> 24) & 0xff; 647 } 648 Fe32_0(int x)649 private int Fe32_0(int x) 650 { 651 return gSBox[ 0x000 + 2*(x & 0xff) ] ^ 652 gSBox[ 0x001 + 2*((x >>> 8) & 0xff) ] ^ 653 gSBox[ 0x200 + 2*((x >>> 16) & 0xff) ] ^ 654 gSBox[ 0x201 + 2*((x >>> 24) & 0xff) ]; 655 } 656 Fe32_3(int x)657 private int Fe32_3(int x) 658 { 659 return gSBox[ 0x000 + 2*((x >>> 24) & 0xff) ] ^ 660 gSBox[ 0x001 + 2*(x & 0xff) ] ^ 661 gSBox[ 0x200 + 2*((x >>> 8) & 0xff) ] ^ 662 gSBox[ 0x201 + 2*((x >>> 16) & 0xff) ]; 663 } 664 BytesTo32Bits(byte[] b, int p)665 private int BytesTo32Bits(byte[] b, int p) 666 { 667 return ((b[p] & 0xff)) | 668 ((b[p+1] & 0xff) << 8) | 669 ((b[p+2] & 0xff) << 16) | 670 ((b[p+3] & 0xff) << 24); 671 } 672 Bits32ToBytes(int in, byte[] b, int offset)673 private void Bits32ToBytes(int in, byte[] b, int offset) 674 { 675 b[offset] = (byte)in; 676 b[offset + 1] = (byte)(in >> 8); 677 b[offset + 2] = (byte)(in >> 16); 678 b[offset + 3] = (byte)(in >> 24); 679 } 680 } 681