1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.crypto.engines; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.BlockCipher; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.CipherParameters; 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.DataLengthException; 6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.params.KeyParameter; 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/** 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * an implementation of the AES (Rijndael), from FIPS-197. 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <p> 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * For further details see: <a href="http://csrc.nist.gov/encryption/aes/">http://csrc.nist.gov/encryption/aes/</a>. 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a> 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * There are three levels of tradeoff of speed vs memory 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Because java has no preprocessor, they are written as three separate classes from which to choose 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * and 4 for decryption. 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * The middle performance version uses only one 256 word table for each, for a total of 2Kbytes, 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * adding 12 rotate operations per round to compute the values contained in the other tables from 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * the contents of the first. 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * The slowest version uses no static tables at all and computes the values in each round. 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <p> 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * This file contains the middle performance version with 2Kbytes of static tables for round precomputation. 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class AESEngine 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam implements BlockCipher 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // The S box 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final byte[] S = { 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)99, (byte)124, (byte)119, (byte)123, (byte)242, (byte)107, (byte)111, (byte)197, 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)48, (byte)1, (byte)103, (byte)43, (byte)254, (byte)215, (byte)171, (byte)118, 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)202, (byte)130, (byte)201, (byte)125, (byte)250, (byte)89, (byte)71, (byte)240, 39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)173, (byte)212, (byte)162, (byte)175, (byte)156, (byte)164, (byte)114, (byte)192, 40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)183, (byte)253, (byte)147, (byte)38, (byte)54, (byte)63, (byte)247, (byte)204, 41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)52, (byte)165, (byte)229, (byte)241, (byte)113, (byte)216, (byte)49, (byte)21, 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)4, (byte)199, (byte)35, (byte)195, (byte)24, (byte)150, (byte)5, (byte)154, 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)7, (byte)18, (byte)128, (byte)226, (byte)235, (byte)39, (byte)178, (byte)117, 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)9, (byte)131, (byte)44, (byte)26, (byte)27, (byte)110, (byte)90, (byte)160, 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)82, (byte)59, (byte)214, (byte)179, (byte)41, (byte)227, (byte)47, (byte)132, 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)83, (byte)209, (byte)0, (byte)237, (byte)32, (byte)252, (byte)177, (byte)91, 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)106, (byte)203, (byte)190, (byte)57, (byte)74, (byte)76, (byte)88, (byte)207, 48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)208, (byte)239, (byte)170, (byte)251, (byte)67, (byte)77, (byte)51, (byte)133, 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)69, (byte)249, (byte)2, (byte)127, (byte)80, (byte)60, (byte)159, (byte)168, 50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)81, (byte)163, (byte)64, (byte)143, (byte)146, (byte)157, (byte)56, (byte)245, 51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)188, (byte)182, (byte)218, (byte)33, (byte)16, (byte)255, (byte)243, (byte)210, 52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)205, (byte)12, (byte)19, (byte)236, (byte)95, (byte)151, (byte)68, (byte)23, 53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)196, (byte)167, (byte)126, (byte)61, (byte)100, (byte)93, (byte)25, (byte)115, 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)96, (byte)129, (byte)79, (byte)220, (byte)34, (byte)42, (byte)144, (byte)136, 55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)70, (byte)238, (byte)184, (byte)20, (byte)222, (byte)94, (byte)11, (byte)219, 56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)224, (byte)50, (byte)58, (byte)10, (byte)73, (byte)6, (byte)36, (byte)92, 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)194, (byte)211, (byte)172, (byte)98, (byte)145, (byte)149, (byte)228, (byte)121, 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)231, (byte)200, (byte)55, (byte)109, (byte)141, (byte)213, (byte)78, (byte)169, 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)108, (byte)86, (byte)244, (byte)234, (byte)101, (byte)122, (byte)174, (byte)8, 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)186, (byte)120, (byte)37, (byte)46, (byte)28, (byte)166, (byte)180, (byte)198, 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)232, (byte)221, (byte)116, (byte)31, (byte)75, (byte)189, (byte)139, (byte)138, 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)112, (byte)62, (byte)181, (byte)102, (byte)72, (byte)3, (byte)246, (byte)14, 63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)97, (byte)53, (byte)87, (byte)185, (byte)134, (byte)193, (byte)29, (byte)158, 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)225, (byte)248, (byte)152, (byte)17, (byte)105, (byte)217, (byte)142, (byte)148, 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)155, (byte)30, (byte)135, (byte)233, (byte)206, (byte)85, (byte)40, (byte)223, 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)140, (byte)161, (byte)137, (byte)13, (byte)191, (byte)230, (byte)66, (byte)104, 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)65, (byte)153, (byte)45, (byte)15, (byte)176, (byte)84, (byte)187, (byte)22, 68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam }; 69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // The inverse S-box 71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final byte[] Si = { 72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)82, (byte)9, (byte)106, (byte)213, (byte)48, (byte)54, (byte)165, (byte)56, 73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)191, (byte)64, (byte)163, (byte)158, (byte)129, (byte)243, (byte)215, (byte)251, 74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)124, (byte)227, (byte)57, (byte)130, (byte)155, (byte)47, (byte)255, (byte)135, 75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)52, (byte)142, (byte)67, (byte)68, (byte)196, (byte)222, (byte)233, (byte)203, 76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)84, (byte)123, (byte)148, (byte)50, (byte)166, (byte)194, (byte)35, (byte)61, 77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)238, (byte)76, (byte)149, (byte)11, (byte)66, (byte)250, (byte)195, (byte)78, 78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)8, (byte)46, (byte)161, (byte)102, (byte)40, (byte)217, (byte)36, (byte)178, 79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)118, (byte)91, (byte)162, (byte)73, (byte)109, (byte)139, (byte)209, (byte)37, 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)114, (byte)248, (byte)246, (byte)100, (byte)134, (byte)104, (byte)152, (byte)22, 81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)212, (byte)164, (byte)92, (byte)204, (byte)93, (byte)101, (byte)182, (byte)146, 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)108, (byte)112, (byte)72, (byte)80, (byte)253, (byte)237, (byte)185, (byte)218, 83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)94, (byte)21, (byte)70, (byte)87, (byte)167, (byte)141, (byte)157, (byte)132, 84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)144, (byte)216, (byte)171, (byte)0, (byte)140, (byte)188, (byte)211, (byte)10, 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)247, (byte)228, (byte)88, (byte)5, (byte)184, (byte)179, (byte)69, (byte)6, 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)208, (byte)44, (byte)30, (byte)143, (byte)202, (byte)63, (byte)15, (byte)2, 87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)193, (byte)175, (byte)189, (byte)3, (byte)1, (byte)19, (byte)138, (byte)107, 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)58, (byte)145, (byte)17, (byte)65, (byte)79, (byte)103, (byte)220, (byte)234, 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)151, (byte)242, (byte)207, (byte)206, (byte)240, (byte)180, (byte)230, (byte)115, 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)150, (byte)172, (byte)116, (byte)34, (byte)231, (byte)173, (byte)53, (byte)133, 91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)226, (byte)249, (byte)55, (byte)232, (byte)28, (byte)117, (byte)223, (byte)110, 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)71, (byte)241, (byte)26, (byte)113, (byte)29, (byte)41, (byte)197, (byte)137, 93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)111, (byte)183, (byte)98, (byte)14, (byte)170, (byte)24, (byte)190, (byte)27, 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)252, (byte)86, (byte)62, (byte)75, (byte)198, (byte)210, (byte)121, (byte)32, 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)154, (byte)219, (byte)192, (byte)254, (byte)120, (byte)205, (byte)90, (byte)244, 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)31, (byte)221, (byte)168, (byte)51, (byte)136, (byte)7, (byte)199, (byte)49, 97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)177, (byte)18, (byte)16, (byte)89, (byte)39, (byte)128, (byte)236, (byte)95, 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)96, (byte)81, (byte)127, (byte)169, (byte)25, (byte)181, (byte)74, (byte)13, 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)45, (byte)229, (byte)122, (byte)159, (byte)147, (byte)201, (byte)156, (byte)239, 100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)160, (byte)224, (byte)59, (byte)77, (byte)174, (byte)42, (byte)245, (byte)176, 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)200, (byte)235, (byte)187, (byte)60, (byte)131, (byte)83, (byte)153, (byte)97, 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)23, (byte)43, (byte)4, (byte)126, (byte)186, (byte)119, (byte)214, (byte)38, 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (byte)225, (byte)105, (byte)20, (byte)99, (byte)85, (byte)33, (byte)12, (byte)125, 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam }; 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // vector used in calculating key schedule (powers of x in GF(256)) 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int[] rcon = { 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 }; 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // precomputation tables of calculations for rounds 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int[] T0 = 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41, 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795, 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, 137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, 138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, 143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, 148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, 153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, 154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, 156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, 161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, 162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x3a16162c}; 166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamprivate static final int[] Tinv0 = 168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, 171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03, 174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, 175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, 176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, 178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, 179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, 180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, 181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, 182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, 184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, 185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, 186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, 187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, 189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd, 190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, 191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793, 0xd296eeb4, 192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, 193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, 194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, 195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, 198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, 200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, 201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0x0d927850, 203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, 205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd, 206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea, 208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, 209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, 210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, 211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a, 214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, 215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, 216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, 217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, 219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 0x4257b8d0}; 221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int shift( 223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int r, 224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int shift) 225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (r >>> shift) | (r << -shift); 227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ 230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int m1 = 0x80808080; 232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int m2 = 0x7f7f7f7f; 233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int m3 = 0x0000001b; 234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int FFmulX(int x) 236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (((x & m2) << 1) ^ (((x & m1) >>> 7) * m3)); 238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /* 241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam The following defines provide alternative definitions of FFmulX that might 242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam give improved performance if a fast 32-bit multiply is not available. 243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); } 245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int m4 = 0x1b1b1b1b; 246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); } 247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int inv_mcol(int x) 251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int f2 = FFmulX(x); 253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int f4 = FFmulX(f2); 254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int f8 = FFmulX(f4); 255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int f9 = x ^ f8; 256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return f2 ^ f4 ^ f8 ^ shift(f2 ^ f9, 8) ^ shift(f4 ^ f9, 16) ^ shift(f9, 24); 258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int subWord(int x) 261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (S[x&255]&255 | ((S[(x>>8)&255]&255)<<8) | ((S[(x>>16)&255]&255)<<16) | S[(x>>24)&255]<<24); 263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Calculate the necessary round keys 267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * The number of calculations depends on key size and block size 268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits 269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * This code is written assuming those are the only possible values 270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int[][] generateWorkingKey( 272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] key, 273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean forEncryption) 274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int KC = key.length / 4; // key length in words 276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int t; 277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (((KC != 4) && (KC != 6) && (KC != 8)) || ((KC * 4) != key.length)) 279b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 280b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("Key length not 128/192/256 bits."); 281b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 282b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes 284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int[][] W = new int[ROUNDS+1][4]; // 4 words in a block 285b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 287b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // copy the key into the round key array 288b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 289b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 290b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam t = 0; 291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int i = 0; 292b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (i < key.length) 293b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 294b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam W[t >> 2][t & 3] = (key[i]&0xff) | ((key[i+1]&0xff) << 8) | ((key[i+2]&0xff) << 16) | (key[i+3] << 24); 295b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam i+=4; 296b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam t++; 297b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 298b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 299b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 300b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // while not enough round key material calculated 301b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // calculate new values 302b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 303b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int k = (ROUNDS + 1) << 2; 304b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (i = KC; (i < k); i++) 305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int temp = W[(i-1)>>2][(i-1)&3]; 307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if ((i % KC) == 0) 308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam temp = subWord(shift(temp, 8)) ^ rcon[(i / KC)-1]; 310b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 311b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if ((KC > 6) && ((i % KC) == 4)) 312b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 313b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam temp = subWord(temp); 314b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 315b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 316b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam W[i>>2][i&3] = W[(i - KC)>>2][(i-KC)&3] ^ temp; 317b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 318b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 319b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!forEncryption) 320b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 321b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int j = 1; j < ROUNDS; j++) 322b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 323b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (i = 0; i < 4; i++) 324b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam W[j][i] = inv_mcol(W[j][i]); 326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 328b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 330b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return W; 331b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 332b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 333b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int ROUNDS; 334b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int[][] WorkingKey = null; 335b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int C0, C1, C2, C3; 336b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private boolean forEncryption; 337b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 338b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int BLOCK_SIZE = 16; 339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 340b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 341b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * default constructor - 128 bit block size. 342b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 343b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public AESEngine() 344b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 345b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 346b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 348b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * initialise an AES cipher. 349b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 350b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param forEncryption whether or not we are for encryption. 351b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param params the parameters required to set up the cipher. 352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception IllegalArgumentException if the params argument is 353b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * inappropriate. 354b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 355b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void init( 356b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean forEncryption, 357b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam CipherParameters params) 358b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 359b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (params instanceof KeyParameter) 360b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 361b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam WorkingKey = generateWorkingKey(((KeyParameter)params).getKey(), forEncryption); 362b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.forEncryption = forEncryption; 363b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return; 364b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 365b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 366b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("invalid parameter passed to AES init - " + params.getClass().getName()); 367b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 368b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 369b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public String getAlgorithmName() 370b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 371b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return "AES"; 372b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 373b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 374b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int getBlockSize() 375b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 376b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return BLOCK_SIZE; 377b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 378b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 379b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int processBlock( 380b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] in, 381b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inOff, 382b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] out, 383b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int outOff) 384b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 385b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (WorkingKey == null) 386b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 387b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalStateException("AES engine not initialised"); 388b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 389b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 390b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if ((inOff + (32 / 2)) > in.length) 391b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 392b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new DataLengthException("input buffer too short"); 393b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 394b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 395b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if ((outOff + (32 / 2)) > out.length) 396b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 397b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new DataLengthException("output buffer too short"); 398b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 399b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 400b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (forEncryption) 401b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 402b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam unpackBlock(in, inOff); 403b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam encryptBlock(WorkingKey); 404b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam packBlock(out, outOff); 405b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 406b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 407b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 408b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam unpackBlock(in, inOff); 409b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam decryptBlock(WorkingKey); 410b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam packBlock(out, outOff); 411b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 412b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 413b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return BLOCK_SIZE; 414b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 415b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 416b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void reset() 417b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 418b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 419b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 420c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private void unpackBlock( 421b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] bytes, 422b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int off) 423b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 424b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int index = off; 425b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 426b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C0 = (bytes[index++] & 0xff); 427b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C0 |= (bytes[index++] & 0xff) << 8; 428b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C0 |= (bytes[index++] & 0xff) << 16; 429b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C0 |= bytes[index++] << 24; 430b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 431b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C1 = (bytes[index++] & 0xff); 432b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C1 |= (bytes[index++] & 0xff) << 8; 433b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C1 |= (bytes[index++] & 0xff) << 16; 434b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C1 |= bytes[index++] << 24; 435b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 436b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C2 = (bytes[index++] & 0xff); 437b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C2 |= (bytes[index++] & 0xff) << 8; 438b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C2 |= (bytes[index++] & 0xff) << 16; 439b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C2 |= bytes[index++] << 24; 440b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 441b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C3 = (bytes[index++] & 0xff); 442b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C3 |= (bytes[index++] & 0xff) << 8; 443b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C3 |= (bytes[index++] & 0xff) << 16; 444b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C3 |= bytes[index++] << 24; 445b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 446b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 447c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private void packBlock( 448b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] bytes, 449b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int off) 450b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 451b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int index = off; 452b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 453b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)C0; 454b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)(C0 >> 8); 455b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)(C0 >> 16); 456b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)(C0 >> 24); 457b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 458b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)C1; 459b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)(C1 >> 8); 460b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)(C1 >> 16); 461b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)(C1 >> 24); 462b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 463b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)C2; 464b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)(C2 >> 8); 465b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)(C2 >> 16); 466b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)(C2 >> 24); 467b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 468b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)C3; 469b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)(C3 >> 8); 470b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)(C3 >> 16); 471b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[index++] = (byte)(C3 >> 24); 472b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 473b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 474b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 475c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private void encryptBlock(int[][] KW) 476b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 477b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int r, r0, r1, r2, r3; 478b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 479b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C0 ^= KW[0][0]; 480b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C1 ^= KW[0][1]; 481b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C2 ^= KW[0][2]; 482b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C3 ^= KW[0][3]; 483b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 484b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r = 1; 485b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 486b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (r < ROUNDS - 1) 487b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 488b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r0 = T0[C0&255] ^ shift(T0[(C1>>8)&255], 24) ^ shift(T0[(C2>>16)&255],16) ^ shift(T0[(C3>>24)&255],8) ^ KW[r][0]; 489b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r1 = T0[C1&255] ^ shift(T0[(C2>>8)&255], 24) ^ shift(T0[(C3>>16)&255], 16) ^ shift(T0[(C0>>24)&255], 8) ^ KW[r][1]; 490b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r2 = T0[C2&255] ^ shift(T0[(C3>>8)&255], 24) ^ shift(T0[(C0>>16)&255], 16) ^ shift(T0[(C1>>24)&255], 8) ^ KW[r][2]; 491b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r3 = T0[C3&255] ^ shift(T0[(C0>>8)&255], 24) ^ shift(T0[(C1>>16)&255], 16) ^ shift(T0[(C2>>24)&255], 8) ^ KW[r++][3]; 492b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C0 = T0[r0&255] ^ shift(T0[(r1>>8)&255], 24) ^ shift(T0[(r2>>16)&255], 16) ^ shift(T0[(r3>>24)&255], 8) ^ KW[r][0]; 493b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C1 = T0[r1&255] ^ shift(T0[(r2>>8)&255], 24) ^ shift(T0[(r3>>16)&255], 16) ^ shift(T0[(r0>>24)&255], 8) ^ KW[r][1]; 494b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C2 = T0[r2&255] ^ shift(T0[(r3>>8)&255], 24) ^ shift(T0[(r0>>16)&255], 16) ^ shift(T0[(r1>>24)&255], 8) ^ KW[r][2]; 495b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C3 = T0[r3&255] ^ shift(T0[(r0>>8)&255], 24) ^ shift(T0[(r1>>16)&255], 16) ^ shift(T0[(r2>>24)&255], 8) ^ KW[r++][3]; 496b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 497b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 498b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r0 = T0[C0&255] ^ shift(T0[(C1>>8)&255], 24) ^ shift(T0[(C2>>16)&255], 16) ^ shift(T0[(C3>>24)&255], 8) ^ KW[r][0]; 499b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r1 = T0[C1&255] ^ shift(T0[(C2>>8)&255], 24) ^ shift(T0[(C3>>16)&255], 16) ^ shift(T0[(C0>>24)&255], 8) ^ KW[r][1]; 500b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r2 = T0[C2&255] ^ shift(T0[(C3>>8)&255], 24) ^ shift(T0[(C0>>16)&255], 16) ^ shift(T0[(C1>>24)&255], 8) ^ KW[r][2]; 501b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r3 = T0[C3&255] ^ shift(T0[(C0>>8)&255], 24) ^ shift(T0[(C1>>16)&255], 16) ^ shift(T0[(C2>>24)&255], 8) ^ KW[r++][3]; 502b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 503b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // the final round's table is a simple function of S so we don't use a whole other four tables for it 504b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 505b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((S[(r2>>16)&255]&255)<<16) ^ (S[(r3>>24)&255]<<24) ^ KW[r][0]; 506b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C1 = (S[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (S[(r0>>24)&255]<<24) ^ KW[r][1]; 507b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C2 = (S[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2]; 508b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C3 = (S[r3&255]&255) ^ ((S[(r0>>8)&255]&255)<<8) ^ ((S[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3]; 509b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 510b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 511b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 512c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private void decryptBlock(int[][] KW) 513b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 514b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int r, r0, r1, r2, r3; 515b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 516b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C0 ^= KW[ROUNDS][0]; 517b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C1 ^= KW[ROUNDS][1]; 518b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C2 ^= KW[ROUNDS][2]; 519b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C3 ^= KW[ROUNDS][3]; 520b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 521b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r = ROUNDS-1; 522b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 523b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (r>1) 524b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 525b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r0 = Tinv0[C0&255] ^ shift(Tinv0[(C3>>8)&255], 24) ^ shift(Tinv0[(C2>>16)&255], 16) ^ shift(Tinv0[(C1>>24)&255], 8) ^ KW[r][0]; 526b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r1 = Tinv0[C1&255] ^ shift(Tinv0[(C0>>8)&255], 24) ^ shift(Tinv0[(C3>>16)&255], 16) ^ shift(Tinv0[(C2>>24)&255], 8) ^ KW[r][1]; 527b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r2 = Tinv0[C2&255] ^ shift(Tinv0[(C1>>8)&255], 24) ^ shift(Tinv0[(C0>>16)&255], 16) ^ shift(Tinv0[(C3>>24)&255], 8) ^ KW[r][2]; 528b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r3 = Tinv0[C3&255] ^ shift(Tinv0[(C2>>8)&255], 24) ^ shift(Tinv0[(C1>>16)&255], 16) ^ shift(Tinv0[(C0>>24)&255], 8) ^ KW[r--][3]; 529b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C0 = Tinv0[r0&255] ^ shift(Tinv0[(r3>>8)&255], 24) ^ shift(Tinv0[(r2>>16)&255], 16) ^ shift(Tinv0[(r1>>24)&255], 8) ^ KW[r][0]; 530b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C1 = Tinv0[r1&255] ^ shift(Tinv0[(r0>>8)&255], 24) ^ shift(Tinv0[(r3>>16)&255], 16) ^ shift(Tinv0[(r2>>24)&255], 8) ^ KW[r][1]; 531b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C2 = Tinv0[r2&255] ^ shift(Tinv0[(r1>>8)&255], 24) ^ shift(Tinv0[(r0>>16)&255], 16) ^ shift(Tinv0[(r3>>24)&255], 8) ^ KW[r][2]; 532b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C3 = Tinv0[r3&255] ^ shift(Tinv0[(r2>>8)&255], 24) ^ shift(Tinv0[(r1>>16)&255], 16) ^ shift(Tinv0[(r0>>24)&255], 8) ^ KW[r--][3]; 533b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 534b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 535b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r0 = Tinv0[C0&255] ^ shift(Tinv0[(C3>>8)&255], 24) ^ shift(Tinv0[(C2>>16)&255], 16) ^ shift(Tinv0[(C1>>24)&255], 8) ^ KW[r][0]; 536b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r1 = Tinv0[C1&255] ^ shift(Tinv0[(C0>>8)&255], 24) ^ shift(Tinv0[(C3>>16)&255], 16) ^ shift(Tinv0[(C2>>24)&255], 8) ^ KW[r][1]; 537b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam r2 = Tinv0[C2&255] ^ shift(Tinv0[(C1>>8)&255], 24) ^ shift(Tinv0[(C0>>16)&255], 16) ^ shift(Tinv0[(C3>>24)&255], 8) ^ KW[r][2]; 538c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom r3 = Tinv0[C3&255] ^ shift(Tinv0[(C2>>8)&255], 24) ^ shift(Tinv0[(C1>>16)&255], 16) ^ shift(Tinv0[(C0>>24)&255], 8) ^ KW[r][3]; 539b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 540b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // the final round's table is a simple function of Si so we don't use a whole other four tables for it 541b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 542b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C0 = (Si[r0&255]&255) ^ ((Si[(r3>>8)&255]&255)<<8) ^ ((Si[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0]; 543b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C1 = (Si[r1&255]&255) ^ ((Si[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (Si[(r2>>24)&255]<<24) ^ KW[0][1]; 544b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C2 = (Si[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (Si[(r3>>24)&255]<<24) ^ KW[0][2]; 545b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam C3 = (Si[r3&255]&255) ^ ((Si[(r2>>8)&255]&255)<<8) ^ ((Si[(r1>>16)&255]&255)<<16) ^ (Si[(r0>>24)&255]<<24) ^ KW[0][3]; 546b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 547b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 548