Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/crypto/provider/AESCrypt.java
38922 views
/*1* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/* $Id: Rijndael.java,v 1.6 2000/02/10 01:31:41 gelderen Exp $26*27* Copyright (C) 1995-2000 The Cryptix Foundation Limited.28* All rights reserved.29*30* Use, modification, copying and distribution of this softwareas is subject31* the terms and conditions of the Cryptix General Licence. You should have32* received a copy of the Cryptix General Licence along with this library;33* if not, you can download a copy from http://www.cryptix.org/ .34*/3536package com.sun.crypto.provider;3738import java.security.InvalidKeyException;39import java.security.MessageDigest;4041/**42* Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit43* block size and variable key-size (128-, 192- and 256-bit).44* <p>45* Rijndael was designed by <a href="mailto:[email protected]">Vincent46* Rijmen</a> and <a href="mailto:[email protected]">Joan Daemen</a>.47*/48final class AESCrypt extends SymmetricCipher implements AESConstants49{50private boolean ROUNDS_12 = false;51private boolean ROUNDS_14 = false;5253/** Session and Sub keys */54private int[][] sessionK = null;55private int[] K = null;5657/** Cipher encryption/decryption key */58// skip re-generating Session and Sub keys if the cipher key is59// the same60private byte[] lastKey = null;6162/** ROUNDS * 4 */63private int limit = 0;6465AESCrypt() {66// empty67}6869/**70* Returns this cipher's block size.71*72* @return this cipher's block size73*/74int getBlockSize() {75return AES_BLOCK_SIZE;76}7778void init(boolean decrypting, String algorithm, byte[] key)79throws InvalidKeyException {80if (!algorithm.equalsIgnoreCase("AES")81&& !algorithm.equalsIgnoreCase("Rijndael")) {82throw new InvalidKeyException83("Wrong algorithm: AES or Rijndael required");84}85if (!isKeySizeValid(key.length)) {86throw new InvalidKeyException("Invalid AES key length: " +87key.length + " bytes");88}8990if (!MessageDigest.isEqual(key, lastKey)) {91// re-generate session key 'sessionK' when cipher key changes92makeSessionKey(key);93lastKey = key.clone(); // save cipher key94}9596// set sub key to the corresponding session Key97this.K = sessionK[(decrypting? 1:0)];98}99100/**101* Expand an int[(ROUNDS+1)][4] into int[(ROUNDS+1)*4].102* For decryption round keys, need to rotate right by 4 ints.103* @param kr The round keys for encryption or decryption.104* @param decrypting True if 'kr' is for decryption and false otherwise.105*/106private static final int[] expandToSubKey(int[][] kr, boolean decrypting) {107int total = kr.length;108int[] expK = new int[total*4];109if (decrypting) {110// decrypting, rotate right by 4 ints111// i.e. i==0112for(int j=0; j<4; j++) {113expK[j] = kr[total-1][j];114}115for(int i=1; i<total; i++) {116for(int j=0; j<4; j++) {117expK[i*4 + j] = kr[i-1][j];118}119}120} else {121// encrypting, straight expansion122for(int i=0; i<total; i++) {123for(int j=0; j<4; j++) {124expK[i*4 + j] = kr[i][j];125}126}127}128return expK;129}130131private static int[]132alog = new int[256],133log = new int[256];134135private static final byte[]136S = new byte[256],137Si = new byte[256];138139private static final int[]140T1 = new int[256],141T2 = new int[256],142T3 = new int[256],143T4 = new int[256],144T5 = new int[256],145T6 = new int[256],146T7 = new int[256],147T8 = new int[256];148149private static final int[]150U1 = new int[256],151U2 = new int[256],152U3 = new int[256],153U4 = new int[256];154155private static final byte[] rcon = new byte[30];156157158// Static code - to intialise S-boxes and T-boxes159static160{161int ROOT = 0x11B;162int i, j = 0;163164//165// produce log and alog tables, needed for multiplying in the166// field GF(2^m) (generator = 3)167//168alog[0] = 1;169for (i = 1; i < 256; i++)170{171j = (alog[i-1] << 1) ^ alog[i-1];172if ((j & 0x100) != 0) {173j ^= ROOT;174}175alog[i] = j;176}177for (i = 1; i < 255; i++) {178log[alog[i]] = i;179}180byte[][] A = new byte[][]181{182{1, 1, 1, 1, 1, 0, 0, 0},183{0, 1, 1, 1, 1, 1, 0, 0},184{0, 0, 1, 1, 1, 1, 1, 0},185{0, 0, 0, 1, 1, 1, 1, 1},186{1, 0, 0, 0, 1, 1, 1, 1},187{1, 1, 0, 0, 0, 1, 1, 1},188{1, 1, 1, 0, 0, 0, 1, 1},189{1, 1, 1, 1, 0, 0, 0, 1}190};191byte[] B = new byte[] { 0, 1, 1, 0, 0, 0, 1, 1};192193//194// substitution box based on F^{-1}(x)195//196int t;197byte[][] box = new byte[256][8];198box[1][7] = 1;199for (i = 2; i < 256; i++) {200j = alog[255 - log[i]];201for (t = 0; t < 8; t++) {202box[i][t] = (byte)((j >>> (7 - t)) & 0x01);203}204}205//206// affine transform: box[i] <- B + A*box[i]207//208byte[][] cox = new byte[256][8];209for (i = 0; i < 256; i++) {210for (t = 0; t < 8; t++) {211cox[i][t] = B[t];212for (j = 0; j < 8; j++) {213cox[i][t] ^= A[t][j] * box[i][j];214}215}216}217//218// S-boxes and inverse S-boxes219//220for (i = 0; i < 256; i++) {221S[i] = (byte)(cox[i][0] << 7);222for (t = 1; t < 8; t++) {223S[i] ^= cox[i][t] << (7-t);224}225Si[S[i] & 0xFF] = (byte) i;226}227//228// T-boxes229//230byte[][] G = new byte[][] {231{2, 1, 1, 3},232{3, 2, 1, 1},233{1, 3, 2, 1},234{1, 1, 3, 2}235};236byte[][] AA = new byte[4][8];237for (i = 0; i < 4; i++) {238for (j = 0; j < 4; j++) AA[i][j] = G[i][j];239AA[i][i+4] = 1;240}241byte pivot, tmp;242byte[][] iG = new byte[4][4];243for (i = 0; i < 4; i++) {244pivot = AA[i][i];245if (pivot == 0) {246t = i + 1;247while ((AA[t][i] == 0) && (t < 4)) {248t++;249}250if (t == 4) {251throw new RuntimeException("G matrix is not invertible");252}253else {254for (j = 0; j < 8; j++) {255tmp = AA[i][j];256AA[i][j] = AA[t][j];257AA[t][j] = tmp;258}259pivot = AA[i][i];260}261}262for (j = 0; j < 8; j++) {263if (AA[i][j] != 0) {264AA[i][j] = (byte)265alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF])266% 255];267}268}269for (t = 0; t < 4; t++) {270if (i != t) {271for (j = i+1; j < 8; j++) {272AA[t][j] ^= mul(AA[i][j], AA[t][i]);273}274AA[t][i] = 0;275}276}277}278for (i = 0; i < 4; i++) {279for (j = 0; j < 4; j++) {280iG[i][j] = AA[i][j + 4];281}282}283284int s;285for (t = 0; t < 256; t++) {286s = S[t];287T1[t] = mul4(s, G[0]);288T2[t] = mul4(s, G[1]);289T3[t] = mul4(s, G[2]);290T4[t] = mul4(s, G[3]);291292s = Si[t];293T5[t] = mul4(s, iG[0]);294T6[t] = mul4(s, iG[1]);295T7[t] = mul4(s, iG[2]);296T8[t] = mul4(s, iG[3]);297298U1[t] = mul4(t, iG[0]);299U2[t] = mul4(t, iG[1]);300U3[t] = mul4(t, iG[2]);301U4[t] = mul4(t, iG[3]);302}303//304// round constants305//306rcon[0] = 1;307int r = 1;308for (t = 1; t < 30; t++) {309r = mul(2, r);310rcon[t] = (byte) r;311}312log = null;313alog = null;314}315316// multiply two elements of GF(2^m)317private static final int mul (int a, int b) {318return (a != 0 && b != 0) ?319alog[(log[a & 0xFF] + log[b & 0xFF]) % 255] :3200;321}322323// convenience method used in generating Transposition boxes324private static final int mul4 (int a, byte[] b) {325if (a == 0) return 0;326a = log[a & 0xFF];327int a0 = (b[0] != 0) ? alog[(a + log[b[0] & 0xFF]) % 255] & 0xFF : 0;328int a1 = (b[1] != 0) ? alog[(a + log[b[1] & 0xFF]) % 255] & 0xFF : 0;329int a2 = (b[2] != 0) ? alog[(a + log[b[2] & 0xFF]) % 255] & 0xFF : 0;330int a3 = (b[3] != 0) ? alog[(a + log[b[3] & 0xFF]) % 255] & 0xFF : 0;331return a0 << 24 | a1 << 16 | a2 << 8 | a3;332}333334// check if the specified length (in bytes) is a valid keysize for AES335static final boolean isKeySizeValid(int len) {336for (int i = 0; i < AES_KEYSIZES.length; i++) {337if (len == AES_KEYSIZES[i]) {338return true;339}340}341return false;342}343344/**345* Encrypt exactly one block of plaintext.346*/347void encryptBlock(byte[] in, int inOffset,348byte[] out, int outOffset) {349// Array bound checks are done in caller code, i.e.350// FeedbackCipher.encrypt/decrypt(...) to improve performance.351implEncryptBlock(in, inOffset, out, outOffset);352}353354// Encryption operation. Possibly replaced with a compiler intrinsic.355private void implEncryptBlock(byte[] in, int inOffset,356byte[] out, int outOffset)357{358int keyOffset = 0;359int t0 = ((in[inOffset++] ) << 24 |360(in[inOffset++] & 0xFF) << 16 |361(in[inOffset++] & 0xFF) << 8 |362(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];363int t1 = ((in[inOffset++] ) << 24 |364(in[inOffset++] & 0xFF) << 16 |365(in[inOffset++] & 0xFF) << 8 |366(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];367int t2 = ((in[inOffset++] ) << 24 |368(in[inOffset++] & 0xFF) << 16 |369(in[inOffset++] & 0xFF) << 8 |370(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];371int t3 = ((in[inOffset++] ) << 24 |372(in[inOffset++] & 0xFF) << 16 |373(in[inOffset++] & 0xFF) << 8 |374(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];375376// apply round transforms377while( keyOffset < limit )378{379int a0, a1, a2;380a0 = T1[(t0 >>> 24) ] ^381T2[(t1 >>> 16) & 0xFF] ^382T3[(t2 >>> 8) & 0xFF] ^383T4[(t3 ) & 0xFF] ^ K[keyOffset++];384a1 = T1[(t1 >>> 24) ] ^385T2[(t2 >>> 16) & 0xFF] ^386T3[(t3 >>> 8) & 0xFF] ^387T4[(t0 ) & 0xFF] ^ K[keyOffset++];388a2 = T1[(t2 >>> 24) ] ^389T2[(t3 >>> 16) & 0xFF] ^390T3[(t0 >>> 8) & 0xFF] ^391T4[(t1 ) & 0xFF] ^ K[keyOffset++];392t3 = T1[(t3 >>> 24) ] ^393T2[(t0 >>> 16) & 0xFF] ^394T3[(t1 >>> 8) & 0xFF] ^395T4[(t2 ) & 0xFF] ^ K[keyOffset++];396t0 = a0; t1 = a1; t2 = a2;397}398399// last round is special400int tt = K[keyOffset++];401out[outOffset++] = (byte)(S[(t0 >>> 24) ] ^ (tt >>> 24));402out[outOffset++] = (byte)(S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));403out[outOffset++] = (byte)(S[(t2 >>> 8) & 0xFF] ^ (tt >>> 8));404out[outOffset++] = (byte)(S[(t3 ) & 0xFF] ^ (tt ));405tt = K[keyOffset++];406out[outOffset++] = (byte)(S[(t1 >>> 24) ] ^ (tt >>> 24));407out[outOffset++] = (byte)(S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));408out[outOffset++] = (byte)(S[(t3 >>> 8) & 0xFF] ^ (tt >>> 8));409out[outOffset++] = (byte)(S[(t0 ) & 0xFF] ^ (tt ));410tt = K[keyOffset++];411out[outOffset++] = (byte)(S[(t2 >>> 24) ] ^ (tt >>> 24));412out[outOffset++] = (byte)(S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));413out[outOffset++] = (byte)(S[(t0 >>> 8) & 0xFF] ^ (tt >>> 8));414out[outOffset++] = (byte)(S[(t1 ) & 0xFF] ^ (tt ));415tt = K[keyOffset++];416out[outOffset++] = (byte)(S[(t3 >>> 24) ] ^ (tt >>> 24));417out[outOffset++] = (byte)(S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));418out[outOffset++] = (byte)(S[(t1 >>> 8) & 0xFF] ^ (tt >>> 8));419out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt ));420}421422/**423* Decrypt exactly one block of plaintext.424*/425void decryptBlock(byte[] in, int inOffset,426byte[] out, int outOffset) {427// Array bound checks are done in caller code, i.e.428// FeedbackCipher.encrypt/decrypt(...) to improve performance.429implDecryptBlock(in, inOffset, out, outOffset);430}431432// Decrypt operation. Possibly replaced with a compiler intrinsic.433private void implDecryptBlock(byte[] in, int inOffset,434byte[] out, int outOffset)435{436int keyOffset = 4;437int t0 = ((in[inOffset++] ) << 24 |438(in[inOffset++] & 0xFF) << 16 |439(in[inOffset++] & 0xFF) << 8 |440(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];441int t1 = ((in[inOffset++] ) << 24 |442(in[inOffset++] & 0xFF) << 16 |443(in[inOffset++] & 0xFF) << 8 |444(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];445int t2 = ((in[inOffset++] ) << 24 |446(in[inOffset++] & 0xFF) << 16 |447(in[inOffset++] & 0xFF) << 8 |448(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];449int t3 = ((in[inOffset++] ) << 24 |450(in[inOffset++] & 0xFF) << 16 |451(in[inOffset++] & 0xFF) << 8 |452(in[inOffset ] & 0xFF) ) ^ K[keyOffset++];453454int a0, a1, a2;455if(ROUNDS_12)456{457a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^458T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];459a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^460T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];461a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^462T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];463t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^464T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];465t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^466T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];467t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^468T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];469t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^470T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];471t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^472T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];473474if(ROUNDS_14)475{476a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^477T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];478a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^479T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];480a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^481T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];482t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^483T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];484t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^485T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];486t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^487T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];488t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^489T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];490t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^491T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];492}493}494a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^495T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];496a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^497T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];498a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^499T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];500t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^501T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];502t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^503T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];504t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^505T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];506t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^507T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];508t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^509T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];510a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^511T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];512a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^513T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];514a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^515T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];516t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^517T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];518t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^519T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];520t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^521T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];522t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^523T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];524t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^525T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];526a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^527T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];528a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^529T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];530a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^531T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];532t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^533T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];534t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^535T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];536t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^537T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];538t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^539T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];540t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^541T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];542a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^543T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];544a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^545T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];546a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^547T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];548t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^549T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];550t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^551T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];552t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^553T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];554t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^555T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];556t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^557T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];558a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^559T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];560a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^561T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];562a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^563T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];564t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^565T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];566567t1 = K[0];568out[outOffset++] = (byte)(Si[(a0 >>> 24) ] ^ (t1 >>> 24));569out[outOffset++] = (byte)(Si[(t3 >>> 16) & 0xFF] ^ (t1 >>> 16));570out[outOffset++] = (byte)(Si[(a2 >>> 8) & 0xFF] ^ (t1 >>> 8));571out[outOffset++] = (byte)(Si[(a1 ) & 0xFF] ^ (t1 ));572t1 = K[1];573out[outOffset++] = (byte)(Si[(a1 >>> 24) ] ^ (t1 >>> 24));574out[outOffset++] = (byte)(Si[(a0 >>> 16) & 0xFF] ^ (t1 >>> 16));575out[outOffset++] = (byte)(Si[(t3 >>> 8) & 0xFF] ^ (t1 >>> 8));576out[outOffset++] = (byte)(Si[(a2 ) & 0xFF] ^ (t1 ));577t1 = K[2];578out[outOffset++] = (byte)(Si[(a2 >>> 24) ] ^ (t1 >>> 24));579out[outOffset++] = (byte)(Si[(a1 >>> 16) & 0xFF] ^ (t1 >>> 16));580out[outOffset++] = (byte)(Si[(a0 >>> 8) & 0xFF] ^ (t1 >>> 8));581out[outOffset++] = (byte)(Si[(t3 ) & 0xFF] ^ (t1 ));582t1 = K[3];583out[outOffset++] = (byte)(Si[(t3 >>> 24) ] ^ (t1 >>> 24));584out[outOffset++] = (byte)(Si[(a2 >>> 16) & 0xFF] ^ (t1 >>> 16));585out[outOffset++] = (byte)(Si[(a1 >>> 8) & 0xFF] ^ (t1 >>> 8));586out[outOffset ] = (byte)(Si[(a0 ) & 0xFF] ^ (t1 ));587}588589/**590* Expand a user-supplied key material into a session key.591*592* @param k The 128/192/256-bit cipher key to use.593* @exception InvalidKeyException If the key is invalid.594*/595private void makeSessionKey(byte[] k) throws InvalidKeyException {596if (k == null) {597throw new InvalidKeyException("Empty key");598}599if (!isKeySizeValid(k.length)) {600throw new InvalidKeyException("Invalid AES key length: " +601k.length + " bytes");602}603int ROUNDS = getRounds(k.length);604int ROUND_KEY_COUNT = (ROUNDS + 1) * 4;605606int BC = 4;607int[][] Ke = new int[ROUNDS + 1][4]; // encryption round keys608int[][] Kd = new int[ROUNDS + 1][4]; // decryption round keys609610int KC = k.length/4; // keylen in 32-bit elements611612int[] tk = new int[KC];613int i, j;614615// copy user material bytes into temporary ints616for (i = 0, j = 0; i < KC; i++, j+=4) {617tk[i] = (k[j] ) << 24 |618(k[j+1] & 0xFF) << 16 |619(k[j+2] & 0xFF) << 8 |620(k[j+3] & 0xFF);621}622623// copy values into round key arrays624int t = 0;625for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) {626Ke[t / 4][t % 4] = tk[j];627Kd[ROUNDS - (t / 4)][t % 4] = tk[j];628}629int tt, rconpointer = 0;630while (t < ROUND_KEY_COUNT) {631// extrapolate using phi (the round key evolution function)632tt = tk[KC - 1];633tk[0] ^= (S[(tt >>> 16) & 0xFF] ) << 24 ^634(S[(tt >>> 8) & 0xFF] & 0xFF) << 16 ^635(S[(tt ) & 0xFF] & 0xFF) << 8 ^636(S[(tt >>> 24) ] & 0xFF) ^637(rcon[rconpointer++] ) << 24;638if (KC != 8)639for (i = 1, j = 0; i < KC; i++, j++) tk[i] ^= tk[j];640else {641for (i = 1, j = 0; i < KC / 2; i++, j++) tk[i] ^= tk[j];642tt = tk[KC / 2 - 1];643tk[KC / 2] ^= (S[(tt ) & 0xFF] & 0xFF) ^644(S[(tt >>> 8) & 0xFF] & 0xFF) << 8 ^645(S[(tt >>> 16) & 0xFF] & 0xFF) << 16 ^646(S[(tt >>> 24) ] ) << 24;647for (j = KC / 2, i = j + 1; i < KC; i++, j++) tk[i] ^= tk[j];648}649// copy values into round key arrays650for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) {651Ke[t / 4][t % 4] = tk[j];652Kd[ROUNDS - (t / 4)][t % 4] = tk[j];653}654}655for (int r = 1; r < ROUNDS; r++) {656// inverse MixColumn where needed657for (j = 0; j < BC; j++) {658tt = Kd[r][j];659Kd[r][j] = U1[(tt >>> 24) & 0xFF] ^660U2[(tt >>> 16) & 0xFF] ^661U3[(tt >>> 8) & 0xFF] ^662U4[ tt & 0xFF];663}664}665666// assemble the encryption (Ke) and decryption (Kd) round keys667// and expand them into arrays of ints.668int[] expandedKe = expandToSubKey(Ke, false); // decrypting==false669int[] expandedKd = expandToSubKey(Kd, true); // decrypting==true670671ROUNDS_12 = (ROUNDS>=12);672ROUNDS_14 = (ROUNDS==14);673limit = ROUNDS*4;674675// store the expanded sub keys into 'sessionK'676sessionK = new int[][] { expandedKe, expandedKd };677}678679680/**681* Return The number of rounds for a given Rijndael keysize.682*683* @param keySize The size of the user key material in bytes.684* MUST be one of (16, 24, 32).685* @return The number of rounds.686*/687private static int getRounds(int keySize) {688return (keySize >> 2) + 6;689}690}691692693