Remove support for the "rijndael256-cbc", "rijndael192-cbc", and
[u/mdw/putty] / sshaes.c
1 /*
2 * aes.c - implementation of AES / Rijndael
3 *
4 * AES is a flexible algorithm as regards endianness: it has no
5 * inherent preference as to which way round you should form words
6 * from the input byte stream. It talks endlessly of four-byte
7 * _vectors_, but never of 32-bit _words_ - there's no 32-bit
8 * addition at all, which would force an endianness by means of
9 * which way the carries went. So it would be possible to write a
10 * working AES that read words big-endian, and another working one
11 * that read them little-endian, just by computing a different set
12 * of tables - with no speed drop.
13 *
14 * It's therefore tempting to do just that, and remove the overhead
15 * of GET_32BIT_MSB_FIRST() et al, allowing every system to use its
16 * own endianness-native code; but I decided not to, partly for
17 * ease of testing, and mostly because I like the flexibility that
18 * allows you to encrypt a non-word-aligned block of memory (which
19 * many systems would stop being able to do if I went the
20 * endianness-dependent route).
21 *
22 * This implementation reads and stores words big-endian, but
23 * that's a minor implementation detail. By flipping the endianness
24 * of everything in the E0..E3, D0..D3 tables, and substituting
25 * GET_32BIT_LSB_FIRST for GET_32BIT_MSB_FIRST, I could create an
26 * implementation that worked internally little-endian and gave the
27 * same answers at the same speed.
28 */
29
30 #include <assert.h>
31 #include <stdlib.h>
32
33 #include "ssh.h"
34
35 #define MAX_NR 14 /* max no of rounds */
36 #define MAX_NK 8 /* max no of words in input key */
37 #define MAX_NB 8 /* max no of words in cipher blk */
38
39 #define mulby2(x) ( ((x&0x7F) << 1) ^ (x & 0x80 ? 0x1B : 0) )
40
41 #define GET_32BIT_MSB_FIRST(cp) \
42 (((unsigned long)(unsigned char)(cp)[3]) | \
43 ((unsigned long)(unsigned char)(cp)[2] << 8) | \
44 ((unsigned long)(unsigned char)(cp)[1] << 16) | \
45 ((unsigned long)(unsigned char)(cp)[0] << 24))
46
47 #define PUT_32BIT_MSB_FIRST(cp, value) do { \
48 (cp)[3] = (value); \
49 (cp)[2] = (value) >> 8; \
50 (cp)[1] = (value) >> 16; \
51 (cp)[0] = (value) >> 24; } while (0)
52
53 typedef struct AESContext AESContext;
54
55 struct AESContext {
56 word32 keysched[(MAX_NR + 1) * MAX_NB];
57 word32 invkeysched[(MAX_NR + 1) * MAX_NB];
58 void (*encrypt) (AESContext * ctx, word32 * block);
59 void (*decrypt) (AESContext * ctx, word32 * block);
60 word32 iv[MAX_NB];
61 int Nb, Nr;
62 };
63
64 static const unsigned char Sbox[256] = {
65 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
66 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
67 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
68 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
69 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
70 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
71 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
72 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
73 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
74 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
75 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
76 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
77 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
78 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
79 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
80 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
81 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
82 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
83 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
84 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
85 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
86 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
87 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
88 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
89 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
90 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
91 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
92 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
93 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
94 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
95 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
96 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
97 };
98
99 static const unsigned char Sboxinv[256] = {
100 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
101 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
102 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
103 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
104 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
105 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
106 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
107 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
108 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
109 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
110 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
111 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
112 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
113 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
114 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
115 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
116 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
117 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
118 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
119 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
120 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
121 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
122 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
123 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
124 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
125 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
126 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
127 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
128 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
129 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
130 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
131 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
132 };
133
134 static const word32 E0[256] = {
135 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
136 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
137 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
138 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
139 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
140 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
141 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
142 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
143 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
144 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
145 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
146 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
147 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
148 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
149 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
150 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
151 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
152 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
153 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
154 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
155 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
156 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
157 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
158 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
159 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
160 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
161 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
162 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
163 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
164 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
165 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
166 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
167 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
168 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
169 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
170 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
171 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
172 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
173 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
174 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
175 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
176 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
177 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
178 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
179 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
180 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
181 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
182 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
183 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
184 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
185 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
186 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
187 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
188 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
189 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
190 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
191 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
192 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
193 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
194 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
195 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
196 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
197 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
198 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a,
199 };
200 static const word32 E1[256] = {
201 0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b,
202 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
203 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b,
204 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,
205 0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d,
206 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
207 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf,
208 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,
209 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626,
210 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc,
211 0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1,
212 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
213 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3,
214 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a,
215 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2,
216 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,
217 0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a,
218 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
219 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3,
220 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,
221 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded,
222 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,
223 0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939,
224 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
225 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb,
226 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,
227 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f,
228 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,
229 0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f,
230 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
231 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121,
232 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2,
233 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec,
234 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,
235 0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d,
236 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
237 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc,
238 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,
239 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414,
240 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,
241 0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a,
242 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
243 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262,
244 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,
245 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d,
246 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,
247 0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea,
248 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
249 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e,
250 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,
251 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f,
252 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,
253 0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666,
254 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
255 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9,
256 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,
257 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111,
258 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,
259 0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9,
260 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
261 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d,
262 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,
263 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f,
264 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616,
265 };
266 static const word32 E2[256] = {
267 0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b,
268 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
269 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b,
270 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,
271 0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d,
272 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
273 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af,
274 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,
275 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26,
276 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,
277 0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1,
278 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
279 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3,
280 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a,
281 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2,
282 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,
283 0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a,
284 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
285 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3,
286 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,
287 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed,
288 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,
289 0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239,
290 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
291 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb,
292 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,
293 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f,
294 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,
295 0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f,
296 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
297 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221,
298 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,
299 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec,
300 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,
301 0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d,
302 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
303 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc,
304 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,
305 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814,
306 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb,
307 0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a,
308 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
309 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462,
310 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,
311 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d,
312 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,
313 0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea,
314 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
315 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e,
316 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,
317 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f,
318 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,
319 0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66,
320 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
321 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9,
322 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,
323 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211,
324 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,
325 0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9,
326 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
327 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d,
328 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,
329 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f,
330 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16,
331 };
332 static const word32 E3[256] = {
333 0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6,
334 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
335 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56,
336 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,
337 0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa,
338 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
339 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45,
340 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,
341 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c,
342 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,
343 0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9,
344 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
345 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d,
346 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f,
347 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf,
348 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,
349 0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34,
350 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
351 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d,
352 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,
353 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1,
354 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,
355 0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72,
356 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
357 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed,
358 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,
359 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe,
360 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,
361 0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05,
362 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
363 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342,
364 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,
365 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3,
366 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,
367 0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a,
368 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
369 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3,
370 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,
371 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28,
372 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad,
373 0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14,
374 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
375 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4,
376 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,
377 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da,
378 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,
379 0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf,
380 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
381 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c,
382 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,
383 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e,
384 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,
385 0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc,
386 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
387 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069,
388 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,
389 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322,
390 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,
391 0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9,
392 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
393 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a,
394 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,
395 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e,
396 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c,
397 };
398 static const word32 D0[256] = {
399 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
400 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
401 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
402 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
403 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
404 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
405 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
406 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
407 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
408 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
409 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
410 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
411 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
412 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
413 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
414 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
415 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
416 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
417 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
418 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
419 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
420 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
421 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
422 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
423 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
424 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
425 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
426 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
427 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
428 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
429 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
430 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
431 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
432 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
433 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
434 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
435 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
436 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
437 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
438 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
439 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
440 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
441 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
442 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
443 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
444 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
445 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
446 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
447 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
448 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
449 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
450 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
451 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
452 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
453 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
454 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
455 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
456 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
457 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
458 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
459 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
460 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
461 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
462 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742,
463 };
464 static const word32 D1[256] = {
465 0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e,
466 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,
467 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c,
468 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3,
469 0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0,
470 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,
471 0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259,
472 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8,
473 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971,
474 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a,
475 0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f,
476 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,
477 0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8,
478 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab,
479 0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708,
480 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682,
481 0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2,
482 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,
483 0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb,
484 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10,
485 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd,
486 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015,
487 0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e,
488 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,
489 0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000,
490 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72,
491 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39,
492 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e,
493 0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91,
494 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,
495 0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17,
496 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9,
497 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60,
498 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e,
499 0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1,
500 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,
501 0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1,
502 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3,
503 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964,
504 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390,
505 0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b,
506 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,
507 0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46,
508 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af,
509 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512,
510 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb,
511 0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a,
512 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8,
513 0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c,
514 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266,
515 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8,
516 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6,
517 0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604,
518 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,
519 0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41,
520 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647,
521 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c,
522 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1,
523 0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737,
524 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,
525 0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340,
526 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95,
527 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1,
528 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857,
529 };
530 static const word32 D2[256] = {
531 0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27,
532 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3,
533 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502,
534 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562,
535 0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe,
536 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,
537 0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552,
538 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9,
539 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9,
540 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce,
541 0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253,
542 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,
543 0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b,
544 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655,
545 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337,
546 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16,
547 0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69,
548 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,
549 0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6,
550 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e,
551 0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6,
552 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050,
553 0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9,
554 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,
555 0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000,
556 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a,
557 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d,
558 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436,
559 0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b,
560 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,
561 0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b,
562 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e,
563 0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f,
564 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb,
565 0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4,
566 0xdccad731, 0x85104263, 0x22401397, 0x112084c6,
567 0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729,
568 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1,
569 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9,
570 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233,
571 0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4,
572 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,
573 0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e,
574 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3,
575 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25,
576 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b,
577 0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f,
578 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,
579 0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0,
580 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2,
581 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7,
582 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791,
583 0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496,
584 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,
585 0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b,
586 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6,
587 0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13,
588 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47,
589 0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7,
590 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,
591 0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3,
592 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d,
593 0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456,
594 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8,
595 };
596 static const word32 D3[256] = {
597 0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a,
598 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,
599 0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5,
600 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5,
601 0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d,
602 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,
603 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95,
604 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e,
605 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27,
606 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d,
607 0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562,
608 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9,
609 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752,
610 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66,
611 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3,
612 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced,
613 0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e,
614 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4,
615 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4,
616 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd,
617 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d,
618 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60,
619 0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767,
620 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,
621 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000,
622 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c,
623 0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736,
624 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24,
625 0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b,
626 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,
627 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12,
628 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814,
629 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3,
630 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b,
631 0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8,
632 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,
633 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7,
634 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077,
635 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247,
636 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22,
637 0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698,
638 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,
639 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254,
640 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582,
641 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf,
642 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb,
643 0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883,
644 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,
645 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629,
646 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035,
647 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533,
648 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17,
649 0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4,
650 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,
651 0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb,
652 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d,
653 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb,
654 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a,
655 0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73,
656 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,
657 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2,
658 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff,
659 0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064,
660 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0,
661 };
662
663 /*
664 * Common macros in both the encryption and decryption routines.
665 */
666 #define ADD_ROUND_KEY_4 (block[0]^=*keysched++, block[1]^=*keysched++, \
667 block[2]^=*keysched++, block[3]^=*keysched++)
668 #define ADD_ROUND_KEY_6 (block[0]^=*keysched++, block[1]^=*keysched++, \
669 block[2]^=*keysched++, block[3]^=*keysched++, \
670 block[4]^=*keysched++, block[5]^=*keysched++)
671 #define ADD_ROUND_KEY_8 (block[0]^=*keysched++, block[1]^=*keysched++, \
672 block[2]^=*keysched++, block[3]^=*keysched++, \
673 block[4]^=*keysched++, block[5]^=*keysched++, \
674 block[6]^=*keysched++, block[7]^=*keysched++)
675 #define MOVEWORD(i) ( block[i] = newstate[i] )
676
677 /*
678 * Macros for the encryption routine. There are three encryption
679 * cores, for Nb=4,6,8.
680 */
681 #define MAKEWORD(i) ( newstate[i] = (E0[(block[i] >> 24) & 0xFF] ^ \
682 E1[(block[(i+C1)%Nb] >> 16) & 0xFF] ^ \
683 E2[(block[(i+C2)%Nb] >> 8) & 0xFF] ^ \
684 E3[block[(i+C3)%Nb] & 0xFF]) )
685 #define LASTWORD(i) ( newstate[i] = (Sbox[(block[i] >> 24) & 0xFF] << 24) | \
686 (Sbox[(block[(i+C1)%Nb] >> 16) & 0xFF] << 16) | \
687 (Sbox[(block[(i+C2)%Nb] >> 8) & 0xFF] << 8) | \
688 (Sbox[(block[(i+C3)%Nb] ) & 0xFF] ) )
689
690 /*
691 * Core encrypt routines, expecting word32 inputs read big-endian
692 * from the byte-oriented input stream.
693 */
694 static void aes_encrypt_nb_4(AESContext * ctx, word32 * block)
695 {
696 int i;
697 static const int C1 = 1, C2 = 2, C3 = 3, Nb = 4;
698 word32 *keysched = ctx->keysched;
699 word32 newstate[4];
700 for (i = 0; i < ctx->Nr - 1; i++) {
701 ADD_ROUND_KEY_4;
702 MAKEWORD(0);
703 MAKEWORD(1);
704 MAKEWORD(2);
705 MAKEWORD(3);
706 MOVEWORD(0);
707 MOVEWORD(1);
708 MOVEWORD(2);
709 MOVEWORD(3);
710 }
711 ADD_ROUND_KEY_4;
712 LASTWORD(0);
713 LASTWORD(1);
714 LASTWORD(2);
715 LASTWORD(3);
716 MOVEWORD(0);
717 MOVEWORD(1);
718 MOVEWORD(2);
719 MOVEWORD(3);
720 ADD_ROUND_KEY_4;
721 }
722 static void aes_encrypt_nb_6(AESContext * ctx, word32 * block)
723 {
724 int i;
725 static const int C1 = 1, C2 = 2, C3 = 3, Nb = 6;
726 word32 *keysched = ctx->keysched;
727 word32 newstate[6];
728 for (i = 0; i < ctx->Nr - 1; i++) {
729 ADD_ROUND_KEY_6;
730 MAKEWORD(0);
731 MAKEWORD(1);
732 MAKEWORD(2);
733 MAKEWORD(3);
734 MAKEWORD(4);
735 MAKEWORD(5);
736 MOVEWORD(0);
737 MOVEWORD(1);
738 MOVEWORD(2);
739 MOVEWORD(3);
740 MOVEWORD(4);
741 MOVEWORD(5);
742 }
743 ADD_ROUND_KEY_6;
744 LASTWORD(0);
745 LASTWORD(1);
746 LASTWORD(2);
747 LASTWORD(3);
748 LASTWORD(4);
749 LASTWORD(5);
750 MOVEWORD(0);
751 MOVEWORD(1);
752 MOVEWORD(2);
753 MOVEWORD(3);
754 MOVEWORD(4);
755 MOVEWORD(5);
756 ADD_ROUND_KEY_6;
757 }
758 static void aes_encrypt_nb_8(AESContext * ctx, word32 * block)
759 {
760 int i;
761 static const int C1 = 1, C2 = 3, C3 = 4, Nb = 8;
762 word32 *keysched = ctx->keysched;
763 word32 newstate[8];
764 for (i = 0; i < ctx->Nr - 1; i++) {
765 ADD_ROUND_KEY_8;
766 MAKEWORD(0);
767 MAKEWORD(1);
768 MAKEWORD(2);
769 MAKEWORD(3);
770 MAKEWORD(4);
771 MAKEWORD(5);
772 MAKEWORD(6);
773 MAKEWORD(7);
774 MOVEWORD(0);
775 MOVEWORD(1);
776 MOVEWORD(2);
777 MOVEWORD(3);
778 MOVEWORD(4);
779 MOVEWORD(5);
780 MOVEWORD(6);
781 MOVEWORD(7);
782 }
783 ADD_ROUND_KEY_8;
784 LASTWORD(0);
785 LASTWORD(1);
786 LASTWORD(2);
787 LASTWORD(3);
788 LASTWORD(4);
789 LASTWORD(5);
790 LASTWORD(6);
791 LASTWORD(7);
792 MOVEWORD(0);
793 MOVEWORD(1);
794 MOVEWORD(2);
795 MOVEWORD(3);
796 MOVEWORD(4);
797 MOVEWORD(5);
798 MOVEWORD(6);
799 MOVEWORD(7);
800 ADD_ROUND_KEY_8;
801 }
802
803 #undef MAKEWORD
804 #undef LASTWORD
805
806 /*
807 * Macros for the decryption routine. There are three decryption
808 * cores, for Nb=4,6,8.
809 */
810 #define MAKEWORD(i) ( newstate[i] = (D0[(block[i] >> 24) & 0xFF] ^ \
811 D1[(block[(i+C1)%Nb] >> 16) & 0xFF] ^ \
812 D2[(block[(i+C2)%Nb] >> 8) & 0xFF] ^ \
813 D3[block[(i+C3)%Nb] & 0xFF]) )
814 #define LASTWORD(i) (newstate[i] = (Sboxinv[(block[i] >> 24) & 0xFF] << 24) | \
815 (Sboxinv[(block[(i+C1)%Nb] >> 16) & 0xFF] << 16) | \
816 (Sboxinv[(block[(i+C2)%Nb] >> 8) & 0xFF] << 8) | \
817 (Sboxinv[(block[(i+C3)%Nb] ) & 0xFF] ) )
818
819 /*
820 * Core decrypt routines, expecting word32 inputs read big-endian
821 * from the byte-oriented input stream.
822 */
823 static void aes_decrypt_nb_4(AESContext * ctx, word32 * block)
824 {
825 int i;
826 static const int C1 = 4 - 1, C2 = 4 - 2, C3 = 4 - 3, Nb = 4;
827 word32 *keysched = ctx->invkeysched;
828 word32 newstate[4];
829 for (i = 0; i < ctx->Nr - 1; i++) {
830 ADD_ROUND_KEY_4;
831 MAKEWORD(0);
832 MAKEWORD(1);
833 MAKEWORD(2);
834 MAKEWORD(3);
835 MOVEWORD(0);
836 MOVEWORD(1);
837 MOVEWORD(2);
838 MOVEWORD(3);
839 }
840 ADD_ROUND_KEY_4;
841 LASTWORD(0);
842 LASTWORD(1);
843 LASTWORD(2);
844 LASTWORD(3);
845 MOVEWORD(0);
846 MOVEWORD(1);
847 MOVEWORD(2);
848 MOVEWORD(3);
849 ADD_ROUND_KEY_4;
850 }
851 static void aes_decrypt_nb_6(AESContext * ctx, word32 * block)
852 {
853 int i;
854 static const int C1 = 6 - 1, C2 = 6 - 2, C3 = 6 - 3, Nb = 6;
855 word32 *keysched = ctx->invkeysched;
856 word32 newstate[6];
857 for (i = 0; i < ctx->Nr - 1; i++) {
858 ADD_ROUND_KEY_6;
859 MAKEWORD(0);
860 MAKEWORD(1);
861 MAKEWORD(2);
862 MAKEWORD(3);
863 MAKEWORD(4);
864 MAKEWORD(5);
865 MOVEWORD(0);
866 MOVEWORD(1);
867 MOVEWORD(2);
868 MOVEWORD(3);
869 MOVEWORD(4);
870 MOVEWORD(5);
871 }
872 ADD_ROUND_KEY_6;
873 LASTWORD(0);
874 LASTWORD(1);
875 LASTWORD(2);
876 LASTWORD(3);
877 LASTWORD(4);
878 LASTWORD(5);
879 MOVEWORD(0);
880 MOVEWORD(1);
881 MOVEWORD(2);
882 MOVEWORD(3);
883 MOVEWORD(4);
884 MOVEWORD(5);
885 ADD_ROUND_KEY_6;
886 }
887 static void aes_decrypt_nb_8(AESContext * ctx, word32 * block)
888 {
889 int i;
890 static const int C1 = 8 - 1, C2 = 8 - 3, C3 = 8 - 4, Nb = 8;
891 word32 *keysched = ctx->invkeysched;
892 word32 newstate[8];
893 for (i = 0; i < ctx->Nr - 1; i++) {
894 ADD_ROUND_KEY_8;
895 MAKEWORD(0);
896 MAKEWORD(1);
897 MAKEWORD(2);
898 MAKEWORD(3);
899 MAKEWORD(4);
900 MAKEWORD(5);
901 MAKEWORD(6);
902 MAKEWORD(7);
903 MOVEWORD(0);
904 MOVEWORD(1);
905 MOVEWORD(2);
906 MOVEWORD(3);
907 MOVEWORD(4);
908 MOVEWORD(5);
909 MOVEWORD(6);
910 MOVEWORD(7);
911 }
912 ADD_ROUND_KEY_8;
913 LASTWORD(0);
914 LASTWORD(1);
915 LASTWORD(2);
916 LASTWORD(3);
917 LASTWORD(4);
918 LASTWORD(5);
919 LASTWORD(6);
920 LASTWORD(7);
921 MOVEWORD(0);
922 MOVEWORD(1);
923 MOVEWORD(2);
924 MOVEWORD(3);
925 MOVEWORD(4);
926 MOVEWORD(5);
927 MOVEWORD(6);
928 MOVEWORD(7);
929 ADD_ROUND_KEY_8;
930 }
931
932 #undef MAKEWORD
933 #undef LASTWORD
934
935
936 /*
937 * Set up an AESContext. `keylen' and `blocklen' are measured in
938 * bytes; each can be either 16 (128-bit), 24 (192-bit), or 32
939 * (256-bit).
940 */
941 static void aes_setup(AESContext * ctx, int blocklen,
942 unsigned char *key, int keylen)
943 {
944 int i, j, Nk, rconst;
945
946 assert(blocklen == 16 || blocklen == 24 || blocklen == 32);
947 assert(keylen == 16 || keylen == 24 || keylen == 32);
948
949 /*
950 * Basic parameters. Words per block, words in key, rounds.
951 */
952 Nk = keylen / 4;
953 ctx->Nb = blocklen / 4;
954 ctx->Nr = 6 + (ctx->Nb > Nk ? ctx->Nb : Nk);
955
956 /*
957 * Assign core-function pointers.
958 */
959 if (ctx->Nb == 8)
960 ctx->encrypt = aes_encrypt_nb_8, ctx->decrypt = aes_decrypt_nb_8;
961 else if (ctx->Nb == 6)
962 ctx->encrypt = aes_encrypt_nb_6, ctx->decrypt = aes_decrypt_nb_6;
963 else if (ctx->Nb == 4)
964 ctx->encrypt = aes_encrypt_nb_4, ctx->decrypt = aes_decrypt_nb_4;
965
966 /*
967 * Now do the key setup itself.
968 */
969 rconst = 1;
970 for (i = 0; i < (ctx->Nr + 1) * ctx->Nb; i++) {
971 if (i < Nk)
972 ctx->keysched[i] = GET_32BIT_MSB_FIRST(key + 4 * i);
973 else {
974 word32 temp = ctx->keysched[i - 1];
975 if (i % Nk == 0) {
976 int a, b, c, d;
977 a = (temp >> 16) & 0xFF;
978 b = (temp >> 8) & 0xFF;
979 c = (temp >> 0) & 0xFF;
980 d = (temp >> 24) & 0xFF;
981 temp = Sbox[a] ^ rconst;
982 temp = (temp << 8) | Sbox[b];
983 temp = (temp << 8) | Sbox[c];
984 temp = (temp << 8) | Sbox[d];
985 rconst = mulby2(rconst);
986 } else if (i % Nk == 4 && Nk > 6) {
987 int a, b, c, d;
988 a = (temp >> 24) & 0xFF;
989 b = (temp >> 16) & 0xFF;
990 c = (temp >> 8) & 0xFF;
991 d = (temp >> 0) & 0xFF;
992 temp = Sbox[a];
993 temp = (temp << 8) | Sbox[b];
994 temp = (temp << 8) | Sbox[c];
995 temp = (temp << 8) | Sbox[d];
996 }
997 ctx->keysched[i] = ctx->keysched[i - Nk] ^ temp;
998 }
999 }
1000
1001 /*
1002 * Now prepare the modified keys for the inverse cipher.
1003 */
1004 for (i = 0; i <= ctx->Nr; i++) {
1005 for (j = 0; j < ctx->Nb; j++) {
1006 word32 temp;
1007 temp = ctx->keysched[(ctx->Nr - i) * ctx->Nb + j];
1008 if (i != 0 && i != ctx->Nr) {
1009 /*
1010 * Perform the InvMixColumn operation on i. The D
1011 * tables give the result of InvMixColumn applied
1012 * to Sboxinv on individual bytes, so we should
1013 * compose Sbox with the D tables for this.
1014 */
1015 int a, b, c, d;
1016 a = (temp >> 24) & 0xFF;
1017 b = (temp >> 16) & 0xFF;
1018 c = (temp >> 8) & 0xFF;
1019 d = (temp >> 0) & 0xFF;
1020 temp = D0[Sbox[a]];
1021 temp ^= D1[Sbox[b]];
1022 temp ^= D2[Sbox[c]];
1023 temp ^= D3[Sbox[d]];
1024 }
1025 ctx->invkeysched[i * ctx->Nb + j] = temp;
1026 }
1027 }
1028 }
1029
1030 static void aes_encrypt(AESContext * ctx, word32 * block)
1031 {
1032 ctx->encrypt(ctx, block);
1033 }
1034
1035 static void aes_decrypt(AESContext * ctx, word32 * block)
1036 {
1037 ctx->decrypt(ctx, block);
1038 }
1039
1040 static void aes_encrypt_cbc(unsigned char *blk, int len, AESContext * ctx)
1041 {
1042 word32 iv[4];
1043 int i;
1044
1045 assert((len & 15) == 0);
1046
1047 memcpy(iv, ctx->iv, sizeof(iv));
1048
1049 while (len > 0) {
1050 for (i = 0; i < 4; i++)
1051 iv[i] ^= GET_32BIT_MSB_FIRST(blk + 4 * i);
1052 aes_encrypt(ctx, iv);
1053 for (i = 0; i < 4; i++)
1054 PUT_32BIT_MSB_FIRST(blk + 4 * i, iv[i]);
1055 blk += 16;
1056 len -= 16;
1057 }
1058
1059 memcpy(ctx->iv, iv, sizeof(iv));
1060 }
1061
1062 static void aes_decrypt_cbc(unsigned char *blk, int len, AESContext * ctx)
1063 {
1064 word32 iv[4], x[4], ct[4];
1065 int i;
1066
1067 assert((len & 15) == 0);
1068
1069 memcpy(iv, ctx->iv, sizeof(iv));
1070
1071 while (len > 0) {
1072 for (i = 0; i < 4; i++)
1073 x[i] = ct[i] = GET_32BIT_MSB_FIRST(blk + 4 * i);
1074 aes_decrypt(ctx, x);
1075 for (i = 0; i < 4; i++) {
1076 PUT_32BIT_MSB_FIRST(blk + 4 * i, iv[i] ^ x[i]);
1077 iv[i] = ct[i];
1078 }
1079 blk += 16;
1080 len -= 16;
1081 }
1082
1083 memcpy(ctx->iv, iv, sizeof(iv));
1084 }
1085
1086 static void aes_sdctr(unsigned char *blk, int len, AESContext *ctx)
1087 {
1088 word32 iv[4], b[4], tmp;
1089 int i;
1090
1091 assert((len & 15) == 0);
1092
1093 memcpy(iv, ctx->iv, sizeof(iv));
1094
1095 while (len > 0) {
1096 memcpy(b, iv, sizeof(b));
1097 aes_encrypt(ctx, b);
1098 for (i = 0; i < 4; i++) {
1099 tmp = GET_32BIT_MSB_FIRST(blk + 4 * i);
1100 PUT_32BIT_MSB_FIRST(blk + 4 * i, tmp ^ b[i]);
1101 }
1102 for (i = 3; i >= 0; i--)
1103 if ((iv[i] = (iv[i] + 1) & 0xffffffff) != 0)
1104 break;
1105 blk += 16;
1106 len -= 16;
1107 }
1108
1109 memcpy(ctx->iv, iv, sizeof(iv));
1110 }
1111
1112 static void *aes_make_context(void)
1113 {
1114 return snew(AESContext);
1115 }
1116
1117 static void aes_free_context(void *handle)
1118 {
1119 sfree(handle);
1120 }
1121
1122 static void aes128_key(void *handle, unsigned char *key)
1123 {
1124 AESContext *ctx = (AESContext *)handle;
1125 aes_setup(ctx, 16, key, 16);
1126 }
1127
1128 static void aes192_key(void *handle, unsigned char *key)
1129 {
1130 AESContext *ctx = (AESContext *)handle;
1131 aes_setup(ctx, 16, key, 24);
1132 }
1133
1134 static void aes256_key(void *handle, unsigned char *key)
1135 {
1136 AESContext *ctx = (AESContext *)handle;
1137 aes_setup(ctx, 16, key, 32);
1138 }
1139
1140 static void aes_iv(void *handle, unsigned char *iv)
1141 {
1142 AESContext *ctx = (AESContext *)handle;
1143 int i;
1144 for (i = 0; i < 4; i++)
1145 ctx->iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i);
1146 }
1147
1148 static void aes_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len)
1149 {
1150 AESContext *ctx = (AESContext *)handle;
1151 aes_encrypt_cbc(blk, len, ctx);
1152 }
1153
1154 static void aes_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len)
1155 {
1156 AESContext *ctx = (AESContext *)handle;
1157 aes_decrypt_cbc(blk, len, ctx);
1158 }
1159
1160 static void aes_ssh2_sdctr(void *handle, unsigned char *blk, int len)
1161 {
1162 AESContext *ctx = (AESContext *)handle;
1163 aes_sdctr(blk, len, ctx);
1164 }
1165
1166 void aes256_encrypt_pubkey(unsigned char *key, unsigned char *blk, int len)
1167 {
1168 AESContext ctx;
1169 aes_setup(&ctx, 16, key, 32);
1170 memset(ctx.iv, 0, sizeof(ctx.iv));
1171 aes_encrypt_cbc(blk, len, &ctx);
1172 memset(&ctx, 0, sizeof(ctx));
1173 }
1174
1175 void aes256_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len)
1176 {
1177 AESContext ctx;
1178 aes_setup(&ctx, 16, key, 32);
1179 memset(ctx.iv, 0, sizeof(ctx.iv));
1180 aes_decrypt_cbc(blk, len, &ctx);
1181 memset(&ctx, 0, sizeof(ctx));
1182 }
1183
1184 static const struct ssh2_cipher ssh_aes128_ctr = {
1185 aes_make_context, aes_free_context, aes_iv, aes128_key,
1186 aes_ssh2_sdctr, aes_ssh2_sdctr,
1187 "aes128-ctr",
1188 16, 128, "AES-128 SDCTR"
1189 };
1190
1191 static const struct ssh2_cipher ssh_aes192_ctr = {
1192 aes_make_context, aes_free_context, aes_iv, aes192_key,
1193 aes_ssh2_sdctr, aes_ssh2_sdctr,
1194 "aes192-ctr",
1195 16, 192, "AES-192 SDCTR"
1196 };
1197
1198 static const struct ssh2_cipher ssh_aes256_ctr = {
1199 aes_make_context, aes_free_context, aes_iv, aes256_key,
1200 aes_ssh2_sdctr, aes_ssh2_sdctr,
1201 "aes256-ctr",
1202 16, 256, "AES-256 SDCTR"
1203 };
1204
1205 static const struct ssh2_cipher ssh_aes128 = {
1206 aes_make_context, aes_free_context, aes_iv, aes128_key,
1207 aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
1208 "aes128-cbc",
1209 16, 128, "AES-128 CBC"
1210 };
1211
1212 static const struct ssh2_cipher ssh_aes192 = {
1213 aes_make_context, aes_free_context, aes_iv, aes192_key,
1214 aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
1215 "aes192-cbc",
1216 16, 192, "AES-192 CBC"
1217 };
1218
1219 static const struct ssh2_cipher ssh_aes256 = {
1220 aes_make_context, aes_free_context, aes_iv, aes256_key,
1221 aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
1222 "aes256-cbc",
1223 16, 256, "AES-256 CBC"
1224 };
1225
1226 static const struct ssh2_cipher ssh_rijndael_lysator = {
1227 aes_make_context, aes_free_context, aes_iv, aes256_key,
1228 aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
1229 "rijndael-cbc@lysator.liu.se",
1230 16, 256, "AES-256 CBC"
1231 };
1232
1233 static const struct ssh2_cipher *const aes_list[] = {
1234 &ssh_aes256_ctr,
1235 &ssh_aes256,
1236 &ssh_rijndael_lysator,
1237 &ssh_aes192_ctr,
1238 &ssh_aes192,
1239 &ssh_aes128_ctr,
1240 &ssh_aes128,
1241 };
1242
1243 const struct ssh2_ciphers ssh2_aes = {
1244 sizeof(aes_list) / sizeof(*aes_list),
1245 aes_list
1246 };