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