OSDN Git Service

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