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 Object[] 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 = (int[]) 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 Object[] { 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 }
--- EOF ---