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