View Javadoc
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 }