]> begriffs open source - freertos/blob - FreeRTOS-Plus/Source/CyaSSL/ctaocrypt/src/aes.c
Add FreeRTOS-Plus directory with new directory structure so it matches the FreeRTOS...
[freertos] / FreeRTOS-Plus / Source / CyaSSL / ctaocrypt / src / aes.c
1 /* aes.c
2  *
3  * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #ifndef NO_AES
27
28 #include <cyassl/ctaocrypt/aes.h>
29 #include <cyassl/ctaocrypt/error.h>
30 #include <cyassl/ctaocrypt/logging.h>
31 #ifdef NO_INLINE
32     #include <cyassl/ctaocrypt/misc.h>
33 #else
34     #include <ctaocrypt/src/misc.c>
35 #endif
36
37
38 #ifdef _MSC_VER
39     /* 4127 warning constant while(1)  */
40     #pragma warning(disable: 4127)
41 #endif
42
43
44 static const word32 rcon[] = {
45     0x01000000, 0x02000000, 0x04000000, 0x08000000,
46     0x10000000, 0x20000000, 0x40000000, 0x80000000,
47     0x1B000000, 0x36000000, 
48     /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
49 };
50
51
52 static const word32 Te[5][256] = {
53 {
54     0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
55     0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
56     0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
57     0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
58     0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
59     0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
60     0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
61     0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
62     0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
63     0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
64     0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
65     0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
66     0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
67     0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
68     0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
69     0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
70     0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
71     0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
72     0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
73     0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
74     0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
75     0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
76     0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
77     0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
78     0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
79     0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
80     0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
81     0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
82     0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
83     0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
84     0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
85     0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
86     0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
87     0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
88     0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
89     0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
90     0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
91     0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
92     0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
93     0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
94     0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
95     0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
96     0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
97     0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
98     0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
99     0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
100     0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
101     0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
102     0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
103     0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
104     0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
105     0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
106     0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
107     0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
108     0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
109     0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
110     0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
111     0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
112     0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
113     0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
114     0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
115     0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
116     0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
117     0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
118 },
119 {
120     0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
121     0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
122     0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
123     0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
124     0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
125     0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
126     0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
127     0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
128     0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
129     0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
130     0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
131     0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
132     0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
133     0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
134     0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
135     0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
136     0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
137     0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
138     0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
139     0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
140     0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
141     0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
142     0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
143     0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
144     0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
145     0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
146     0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
147     0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
148     0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
149     0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
150     0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
151     0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
152     0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
153     0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
154     0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
155     0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
156     0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
157     0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
158     0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
159     0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
160     0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
161     0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
162     0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
163     0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
164     0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
165     0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
166     0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
167     0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
168     0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
169     0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
170     0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
171     0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
172     0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
173     0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
174     0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
175     0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
176     0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
177     0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
178     0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
179     0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
180     0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
181     0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
182     0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
183     0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
184 },
185 {
186     0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
187     0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
188     0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
189     0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
190     0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
191     0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
192     0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
193     0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
194     0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
195     0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
196     0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
197     0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
198     0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
199     0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
200     0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
201     0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
202     0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
203     0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
204     0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
205     0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
206     0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
207     0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
208     0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
209     0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
210     0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
211     0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
212     0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
213     0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
214     0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
215     0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
216     0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
217     0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
218     0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
219     0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
220     0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
221     0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
222     0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
223     0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
224     0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
225     0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
226     0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
227     0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
228     0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
229     0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
230     0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
231     0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
232     0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
233     0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
234     0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
235     0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
236     0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
237     0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
238     0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
239     0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
240     0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
241     0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
242     0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
243     0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
244     0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
245     0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
246     0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
247     0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
248     0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
249     0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
250 },
251 {
252     0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
253     0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
254     0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
255     0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
256     0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
257     0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
258     0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
259     0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
260     0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
261     0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
262     0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
263     0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
264     0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
265     0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
266     0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
267     0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
268     0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
269     0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
270     0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
271     0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
272     0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
273     0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
274     0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
275     0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
276     0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
277     0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
278     0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
279     0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
280     0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
281     0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
282     0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
283     0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
284     0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
285     0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
286     0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
287     0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
288     0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
289     0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
290     0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
291     0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
292     0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
293     0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
294     0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
295     0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
296     0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
297     0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
298     0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
299     0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
300     0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
301     0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
302     0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
303     0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
304     0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
305     0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
306     0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
307     0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
308     0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
309     0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
310     0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
311     0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
312     0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
313     0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
314     0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
315     0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
316 },
317 {
318     0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
319     0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
320     0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
321     0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
322     0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
323     0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
324     0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
325     0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
326     0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
327     0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
328     0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
329     0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
330     0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
331     0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
332     0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
333     0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
334     0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
335     0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
336     0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
337     0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
338     0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
339     0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
340     0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
341     0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
342     0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
343     0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
344     0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
345     0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
346     0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
347     0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
348     0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
349     0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
350     0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
351     0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
352     0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
353     0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
354     0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
355     0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
356     0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
357     0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
358     0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
359     0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
360     0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
361     0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
362     0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
363     0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
364     0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
365     0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
366     0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
367     0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
368     0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
369     0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
370     0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
371     0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
372     0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
373     0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
374     0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
375     0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
376     0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
377     0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
378     0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
379     0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
380     0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
381     0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
382 }
383 };
384
385
386 static const word32 Td[5][256] = {
387 {
388     0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
389     0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
390     0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
391     0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
392     0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
393     0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
394     0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
395     0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
396     0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
397     0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
398     0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
399     0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
400     0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
401     0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
402     0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
403     0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
404     0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
405     0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
406     0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
407     0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
408     0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
409     0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
410     0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
411     0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
412     0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
413     0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
414     0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
415     0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
416     0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
417     0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
418     0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
419     0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
420     0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
421     0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
422     0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
423     0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
424     0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
425     0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
426     0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
427     0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
428     0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
429     0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
430     0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
431     0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
432     0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
433     0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
434     0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
435     0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
436     0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
437     0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
438     0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
439     0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
440     0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
441     0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
442     0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
443     0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
444     0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
445     0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
446     0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
447     0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
448     0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
449     0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
450     0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
451     0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
452 },
453 {
454     0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
455     0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
456     0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
457     0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
458     0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
459     0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
460     0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
461     0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
462     0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
463     0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
464     0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
465     0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
466     0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
467     0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
468     0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
469     0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
470     0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
471     0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
472     0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
473     0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
474     0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
475     0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
476     0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
477     0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
478     0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
479     0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
480     0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
481     0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
482     0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
483     0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
484     0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
485     0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
486     0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
487     0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
488     0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
489     0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
490     0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
491     0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
492     0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
493     0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
494     0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
495     0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
496     0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
497     0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
498     0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
499     0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
500     0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
501     0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
502     0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
503     0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
504     0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
505     0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
506     0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
507     0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
508     0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
509     0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
510     0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
511     0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
512     0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
513     0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
514     0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
515     0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
516     0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
517     0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
518 },
519 {
520     0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
521     0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
522     0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
523     0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
524     0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
525     0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
526     0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
527     0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
528     0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
529     0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
530     0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
531     0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
532     0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
533     0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
534     0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
535     0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
536     0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
537     0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
538     0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
539     0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
540
541     0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
542     0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
543     0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
544     0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
545     0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
546     0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
547     0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
548     0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
549     0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
550     0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
551     0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
552     0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
553     0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
554     0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
555     0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
556     0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
557     0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
558     0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
559     0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
560     0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
561     0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
562     0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
563     0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
564     0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
565     0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
566     0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
567     0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
568     0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
569     0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
570     0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
571     0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
572     0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
573     0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
574     0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
575     0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
576     0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
577     0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
578     0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
579     0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
580     0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
581     0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
582     0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
583     0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
584     0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
585 },
586 {
587     0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
588     0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
589     0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
590     0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
591     0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
592     0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
593     0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
594     0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
595     0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
596     0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
597     0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
598     0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
599     0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
600     0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
601     0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
602     0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
603     0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
604     0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
605     0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
606     0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
607     0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
608     0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
609     0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
610     0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
611     0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
612     0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
613     0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
614     0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
615     0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
616     0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
617     0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
618     0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
619     0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
620     0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
621     0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
622     0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
623     0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
624     0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
625     0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
626     0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
627     0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
628     0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
629     0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
630     0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
631     0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
632     0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
633     0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
634     0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
635     0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
636     0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
637     0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
638     0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
639     0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
640     0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
641     0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
642     0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
643     0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
644     0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
645     0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
646     0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
647     0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
648     0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
649     0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
650     0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
651 },
652 {
653     0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
654     0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
655     0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
656     0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
657     0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
658     0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
659     0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
660     0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
661     0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
662     0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
663     0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
664     0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
665     0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
666     0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
667     0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
668     0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
669     0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
670     0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
671     0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
672     0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
673     0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
674     0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
675     0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
676     0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
677     0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
678     0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
679     0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
680     0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
681     0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
682     0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
683     0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
684     0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
685     0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
686     0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
687     0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
688     0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
689     0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
690     0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
691     0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
692     0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
693     0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
694     0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
695     0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
696     0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
697     0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
698     0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
699     0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
700     0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
701     0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
702     0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
703     0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
704     0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
705     0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
706     0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
707     0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
708     0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
709     0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
710     0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
711     0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
712     0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
713     0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
714     0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
715     0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
716     0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
717 }
718 };
719
720
721
722 #define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
723
724
725 #ifdef CYASSL_AESNI
726
727 #ifndef _MSC_VER
728
729     #define cpuid(func,ax,bx,cx,dx)\
730         __asm__ __volatile__ ("cpuid":\
731                        "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func));
732
733 #else
734
735     #define cpuid(func,ax,bx,cx,dx)\
736         __asm mov eax, func \
737         __asm cpuid \
738         __asm mov ax, eax \
739         __asm mov bx, ebx \
740         __asm mov cx, ecx \
741         __asm mov dx, edx
742
743 #endif /* _MSC_VER */
744
745             
746 static int Check_CPU_support_AES()
747 {
748     unsigned int a,b,c,d;
749     cpuid(1,a,b,c,d);
750
751     if (c & 0x2000000)
752         return 1;
753
754     return 0;
755 }
756
757 static int checkAESNI = 0;
758 static int haveAESNI  = 0;
759
760
761 void AES_CBC_encrypt(const unsigned char* in, unsigned char* out,
762                      unsigned char* ivec, unsigned long length,
763                      const unsigned char* KS, int nr);
764
765
766 void AES_CBC_decrypt(const unsigned char* in, unsigned char* out,
767                      unsigned char* ivec, unsigned long length,
768                      const unsigned char* KS, int nr);
769
770 void AES_128_Key_Expansion(const unsigned char* userkey, 
771                            unsigned char* key_schedule);
772
773 void AES_192_Key_Expansion(const unsigned char* userkey, 
774                            unsigned char* key_schedule);
775
776 void AES_256_Key_Expansion(const unsigned char* userkey, 
777                            unsigned char* key_schedule);
778
779
780 int AES_set_encrypt_key (const unsigned char *userKey, const int bits,
781                          Aes* aes)
782
783     if (!userKey || !aes)
784         return BAD_FUNC_ARG;
785     
786     if (bits == 128) {
787        AES_128_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 10;
788        return 0;
789     }
790     else if (bits == 192) {
791        AES_192_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 12;
792        return 0;
793     }
794     else if (bits == 256) {
795        AES_256_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 14;
796        return 0;
797     }
798     return BAD_FUNC_ARG;
799 }
800
801
802 int AES_set_decrypt_key (const unsigned char* userKey, const int bits,
803                          Aes* aes)
804 {
805     int nr;
806     Aes temp_key;
807     __m128i *Key_Schedule = (__m128i*)aes->key;
808     __m128i *Temp_Key_Schedule = (__m128i*)temp_key.key;
809     
810     if (!userKey || !aes)
811         return BAD_FUNC_ARG;
812
813     if (AES_set_encrypt_key(userKey,bits,&temp_key) == BAD_FUNC_ARG)
814         return BAD_FUNC_ARG;
815
816     nr = temp_key.rounds;
817     aes->rounds = nr;
818
819     Key_Schedule[nr] = Temp_Key_Schedule[0];
820     Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
821     Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
822     Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
823     Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
824     Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
825     Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
826     Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
827     Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
828     Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
829     
830     if(nr>10) {
831         Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
832         Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
833     }
834
835     if(nr>12) {
836         Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
837         Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
838     }
839
840     Key_Schedule[0] = Temp_Key_Schedule[nr];
841     
842     return 0;
843 }
844
845
846
847 #endif /* CYASSL_AESNI */
848
849
850 int AesSetIV(Aes* aes, const byte* iv)
851 {
852     if (aes == NULL)
853         return BAD_FUNC_ARG;
854
855     if (iv)
856         XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
857
858     return 0;
859 }
860
861
862 int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
863               int dir)
864 {
865     word32 temp, *rk = aes->key;
866     unsigned int i = 0;
867
868     if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
869         return BAD_FUNC_ARG;
870
871 #ifdef CYASSL_AESNI
872     if (checkAESNI == 0) {
873         haveAESNI  = Check_CPU_support_AES();
874         checkAESNI = 1;
875     }
876     if (haveAESNI) {
877         if (iv)
878             XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
879         if (dir == AES_ENCRYPTION)
880             return AES_set_encrypt_key(userKey, keylen * 8, aes);
881         else
882             return AES_set_decrypt_key(userKey, keylen * 8, aes);
883     }
884 #endif /* CYASSL_AESNI */
885
886     aes->rounds = keylen/4 + 6;
887
888     XMEMCPY(rk, userKey, keylen);
889     #ifdef LITTLE_ENDIAN_ORDER
890         ByteReverseWords(rk, rk, keylen);
891     #endif
892
893     switch(keylen)
894     {
895     case 16:
896         while (1)
897         {
898             temp  = rk[3];
899             rk[4] = rk[0] ^
900                 (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
901                 (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
902                 (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
903                 (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
904                 rcon[i];
905             rk[5] = rk[1] ^ rk[4];
906             rk[6] = rk[2] ^ rk[5];
907             rk[7] = rk[3] ^ rk[6];
908             if (++i == 10)
909                 break;
910             rk += 4;
911         }
912         break;
913
914     case 24:
915         while (1)  /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
916         {
917             temp = rk[ 5];
918             rk[ 6] = rk[ 0] ^
919                 (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
920                 (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
921                 (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
922                 (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
923                 rcon[i];
924             rk[ 7] = rk[ 1] ^ rk[ 6];
925             rk[ 8] = rk[ 2] ^ rk[ 7];
926             rk[ 9] = rk[ 3] ^ rk[ 8];
927             if (++i == 8)
928                 break;
929             rk[10] = rk[ 4] ^ rk[ 9];
930             rk[11] = rk[ 5] ^ rk[10];
931             rk += 6;
932         }
933         break;
934
935     case 32:
936         while (1)
937         {
938             temp = rk[ 7];
939             rk[ 8] = rk[ 0] ^
940                 (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
941                 (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
942                 (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
943                 (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
944                 rcon[i];
945             rk[ 9] = rk[ 1] ^ rk[ 8];
946             rk[10] = rk[ 2] ^ rk[ 9];
947             rk[11] = rk[ 3] ^ rk[10];
948             if (++i == 7)
949                 break;
950             temp = rk[11];
951             rk[12] = rk[ 4] ^
952                 (Te[4][GETBYTE(temp, 3)] & 0xff000000) ^
953                 (Te[4][GETBYTE(temp, 2)] & 0x00ff0000) ^
954                 (Te[4][GETBYTE(temp, 1)] & 0x0000ff00) ^
955                 (Te[4][GETBYTE(temp, 0)] & 0x000000ff);
956             rk[13] = rk[ 5] ^ rk[12];
957             rk[14] = rk[ 6] ^ rk[13];
958             rk[15] = rk[ 7] ^ rk[14];
959
960             rk += 8;
961         }
962         break;
963
964     default:
965         return BAD_FUNC_ARG;
966     }
967
968     if (dir == AES_DECRYPTION)
969     {
970         unsigned int j;
971         rk = aes->key;
972
973         /* invert the order of the round keys: */
974         for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
975             temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
976             temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
977             temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
978             temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
979         }
980         /* apply the inverse MixColumn transform to all round keys but the
981            first and the last: */
982         for (i = 1; i < aes->rounds; i++) {
983             rk += 4;
984             rk[0] =
985                 Td[0][Te[4][GETBYTE(rk[0], 3)] & 0xff] ^
986                 Td[1][Te[4][GETBYTE(rk[0], 2)] & 0xff] ^
987                 Td[2][Te[4][GETBYTE(rk[0], 1)] & 0xff] ^
988                 Td[3][Te[4][GETBYTE(rk[0], 0)] & 0xff];
989             rk[1] =
990                 Td[0][Te[4][GETBYTE(rk[1], 3)] & 0xff] ^
991                 Td[1][Te[4][GETBYTE(rk[1], 2)] & 0xff] ^
992                 Td[2][Te[4][GETBYTE(rk[1], 1)] & 0xff] ^
993                 Td[3][Te[4][GETBYTE(rk[1], 0)] & 0xff];
994             rk[2] =
995                 Td[0][Te[4][GETBYTE(rk[2], 3)] & 0xff] ^
996                 Td[1][Te[4][GETBYTE(rk[2], 2)] & 0xff] ^
997                 Td[2][Te[4][GETBYTE(rk[2], 1)] & 0xff] ^
998                 Td[3][Te[4][GETBYTE(rk[2], 0)] & 0xff];
999             rk[3] =
1000                 Td[0][Te[4][GETBYTE(rk[3], 3)] & 0xff] ^
1001                 Td[1][Te[4][GETBYTE(rk[3], 2)] & 0xff] ^
1002                 Td[2][Te[4][GETBYTE(rk[3], 1)] & 0xff] ^
1003                 Td[3][Te[4][GETBYTE(rk[3], 0)] & 0xff];
1004         }
1005     }
1006
1007     return AesSetIV(aes, iv);
1008 }
1009
1010
1011 static void AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
1012 {
1013     word32 s0, s1, s2, s3;
1014     word32 t0, t1, t2, t3;
1015     word32 r = aes->rounds >> 1;
1016
1017     const word32* rk = aes->key;
1018     if (r > 7 || r == 0) {
1019         CYASSL_MSG("AesEncrypt encountered improper key, set it up");
1020         return;  /* stop instead of segfaulting, set up your keys! */
1021     }
1022     /*
1023      * map byte array block to cipher state
1024      * and add initial round key:
1025      */
1026     XMEMCPY(&s0, inBlock,                  sizeof(s0));
1027     XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
1028     XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
1029     XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
1030
1031     #ifdef LITTLE_ENDIAN_ORDER
1032         s0 = ByteReverseWord32(s0);
1033         s1 = ByteReverseWord32(s1);
1034         s2 = ByteReverseWord32(s2);
1035         s3 = ByteReverseWord32(s3);
1036     #endif
1037
1038     s0 ^= rk[0];
1039     s1 ^= rk[1];
1040     s2 ^= rk[2];
1041     s3 ^= rk[3];
1042    
1043     /*
1044      * Nr - 1 full rounds:
1045      */
1046
1047     for (;;) {
1048         t0 =
1049             Te[0][GETBYTE(s0, 3)]  ^
1050             Te[1][GETBYTE(s1, 2)]  ^
1051             Te[2][GETBYTE(s2, 1)]  ^
1052             Te[3][GETBYTE(s3, 0)]  ^
1053             rk[4];
1054         t1 =
1055             Te[0][GETBYTE(s1, 3)]  ^
1056             Te[1][GETBYTE(s2, 2)]  ^
1057             Te[2][GETBYTE(s3, 1)]  ^
1058             Te[3][GETBYTE(s0, 0)]  ^
1059             rk[5];
1060         t2 =
1061             Te[0][GETBYTE(s2, 3)] ^
1062             Te[1][GETBYTE(s3, 2)]  ^
1063             Te[2][GETBYTE(s0, 1)]  ^
1064             Te[3][GETBYTE(s1, 0)]  ^
1065             rk[6];
1066         t3 =
1067             Te[0][GETBYTE(s3, 3)] ^
1068             Te[1][GETBYTE(s0, 2)]  ^
1069             Te[2][GETBYTE(s1, 1)]  ^
1070             Te[3][GETBYTE(s2, 0)]  ^
1071             rk[7];
1072
1073         rk += 8;
1074         if (--r == 0) {
1075             break;
1076         }
1077         
1078         s0 =
1079             Te[0][GETBYTE(t0, 3)] ^
1080             Te[1][GETBYTE(t1, 2)] ^
1081             Te[2][GETBYTE(t2, 1)] ^
1082             Te[3][GETBYTE(t3, 0)] ^
1083             rk[0];
1084         s1 =
1085             Te[0][GETBYTE(t1, 3)] ^
1086             Te[1][GETBYTE(t2, 2)] ^
1087             Te[2][GETBYTE(t3, 1)] ^
1088             Te[3][GETBYTE(t0, 0)] ^
1089             rk[1];
1090         s2 =
1091             Te[0][GETBYTE(t2, 3)] ^
1092             Te[1][GETBYTE(t3, 2)] ^
1093             Te[2][GETBYTE(t0, 1)] ^
1094             Te[3][GETBYTE(t1, 0)] ^
1095             rk[2];
1096         s3 =
1097             Te[0][GETBYTE(t3, 3)] ^
1098             Te[1][GETBYTE(t0, 2)] ^
1099             Te[2][GETBYTE(t1, 1)] ^
1100             Te[3][GETBYTE(t2, 0)] ^
1101             rk[3];
1102     }
1103
1104     /*
1105      * apply last round and
1106      * map cipher state to byte array block:
1107      */
1108
1109     s0 =
1110         (Te[4][GETBYTE(t0, 3)] & 0xff000000) ^
1111         (Te[4][GETBYTE(t1, 2)] & 0x00ff0000) ^
1112         (Te[4][GETBYTE(t2, 1)] & 0x0000ff00) ^
1113         (Te[4][GETBYTE(t3, 0)] & 0x000000ff) ^
1114         rk[0];
1115     s1 =
1116         (Te[4][GETBYTE(t1, 3)] & 0xff000000) ^
1117         (Te[4][GETBYTE(t2, 2)] & 0x00ff0000) ^
1118         (Te[4][GETBYTE(t3, 1)] & 0x0000ff00) ^
1119         (Te[4][GETBYTE(t0, 0)] & 0x000000ff) ^
1120         rk[1];
1121     s2 =
1122         (Te[4][GETBYTE(t2, 3)] & 0xff000000) ^
1123         (Te[4][GETBYTE(t3, 2)] & 0x00ff0000) ^
1124         (Te[4][GETBYTE(t0, 1)] & 0x0000ff00) ^
1125         (Te[4][GETBYTE(t1, 0)] & 0x000000ff) ^
1126         rk[2];
1127     s3 =
1128         (Te[4][GETBYTE(t3, 3)] & 0xff000000) ^
1129         (Te[4][GETBYTE(t0, 2)] & 0x00ff0000) ^
1130         (Te[4][GETBYTE(t1, 1)] & 0x0000ff00) ^
1131         (Te[4][GETBYTE(t2, 0)] & 0x000000ff) ^
1132         rk[3];
1133
1134     /* write out */
1135     #ifdef LITTLE_ENDIAN_ORDER
1136         s0 = ByteReverseWord32(s0);
1137         s1 = ByteReverseWord32(s1);
1138         s2 = ByteReverseWord32(s2);
1139         s3 = ByteReverseWord32(s3);
1140     #endif
1141
1142     XMEMCPY(outBlock,                  &s0, sizeof(s0));
1143     XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
1144     XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
1145     XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
1146 }
1147
1148
1149 static void AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
1150 {
1151     word32 s0, s1, s2, s3;
1152     word32 t0, t1, t2, t3;
1153     word32 r = aes->rounds >> 1;
1154
1155     const word32* rk = aes->key;
1156     if (r > 7 || r == 0) {
1157         CYASSL_MSG("AesDecrypt encountered improper key, set it up");
1158         return;  /* stop instead of segfaulting, set up your keys! */
1159     }
1160     /*
1161      * map byte array block to cipher state
1162      * and add initial round key:
1163      */
1164     XMEMCPY(&s0, inBlock,                  sizeof(s0));
1165     XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
1166     XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
1167     XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
1168
1169     #ifdef LITTLE_ENDIAN_ORDER
1170         s0 = ByteReverseWord32(s0);
1171         s1 = ByteReverseWord32(s1);
1172         s2 = ByteReverseWord32(s2);
1173         s3 = ByteReverseWord32(s3);
1174     #endif
1175
1176     s0 ^= rk[0];
1177     s1 ^= rk[1];
1178     s2 ^= rk[2];
1179     s3 ^= rk[3];
1180    
1181     /*
1182      * Nr - 1 full rounds:
1183      */
1184
1185     for (;;) {
1186         t0 =
1187             Td[0][GETBYTE(s0, 3)] ^
1188             Td[1][GETBYTE(s3, 2)] ^
1189             Td[2][GETBYTE(s2, 1)] ^
1190             Td[3][GETBYTE(s1, 0)] ^
1191             rk[4];
1192         t1 =
1193             Td[0][GETBYTE(s1, 3)] ^
1194             Td[1][GETBYTE(s0, 2)] ^
1195             Td[2][GETBYTE(s3, 1)] ^
1196             Td[3][GETBYTE(s2, 0)] ^
1197             rk[5];
1198         t2 =
1199             Td[0][GETBYTE(s2, 3)] ^
1200             Td[1][GETBYTE(s1, 2)] ^
1201             Td[2][GETBYTE(s0, 1)] ^
1202             Td[3][GETBYTE(s3, 0)] ^
1203             rk[6];
1204         t3 =
1205             Td[0][GETBYTE(s3, 3)] ^
1206             Td[1][GETBYTE(s2, 2)] ^
1207             Td[2][GETBYTE(s1, 1)] ^
1208             Td[3][GETBYTE(s0, 0)] ^
1209             rk[7];
1210
1211         rk += 8;
1212         if (--r == 0) {
1213             break;
1214         }
1215
1216         s0 =
1217             Td[0][GETBYTE(t0, 3)] ^
1218             Td[1][GETBYTE(t3, 2)] ^
1219             Td[2][GETBYTE(t2, 1)] ^
1220             Td[3][GETBYTE(t1, 0)] ^
1221             rk[0];
1222         s1 =
1223             Td[0][GETBYTE(t1, 3)] ^
1224             Td[1][GETBYTE(t0, 2)] ^
1225             Td[2][GETBYTE(t3, 1)] ^
1226             Td[3][GETBYTE(t2, 0)] ^
1227             rk[1];
1228         s2 =
1229             Td[0][GETBYTE(t2, 3)] ^
1230             Td[1][GETBYTE(t1, 2)] ^
1231             Td[2][GETBYTE(t0, 1)] ^
1232             Td[3][GETBYTE(t3, 0)] ^
1233             rk[2];
1234         s3 =
1235             Td[0][GETBYTE(t3, 3)] ^
1236             Td[1][GETBYTE(t2, 2)] ^
1237             Td[2][GETBYTE(t1, 1)] ^
1238             Td[3][GETBYTE(t0, 0)] ^
1239             rk[3];
1240     }
1241     /*
1242      * apply last round and
1243      * map cipher state to byte array block:
1244      */
1245     s0 =
1246         (Td[4][GETBYTE(t0, 3)] & 0xff000000) ^
1247         (Td[4][GETBYTE(t3, 2)] & 0x00ff0000) ^
1248         (Td[4][GETBYTE(t2, 1)] & 0x0000ff00) ^
1249         (Td[4][GETBYTE(t1, 0)] & 0x000000ff) ^
1250         rk[0];
1251     s1 =
1252         (Td[4][GETBYTE(t1, 3)] & 0xff000000) ^
1253         (Td[4][GETBYTE(t0, 2)] & 0x00ff0000) ^
1254         (Td[4][GETBYTE(t3, 1)] & 0x0000ff00) ^
1255         (Td[4][GETBYTE(t2, 0)] & 0x000000ff) ^
1256         rk[1];
1257     s2 =
1258         (Td[4][GETBYTE(t2, 3)] & 0xff000000) ^
1259         (Td[4][GETBYTE(t1, 2)] & 0x00ff0000) ^
1260         (Td[4][GETBYTE(t0, 1)] & 0x0000ff00) ^
1261         (Td[4][GETBYTE(t3, 0)] & 0x000000ff) ^
1262         rk[2];
1263     s3 =
1264         (Td[4][GETBYTE(t3, 3)] & 0xff000000) ^
1265         (Td[4][GETBYTE(t2, 2)] & 0x00ff0000) ^
1266         (Td[4][GETBYTE(t1, 1)] & 0x0000ff00) ^
1267         (Td[4][GETBYTE(t0, 0)] & 0x000000ff) ^
1268         rk[3];
1269
1270     /* write out */
1271     #ifdef LITTLE_ENDIAN_ORDER
1272         s0 = ByteReverseWord32(s0);
1273         s1 = ByteReverseWord32(s1);
1274         s2 = ByteReverseWord32(s2);
1275         s3 = ByteReverseWord32(s3);
1276     #endif
1277
1278     XMEMCPY(outBlock,                  &s0, sizeof(s0));
1279     XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
1280     XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
1281     XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
1282 }
1283
1284
1285 void AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
1286 {
1287     word32 blocks = sz / AES_BLOCK_SIZE;
1288
1289 #ifdef CYASSL_AESNI
1290     if (haveAESNI) {
1291         #ifdef DEBUG_AESNI
1292             printf("about to aes cbc encrypt\n");
1293             printf("in  = %p\n", in);
1294             printf("out = %p\n", out);
1295             printf("aes->key = %p\n", aes->key);
1296             printf("aes->reg = %p\n", aes->reg);
1297             printf("aes->rounds = %d\n", aes->rounds);
1298             printf("sz = %d\n", sz);
1299         #endif
1300         AES_CBC_encrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
1301                         aes->rounds);
1302         /* store iv for next call */
1303         XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
1304         return;
1305     }
1306 #endif
1307
1308     while (blocks--) {
1309         xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE);
1310         AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg);
1311         XMEMCPY(out, aes->reg, AES_BLOCK_SIZE);
1312
1313         out += AES_BLOCK_SIZE;
1314         in  += AES_BLOCK_SIZE; 
1315     }
1316 }
1317
1318
1319 void AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
1320 {
1321     word32 blocks = sz / AES_BLOCK_SIZE;
1322
1323 #ifdef CYASSL_AESNI
1324     if (haveAESNI) {
1325         #ifdef DEBUG_AESNI
1326             printf("about to aes cbc decrypt\n");
1327             printf("in  = %p\n", in);
1328             printf("out = %p\n", out);
1329             printf("aes->key = %p\n", aes->key);
1330             printf("aes->reg = %p\n", aes->reg);
1331             printf("aes->rounds = %d\n", aes->rounds);
1332             printf("sz = %d\n", sz);
1333         #endif
1334
1335         /* if input and output same will overwrite input iv */
1336         XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
1337         AES_CBC_decrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
1338                         aes->rounds);
1339         /* store iv for next call */
1340         XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
1341         return;
1342     }
1343 #endif
1344
1345     while (blocks--) {
1346         XMEMCPY(aes->tmp, in, AES_BLOCK_SIZE);
1347         AesDecrypt(aes, (byte*)aes->tmp, out);
1348         xorbuf(out, (byte*)aes->reg, AES_BLOCK_SIZE);
1349         XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
1350
1351         out += AES_BLOCK_SIZE;
1352         in  += AES_BLOCK_SIZE; 
1353     }
1354 }
1355
1356
1357 #ifdef CYASSL_AES_DIRECT
1358
1359 /* Allow direct access to one block encrypt */
1360 void AesEncryptDirect(Aes* aes, byte* out, const byte* in)
1361 {
1362     return AesEncrypt(aes, in, out);
1363 }
1364
1365
1366 /* Allow direct access to one block decrypt */
1367 void AesDecryptDirect(Aes* aes, byte* out, const byte* in)
1368 {
1369     return AesDecrypt(aes, in, out);
1370 }
1371
1372
1373 #endif /* CYASSL_AES_DIRECT */
1374
1375
1376 #ifdef CYASSL_AES_COUNTER
1377
1378 /* Increment AES counter */
1379 static INLINE void IncrementAesCounter(byte* inOutCtr)
1380 {
1381     int i;
1382
1383     /* in network byte order so start at end and work back */
1384     for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
1385         if (++inOutCtr[i])  /* we're done unless we overflow */
1386             return;
1387     }
1388 }
1389   
1390
1391 void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
1392 {
1393     word32 blocks = sz / AES_BLOCK_SIZE;
1394
1395     while (blocks--) {
1396         AesEncrypt(aes, (byte*)aes->reg, out);
1397         IncrementAesCounter((byte*)aes->reg);
1398         xorbuf(out, in, AES_BLOCK_SIZE);
1399
1400         out += AES_BLOCK_SIZE;
1401         in  += AES_BLOCK_SIZE; 
1402     }
1403 }
1404
1405 #endif /* CYASSL_AES_COUNTER */
1406
1407
1408 #ifdef HAVE_AESGCM
1409
1410 /*
1411  * The IV for AES GCM, stored in struct Aes's member reg, is comprised of
1412  * three parts in order:
1413  *   1. The implicit IV. This is generated from the PRF using the shared
1414  *      secrets between endpoints. It is 4 bytes long.
1415  *   2. The explicit IV. This is set by the user of the AES. It needs to be
1416  *      unique for each call to encrypt. The explicit IV is shared with the
1417  *      other end of the transaction in the clear.
1418  *   3. The counter. Each block of data is encrypted with its own sequence
1419  *      number counter.
1420  */
1421
1422 enum {
1423     IMPLICIT_IV_SZ = 4,
1424     EXPLICIT_IV_SZ = 8,
1425     CTR_SZ = 4
1426 };
1427
1428
1429 static INLINE void InitGcmCounter(byte* inOutCtr)
1430 {
1431     inOutCtr[AES_BLOCK_SIZE - 4] = 0;
1432     inOutCtr[AES_BLOCK_SIZE - 3] = 0;
1433     inOutCtr[AES_BLOCK_SIZE - 2] = 0;
1434     inOutCtr[AES_BLOCK_SIZE - 1] = 1;
1435 }
1436
1437
1438 static INLINE void IncrementGcmCounter(byte* inOutCtr)
1439 {
1440     int i;
1441
1442     /* in network byte order so start at end and work back */
1443     for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) {
1444         if (++inOutCtr[i])  /* we're done unless we overflow */
1445             return;
1446     }
1447 }
1448
1449
1450 /*
1451  * The explicit IV is set by the caller. A common practice is to treat it as
1452  * a sequence number seeded with a random number. The caller manages
1453  * incrementing the explicit IV when appropriate.
1454  */
1455
1456 void AesGcmSetExpIV(Aes* aes, const byte* iv)
1457 {
1458     XMEMCPY((byte*)aes->reg + IMPLICIT_IV_SZ, iv, EXPLICIT_IV_SZ);
1459 }
1460
1461
1462 void AesGcmGetExpIV(Aes* aes, byte* iv)
1463 {
1464     XMEMCPY(iv, (byte*)aes->reg + IMPLICIT_IV_SZ, EXPLICIT_IV_SZ);
1465 }
1466
1467
1468 void AesGcmIncExpIV(Aes* aes)
1469 {
1470     int i;
1471     byte* iv = (byte*)aes->reg + IMPLICIT_IV_SZ;
1472
1473     for (i = EXPLICIT_IV_SZ - 1; i >= 0; i--) {
1474         if (++iv[i])
1475             return;
1476     }
1477 }
1478
1479
1480 #if defined(GCM_SMALL) || defined(GCM_TABLE)
1481
1482 static INLINE void FlattenSzInBits(byte* buf, word32 sz)
1483 {
1484     /* Multiply the sz by 8 */
1485     word32 szHi = (sz >> (8*sizeof(sz) - 3));
1486     sz <<= 3;
1487
1488     /* copy over the words of the sz into the destination buffer */
1489     buf[0] = (szHi >> 24) & 0xff;
1490     buf[1] = (szHi >> 16) & 0xff;
1491     buf[2] = (szHi >>  8) & 0xff;
1492     buf[3] = szHi & 0xff;
1493     buf[4] = (sz >> 24) & 0xff;
1494     buf[5] = (sz >> 16) & 0xff;
1495     buf[6] = (sz >>  8) & 0xff;
1496     buf[7] = sz & 0xff;
1497 }
1498
1499
1500 static INLINE void RIGHTSHIFTX(byte* x)
1501 {
1502     int i;
1503     int carryOut = 0;
1504     int carryIn = 0;
1505     int borrow = x[15] & 0x01;
1506
1507     for (i = 0; i < AES_BLOCK_SIZE; i++) {
1508         carryOut = x[i] & 0x01;
1509         x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0);
1510         carryIn = carryOut;
1511     }
1512     if (borrow) x[0] ^= 0xE1;
1513 }
1514
1515 #endif /* defined(GCM_SMALL) || defined(GCM_TABLE) */
1516
1517
1518 #ifdef GCM_TABLE
1519
1520 static void GenerateM0(Aes* aes)
1521 {
1522     int i, j;
1523     byte (*m)[AES_BLOCK_SIZE] = aes->M0;
1524
1525     XMEMCPY(m[128], aes->H, AES_BLOCK_SIZE);
1526
1527     for (i = 64; i > 0; i /= 2) {
1528         XMEMCPY(m[i], m[i*2], AES_BLOCK_SIZE);
1529         RIGHTSHIFTX(m[i]);
1530     }
1531
1532     for (i = 2; i < 256; i *= 2) {
1533         for (j = 1; j < i; j++) {
1534             XMEMCPY(m[i+j], m[i], AES_BLOCK_SIZE);
1535             xorbuf(m[i+j], m[j], AES_BLOCK_SIZE);
1536         }
1537     }
1538
1539     XMEMSET(m[0], 0, AES_BLOCK_SIZE);
1540 }
1541
1542 #endif /* GCM_TABLE */
1543
1544
1545 void AesGcmSetKey(Aes* aes, const byte* key, word32 len,
1546                                                     const byte* implicitIV)
1547 {
1548     byte fullIV[AES_BLOCK_SIZE];
1549
1550     XMEMSET(fullIV, 0, AES_BLOCK_SIZE);
1551     XMEMCPY(fullIV, implicitIV, IMPLICIT_IV_SZ);
1552     AesSetKey(aes, key, len, fullIV, AES_ENCRYPTION);
1553
1554     XMEMSET(fullIV, 0, AES_BLOCK_SIZE);
1555     AesEncrypt(aes, fullIV, aes->H);
1556 #ifdef GCM_TABLE
1557     GenerateM0(aes);
1558 #endif /* GCM_TABLE */
1559 }
1560
1561
1562 #if defined(GCM_SMALL)
1563
1564 static void GMULT(byte* X, byte* Y)
1565 {
1566     byte Z[AES_BLOCK_SIZE];
1567     byte V[AES_BLOCK_SIZE];
1568     int i, j;
1569
1570     XMEMSET(Z, 0, AES_BLOCK_SIZE);
1571     XMEMCPY(V, X, AES_BLOCK_SIZE);
1572     for (i = 0; i < AES_BLOCK_SIZE; i++)
1573     {
1574         byte y = Y[i];
1575         for (j = 0; j < 8; j++)
1576         {
1577             if (y & 0x80) {
1578                 xorbuf(Z, V, AES_BLOCK_SIZE);
1579             }
1580
1581             RIGHTSHIFTX(V);
1582             y = y << 1;
1583         }
1584     }
1585     XMEMCPY(X, Z, AES_BLOCK_SIZE);
1586 }
1587
1588
1589 static void GHASH(Aes* aes, const byte* a, word32 aSz,
1590                                 const byte* c, word32 cSz, byte* s, word32 sSz)
1591 {
1592     byte x[AES_BLOCK_SIZE];
1593     byte scratch[AES_BLOCK_SIZE];
1594     word32 blocks, partial;
1595     byte* h = aes->H;
1596
1597     XMEMSET(x, 0, AES_BLOCK_SIZE);
1598
1599     /* Hash in A, the Additional Authentication Data */
1600     if (aSz != 0 && a != NULL) {
1601         blocks = aSz / AES_BLOCK_SIZE;
1602         partial = aSz % AES_BLOCK_SIZE;
1603         while (blocks--) {
1604             xorbuf(x, a, AES_BLOCK_SIZE);
1605             GMULT(x, h);
1606             a += AES_BLOCK_SIZE;
1607         }
1608         if (partial != 0) {
1609             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
1610             XMEMCPY(scratch, a, partial);
1611             xorbuf(x, scratch, AES_BLOCK_SIZE);
1612             GMULT(x, h);
1613         }
1614     }
1615
1616     /* Hash in C, the Ciphertext */
1617     if (cSz != 0 && c != NULL) {
1618         blocks = cSz / AES_BLOCK_SIZE;
1619         partial = cSz % AES_BLOCK_SIZE;
1620         while (blocks--) {
1621             xorbuf(x, c, AES_BLOCK_SIZE);
1622             GMULT(x, h);
1623             c += AES_BLOCK_SIZE;
1624         }
1625         if (partial != 0) {
1626             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
1627             XMEMCPY(scratch, c, partial);
1628             xorbuf(x, scratch, AES_BLOCK_SIZE);
1629             GMULT(x, h);
1630         }
1631     }
1632
1633     /* Hash in the lengths of A and C in bits */
1634     FlattenSzInBits(&scratch[0], aSz);
1635     FlattenSzInBits(&scratch[8], cSz);
1636     xorbuf(x, scratch, AES_BLOCK_SIZE);
1637     GMULT(x, h);
1638
1639     /* Copy the result into s. */
1640     XMEMCPY(s, x, sSz);
1641 }
1642
1643 /* end GCM_SMALL */
1644 #elif defined(GCM_TABLE)
1645
1646 static const byte R[256][2] = {
1647     {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
1648     {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
1649     {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
1650     {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
1651     {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
1652     {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
1653     {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
1654     {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
1655     {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
1656     {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
1657     {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
1658     {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
1659     {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
1660     {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
1661     {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
1662     {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
1663     {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
1664     {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
1665     {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
1666     {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
1667     {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
1668     {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
1669     {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
1670     {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
1671     {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
1672     {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
1673     {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
1674     {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
1675     {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
1676     {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
1677     {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
1678     {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
1679     {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
1680     {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
1681     {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
1682     {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
1683     {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
1684     {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
1685     {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
1686     {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
1687     {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
1688     {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
1689     {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
1690     {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
1691     {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
1692     {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
1693     {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
1694     {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
1695     {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
1696     {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
1697     {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
1698     {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
1699     {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
1700     {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
1701     {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
1702     {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
1703     {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
1704     {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
1705     {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
1706     {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
1707     {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
1708     {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
1709     {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
1710     {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
1711
1712
1713 static void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE])
1714 {
1715     int i, j;
1716     byte Z[AES_BLOCK_SIZE];
1717     byte a;
1718
1719     XMEMSET(Z, 0, sizeof(Z));
1720
1721     for (i = 15; i > 0; i--) {
1722         xorbuf(Z, m[x[i]], AES_BLOCK_SIZE);
1723         a = Z[15];
1724
1725         for (j = 15; j > 0; j--) {
1726             Z[j] = Z[j-1];
1727         }
1728
1729         Z[0] = R[a][0];
1730         Z[1] ^= R[a][1];
1731     }
1732     xorbuf(Z, m[x[0]], AES_BLOCK_SIZE);
1733
1734     XMEMCPY(x, Z, AES_BLOCK_SIZE);
1735 }
1736
1737
1738 static void GHASH(Aes* aes, const byte* a, word32 aSz,
1739                                 const byte* c, word32 cSz, byte* s, word32 sSz)
1740 {
1741     byte x[AES_BLOCK_SIZE];
1742     byte scratch[AES_BLOCK_SIZE];
1743     word32 blocks, partial;
1744
1745     XMEMSET(x, 0, AES_BLOCK_SIZE);
1746
1747     /* Hash in A, the Additional Authentication Data */
1748     if (aSz != 0 && a != NULL) {
1749         blocks = aSz / AES_BLOCK_SIZE;
1750         partial = aSz % AES_BLOCK_SIZE;
1751         while (blocks--) {
1752             xorbuf(x, a, AES_BLOCK_SIZE);
1753             GMULT(x, aes->M0);
1754             a += AES_BLOCK_SIZE;
1755         }
1756         if (partial != 0) {
1757             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
1758             XMEMCPY(scratch, a, partial);
1759             xorbuf(x, scratch, AES_BLOCK_SIZE);
1760             GMULT(x, aes->M0);
1761         }
1762     }
1763
1764     /* Hash in C, the Ciphertext */
1765     if (cSz != 0 && c != NULL) {
1766         blocks = cSz / AES_BLOCK_SIZE;
1767         partial = cSz % AES_BLOCK_SIZE;
1768         while (blocks--) {
1769             xorbuf(x, c, AES_BLOCK_SIZE);
1770             GMULT(x, aes->M0);
1771             c += AES_BLOCK_SIZE;
1772         }
1773         if (partial != 0) {
1774             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
1775             XMEMCPY(scratch, c, partial);
1776             xorbuf(x, scratch, AES_BLOCK_SIZE);
1777             GMULT(x, aes->M0);
1778         }
1779     }
1780
1781     /* Hash in the lengths of A and C in bits */
1782     FlattenSzInBits(&scratch[0], aSz);
1783     FlattenSzInBits(&scratch[8], cSz);
1784     xorbuf(x, scratch, AES_BLOCK_SIZE);
1785     GMULT(x, aes->M0);
1786
1787     /* Copy the result into s. */
1788     XMEMCPY(s, x, sSz);
1789 }
1790
1791 /* end GCM_TABLE */
1792 #elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
1793
1794 static void GMULT(word64* X, word64* Y)
1795 {
1796     word64 Z[2] = {0,0};
1797     word64 V[2] = {X[0], X[1]};
1798     int i, j;
1799
1800     for (i = 0; i < 2; i++)
1801     {
1802         word64 y = Y[i];
1803         for (j = 0; j < 64; j++)
1804         {
1805             if (y & 0x8000000000000000) {
1806                 Z[0] ^= V[0];
1807                 Z[1] ^= V[1];
1808             }
1809
1810             if (V[1] & 0x0000000000000001) {
1811                 V[1] >>= 1;
1812                 V[1] |= ((V[0] & 0x0000000000000001) ? 0x8000000000000000 : 0);
1813                 V[0] >>= 1;
1814                 V[0] ^= 0xE100000000000000;
1815             }
1816             else {
1817                 V[1] >>= 1;
1818                 V[1] |= ((V[0] & 0x0000000000000001) ? 0x8000000000000000 : 0);
1819                 V[0] >>= 1;
1820             }
1821             y <<= 1;
1822         }
1823     }
1824     X[0] = Z[0];
1825     X[1] = Z[1];
1826 }
1827
1828
1829 static void GHASH(Aes* aes, const byte* a, word32 aSz,
1830                                 const byte* c, word32 cSz, byte* s, word32 sSz)
1831 {
1832     word64 x[2] = {0,0};
1833     word32 blocks, partial;
1834     word64 bigH[2];
1835
1836     XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
1837     #ifdef LITTLE_ENDIAN_ORDER
1838         ByteReverseWords64(bigH, bigH, AES_BLOCK_SIZE); 
1839     #endif
1840
1841     /* Hash in A, the Additional Authentication Data */
1842     if (aSz != 0 && a != NULL) {
1843         word64 bigA[2];
1844         blocks = aSz / AES_BLOCK_SIZE;
1845         partial = aSz % AES_BLOCK_SIZE;
1846         while (blocks--) {
1847             XMEMCPY(bigA, a, AES_BLOCK_SIZE);
1848             #ifdef LITTLE_ENDIAN_ORDER
1849                 ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
1850             #endif
1851             x[0] ^= bigA[0];
1852             x[1] ^= bigA[1];
1853             GMULT(x, bigH);
1854             a += AES_BLOCK_SIZE;
1855         }
1856         if (partial != 0) {
1857             XMEMSET(bigA, 0, AES_BLOCK_SIZE);
1858             XMEMCPY(bigA, a, partial);
1859             #ifdef LITTLE_ENDIAN_ORDER
1860                 ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
1861             #endif
1862             x[0] ^= bigA[0];
1863             x[1] ^= bigA[1];
1864             GMULT(x, bigH);
1865         }
1866     }
1867
1868     /* Hash in C, the Ciphertext */
1869     if (cSz != 0 && c != NULL) {
1870         word64 bigC[2];
1871         blocks = cSz / AES_BLOCK_SIZE;
1872         partial = cSz % AES_BLOCK_SIZE;
1873         while (blocks--) {
1874             XMEMCPY(bigC, c, AES_BLOCK_SIZE);
1875             #ifdef LITTLE_ENDIAN_ORDER
1876                 ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
1877             #endif
1878             x[0] ^= bigC[0];
1879             x[1] ^= bigC[1];
1880             GMULT(x, bigH);
1881             c += AES_BLOCK_SIZE;
1882         }
1883         if (partial != 0) {
1884             XMEMSET(bigC, 0, AES_BLOCK_SIZE);
1885             XMEMCPY(bigC, c, partial);
1886             #ifdef LITTLE_ENDIAN_ORDER
1887                 ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
1888             #endif
1889             x[0] ^= bigC[0];
1890             x[1] ^= bigC[1];
1891             GMULT(x, bigH);
1892         }
1893     }
1894
1895     /* Hash in the lengths in bits of A and C */
1896     {
1897         word64 len[2] = {aSz, cSz};
1898
1899         /* Lengths are in bytes. Convert to bits. */
1900         len[0] *= 8;
1901         len[1] *= 8;
1902
1903         x[0] ^= len[0];
1904         x[1] ^= len[1];
1905         GMULT(x, bigH);
1906     }
1907     #ifdef LITTLE_ENDIAN_ORDER
1908         ByteReverseWords64(x, x, AES_BLOCK_SIZE);
1909     #endif
1910     XMEMCPY(s, x, sSz);
1911 }
1912
1913 /* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
1914 #else /* GCM_WORD32 */
1915
1916 static void GMULT(word32* X, word32* Y)
1917 {
1918     word32 Z[4] = {0,0,0,0};
1919     word32 V[4] = {X[0], X[1], X[2], X[3]};
1920     int i, j;
1921
1922     for (i = 0; i < 4; i++)
1923     {
1924         word32 y = Y[i];
1925         for (j = 0; j < 32; j++)
1926         {
1927             if (y & 0x80000000) {
1928                 Z[0] ^= V[0];
1929                 Z[1] ^= V[1];
1930                 Z[2] ^= V[2];
1931                 Z[3] ^= V[3];
1932             }
1933
1934             if (V[3] & 0x00000001) {
1935                 V[3] >>= 1;
1936                 V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
1937                 V[2] >>= 1;
1938                 V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
1939                 V[1] >>= 1;
1940                 V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
1941                 V[0] >>= 1;
1942                 V[0] ^= 0xE1000000;
1943             } else {
1944                 V[3] >>= 1;
1945                 V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
1946                 V[2] >>= 1;
1947                 V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
1948                 V[1] >>= 1;
1949                 V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
1950                 V[0] >>= 1;
1951             }
1952             y <<= 1;
1953         }
1954     }
1955     X[0] = Z[0];
1956     X[1] = Z[1];
1957     X[2] = Z[2];
1958     X[3] = Z[3];
1959 }
1960
1961
1962 static void GHASH(Aes* aes, const byte* a, word32 aSz,
1963                                 const byte* c, word32 cSz, byte* s, word32 sSz)
1964 {
1965     word32 x[4] = {0,0,0,0};
1966     word32 blocks, partial;
1967     word32 bigH[4];
1968
1969     XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
1970     #ifdef LITTLE_ENDIAN_ORDER
1971         ByteReverseWords(bigH, bigH, AES_BLOCK_SIZE); 
1972     #endif
1973
1974     /* Hash in A, the Additional Authentication Data */
1975     if (aSz != 0 && a != NULL) {
1976         word32 bigA[4];
1977         blocks = aSz / AES_BLOCK_SIZE;
1978         partial = aSz % AES_BLOCK_SIZE;
1979         while (blocks--) {
1980             XMEMCPY(bigA, a, AES_BLOCK_SIZE);
1981             #ifdef LITTLE_ENDIAN_ORDER
1982                 ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
1983             #endif
1984             x[0] ^= bigA[0];
1985             x[1] ^= bigA[1];
1986             x[2] ^= bigA[2];
1987             x[3] ^= bigA[3];
1988             GMULT(x, bigH);
1989             a += AES_BLOCK_SIZE;
1990         }
1991         if (partial != 0) {
1992             XMEMSET(bigA, 0, AES_BLOCK_SIZE);
1993             XMEMCPY(bigA, a, partial);
1994             #ifdef LITTLE_ENDIAN_ORDER
1995                 ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
1996             #endif
1997             x[0] ^= bigA[0];
1998             x[1] ^= bigA[1];
1999             x[2] ^= bigA[2];
2000             x[3] ^= bigA[3];
2001             GMULT(x, bigH);
2002         }
2003     }
2004
2005     /* Hash in C, the Ciphertext */
2006     if (cSz != 0 && c != NULL) {
2007         word32 bigC[4];
2008         blocks = cSz / AES_BLOCK_SIZE;
2009         partial = cSz % AES_BLOCK_SIZE;
2010         while (blocks--) {
2011             XMEMCPY(bigC, c, AES_BLOCK_SIZE);
2012             #ifdef LITTLE_ENDIAN_ORDER
2013                 ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
2014             #endif
2015             x[0] ^= bigC[0];
2016             x[1] ^= bigC[1];
2017             x[2] ^= bigC[2];
2018             x[3] ^= bigC[3];
2019             GMULT(x, bigH);
2020             c += AES_BLOCK_SIZE;
2021         }
2022         if (partial != 0) {
2023             XMEMSET(bigC, 0, AES_BLOCK_SIZE);
2024             XMEMCPY(bigC, c, partial);
2025             #ifdef LITTLE_ENDIAN_ORDER
2026                 ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
2027             #endif
2028             x[0] ^= bigC[0];
2029             x[1] ^= bigC[1];
2030             x[2] ^= bigC[2];
2031             x[3] ^= bigC[3];
2032             GMULT(x, bigH);
2033         }
2034     }
2035
2036     /* Hash in the lengths in bits of A and C */
2037     {
2038         word32 len[4];
2039
2040         /* Lengths are in bytes. Convert to bits. */
2041         len[0] = (aSz >> (8*sizeof(aSz) - 3));
2042         len[1] = aSz << 3;
2043         len[2] = (cSz >> (8*sizeof(cSz) - 3));
2044         len[3] = cSz << 3;
2045
2046         x[0] ^= len[0];
2047         x[1] ^= len[1];
2048         x[2] ^= len[2];
2049         x[3] ^= len[3];
2050         GMULT(x, bigH);
2051     }
2052     #ifdef LITTLE_ENDIAN_ORDER
2053         ByteReverseWords(x, x, AES_BLOCK_SIZE);
2054     #endif
2055     XMEMCPY(s, x, sSz);
2056 }
2057
2058 #endif /* end GCM_WORD32 */
2059
2060
2061 void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
2062                    byte* authTag, word32 authTagSz,
2063                    const byte* authIn, word32 authInSz)
2064 {
2065     word32 blocks = sz / AES_BLOCK_SIZE;
2066     word32 partial = sz % AES_BLOCK_SIZE;
2067     const byte* p = in;
2068     byte* c = out;
2069     byte ctr[AES_BLOCK_SIZE];
2070     byte scratch[AES_BLOCK_SIZE];
2071
2072     CYASSL_ENTER("AesGcmEncrypt");
2073
2074     /* Initialize the counter with the MS 96 bits of IV, and the counter
2075      * portion set to "1". */
2076     XMEMCPY(ctr, aes->reg, AES_BLOCK_SIZE);
2077     InitGcmCounter(ctr);
2078
2079     while (blocks--) {
2080         IncrementGcmCounter(ctr);
2081         AesEncrypt(aes, ctr, scratch);
2082         xorbuf(scratch, p, AES_BLOCK_SIZE);
2083         XMEMCPY(c, scratch, AES_BLOCK_SIZE);
2084
2085         p += AES_BLOCK_SIZE;
2086         c += AES_BLOCK_SIZE;
2087     }
2088     if (partial != 0) {
2089         IncrementGcmCounter(ctr);
2090         AesEncrypt(aes, ctr, scratch);
2091         xorbuf(scratch, p, partial);
2092         XMEMCPY(c, scratch, partial);
2093     }
2094     GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
2095     InitGcmCounter(ctr);
2096     AesEncrypt(aes, ctr, scratch);
2097     xorbuf(authTag, scratch, authTagSz);
2098 }
2099
2100
2101 int  AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
2102                    const byte* authTag, word32 authTagSz,
2103                    const byte* authIn, word32 authInSz)
2104 {
2105     word32 blocks = sz / AES_BLOCK_SIZE;
2106     word32 partial = sz % AES_BLOCK_SIZE;
2107     const byte* c = in;
2108     byte* p = out;
2109     byte ctr[AES_BLOCK_SIZE];
2110     byte scratch[AES_BLOCK_SIZE];
2111
2112     CYASSL_ENTER("AesGcmDecrypt");
2113
2114     /* Initialize the counter with the MS 96 bits of IV, and the counter
2115      * portion set to "1". */
2116     XMEMCPY(ctr, aes->reg, AES_BLOCK_SIZE);
2117     InitGcmCounter(ctr);
2118
2119     /* Calculate the authTag again using the received auth data and the
2120      * cipher text. */
2121     {
2122         byte Tprime[AES_BLOCK_SIZE];
2123         byte EKY0[AES_BLOCK_SIZE];
2124
2125         GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
2126         AesEncrypt(aes, ctr, EKY0);
2127         xorbuf(Tprime, EKY0, sizeof(Tprime));
2128         if (XMEMCMP(authTag, Tprime, authTagSz) != 0) {
2129             return AES_GCM_AUTH_E;
2130         }
2131     }
2132
2133     while (blocks--) {
2134         IncrementGcmCounter(ctr);
2135         AesEncrypt(aes, ctr, scratch);
2136         xorbuf(scratch, c, AES_BLOCK_SIZE);
2137         XMEMCPY(p, scratch, AES_BLOCK_SIZE);
2138
2139         p += AES_BLOCK_SIZE;
2140         c += AES_BLOCK_SIZE;
2141     }
2142     if (partial != 0) {
2143         IncrementGcmCounter(ctr);
2144         AesEncrypt(aes, ctr, scratch);
2145         xorbuf(scratch, c, partial);
2146         XMEMCPY(p, scratch, partial);
2147     }
2148
2149     return 0;
2150 }
2151
2152 #endif /* HAVE_AESGCM */
2153
2154
2155 #endif /* NO_AES */
2156