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