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