Path: blob/master/src/java.base/share/classes/com/sun/crypto/provider/AESCrypt.java
41161 views
/*1* Copyright (c) 2002, 2021, 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;40import java.util.Arrays;4142import jdk.internal.vm.annotation.IntrinsicCandidate;4344/**45* Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit46* block size and variable key-size (128-, 192- and 256-bit).47* <p>48* Rijndael was designed by <a href="mailto:[email protected]">Vincent49* Rijmen</a> and <a href="mailto:[email protected]">Joan Daemen</a>.50*/51final class AESCrypt extends SymmetricCipher implements AESConstants52{53private boolean ROUNDS_12 = false;54private boolean ROUNDS_14 = false;5556/** Session and Sub keys */57private int[][] sessionK = null;58private int[] K = null;5960/** Cipher encryption/decryption key */61// skip re-generating Session and Sub keys if the cipher key is62// the same63private byte[] lastKey = null;6465/** ROUNDS * 4 */66private int limit = 0;6768AESCrypt() {69// empty70}7172/**73* Returns this cipher's block size.74*75* @return this cipher's block size76*/77int getBlockSize() {78return AES_BLOCK_SIZE;79}8081void init(boolean decrypting, String algorithm, byte[] key)82throws InvalidKeyException {83if (!algorithm.equalsIgnoreCase("AES")84&& !algorithm.equalsIgnoreCase("Rijndael")) {85throw new InvalidKeyException86("Wrong algorithm: AES or Rijndael required");87}88if (!isKeySizeValid(key.length)) {89throw new InvalidKeyException("Invalid AES key length: " +90key.length + " bytes");91}9293if (!MessageDigest.isEqual(key, lastKey)) {94// re-generate session key 'sessionK' when cipher key changes95makeSessionKey(key);96if (lastKey != null) {97Arrays.fill(lastKey, (byte)0);98}99lastKey = key.clone(); // save cipher key100}101102// set sub key to the corresponding session Key103this.K = sessionK[(decrypting? 1:0)];104}105106/**107* Expand an int[(ROUNDS+1)][4] into int[(ROUNDS+1)*4].108* For decryption round keys, need to rotate right by 4 ints.109* @param kr The round keys for encryption or decryption.110* @param decrypting True if 'kr' is for decryption and false otherwise.111*/112private static final int[] expandToSubKey(int[][] kr, boolean decrypting) {113int total = kr.length;114int[] expK = new int[total*4];115if (decrypting) {116// decrypting, rotate right by 4 ints117// i.e. i==0118for(int j=0; j<4; j++) {119expK[j] = kr[total-1][j];120}121for(int i=1; i<total; i++) {122for(int j=0; j<4; j++) {123expK[i*4 + j] = kr[i-1][j];124}125}126} else {127// encrypting, straight expansion128for(int i=0; i<total; i++) {129for(int j=0; j<4; j++) {130expK[i*4 + j] = kr[i][j];131}132}133}134return expK;135}136137private static int[]138alog = new int[256],139log = new int[256];140141private static final byte[]142S = new byte[256],143Si = new byte[256];144145private static final int[]146T1 = new int[256],147T2 = new int[256],148T3 = new int[256],149T4 = new int[256],150T5 = new int[256],151T6 = new int[256],152T7 = new int[256],153T8 = new int[256];154155private static final int[]156U1 = new int[256],157U2 = new int[256],158U3 = new int[256],159U4 = new int[256];160161private static final byte[] rcon = new byte[30];162163164// Static code - to intialise S-boxes and T-boxes165static166{167int ROOT = 0x11B;168int i, j = 0;169170//171// produce log and alog tables, needed for multiplying in the172// field GF(2^m) (generator = 3)173//174alog[0] = 1;175for (i = 1; i < 256; i++)176{177j = (alog[i-1] << 1) ^ alog[i-1];178if ((j & 0x100) != 0) {179j ^= ROOT;180}181alog[i] = j;182}183for (i = 1; i < 255; i++) {184log[alog[i]] = i;185}186byte[][] A = new byte[][]187{188{1, 1, 1, 1, 1, 0, 0, 0},189{0, 1, 1, 1, 1, 1, 0, 0},190{0, 0, 1, 1, 1, 1, 1, 0},191{0, 0, 0, 1, 1, 1, 1, 1},192{1, 0, 0, 0, 1, 1, 1, 1},193{1, 1, 0, 0, 0, 1, 1, 1},194{1, 1, 1, 0, 0, 0, 1, 1},195{1, 1, 1, 1, 0, 0, 0, 1}196};197byte[] B = new byte[] { 0, 1, 1, 0, 0, 0, 1, 1};198199//200// substitution box based on F^{-1}(x)201//202int t;203byte[][] box = new byte[256][8];204box[1][7] = 1;205for (i = 2; i < 256; i++) {206j = alog[255 - log[i]];207for (t = 0; t < 8; t++) {208box[i][t] = (byte)((j >>> (7 - t)) & 0x01);209}210}211//212// affine transform: box[i] <- B + A*box[i]213//214byte[][] cox = new byte[256][8];215for (i = 0; i < 256; i++) {216for (t = 0; t < 8; t++) {217cox[i][t] = B[t];218for (j = 0; j < 8; j++) {219cox[i][t] ^= A[t][j] * box[i][j];220}221}222}223//224// S-boxes and inverse S-boxes225//226for (i = 0; i < 256; i++) {227S[i] = (byte)(cox[i][0] << 7);228for (t = 1; t < 8; t++) {229S[i] ^= cox[i][t] << (7-t);230}231Si[S[i] & 0xFF] = (byte) i;232}233//234// T-boxes235//236byte[][] G = new byte[][] {237{2, 1, 1, 3},238{3, 2, 1, 1},239{1, 3, 2, 1},240{1, 1, 3, 2}241};242byte[][] AA = new byte[4][8];243for (i = 0; i < 4; i++) {244for (j = 0; j < 4; j++) AA[i][j] = G[i][j];245AA[i][i+4] = 1;246}247byte pivot, tmp;248byte[][] iG = new byte[4][4];249for (i = 0; i < 4; i++) {250pivot = AA[i][i];251if (pivot == 0) {252t = i + 1;253while ((AA[t][i] == 0) && (t < 4)) {254t++;255}256if (t == 4) {257throw new RuntimeException("G matrix is not invertible");258}259else {260for (j = 0; j < 8; j++) {261tmp = AA[i][j];262AA[i][j] = AA[t][j];263AA[t][j] = tmp;264}265pivot = AA[i][i];266}267}268for (j = 0; j < 8; j++) {269if (AA[i][j] != 0) {270AA[i][j] = (byte)271alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF])272% 255];273}274}275for (t = 0; t < 4; t++) {276if (i != t) {277for (j = i+1; j < 8; j++) {278AA[t][j] ^= mul(AA[i][j], AA[t][i]);279}280AA[t][i] = 0;281}282}283}284for (i = 0; i < 4; i++) {285for (j = 0; j < 4; j++) {286iG[i][j] = AA[i][j + 4];287}288}289290int s;291for (t = 0; t < 256; t++) {292s = S[t];293T1[t] = mul4(s, G[0]);294T2[t] = mul4(s, G[1]);295T3[t] = mul4(s, G[2]);296T4[t] = mul4(s, G[3]);297298s = Si[t];299T5[t] = mul4(s, iG[0]);300T6[t] = mul4(s, iG[1]);301T7[t] = mul4(s, iG[2]);302T8[t] = mul4(s, iG[3]);303304U1[t] = mul4(t, iG[0]);305U2[t] = mul4(t, iG[1]);306U3[t] = mul4(t, iG[2]);307U4[t] = mul4(t, iG[3]);308}309//310// round constants311//312rcon[0] = 1;313int r = 1;314for (t = 1; t < 30; t++) {315r = mul(2, r);316rcon[t] = (byte) r;317}318log = null;319alog = null;320}321322// multiply two elements of GF(2^m)323private static final int mul (int a, int b) {324return (a != 0 && b != 0) ?325alog[(log[a & 0xFF] + log[b & 0xFF]) % 255] :3260;327}328329// convenience method used in generating Transposition boxes330private static final int mul4 (int a, byte[] b) {331if (a == 0) return 0;332a = log[a & 0xFF];333int a0 = (b[0] != 0) ? alog[(a + log[b[0] & 0xFF]) % 255] & 0xFF : 0;334int a1 = (b[1] != 0) ? alog[(a + log[b[1] & 0xFF]) % 255] & 0xFF : 0;335int a2 = (b[2] != 0) ? alog[(a + log[b[2] & 0xFF]) % 255] & 0xFF : 0;336int a3 = (b[3] != 0) ? alog[(a + log[b[3] & 0xFF]) % 255] & 0xFF : 0;337return a0 << 24 | a1 << 16 | a2 << 8 | a3;338}339340// check if the specified length (in bytes) is a valid keysize for AES341static final boolean isKeySizeValid(int len) {342for (int i = 0; i < AES_KEYSIZES.length; i++) {343if (len == AES_KEYSIZES[i]) {344return true;345}346}347return false;348}349350/**351* Encrypt exactly one block of plaintext.352*/353void encryptBlock(byte[] in, int inOffset,354byte[] out, int outOffset) {355// Array bound checks are done in caller code, i.e.356// FeedbackCipher.encrypt/decrypt(...) to improve performance.357implEncryptBlock(in, inOffset, out, outOffset);358}359360// Encryption operation. Possibly replaced with a compiler intrinsic.361@IntrinsicCandidate362private void implEncryptBlock(byte[] in, int inOffset,363byte[] out, int outOffset)364{365int keyOffset = 0;366int t0 = ((in[inOffset++] ) << 24 |367(in[inOffset++] & 0xFF) << 16 |368(in[inOffset++] & 0xFF) << 8 |369(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];370int t1 = ((in[inOffset++] ) << 24 |371(in[inOffset++] & 0xFF) << 16 |372(in[inOffset++] & 0xFF) << 8 |373(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];374int t2 = ((in[inOffset++] ) << 24 |375(in[inOffset++] & 0xFF) << 16 |376(in[inOffset++] & 0xFF) << 8 |377(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];378int t3 = ((in[inOffset++] ) << 24 |379(in[inOffset++] & 0xFF) << 16 |380(in[inOffset++] & 0xFF) << 8 |381(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];382383// apply round transforms384while( keyOffset < limit )385{386int a0, a1, a2;387a0 = T1[(t0 >>> 24) ] ^388T2[(t1 >>> 16) & 0xFF] ^389T3[(t2 >>> 8) & 0xFF] ^390T4[(t3 ) & 0xFF] ^ K[keyOffset++];391a1 = T1[(t1 >>> 24) ] ^392T2[(t2 >>> 16) & 0xFF] ^393T3[(t3 >>> 8) & 0xFF] ^394T4[(t0 ) & 0xFF] ^ K[keyOffset++];395a2 = T1[(t2 >>> 24) ] ^396T2[(t3 >>> 16) & 0xFF] ^397T3[(t0 >>> 8) & 0xFF] ^398T4[(t1 ) & 0xFF] ^ K[keyOffset++];399t3 = T1[(t3 >>> 24) ] ^400T2[(t0 >>> 16) & 0xFF] ^401T3[(t1 >>> 8) & 0xFF] ^402T4[(t2 ) & 0xFF] ^ K[keyOffset++];403t0 = a0; t1 = a1; t2 = a2;404}405406// last round is special407int tt = K[keyOffset++];408out[outOffset++] = (byte)(S[(t0 >>> 24) ] ^ (tt >>> 24));409out[outOffset++] = (byte)(S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));410out[outOffset++] = (byte)(S[(t2 >>> 8) & 0xFF] ^ (tt >>> 8));411out[outOffset++] = (byte)(S[(t3 ) & 0xFF] ^ (tt ));412tt = K[keyOffset++];413out[outOffset++] = (byte)(S[(t1 >>> 24) ] ^ (tt >>> 24));414out[outOffset++] = (byte)(S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));415out[outOffset++] = (byte)(S[(t3 >>> 8) & 0xFF] ^ (tt >>> 8));416out[outOffset++] = (byte)(S[(t0 ) & 0xFF] ^ (tt ));417tt = K[keyOffset++];418out[outOffset++] = (byte)(S[(t2 >>> 24) ] ^ (tt >>> 24));419out[outOffset++] = (byte)(S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));420out[outOffset++] = (byte)(S[(t0 >>> 8) & 0xFF] ^ (tt >>> 8));421out[outOffset++] = (byte)(S[(t1 ) & 0xFF] ^ (tt ));422tt = K[keyOffset++];423out[outOffset++] = (byte)(S[(t3 >>> 24) ] ^ (tt >>> 24));424out[outOffset++] = (byte)(S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));425out[outOffset++] = (byte)(S[(t1 >>> 8) & 0xFF] ^ (tt >>> 8));426out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt ));427}428429/**430* Decrypt exactly one block of plaintext.431*/432void decryptBlock(byte[] in, int inOffset,433byte[] out, int outOffset) {434// Array bound checks are done in caller code, i.e.435// FeedbackCipher.encrypt/decrypt(...) to improve performance.436implDecryptBlock(in, inOffset, out, outOffset);437}438439// Decrypt operation. Possibly replaced with a compiler intrinsic.440@IntrinsicCandidate441private void implDecryptBlock(byte[] in, int inOffset,442byte[] out, int outOffset)443{444int keyOffset = 4;445int t0 = ((in[inOffset++] ) << 24 |446(in[inOffset++] & 0xFF) << 16 |447(in[inOffset++] & 0xFF) << 8 |448(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];449int t1 = ((in[inOffset++] ) << 24 |450(in[inOffset++] & 0xFF) << 16 |451(in[inOffset++] & 0xFF) << 8 |452(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];453int t2 = ((in[inOffset++] ) << 24 |454(in[inOffset++] & 0xFF) << 16 |455(in[inOffset++] & 0xFF) << 8 |456(in[inOffset++] & 0xFF) ) ^ K[keyOffset++];457int t3 = ((in[inOffset++] ) << 24 |458(in[inOffset++] & 0xFF) << 16 |459(in[inOffset++] & 0xFF) << 8 |460(in[inOffset ] & 0xFF) ) ^ K[keyOffset++];461462int a0, a1, a2;463if(ROUNDS_12)464{465a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^466T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];467a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^468T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];469a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^470T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];471t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^472T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];473t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^474T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];475t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^476T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];477t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^478T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];479t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^480T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];481482if(ROUNDS_14)483{484a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^485T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];486a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^487T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];488a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^489T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];490t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^491T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];492t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^493T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];494t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^495T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];496t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^497T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];498t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^499T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];500}501}502a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^503T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];504a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^505T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];506a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^507T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];508t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^509T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];510t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^511T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];512t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^513T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];514t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^515T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];516t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^517T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];518a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^519T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];520a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^521T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];522a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^523T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];524t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^525T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];526t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^527T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];528t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^529T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];530t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^531T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];532t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^533T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];534a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^535T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];536a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^537T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];538a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^539T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];540t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^541T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];542t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^543T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];544t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^545T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];546t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^547T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];548t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^549T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];550a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^551T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];552a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^553T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];554a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^555T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];556t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^557T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];558t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^559T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];560t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^561T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];562t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^563T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];564t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^565T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];566a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^567T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];568a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^569T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];570a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^571T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];572t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^573T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];574575t1 = K[0];576out[outOffset++] = (byte)(Si[(a0 >>> 24) ] ^ (t1 >>> 24));577out[outOffset++] = (byte)(Si[(t3 >>> 16) & 0xFF] ^ (t1 >>> 16));578out[outOffset++] = (byte)(Si[(a2 >>> 8) & 0xFF] ^ (t1 >>> 8));579out[outOffset++] = (byte)(Si[(a1 ) & 0xFF] ^ (t1 ));580t1 = K[1];581out[outOffset++] = (byte)(Si[(a1 >>> 24) ] ^ (t1 >>> 24));582out[outOffset++] = (byte)(Si[(a0 >>> 16) & 0xFF] ^ (t1 >>> 16));583out[outOffset++] = (byte)(Si[(t3 >>> 8) & 0xFF] ^ (t1 >>> 8));584out[outOffset++] = (byte)(Si[(a2 ) & 0xFF] ^ (t1 ));585t1 = K[2];586out[outOffset++] = (byte)(Si[(a2 >>> 24) ] ^ (t1 >>> 24));587out[outOffset++] = (byte)(Si[(a1 >>> 16) & 0xFF] ^ (t1 >>> 16));588out[outOffset++] = (byte)(Si[(a0 >>> 8) & 0xFF] ^ (t1 >>> 8));589out[outOffset++] = (byte)(Si[(t3 ) & 0xFF] ^ (t1 ));590t1 = K[3];591out[outOffset++] = (byte)(Si[(t3 >>> 24) ] ^ (t1 >>> 24));592out[outOffset++] = (byte)(Si[(a2 >>> 16) & 0xFF] ^ (t1 >>> 16));593out[outOffset++] = (byte)(Si[(a1 >>> 8) & 0xFF] ^ (t1 >>> 8));594out[outOffset ] = (byte)(Si[(a0 ) & 0xFF] ^ (t1 ));595}596597/**598* Expand a user-supplied key material into a session key.599*600* @param k The 128/192/256-bit cipher key to use.601* @exception InvalidKeyException If the key is invalid.602*/603private void makeSessionKey(byte[] k) throws InvalidKeyException {604if (k == null) {605throw new InvalidKeyException("Empty key");606}607if (!isKeySizeValid(k.length)) {608throw new InvalidKeyException("Invalid AES key length: " +609k.length + " bytes");610}611int ROUNDS = getRounds(k.length);612int ROUND_KEY_COUNT = (ROUNDS + 1) * 4;613614int BC = 4;615int[][] Ke = new int[ROUNDS + 1][4]; // encryption round keys616int[][] Kd = new int[ROUNDS + 1][4]; // decryption round keys617618int KC = k.length/4; // keylen in 32-bit elements619620int[] tk = new int[KC];621int i, j;622623// copy user material bytes into temporary ints624for (i = 0, j = 0; i < KC; i++, j+=4) {625tk[i] = (k[j] ) << 24 |626(k[j+1] & 0xFF) << 16 |627(k[j+2] & 0xFF) << 8 |628(k[j+3] & 0xFF);629}630631// copy values into round key arrays632int t = 0;633for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) {634Ke[t / 4][t % 4] = tk[j];635Kd[ROUNDS - (t / 4)][t % 4] = tk[j];636}637int tt, rconpointer = 0;638while (t < ROUND_KEY_COUNT) {639// extrapolate using phi (the round key evolution function)640tt = tk[KC - 1];641tk[0] ^= (S[(tt >>> 16) & 0xFF] ) << 24 ^642(S[(tt >>> 8) & 0xFF] & 0xFF) << 16 ^643(S[(tt ) & 0xFF] & 0xFF) << 8 ^644(S[(tt >>> 24) ] & 0xFF) ^645(rcon[rconpointer++] ) << 24;646if (KC != 8)647for (i = 1, j = 0; i < KC; i++, j++) tk[i] ^= tk[j];648else {649for (i = 1, j = 0; i < KC / 2; i++, j++) tk[i] ^= tk[j];650tt = tk[KC / 2 - 1];651tk[KC / 2] ^= (S[(tt ) & 0xFF] & 0xFF) ^652(S[(tt >>> 8) & 0xFF] & 0xFF) << 8 ^653(S[(tt >>> 16) & 0xFF] & 0xFF) << 16 ^654(S[(tt >>> 24) ] ) << 24;655for (j = KC / 2, i = j + 1; i < KC; i++, j++) tk[i] ^= tk[j];656}657// copy values into round key arrays658for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) {659Ke[t / 4][t % 4] = tk[j];660Kd[ROUNDS - (t / 4)][t % 4] = tk[j];661}662}663for (int r = 1; r < ROUNDS; r++) {664// inverse MixColumn where needed665for (j = 0; j < BC; j++) {666tt = Kd[r][j];667Kd[r][j] = U1[(tt >>> 24) & 0xFF] ^668U2[(tt >>> 16) & 0xFF] ^669U3[(tt >>> 8) & 0xFF] ^670U4[ tt & 0xFF];671}672}673674// assemble the encryption (Ke) and decryption (Kd) round keys675// and expand them into arrays of ints.676int[] expandedKe = expandToSubKey(Ke, false); // decrypting==false677int[] expandedKd = expandToSubKey(Kd, true); // decrypting==true678Arrays.fill(tk, 0);679for (int[] ia: Ke) {680Arrays.fill(ia, 0);681}682for (int[] ia: Kd) {683Arrays.fill(ia, 0);684}685ROUNDS_12 = (ROUNDS>=12);686ROUNDS_14 = (ROUNDS==14);687limit = ROUNDS*4;688689// store the expanded sub keys into 'sessionK'690if (sessionK != null) {691// erase the previous values in sessionK692Arrays.fill(sessionK[0], 0);693Arrays.fill(sessionK[1], 0);694}695sessionK = new int[][] { expandedKe, expandedKd };696}697698699/**700* Return The number of rounds for a given Rijndael keysize.701*702* @param keySize The size of the user key material in bytes.703* MUST be one of (16, 24, 32).704* @return The number of rounds.705*/706private static int getRounds(int keySize) {707return (keySize >> 2) + 6;708}709}710711712