1 /* 2 * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* $Id: Rijndael.java,v 1.6 2000/02/10 01:31:41 gelderen Exp $ 27 * 28 * Copyright (C) 1995-2000 The Cryptix Foundation Limited. 29 * All rights reserved. 30 * 31 * Use, modification, copying and distribution of this softwareas is subject 32 * the terms and conditions of the Cryptix General Licence. You should have 33 * received a copy of the Cryptix General Licence along with this library; 34 * if not, you can download a copy from http://www.cryptix.org/ . 35 */ 36 37 package com.sun.crypto.provider; 38 39 import java.security.InvalidKeyException; 40 import java.security.MessageDigest; 41 import java.util.Arrays; 42 import java.util.Objects; 43 44 import jdk.internal.HotSpotIntrinsicCandidate; 45 46 /** 47 * Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit 48 * block size and variable key-size (128-, 192- and 256-bit). 49 * <p> 50 * Rijndael was designed by <a href="mailto:rijmen@esat.kuleuven.ac.be">Vincent 51 * Rijmen</a> and <a href="mailto:Joan.Daemen@village.uunet.be">Joan Daemen</a>. 52 */ 53 final class AESCrypt extends SymmetricCipher implements AESConstants 54 { 55 private boolean ROUNDS_12 = false; 56 private boolean ROUNDS_14 = false; 57 58 /** Session and Sub keys */ 59 private int[][] sessionK = null; 60 private int[] K = null; 61 62 /** Cipher encryption/decryption key */ 63 // skip re-generating Session and Sub keys if the cipher key is 64 // the same 65 private byte[] lastKey = null; 66 67 /** ROUNDS * 4 */ 68 private int limit = 0; 69 70 AESCrypt() { 71 // empty 72 } 73 74 /** 75 * Returns this cipher's block size. 76 * 77 * @return this cipher's block size 78 */ 79 int getBlockSize() { 80 return AES_BLOCK_SIZE; 81 } 82 83 void init(boolean decrypting, String algorithm, byte[] key) 84 throws InvalidKeyException { 85 if (!algorithm.equalsIgnoreCase("AES") 86 && !algorithm.equalsIgnoreCase("Rijndael")) { 87 throw new InvalidKeyException 88 ("Wrong algorithm: AES or Rijndael required"); 89 } 90 if (!isKeySizeValid(key.length)) { 91 throw new InvalidKeyException("Invalid AES key length: " + 92 key.length + " bytes"); 93 } 94 95 if (!MessageDigest.isEqual(key, lastKey)) { 96 // re-generate session key 'sessionK' when cipher key changes 97 makeSessionKey(key); 98 lastKey = key.clone(); // save cipher key 99 } 100 101 // set sub key to the corresponding session Key 102 this.K = sessionK[(decrypting? 1:0)]; 103 } 104 105 /** 106 * Expand an int[(ROUNDS+1)][4] into int[(ROUNDS+1)*4]. 107 * For decryption round keys, need to rotate right by 4 ints. 108 * @param kr The round keys for encryption or decryption. 109 * @param decrypting True if 'kr' is for decryption and false otherwise. 110 */ 111 private static final int[] expandToSubKey(int[][] kr, boolean decrypting) { 112 int total = kr.length; 113 int[] expK = new int[total*4]; 114 if (decrypting) { 115 // decrypting, rotate right by 4 ints 116 // i.e. i==0 117 for(int j=0; j<4; j++) { 118 expK[j] = kr[total-1][j]; 119 } 120 for(int i=1; i<total; i++) { 121 for(int j=0; j<4; j++) { 122 expK[i*4 + j] = kr[i-1][j]; 123 } 124 } 125 } else { 126 // encrypting, straight expansion 127 for(int i=0; i<total; i++) { 128 for(int j=0; j<4; j++) { 129 expK[i*4 + j] = kr[i][j]; 130 } 131 } 132 } 133 return expK; 134 } 135 136 private static int[] 137 alog = new int[256], 138 log = new int[256]; 139 140 private static final byte[] 141 S = new byte[256], 142 Si = new byte[256]; 143 144 private static final int[] 145 T1 = new int[256], 146 T2 = new int[256], 147 T3 = new int[256], 148 T4 = new int[256], 149 T5 = new int[256], 150 T6 = new int[256], 151 T7 = new int[256], 152 T8 = new int[256]; 153 154 private static final int[] 155 U1 = new int[256], 156 U2 = new int[256], 157 U3 = new int[256], 158 U4 = new int[256]; 159 160 private static final byte[] rcon = new byte[30]; 161 162 163 // Static code - to intialise S-boxes and T-boxes 164 static 165 { 166 int ROOT = 0x11B; 167 int i, j = 0; 168 169 // 170 // produce log and alog tables, needed for multiplying in the 171 // field GF(2^m) (generator = 3) 172 // 173 alog[0] = 1; 174 for (i = 1; i < 256; i++) 175 { 176 j = (alog[i-1] << 1) ^ alog[i-1]; 177 if ((j & 0x100) != 0) { 178 j ^= ROOT; 179 } 180 alog[i] = j; 181 } 182 for (i = 1; i < 255; i++) { 183 log[alog[i]] = i; 184 } 185 byte[][] A = new byte[][] 186 { 187 {1, 1, 1, 1, 1, 0, 0, 0}, 188 {0, 1, 1, 1, 1, 1, 0, 0}, 189 {0, 0, 1, 1, 1, 1, 1, 0}, 190 {0, 0, 0, 1, 1, 1, 1, 1}, 191 {1, 0, 0, 0, 1, 1, 1, 1}, 192 {1, 1, 0, 0, 0, 1, 1, 1}, 193 {1, 1, 1, 0, 0, 0, 1, 1}, 194 {1, 1, 1, 1, 0, 0, 0, 1} 195 }; 196 byte[] B = new byte[] { 0, 1, 1, 0, 0, 0, 1, 1}; 197 198 // 199 // substitution box based on F^{-1}(x) 200 // 201 int t; 202 byte[][] box = new byte[256][8]; 203 box[1][7] = 1; 204 for (i = 2; i < 256; i++) { 205 j = alog[255 - log[i]]; 206 for (t = 0; t < 8; t++) { 207 box[i][t] = (byte)((j >>> (7 - t)) & 0x01); 208 } 209 } 210 // 211 // affine transform: box[i] <- B + A*box[i] 212 // 213 byte[][] cox = new byte[256][8]; 214 for (i = 0; i < 256; i++) { 215 for (t = 0; t < 8; t++) { 216 cox[i][t] = B[t]; 217 for (j = 0; j < 8; j++) { 218 cox[i][t] ^= A[t][j] * box[i][j]; 219 } 220 } 221 } 222 // 223 // S-boxes and inverse S-boxes 224 // 225 for (i = 0; i < 256; i++) { 226 S[i] = (byte)(cox[i][0] << 7); 227 for (t = 1; t < 8; t++) { 228 S[i] ^= cox[i][t] << (7-t); 229 } 230 Si[S[i] & 0xFF] = (byte) i; 231 } 232 // 233 // T-boxes 234 // 235 byte[][] G = new byte[][] { 236 {2, 1, 1, 3}, 237 {3, 2, 1, 1}, 238 {1, 3, 2, 1}, 239 {1, 1, 3, 2} 240 }; 241 byte[][] AA = new byte[4][8]; 242 for (i = 0; i < 4; i++) { 243 for (j = 0; j < 4; j++) AA[i][j] = G[i][j]; 244 AA[i][i+4] = 1; 245 } 246 byte pivot, tmp; 247 byte[][] iG = new byte[4][4]; 248 for (i = 0; i < 4; i++) { 249 pivot = AA[i][i]; 250 if (pivot == 0) { 251 t = i + 1; 252 while ((AA[t][i] == 0) && (t < 4)) { 253 t++; 254 } 255 if (t == 4) { 256 throw new RuntimeException("G matrix is not invertible"); 257 } 258 else { 259 for (j = 0; j < 8; j++) { 260 tmp = AA[i][j]; 261 AA[i][j] = AA[t][j]; 262 AA[t][j] = tmp; 263 } 264 pivot = AA[i][i]; 265 } 266 } 267 for (j = 0; j < 8; j++) { 268 if (AA[i][j] != 0) { 269 AA[i][j] = (byte) 270 alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF]) 271 % 255]; 272 } 273 } 274 for (t = 0; t < 4; t++) { 275 if (i != t) { 276 for (j = i+1; j < 8; j++) { 277 AA[t][j] ^= mul(AA[i][j], AA[t][i]); 278 } 279 AA[t][i] = 0; 280 } 281 } 282 } 283 for (i = 0; i < 4; i++) { 284 for (j = 0; j < 4; j++) { 285 iG[i][j] = AA[i][j + 4]; 286 } 287 } 288 289 int s; 290 for (t = 0; t < 256; t++) { 291 s = S[t]; 292 T1[t] = mul4(s, G[0]); 293 T2[t] = mul4(s, G[1]); 294 T3[t] = mul4(s, G[2]); 295 T4[t] = mul4(s, G[3]); 296 297 s = Si[t]; 298 T5[t] = mul4(s, iG[0]); 299 T6[t] = mul4(s, iG[1]); 300 T7[t] = mul4(s, iG[2]); 301 T8[t] = mul4(s, iG[3]); 302 303 U1[t] = mul4(t, iG[0]); 304 U2[t] = mul4(t, iG[1]); 305 U3[t] = mul4(t, iG[2]); 306 U4[t] = mul4(t, iG[3]); 307 } 308 // 309 // round constants 310 // 311 rcon[0] = 1; 312 int r = 1; 313 for (t = 1; t < 30; t++) { 314 r = mul(2, r); 315 rcon[t] = (byte) r; 316 } 317 log = null; 318 alog = null; 319 } 320 321 // multiply two elements of GF(2^m) 322 private static final int mul (int a, int b) { 323 return (a != 0 && b != 0) ? 324 alog[(log[a & 0xFF] + log[b & 0xFF]) % 255] : 325 0; 326 } 327 328 // convenience method used in generating Transposition boxes 329 private static final int mul4 (int a, byte[] b) { 330 if (a == 0) return 0; 331 a = log[a & 0xFF]; 332 int a0 = (b[0] != 0) ? alog[(a + log[b[0] & 0xFF]) % 255] & 0xFF : 0; 333 int a1 = (b[1] != 0) ? alog[(a + log[b[1] & 0xFF]) % 255] & 0xFF : 0; 334 int a2 = (b[2] != 0) ? alog[(a + log[b[2] & 0xFF]) % 255] & 0xFF : 0; 335 int a3 = (b[3] != 0) ? alog[(a + log[b[3] & 0xFF]) % 255] & 0xFF : 0; 336 return a0 << 24 | a1 << 16 | a2 << 8 | a3; 337 } 338 339 // check if the specified length (in bytes) is a valid keysize for AES 340 static final boolean isKeySizeValid(int len) { 341 for (int i = 0; i < AES_KEYSIZES.length; i++) { 342 if (len == AES_KEYSIZES[i]) { 343 return true; 344 } 345 } 346 return false; 347 } 348 349 /** 350 * Encrypt exactly one block of plaintext. 351 */ 352 void encryptBlock(byte[] in, int inOffset, 353 byte[] out, int outOffset) { 354 Objects.checkFromIndexSize(inOffset, AES_BLOCK_SIZE, in.length); 355 Objects.checkFromIndexSize(outOffset, AES_BLOCK_SIZE, out.length); 356 implEncryptBlock(in, inOffset, out, outOffset); 357 } 358 359 // Encryption operation. Possibly replaced with a compiler intrinsic. 360 @HotSpotIntrinsicCandidate 361 private void implEncryptBlock(byte[] in, int inOffset, 362 byte[] out, int outOffset) 363 { 364 int keyOffset = 0; 365 int t0 = ((in[inOffset++] ) << 24 | 366 (in[inOffset++] & 0xFF) << 16 | 367 (in[inOffset++] & 0xFF) << 8 | 368 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; 369 int t1 = ((in[inOffset++] ) << 24 | 370 (in[inOffset++] & 0xFF) << 16 | 371 (in[inOffset++] & 0xFF) << 8 | 372 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; 373 int t2 = ((in[inOffset++] ) << 24 | 374 (in[inOffset++] & 0xFF) << 16 | 375 (in[inOffset++] & 0xFF) << 8 | 376 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; 377 int t3 = ((in[inOffset++] ) << 24 | 378 (in[inOffset++] & 0xFF) << 16 | 379 (in[inOffset++] & 0xFF) << 8 | 380 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; 381 382 // apply round transforms 383 while( keyOffset < limit ) 384 { 385 int a0, a1, a2; 386 a0 = T1[(t0 >>> 24) ] ^ 387 T2[(t1 >>> 16) & 0xFF] ^ 388 T3[(t2 >>> 8) & 0xFF] ^ 389 T4[(t3 ) & 0xFF] ^ K[keyOffset++]; 390 a1 = T1[(t1 >>> 24) ] ^ 391 T2[(t2 >>> 16) & 0xFF] ^ 392 T3[(t3 >>> 8) & 0xFF] ^ 393 T4[(t0 ) & 0xFF] ^ K[keyOffset++]; 394 a2 = T1[(t2 >>> 24) ] ^ 395 T2[(t3 >>> 16) & 0xFF] ^ 396 T3[(t0 >>> 8) & 0xFF] ^ 397 T4[(t1 ) & 0xFF] ^ K[keyOffset++]; 398 t3 = T1[(t3 >>> 24) ] ^ 399 T2[(t0 >>> 16) & 0xFF] ^ 400 T3[(t1 >>> 8) & 0xFF] ^ 401 T4[(t2 ) & 0xFF] ^ K[keyOffset++]; 402 t0 = a0; t1 = a1; t2 = a2; 403 } 404 405 // last round is special 406 int tt = K[keyOffset++]; 407 out[outOffset++] = (byte)(S[(t0 >>> 24) ] ^ (tt >>> 24)); 408 out[outOffset++] = (byte)(S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16)); 409 out[outOffset++] = (byte)(S[(t2 >>> 8) & 0xFF] ^ (tt >>> 8)); 410 out[outOffset++] = (byte)(S[(t3 ) & 0xFF] ^ (tt )); 411 tt = K[keyOffset++]; 412 out[outOffset++] = (byte)(S[(t1 >>> 24) ] ^ (tt >>> 24)); 413 out[outOffset++] = (byte)(S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16)); 414 out[outOffset++] = (byte)(S[(t3 >>> 8) & 0xFF] ^ (tt >>> 8)); 415 out[outOffset++] = (byte)(S[(t0 ) & 0xFF] ^ (tt )); 416 tt = K[keyOffset++]; 417 out[outOffset++] = (byte)(S[(t2 >>> 24) ] ^ (tt >>> 24)); 418 out[outOffset++] = (byte)(S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16)); 419 out[outOffset++] = (byte)(S[(t0 >>> 8) & 0xFF] ^ (tt >>> 8)); 420 out[outOffset++] = (byte)(S[(t1 ) & 0xFF] ^ (tt )); 421 tt = K[keyOffset++]; 422 out[outOffset++] = (byte)(S[(t3 >>> 24) ] ^ (tt >>> 24)); 423 out[outOffset++] = (byte)(S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16)); 424 out[outOffset++] = (byte)(S[(t1 >>> 8) & 0xFF] ^ (tt >>> 8)); 425 out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt )); 426 } 427 428 /** 429 * Decrypt exactly one block of plaintext. 430 */ 431 void decryptBlock(byte[] in, int inOffset, 432 byte[] out, int outOffset) { 433 Objects.checkFromIndexSize(inOffset, AES_BLOCK_SIZE, in.length); 434 Objects.checkFromIndexSize(outOffset, AES_BLOCK_SIZE, out.length); 435 implDecryptBlock(in, inOffset, out, outOffset); 436 } 437 438 // Decrypt operation. Possibly replaced with a compiler intrinsic. 439 @HotSpotIntrinsicCandidate 440 private void implDecryptBlock(byte[] in, int inOffset, 441 byte[] out, int outOffset) 442 { 443 int keyOffset = 4; 444 int t0 = ((in[inOffset++] ) << 24 | 445 (in[inOffset++] & 0xFF) << 16 | 446 (in[inOffset++] & 0xFF) << 8 | 447 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; 448 int t1 = ((in[inOffset++] ) << 24 | 449 (in[inOffset++] & 0xFF) << 16 | 450 (in[inOffset++] & 0xFF) << 8 | 451 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; 452 int t2 = ((in[inOffset++] ) << 24 | 453 (in[inOffset++] & 0xFF) << 16 | 454 (in[inOffset++] & 0xFF) << 8 | 455 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; 456 int t3 = ((in[inOffset++] ) << 24 | 457 (in[inOffset++] & 0xFF) << 16 | 458 (in[inOffset++] & 0xFF) << 8 | 459 (in[inOffset ] & 0xFF) ) ^ K[keyOffset++]; 460 461 int a0, a1, a2; 462 if(ROUNDS_12) 463 { 464 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ 465 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; 466 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ 467 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; 468 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ 469 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; 470 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ 471 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; 472 t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ 473 T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; 474 t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ 475 T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; 476 t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ 477 T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; 478 t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ 479 T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; 480 481 if(ROUNDS_14) 482 { 483 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ 484 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; 485 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ 486 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; 487 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ 488 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; 489 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ 490 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; 491 t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ 492 T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; 493 t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ 494 T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; 495 t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ 496 T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; 497 t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ 498 T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; 499 } 500 } 501 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ 502 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; 503 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ 504 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; 505 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ 506 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; 507 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ 508 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; 509 t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ 510 T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; 511 t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ 512 T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; 513 t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ 514 T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; 515 t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ 516 T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; 517 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ 518 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; 519 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ 520 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; 521 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ 522 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; 523 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ 524 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; 525 t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ 526 T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; 527 t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ 528 T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; 529 t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ 530 T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; 531 t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ 532 T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; 533 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ 534 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; 535 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ 536 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; 537 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ 538 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; 539 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ 540 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; 541 t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ 542 T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; 543 t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ 544 T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; 545 t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ 546 T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; 547 t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ 548 T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; 549 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ 550 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; 551 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ 552 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; 553 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ 554 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; 555 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ 556 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; 557 t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ 558 T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; 559 t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ 560 T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; 561 t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ 562 T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; 563 t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ 564 T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; 565 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ 566 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; 567 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ 568 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; 569 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ 570 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; 571 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ 572 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; 573 574 t1 = K[0]; 575 out[outOffset++] = (byte)(Si[(a0 >>> 24) ] ^ (t1 >>> 24)); 576 out[outOffset++] = (byte)(Si[(t3 >>> 16) & 0xFF] ^ (t1 >>> 16)); 577 out[outOffset++] = (byte)(Si[(a2 >>> 8) & 0xFF] ^ (t1 >>> 8)); 578 out[outOffset++] = (byte)(Si[(a1 ) & 0xFF] ^ (t1 )); 579 t1 = K[1]; 580 out[outOffset++] = (byte)(Si[(a1 >>> 24) ] ^ (t1 >>> 24)); 581 out[outOffset++] = (byte)(Si[(a0 >>> 16) & 0xFF] ^ (t1 >>> 16)); 582 out[outOffset++] = (byte)(Si[(t3 >>> 8) & 0xFF] ^ (t1 >>> 8)); 583 out[outOffset++] = (byte)(Si[(a2 ) & 0xFF] ^ (t1 )); 584 t1 = K[2]; 585 out[outOffset++] = (byte)(Si[(a2 >>> 24) ] ^ (t1 >>> 24)); 586 out[outOffset++] = (byte)(Si[(a1 >>> 16) & 0xFF] ^ (t1 >>> 16)); 587 out[outOffset++] = (byte)(Si[(a0 >>> 8) & 0xFF] ^ (t1 >>> 8)); 588 out[outOffset++] = (byte)(Si[(t3 ) & 0xFF] ^ (t1 )); 589 t1 = K[3]; 590 out[outOffset++] = (byte)(Si[(t3 >>> 24) ] ^ (t1 >>> 24)); 591 out[outOffset++] = (byte)(Si[(a2 >>> 16) & 0xFF] ^ (t1 >>> 16)); 592 out[outOffset++] = (byte)(Si[(a1 >>> 8) & 0xFF] ^ (t1 >>> 8)); 593 out[outOffset ] = (byte)(Si[(a0 ) & 0xFF] ^ (t1 )); 594 } 595 596 /** 597 * Expand a user-supplied key material into a session key. 598 * 599 * @param k The 128/192/256-bit cipher key to use. 600 * @exception InvalidKeyException If the key is invalid. 601 */ 602 private void makeSessionKey(byte[] k) throws InvalidKeyException { 603 if (k == null) { 604 throw new InvalidKeyException("Empty key"); 605 } 606 if (!isKeySizeValid(k.length)) { 607 throw new InvalidKeyException("Invalid AES key length: " + 608 k.length + " bytes"); 609 } 610 int ROUNDS = getRounds(k.length); 611 int ROUND_KEY_COUNT = (ROUNDS + 1) * 4; 612 613 int BC = 4; 614 int[][] Ke = new int[ROUNDS + 1][4]; // encryption round keys 615 int[][] Kd = new int[ROUNDS + 1][4]; // decryption round keys 616 617 int KC = k.length/4; // keylen in 32-bit elements 618 619 int[] tk = new int[KC]; 620 int i, j; 621 622 // copy user material bytes into temporary ints 623 for (i = 0, j = 0; i < KC; i++, j+=4) { 624 tk[i] = (k[j] ) << 24 | 625 (k[j+1] & 0xFF) << 16 | 626 (k[j+2] & 0xFF) << 8 | 627 (k[j+3] & 0xFF); 628 } 629 630 // copy values into round key arrays 631 int t = 0; 632 for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) { 633 Ke[t / 4][t % 4] = tk[j]; 634 Kd[ROUNDS - (t / 4)][t % 4] = tk[j]; 635 } 636 int tt, rconpointer = 0; 637 while (t < ROUND_KEY_COUNT) { 638 // extrapolate using phi (the round key evolution function) 639 tt = tk[KC - 1]; 640 tk[0] ^= (S[(tt >>> 16) & 0xFF] ) << 24 ^ 641 (S[(tt >>> 8) & 0xFF] & 0xFF) << 16 ^ 642 (S[(tt ) & 0xFF] & 0xFF) << 8 ^ 643 (S[(tt >>> 24) ] & 0xFF) ^ 644 (rcon[rconpointer++] ) << 24; 645 if (KC != 8) 646 for (i = 1, j = 0; i < KC; i++, j++) tk[i] ^= tk[j]; 647 else { 648 for (i = 1, j = 0; i < KC / 2; i++, j++) tk[i] ^= tk[j]; 649 tt = tk[KC / 2 - 1]; 650 tk[KC / 2] ^= (S[(tt ) & 0xFF] & 0xFF) ^ 651 (S[(tt >>> 8) & 0xFF] & 0xFF) << 8 ^ 652 (S[(tt >>> 16) & 0xFF] & 0xFF) << 16 ^ 653 (S[(tt >>> 24) ] ) << 24; 654 for (j = KC / 2, i = j + 1; i < KC; i++, j++) tk[i] ^= tk[j]; 655 } 656 // copy values into round key arrays 657 for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) { 658 Ke[t / 4][t % 4] = tk[j]; 659 Kd[ROUNDS - (t / 4)][t % 4] = tk[j]; 660 } 661 } 662 for (int r = 1; r < ROUNDS; r++) { 663 // inverse MixColumn where needed 664 for (j = 0; j < BC; j++) { 665 tt = Kd[r][j]; 666 Kd[r][j] = U1[(tt >>> 24) & 0xFF] ^ 667 U2[(tt >>> 16) & 0xFF] ^ 668 U3[(tt >>> 8) & 0xFF] ^ 669 U4[ tt & 0xFF]; 670 } 671 } 672 673 // assemble the encryption (Ke) and decryption (Kd) round keys 674 // and expand them into arrays of ints. 675 int[] expandedKe = expandToSubKey(Ke, false); // decrypting==false 676 int[] expandedKd = expandToSubKey(Kd, true); // decrypting==true 677 678 ROUNDS_12 = (ROUNDS>=12); 679 ROUNDS_14 = (ROUNDS==14); 680 limit = ROUNDS*4; 681 682 // store the expanded sub keys into 'sessionK' 683 sessionK = new int[][] { expandedKe, expandedKd }; 684 } 685 686 687 /** 688 * Return The number of rounds for a given Rijndael keysize. 689 * 690 * @param keySize The size of the user key material in bytes. 691 * MUST be one of (16, 24, 32). 692 * @return The number of rounds. 693 */ 694 private static int getRounds(int keySize) { 695 return (keySize >> 2) + 6; 696 } 697 }