store the pre-alphacomposit hook and allow it to be queried.
[AROS.git] / workbench / devs / networks / atheros5000 / encryption.c
blob758d7c6f66f3ebfd30a7cb6c91610f7c21609473
1 /*
3 Copyright (C) 2011 Neil Cafferkey
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 MA 02111-1307, USA.
23 #include <proto/exec.h>
25 #include "device.h"
27 #include "encryption_protos.h"
29 static VOID WEPEncrypt(struct DevUnit *unit, const UBYTE *data, UWORD size,
30 UBYTE *buffer, BOOL iv_only, struct DevBase *base);
31 static BOOL WEPDecrypt(struct DevUnit *unit, const UBYTE *data, UWORD size,
32 UBYTE *buffer, struct DevBase *base);
33 static VOID TKIPEncrypt(struct DevUnit *unit, UBYTE *data, UWORD size,
34 UBYTE *buffer, BOOL iv_only, struct DevBase *base);
35 static BOOL TKIPDecrypt(struct DevUnit *unit, UBYTE *data, UWORD size,
36 UBYTE *buffer, BOOL iv_only, struct DevBase *base);
37 static VOID CCMPSetIV(struct DevUnit *unit, UBYTE *data, UBYTE *buffer,
38 struct DevBase *base);
39 static VOID CCMPEncrypt(struct DevUnit *unit, const UBYTE *header,
40 const UBYTE *data, UWORD size, UBYTE *buffer, struct DevBase *base);
41 static BOOL CCMPCheckIV(struct DevUnit *unit, UBYTE *data, UWORD *key_no,
42 struct DevBase *base);
43 static BOOL CCMPDecrypt(struct DevUnit *unit, const UBYTE *header,
44 const UBYTE *data, UWORD size, UBYTE *buffer, UWORD key_no,
45 struct DevBase *base);
46 VOID UpdateMIC(ULONG *left, ULONG *right, const ULONG *data,
47 ULONG count);
48 static VOID TKIPKeyMix1(UWORD *ttak, const UWORD *tk, const UWORD *ta,
49 ULONG iv_high, struct DevBase *base);
50 VOID TKIPKeyMix2(UBYTE *rc4_seed, const UWORD *ttak, const UWORD *tk,
51 UWORD iv16, struct DevBase *base);
52 VOID EOREncrypt(const ULONG *data, ULONG *buffer, ULONG *key,
53 struct DevBase *base);
54 static VOID AESKeyMix(ULONG *stream, const ULONG *key,
55 struct DevBase *base);
56 VOID AESEncrypt(const ULONG *data, ULONG *buffer, ULONG *key,
57 struct DevBase *base);
60 static const UBYTE mic_padding[] =
61 {0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
64 const UWORD sbox[] =
66 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
67 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
68 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
69 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
70 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
71 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
72 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
73 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
74 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
75 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
76 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
77 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
78 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
79 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
80 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
81 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
82 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
83 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
84 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
85 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
86 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
87 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
88 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
89 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
90 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
91 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
92 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
93 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
94 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
95 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
96 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
97 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A
101 const ULONG crc32[] =
103 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
104 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
105 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
106 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
107 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
108 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
109 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
110 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
111 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
112 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
113 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
114 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
115 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
116 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
117 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
118 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
119 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
120 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
121 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
122 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
123 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
124 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
125 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
126 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
127 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
128 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
129 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
130 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
131 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
132 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
133 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
134 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
135 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
136 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
137 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
138 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
139 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
140 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
141 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
142 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
143 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
144 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
145 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
146 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
147 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
148 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
149 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
150 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
151 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
152 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
153 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
154 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
155 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
156 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
157 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
158 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
159 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
160 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
161 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
162 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
163 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
164 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
165 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
166 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
170 #define SBox(A) \
171 ({ \
172 UWORD _SBox_A = (A); \
173 UBYTE _SBox_low = _SBox_A; \
174 UBYTE _SBox_high = _SBox_A >> 8; \
175 _SBox_A = sbox[_SBox_low] ^ FlipWord(sbox[_SBox_high]); \
179 const ULONG te0[] =
181 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
182 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
183 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
184 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
185 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
186 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
187 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
188 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
189 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
190 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
191 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
192 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
193 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
194 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
195 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
196 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
197 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
198 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
199 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
200 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
201 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
202 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
203 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
204 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
205 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
206 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
207 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
208 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
209 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
210 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
211 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
212 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
213 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
214 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
215 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
216 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
217 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
218 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
219 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
220 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
221 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
222 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
223 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
224 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
225 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
226 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
227 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
228 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
229 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
230 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
231 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
232 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
233 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
234 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
235 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
236 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
237 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
238 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
239 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
240 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
241 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
242 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
243 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
244 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
248 const ULONG te1[] =
250 0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b,
251 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
252 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b,
253 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,
254 0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d,
255 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
256 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf,
257 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,
258 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626,
259 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc,
260 0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1,
261 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
262 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3,
263 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a,
264 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2,
265 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,
266 0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a,
267 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
268 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3,
269 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,
270 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded,
271 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,
272 0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939,
273 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
274 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb,
275 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,
276 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f,
277 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,
278 0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f,
279 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
280 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121,
281 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2,
282 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec,
283 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,
284 0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d,
285 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
286 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc,
287 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,
288 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414,
289 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,
290 0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a,
291 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
292 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262,
293 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,
294 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d,
295 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,
296 0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea,
297 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
298 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e,
299 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,
300 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f,
301 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,
302 0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666,
303 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
304 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9,
305 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,
306 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111,
307 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,
308 0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9,
309 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
310 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d,
311 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,
312 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f,
313 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616
317 const ULONG te2[] =
319 0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b,
320 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
321 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b,
322 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,
323 0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d,
324 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
325 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af,
326 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,
327 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26,
328 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,
329 0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1,
330 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
331 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3,
332 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a,
333 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2,
334 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,
335 0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a,
336 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
337 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3,
338 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,
339 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed,
340 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,
341 0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239,
342 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
343 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb,
344 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,
345 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f,
346 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,
347 0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f,
348 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
349 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221,
350 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,
351 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec,
352 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,
353 0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d,
354 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
355 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc,
356 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,
357 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814,
358 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb,
359 0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a,
360 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
361 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462,
362 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,
363 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d,
364 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,
365 0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea,
366 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
367 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e,
368 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,
369 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f,
370 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,
371 0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66,
372 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
373 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9,
374 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,
375 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211,
376 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,
377 0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9,
378 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
379 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d,
380 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,
381 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f,
382 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16
386 const ULONG te3[] =
388 0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6,
389 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
390 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56,
391 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,
392 0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa,
393 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
394 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45,
395 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,
396 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c,
397 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,
398 0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9,
399 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
400 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d,
401 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f,
402 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf,
403 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,
404 0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34,
405 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
406 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d,
407 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,
408 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1,
409 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,
410 0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72,
411 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
412 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed,
413 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,
414 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe,
415 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,
416 0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05,
417 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
418 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342,
419 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,
420 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3,
421 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,
422 0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a,
423 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
424 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3,
425 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,
426 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28,
427 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad,
428 0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14,
429 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
430 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4,
431 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,
432 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da,
433 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,
434 0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf,
435 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
436 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c,
437 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,
438 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e,
439 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,
440 0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc,
441 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
442 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069,
443 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,
444 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322,
445 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,
446 0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9,
447 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
448 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a,
449 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,
450 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e,
451 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c
455 const ULONG te4[] =
457 0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b,
458 0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5,
459 0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b,
460 0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676,
461 0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d,
462 0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0,
463 0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf,
464 0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0,
465 0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626,
466 0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc,
467 0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1,
468 0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515,
469 0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3,
470 0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a,
471 0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2,
472 0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575,
473 0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a,
474 0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0,
475 0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3,
476 0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484,
477 0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed,
478 0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b,
479 0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939,
480 0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf,
481 0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb,
482 0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585,
483 0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f,
484 0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8,
485 0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f,
486 0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5,
487 0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121,
488 0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2,
489 0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec,
490 0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717,
491 0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d,
492 0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373,
493 0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc,
494 0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888,
495 0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414,
496 0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb,
497 0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a,
498 0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c,
499 0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262,
500 0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979,
501 0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d,
502 0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9,
503 0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea,
504 0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808,
505 0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e,
506 0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6,
507 0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f,
508 0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a,
509 0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666,
510 0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e,
511 0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9,
512 0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e,
513 0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111,
514 0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494,
515 0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9,
516 0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf,
517 0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d,
518 0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868,
519 0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f,
520 0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616
524 static const ULONG rcon[] =
526 0x01000000, 0x02000000, 0x04000000, 0x08000000,
527 0x10000000, 0x20000000, 0x40000000, 0x80000000,
528 0x1B000000, 0x36000000
533 /****i* prism2.device/WriteClearFragment ***********************************
535 * NAME
536 * WriteClearFragment -- Install unencrypted fragment data.
538 * SYNOPSIS
539 * WriteClearFragment(unit, header, data, size,
540 * buffer)
542 * VOID WriteClearFragment(struct DevUnit *, UBYTE *, UBYTE *, UWORD *,
543 * UBYTE *);
545 * NOTES
546 * The input data address may be equal to the output buffer address,
547 * but they may not overlap in any other way.
549 ****************************************************************************
553 VOID WriteClearFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
554 UWORD *size, UBYTE *buffer, struct DevBase *base)
556 if(buffer != data)
557 CopyMem(data, buffer, *size);
559 return;
564 /****i* prism2.device/EncryptWEPFragment ***********************************
566 * NAME
567 * EncryptWEPFragment -- Encrypt a fragment using the WEP cipher.
569 * SYNOPSIS
570 * EncryptWEPFragment(unit, header, data, size,
571 * buffer)
573 * VOID EncryptWEPFragment(struct DevUnit *, UBYTE *, UBYTE *, UWORD *,
574 * UBYTE *);
576 * NOTES
577 * The input data may overlap the output buffer as long as the output
578 * address is not higher than the input address.
580 * The output buffer must be at least 8 bytes bigger than the input
581 * data, so that the IV and ICV can be added.
583 ****************************************************************************
587 VOID EncryptWEPFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
588 UWORD *size, UBYTE *buffer, struct DevBase *base)
590 WEPEncrypt(unit, data, *size, buffer, FALSE, base);
591 *size += IV_SIZE + ICV_SIZE;
593 return;
598 /****i* prism2.device/WriteWEPFragment *************************************
600 * NAME
601 * WriteWEPFragment -- Prepare a fragment to use the WEP cipher.
603 * SYNOPSIS
604 * WriteWEPFragment(unit, header, data, size,
605 * buffer)
607 * VOID WriteWEPFragment(struct DevUnit *, UBYTE *, UBYTE *, UWORD *,
608 * UBYTE *);
610 * NOTES
611 * The input data address may be four bytes greater than the output
612 * buffer address, but they may not overlap in any other way.
614 ****************************************************************************
618 VOID WriteWEPFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
619 UWORD *size, UBYTE *buffer, struct DevBase *base)
621 WEPEncrypt(unit, data, *size, buffer, TRUE, base);
622 if(buffer + IV_SIZE != data)
623 CopyMem(data, buffer + IV_SIZE, *size);
624 *size += IV_SIZE + ICV_SIZE;
626 return;
631 /****i* prism2.device/EncryptTKIPFragment **********************************
633 * NAME
634 * EncryptTKIPFragment -- Encrypt a fragment using the TKIP cipher.
636 * SYNOPSIS
637 * EncryptTKIPFragment(unit, header, data,
638 * size, buffer)
640 * VOID EncryptTKIPFragment(struct DevUnit *, UBYTE *, UBYTE *,
641 * UWORD *, UBYTE *);
643 * NOTES
644 * The input data may overlap the output buffer as long as the output
645 * address is not higher than the input address.
647 * The output buffer must be at least 12 bytes bigger than the input
648 * data, so that the Extended IV and the ICV can be added.
650 ****************************************************************************
654 VOID EncryptTKIPFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
655 UWORD *size, UBYTE *buffer, struct DevBase *base)
657 TKIPEncrypt(unit, data, *size, buffer, FALSE, base);
658 *size += EIV_SIZE + ICV_SIZE;
660 return;
665 /****i* prism2.device/WriteTKIPFragment ************************************
667 * NAME
668 * WriteTKIPFragment -- Prepare a fragment to use the TKIP cipher.
670 * SYNOPSIS
671 * WriteTKIPFragment(unit, header, data, size,
672 * buffer)
674 * VOID WriteTKIPFragment(struct DevUnit *, UBYTE *, UBYTE *, UWORD *,
675 * UBYTE *);
677 * NOTES
678 * The input data address may be eight bytes greater than the output
679 * buffer address, but they may not overlap in any other way.
681 ****************************************************************************
685 VOID WriteTKIPFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
686 UWORD *size, UBYTE *buffer, struct DevBase *base)
688 TKIPEncrypt(unit, data, *size, buffer, TRUE, base);
689 if(buffer + EIV_SIZE != data)
690 CopyMem(data, buffer + EIV_SIZE, *size);
691 *size += EIV_SIZE + ICV_SIZE;
693 return;
698 /****i* prism2.device/EncryptCCMPFragment **********************************
700 * NAME
701 * EncryptCCMPFragment -- Encrypt a fragment using the CCMP cipher.
703 * SYNOPSIS
704 * EncryptCCMPFragment(unit, header, data,
705 * size, buffer)
707 * VOID EncryptCCMPFragment(struct DevUnit *, UBYTE *, UBYTE *,
708 * UWORD *, UBYTE *);
710 * NOTES
711 * The input data may overlap the output buffer as long as the output
712 * address is not higher than the input address.
714 * The output buffer must be at least 16 bytes bigger than the input
715 * data, so that the Extended IV and the MIC can be added.
717 ****************************************************************************
721 VOID EncryptCCMPFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
722 UWORD *size, UBYTE *buffer, struct DevBase *base)
724 CCMPSetIV(unit, data, buffer, base);
725 CCMPEncrypt(unit, header, data, *size, buffer + EIV_SIZE, base);
726 *size += EIV_SIZE + MIC_SIZE;
728 return;
733 /****i* prism2.device/WriteCCMPFragment ************************************
735 * NAME
736 * WriteCCMPFragment -- Prepare a fragment to use the CCMP cipher.
738 * SYNOPSIS
739 * WriteCCMPFragment(unit, header, data, size,
740 * buffer)
742 * VOID WriteCCMPFragment(struct DevUnit *, UBYTE *, UBYTE *, UWORD *,
743 * UBYTE *);
745 * NOTES
746 * The input data address may be eight bytes greater than the output
747 * buffer address, but they may not overlap in any other way.
749 ****************************************************************************
753 VOID WriteCCMPFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
754 UWORD *size, UBYTE *buffer, struct DevBase *base)
756 CCMPSetIV(unit, data, buffer, base);
757 if(buffer + EIV_SIZE != data)
758 CopyMem(data, buffer + EIV_SIZE, *size);
759 *size += EIV_SIZE + MIC_SIZE;
761 return;
766 /****i* prism2.device/ReadClearFragment *************************************
768 * NAME
769 * ReadClearFragment -- Extract data from an unencrypted fragment.
771 * SYNOPSIS
772 * success = ReadClearFragment(unit, header, data, size,
773 * buffer)
775 * BOOL ReadClearFragment(struct DevUnit *, UBYTE *, UBYTE *, UWORD *,
776 * UBYTE *);
778 ****************************************************************************
782 BOOL ReadClearFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
783 UWORD *size, UBYTE *buffer, struct DevBase *base)
785 CopyMem(data, buffer, *size);
787 return TRUE;
792 /****i* prism2.device/DecryptWEPFragment ***********************************
794 * NAME
795 * DecryptWEPFragment -- Decrypt a fragment using the WEP cipher.
797 * SYNOPSIS
798 * success = DecryptWEPFragment(unit, header, data, size,
799 * buffer)
801 * BOOL DecryptWEPFragment(struct DevUnit *, UBYTE *, UBYTE *, UWORD *,
802 * UBYTE *);
804 * NOTES
805 * The input data may overlap the output buffer as long as the output
806 * address is not higher than the input address.
808 ****************************************************************************
812 BOOL DecryptWEPFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
813 UWORD *size, UBYTE *buffer, struct DevBase *base)
815 BOOL success;
817 success = WEPDecrypt(unit, data, *size, buffer, base);
818 *size -= IV_SIZE + ICV_SIZE;
820 return success;
825 /****i* prism2.device/ReadWEPFragment **************************************
827 * NAME
828 * ReadWEPFragment -- Extract data from a WEP fragment.
830 * SYNOPSIS
831 * success = ReadWEPFragment(unit, header, data, size,
832 * buffer)
834 * BOOL ReadWEPFragment(struct DevUnit *, UBYTE *, UBYTE *, UWORD *,
835 * UBYTE *);
837 ****************************************************************************
841 BOOL ReadWEPFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
842 UWORD *size, UBYTE *buffer, struct DevBase *base)
844 *size -= IV_SIZE + ICV_SIZE;
845 CopyMem(data + IV_SIZE, buffer, *size);
847 return TRUE;
852 /****i* prism2.device/DecryptTKIPFragment **********************************
854 * NAME
855 * DecryptTKIPFragment -- Decrypt a fragment using the TKIP cipher.
857 * SYNOPSIS
858 * success = DecryptTKIPFragment(unit, header, data,
859 * size, buffer)
861 * BOOL DecryptTKIPFragment(struct DevUnit *, UBYTE *, UBYTE *,
862 * UWORD *, UBYTE *);
864 * NOTES
865 * The input data may overlap the output buffer as long as the output
866 * address is not higher than the input address.
868 ****************************************************************************
872 BOOL DecryptTKIPFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
873 UWORD *size, UBYTE *buffer, struct DevBase *base)
875 BOOL success;
877 success = TKIPDecrypt(unit, data, *size, buffer, FALSE,
878 base);
879 *size -= EIV_SIZE + ICV_SIZE;
881 return success;
886 /****i* prism2.device/ReadTKIPFragment *************************************
888 * NAME
889 * ReadTKIPFragment -- Extract data from a TKIP fragment.
891 * SYNOPSIS
892 * success = ReadTKIPFragment(unit, header, data, size,
893 * buffer)
895 * BOOL ReadTKIPFragment(struct DevUnit *, UBYTE *, UBYTE *, UWORD *,
896 * UBYTE *);
898 ****************************************************************************
902 BOOL ReadTKIPFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
903 UWORD *size, UBYTE *buffer, struct DevBase *base)
905 BOOL success;
907 success = TKIPDecrypt(unit, data, *size, buffer, TRUE,
908 base);
909 *size -= EIV_SIZE + ICV_SIZE;
910 if(success)
911 CopyMem(data + EIV_SIZE, buffer, *size);
913 return success;
918 /****i* prism2.device/DecryptCCMPFragment **********************************
920 * NAME
921 * DecryptCCMPFragment -- Decrypt a fragment using the CCMP cipher.
923 * SYNOPSIS
924 * success = DecryptCCMPFragment(unit, header, data,
925 * size, buffer)
927 * BOOL DecryptCCMPFragment(struct DevUnit *, UBYTE *, UBYTE *,
928 * UWORD *, UBYTE *);
930 * NOTES
931 * The input data may overlap the output buffer as long as the output
932 * address is not higher than the input address.
934 ****************************************************************************
938 BOOL DecryptCCMPFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
939 UWORD *size, UBYTE *buffer, struct DevBase *base)
941 BOOL success = FALSE;
942 UWORD key_no;
943 struct CCMPKey *key;
945 if(CCMPCheckIV(unit, data, &key_no, base))
947 *size -= EIV_SIZE;
948 success = CCMPDecrypt(unit, header, data + EIV_SIZE, *size, buffer,
949 key_no, base);
950 *size -= MIC_SIZE;
953 /* Increment sequence counter */
955 if(success)
957 key = &unit->keys[key_no].u.ccmp;
958 if(++key->rx_iv_low == 0)
959 key->rx_iv_high++;
962 return success;
967 /****i* prism2.device/ReadCCMPFragment *************************************
969 * NAME
970 * ReadCCMPFragment -- Extract data from a CCMP fragment.
972 * SYNOPSIS
973 * success = ReadCCMPFragment(unit, header, data, size,
974 * buffer)
976 * BOOL ReadCCMPFragment(struct DevUnit *, UBYTE *, UBYTE *, UWORD *,
977 * UBYTE *);
979 ****************************************************************************
983 BOOL ReadCCMPFragment(struct DevUnit *unit, UBYTE *header, UBYTE *data,
984 UWORD *size, UBYTE *buffer, struct DevBase *base)
986 BOOL success;
987 UWORD key_no;
988 struct CCMPKey *key;
990 success = CCMPCheckIV(unit, data, &key_no, base);
991 *size -= EIV_SIZE + MIC_SIZE;
992 if(success)
993 CopyMem(data + EIV_SIZE, buffer, *size);
995 /* Increment sequence counter */
997 if(success)
999 key = &unit->keys[key_no].u.ccmp;
1000 if(++key->rx_iv_low == 0)
1001 key->rx_iv_high++;
1004 return success;
1009 /****i* prism2.device/TKIPEncryptFrame *************************************
1011 * NAME
1012 * TKIPEncryptFrame -- Append the Michael MIC to a frame.
1014 * SYNOPSIS
1015 * TKIPEncryptFrame(unit, header, data, size,
1016 * buffer)
1018 * VOID TKIPEncryptFrame(struct DevUnit *, UBYTE *, UBYTE *, UWORD,
1019 * UBYTE *);
1021 * NOTES
1022 * The input data address may be equal to the output buffer address,
1023 * but they may not overlap in any other way.
1025 * The output buffer must be at least 8 bytes bigger than the input
1026 * data, so that the MIC can be added.
1028 ****************************************************************************
1032 VOID TKIPEncryptFrame(struct DevUnit *unit, const UBYTE *header,
1033 UBYTE *data, UWORD size, UBYTE *buffer, struct DevBase *base)
1035 ULONG *mic_key, mic[2];
1036 ULONG mic_l, mic_r, zero = 0;
1037 struct TKIPKey *key = &unit->keys[unit->tx_key_no].u.tkip;
1039 /* Calculate MIC and append to packet data */
1041 if(data != buffer)
1042 CopyMem(data, buffer, size);
1044 mic_key = key->tx_mic_key;
1045 mic_l = LELong(mic_key[0]);
1046 mic_r = LELong(mic_key[1]);
1047 UpdateMIC(&mic_l, &mic_r, (ULONG *)header, 3);
1048 UpdateMIC(&mic_l, &mic_r, &zero, 1);
1049 CopyMem(mic_padding, buffer + size, sizeof(mic_padding));
1050 UpdateMIC(&mic_l, &mic_r, (ULONG *)buffer, size / 4 + 2);
1051 mic[0] = MakeLELong(mic_l);
1052 mic[1] = MakeLELong(mic_r);
1053 CopyMem(mic, buffer + size, sizeof(mic));
1055 return;
1060 /****i* prism2.device/TKIPDecryptFrame *************************************
1062 * NAME
1063 * TKIPDecryptFrame -- Check that a frame's MIC is correct.
1065 * SYNOPSIS
1066 * success = TKIPDecryptFrame(unit, header, data, size,
1067 * buffer, key_no)
1069 * BOOL TKIPDecryptFrame(struct DevUnit *, UBYTE *, UBYTE *, UWORD,
1070 * UBYTE *, UWORD);
1072 * NOTES
1073 * The input data address may be equal to the output buffer address,
1074 * but they may not overlap in any other way.
1076 ****************************************************************************
1080 BOOL TKIPDecryptFrame(struct DevUnit *unit, const UBYTE *header,
1081 UBYTE *data, UWORD size, UBYTE *buffer, UWORD key_no,
1082 struct DevBase *base)
1084 ULONG *mic_key, mic[2];
1085 ULONG mic_l, mic_r, zero = 0;
1087 /* Calculate MIC and compare it with MIC received */
1089 size -= sizeof(mic);
1090 CopyMem(buffer + size, mic, sizeof(mic));
1091 CopyMem(mic_padding, buffer + size, sizeof(mic_padding));
1093 mic_key = unit->keys[key_no].u.tkip.rx_mic_key;
1094 mic_l = LELong(mic_key[0]);
1095 mic_r = LELong(mic_key[1]);
1096 UpdateMIC(&mic_l, &mic_r, (ULONG *)header, 3);
1097 UpdateMIC(&mic_l, &mic_r, &zero, 1);
1098 UpdateMIC(&mic_l, &mic_r, (ULONG *)buffer, size / sizeof(ULONG) + 2);
1100 if(data != buffer)
1101 CopyMem(data, buffer, size);
1103 return LELong(mic[0]) == mic_l && LELong(mic[1]) == mic_r;
1108 /****i* prism2.device/WEPEncrypt *******************************************
1110 * NAME
1111 * WEPEncrypt -- Encrypt a fragment using the WEP cipher.
1113 * SYNOPSIS
1114 * WEPEncrypt(unit, data, size, buffer, seed,
1115 * iv_only)
1117 * VOID WEPEncrypt(struct DevUnit *, UBYTE *, UWORD, UBYTE *, UBYTE *,
1118 * BOOL);
1120 * NOTES
1121 * The input data may overlap the output buffer as long as the output
1122 * address is at least 4 bytes lower than the input address.
1124 ****************************************************************************
1128 static VOID WEPEncrypt(struct DevUnit *unit, const UBYTE *data, UWORD size,
1129 UBYTE *buffer, BOOL iv_only, struct DevBase *base)
1131 UWORD i;
1132 ULONG iv;
1133 const UBYTE *p;
1134 UBYTE seed[16], *q;
1135 struct WEPKey *key = &unit->keys[unit->tx_key_no].u.wep;
1137 /* Create RC4 seed from IV and WEP key */
1139 iv = MakeBELong(++key->tx_iv);
1140 for(i = 0, p = (UBYTE *)&iv + 1, q = seed; i < 3; i++)
1141 *q++ = *p++;
1142 if(!iv_only)
1143 for(i = 0, p = key->key; i < key->length; i++)
1144 *q++ = *p++;
1146 /* Preface encrypted data with the IV and key ID */
1148 for(i = 0; i < 3; i++)
1149 buffer[i] = seed[i];
1150 buffer[3] = unit->tx_key_no << 6;
1152 /* Encrypt data and CRC */
1154 if(!iv_only)
1155 RC4Encrypt(unit, data, size, buffer + 4, seed, base);
1157 return;
1162 /****i* prism2.device/WEPDecrypt *******************************************
1164 * NAME
1165 * WEPDecrypt -- Decrypt a fragment using the WEP cipher.
1167 * SYNOPSIS
1168 * WEPDecrypt(unit, data, size, buffer)
1170 * VOID WEPDecrypt(struct DevUnit *, UBYTE *, UWORD, UBYTE *);
1172 * NOTES
1173 * The input data may overlap the output buffer as long as the output
1174 * address is not higher than the input address.
1176 ****************************************************************************
1180 static BOOL WEPDecrypt(struct DevUnit *unit, const UBYTE *data, UWORD size,
1181 UBYTE *buffer, struct DevBase *base)
1183 UWORD i;
1184 const UBYTE *p;
1185 UBYTE seed[16], *q;
1186 const struct WEPKey *key = &unit->keys[data[3] >> 6].u.wep;
1188 /* Create RC4 seed from IV and WEP key */
1190 for(i = 0, p = data, q = seed; i < 3; i++)
1191 *q++ = *p++;
1192 for(i = 0, p = key->key; i < key->length; i++)
1193 *q++ = *p++;
1195 /* Decrypt data */
1197 return RC4Decrypt(unit, data + 4, size - 4, buffer, seed, base);
1202 /****i* prism2.device/TKIPEncrypt ******************************************
1204 * NAME
1205 * TKIPEncrypt -- Encrypt a fragment using the TKIP cipher.
1207 * SYNOPSIS
1208 * TKIPEncrypt(unit, data, size, buffer, iv_only)
1210 * VOID TKIPEncrypt(struct DevUnit *, UBYTE *, UWORD, UBYTE *, BOOL);
1212 * NOTES
1213 * The input data may overlap the output buffer as long as the output
1214 * address is not higher than the input address.
1216 * The output buffer must be at least 12 bytes bigger than the input
1217 * data, so that the Extended IV and the ICV can be added.
1219 ****************************************************************************
1223 static VOID TKIPEncrypt(struct DevUnit *unit, UBYTE *data, UWORD size,
1224 UBYTE *buffer, BOOL iv_only, struct DevBase *base)
1226 UBYTE seed[16];
1227 struct TKIPKey *key = &unit->keys[unit->tx_key_no].u.tkip;
1229 /* Create RC4 seed from IV, TA and temporal key */
1231 if(!iv_only)
1233 if(!key->tx_ttak_set)
1235 TKIPKeyMix1(key->tx_ttak, (UWORD *)key->key,
1236 (UWORD *)unit->address, key->tx_iv_high, base);
1237 key->tx_ttak_set = TRUE;
1239 TKIPKeyMix2(seed, key->tx_ttak, (UWORD *)key->key, key->tx_iv_low,
1240 base);
1243 /* Preface encrypted data with IV, key ID, TKIP flag and extended IV */
1245 buffer[0] = key->tx_iv_low >> 8;
1246 buffer[1] = (key->tx_iv_low >> 8 | 0x20) & 0x7f;
1247 buffer[2] = key->tx_iv_low;
1248 buffer[3] = unit->tx_key_no << 6 | 0x20;
1249 buffer += 4;
1250 *(ULONG *)buffer =
1251 MakeLELong(key->tx_iv_high);
1252 buffer += 4;
1254 /* Encrypt data and CRC */
1256 if(!iv_only)
1257 RC4Encrypt(unit, data, size, buffer, seed, base);
1259 /* Increment 48-bit sequence counter */
1261 if((++key->tx_iv_low) == 0)
1263 key->tx_iv_high++;
1264 key->tx_ttak_set = FALSE;
1267 return;
1272 /****i* prism2.device/TKIPDecrypt ******************************************
1274 * NAME
1275 * TKIPDecrypt -- Decrypt a fragment using the TKIP cipher.
1277 * SYNOPSIS
1278 * success = TKIPDecrypt(unit, data, size, buffer, iv_only)
1280 * BOOL TKIPDecrypt(struct DevUnit *, UBYTE *, UWORD, UBYTE *, BOOL);
1282 * NOTES
1283 * The input data may overlap the output buffer as long as the output
1284 * address is not higher than the input address.
1286 ****************************************************************************
1290 static BOOL TKIPDecrypt(struct DevUnit *unit, UBYTE *data, UWORD size,
1291 UBYTE *buffer, BOOL iv_only, struct DevBase *base)
1293 UBYTE seed[16];
1294 ULONG iv_low, iv_high;
1295 BOOL success = TRUE;
1296 UWORD key_no;
1297 struct TKIPKey *key;
1299 /* Extract IV, key ID, TKIP flag and extended IV */
1301 iv_low = data[0] << 8 | data[2];
1302 key_no = data[3] >> 6;
1303 data += 4;
1304 iv_high = LELong(*(ULONG *)data);
1305 data += 4;
1307 /* Check for replay attack */
1309 key = &unit->keys[key_no].u.tkip;
1310 if(iv_high < key->rx_iv_high
1311 || iv_high == key->rx_iv_high && iv_low < key->rx_iv_low)
1312 success = FALSE;
1314 /* TO DO: replay timeout */
1316 if(success && !iv_only)
1318 /* Create RC4 seed from IV, TA and temporal key */
1320 if(iv_high > key->rx_iv_high)
1321 key->rx_ttak_set = FALSE;
1322 if(!key->rx_ttak_set)
1324 TKIPKeyMix1(key->rx_ttak,
1325 (UWORD *)unit->keys[key_no].u.tkip.key,
1326 (UWORD *)unit->bssid, iv_high, base);
1327 key->rx_ttak_set = TRUE;
1329 TKIPKeyMix2(seed, key->rx_ttak,
1330 (UWORD *)unit->keys[key_no].u.tkip.key, iv_low, base);
1332 /* Decrypt data and check ICV/CRC */
1334 size -= EIV_SIZE;
1335 success = RC4Decrypt(unit, data, size, buffer, seed, base);
1338 /* Increment 48-bit sequence counter */
1340 if(success)
1342 key->rx_iv_high = iv_high;
1343 key->rx_iv_low = iv_low;
1344 if(++key->rx_iv_low == 0)
1346 key->rx_iv_high++;
1347 key->rx_ttak_set = FALSE;
1351 return success;
1356 /****i* prism2.device/CCMPSetIV ********************************************
1358 * NAME
1359 * CCMPSetIV -- Add CCMP IV to a fragment.
1361 * SYNOPSIS
1362 * CCMPSetIV(unit, data, buffer)
1364 * VOID CCMPSetIV(struct DevUnit *, UBYTE *, UBYTE *);
1366 ****************************************************************************
1370 static VOID CCMPSetIV(struct DevUnit *unit, UBYTE *data, UBYTE *buffer,
1371 struct DevBase *base)
1373 struct CCMPKey *key = &unit->keys[unit->tx_key_no].u.ccmp;
1375 /* Increment 48-bit sequence counter */
1377 if((++key->tx_iv_low) == 0)
1379 key->tx_iv_high++;
1382 /* Preface encrypted data with IV, key ID, CCMP flag and extended IV */
1384 buffer[0] = key->tx_iv_low;
1385 buffer[1] = key->tx_iv_low >> 8;
1386 buffer[2] = 0;
1387 buffer[3] = unit->tx_key_no << 6 | 0x20;
1388 *(ULONG *)(buffer + 4) = MakeLELong(key->tx_iv_high);
1390 return;
1395 /****i* prism2.device/CCMPEncrypt ******************************************
1397 * NAME
1398 * CCMPEncrypt -- Encrypt a fragment using the CCMP cipher.
1400 * SYNOPSIS
1401 * CCMPEncrypt(unit, header, data, size, buffer,
1402 * iv_only)
1404 * VOID CCMPEncrypt(struct DevUnit *, UBYTE *, UBYTE *, UWORD, UBYTE *,
1405 * BOOL);
1407 * NOTES
1408 * The input data may overlap the output buffer as long as the output
1409 * address is not higher than the input address.
1411 * The output buffer must be at least 16 bytes bigger than the input
1412 * data, so that the MIC can be added.
1414 * INTERNALS
1415 * For efficiency, the nonce and AAD are not constructed as separate
1416 * entities, but immediately integrated into their corresponding CBC
1417 * blocks.
1419 ****************************************************************************
1423 static VOID CCMPEncrypt(struct DevUnit *unit, const UBYTE *header,
1424 const UBYTE *data, UWORD size, UBYTE *buffer, struct DevBase *base)
1426 struct CCMPKey *key = &unit->keys[unit->tx_key_no].u.ccmp;
1427 UBYTE aad_blocks[16 * 2], nonce_block[16],
1429 const UBYTE *p;
1430 UWORD i, j, block_count;
1431 ULONG n, data_block[4], mic_block[4], key_block[4];
1433 if(!key->stream_set)
1435 AESKeyMix(key->stream, (ULONG *)key->key, base);
1436 key->stream_set = TRUE;
1439 /* Construct AAD blocks */
1441 aad_blocks[0] = 0;
1442 aad_blocks[1] = 22;
1444 *(UWORD *)(aad_blocks + 2) = *(UWORD *)(header + WIFI_FRM_CONTROL)
1445 & MakeLEWord(WIFI_FRM_CONTROLF_VERSION | WIFI_FRM_CONTROLF_TYPE
1446 | (1 << 7) | WIFI_FRM_CONTROLF_TODS | WIFI_FRM_CONTROLF_FROMDS
1447 | WIFI_FRM_CONTROLF_MOREFRAGS | WIFI_FRM_CONTROLF_ORDER)
1448 | MakeLEWord(WIFI_FRM_CONTROLF_WEP);
1449 CopyMem(header + WIFI_FRM_ADDRESS1, aad_blocks + 4, ETH_ADDRESSSIZE * 3);
1450 *(UWORD *)(aad_blocks + 22) =
1451 *(UWORD *)(header + WIFI_FRM_SEQCONTROL) & MakeLEWord(0xf);
1453 *(ULONG *)(aad_blocks + 24) = 0;
1454 *(ULONG *)(aad_blocks + 28) = 0;
1456 /* Construct nonce block */
1458 nonce_block[0] = 0x59;
1460 nonce_block[1] = 0;
1461 CopyMem(header + WIFI_FRM_ADDRESS2, nonce_block + 2, ETH_ADDRESSSIZE);
1463 n = MakeBELong(key->tx_iv_high);
1464 for(i = 0, p = (UBYTE *)&n; i < 4; i++)
1465 nonce_block[8 + i] = p[i];
1466 n = MakeBELong(key->tx_iv_low);
1467 for(i = 0, p = (UBYTE *)&n + 2; i < 2; i++)
1468 nonce_block[12 + i] = p[i];
1470 *(UWORD *)(nonce_block + 14) = MakeBEWord(size);
1472 /* Initialise MIC block from nonce block */
1474 AESEncrypt((ULONG *)nonce_block, mic_block, key->stream, base);
1476 /* Integrate AAD into MIC */
1478 for(i = 0, p = aad_blocks; i < 2; i++, p += 16)
1480 EOREncrypt((ULONG *)p, mic_block, mic_block, base);
1481 AESEncrypt(mic_block, mic_block, key->stream,
1482 base);
1485 /* Encrypt data and calculate MIC */
1487 nonce_block[0] = 0x01;
1488 block_count = (size - 1) / 16 + 1;
1490 for(i = 1, j = size, p = data, q = buffer; i <= block_count; i++,
1491 p += 16, q += 16, j -= 16)
1493 /* Update MIC */
1495 if(j < 16)
1497 data_block[0] = 0;
1498 data_block[1] = 0;
1499 data_block[2] = 0;
1500 data_block[3] = 0;
1501 CopyMem(p, data_block, j);
1503 else
1504 CopyMem(p, data_block, 16);
1505 EOREncrypt(data_block, mic_block, mic_block, base);
1506 AESEncrypt(mic_block, mic_block, key->stream, base);
1508 /* Encrypt next block */
1510 *(UWORD *)(nonce_block + 14) = MakeBEWord(i);
1511 AESEncrypt((ULONG *)nonce_block, key_block, key->stream, base);
1512 EOREncrypt((ULONG *)p, (ULONG *)q, key_block, base);
1515 /* Append MIC */
1517 *(UWORD *)(nonce_block + 14) = 0;
1518 AESEncrypt((ULONG *)nonce_block, key_block, key->stream, base);
1519 EOREncrypt(mic_block, mic_block, key_block, base);
1520 CopyMem(mic_block, buffer + size, MIC_SIZE);
1522 return;
1527 /****i* prism2.device/CCMPCheckIV ******************************************
1529 * NAME
1530 * CCMPCheckIV -- Process a CCMP fragment's IV.
1532 * SYNOPSIS
1533 * success = CCMPCheckIV(unit, data, key_no)
1535 * BOOL CCMPCheckIV(struct DevUnit *, UBYTE *, UWORD);
1537 ****************************************************************************
1541 static BOOL CCMPCheckIV(struct DevUnit *unit, UBYTE *data, UWORD *key_no,
1542 struct DevBase *base)
1544 BOOL success = TRUE;
1545 ULONG iv_low, iv_high;
1546 struct CCMPKey *key;
1548 /* Extract sequence counter and key ID */
1550 iv_low = data[1] << 8 | data[0];
1551 *key_no = data[3] >> 6;
1552 data += 4;
1553 iv_high = LELong(*(ULONG *)data);
1555 /* Check for replay attack */
1557 key = &unit->keys[*key_no].u.ccmp;
1558 if(iv_high < key->rx_iv_high
1559 || iv_high == key->rx_iv_high && iv_low < key->rx_iv_low)
1560 success = FALSE;
1562 /* TO DO: replay timeout */
1564 /* Store new sequence counter */
1566 if(success)
1568 key->rx_iv_high = iv_high;
1569 key->rx_iv_low = iv_low;
1572 return success;
1577 /****i* prism2.device/CCMPDecrypt ******************************************
1579 * NAME
1580 * CCMPDecrypt -- Decrypt a fragment using the CCMP cipher.
1582 * SYNOPSIS
1583 * success = CCMPDecrypt(unit, header, data, size, buffer,
1584 * iv_only)
1586 * BOOL CCMPDecrypt(struct DevUnit *, UBYTE *, UBYTE *, UWORD, UBYTE *,
1587 * BOOL);
1589 * NOTES
1590 * The input data may overlap the output buffer as long as the output
1591 * address is not higher than the input address.
1593 ****************************************************************************
1597 static BOOL CCMPDecrypt(struct DevUnit *unit, const UBYTE *header,
1598 const UBYTE *data, UWORD size, UBYTE *buffer, UWORD key_no,
1599 struct DevBase *base)
1601 struct CCMPKey *key;
1602 UBYTE aad_blocks[16 * 2], nonce_block[16], *q;
1603 const UBYTE *p;
1604 UWORD i, j, block_count;
1605 ULONG n, mic_block[4], key_block[4];
1606 BOOL success = TRUE;
1607 ULONG data_block[4];
1609 /* Get key */
1611 size -= MIC_SIZE;
1612 key = &unit->keys[key_no].u.ccmp;
1613 if(!key->stream_set)
1615 AESKeyMix(key->stream, (ULONG *)key->key, base);
1616 key->stream_set = TRUE;
1619 /* Construct AAD blocks */
1621 aad_blocks[0] = 0;
1622 aad_blocks[1] = 22;
1624 *(UWORD *)(aad_blocks + 2) = *(UWORD *)(header + WIFI_FRM_CONTROL)
1625 & MakeLEWord(WIFI_FRM_CONTROLF_VERSION | WIFI_FRM_CONTROLF_TYPE
1626 | (1 << 7) | WIFI_FRM_CONTROLF_TODS | WIFI_FRM_CONTROLF_FROMDS
1627 | WIFI_FRM_CONTROLF_MOREFRAGS | WIFI_FRM_CONTROLF_ORDER)
1628 | MakeLEWord(WIFI_FRM_CONTROLF_WEP);
1629 CopyMem(header + WIFI_FRM_ADDRESS1, aad_blocks + 4, ETH_ADDRESSSIZE * 3);
1630 *(UWORD *)(aad_blocks + 22) =
1631 *(UWORD *)(header + WIFI_FRM_SEQCONTROL) & MakeLEWord(0xf);
1633 *(ULONG *)(aad_blocks + 24) = 0;
1634 *(ULONG *)(aad_blocks + 28) = 0;
1636 /* Construct nonce block */
1638 nonce_block[0] = 0x59;
1640 nonce_block[1] = 0;
1641 CopyMem(header + WIFI_FRM_ADDRESS2, nonce_block + 2, ETH_ADDRESSSIZE);
1643 n = MakeBELong(key->rx_iv_high);
1644 for(i = 0, p = (UBYTE *)&n; i < 4; i++)
1645 nonce_block[8 + i] = p[i];
1646 n = MakeBELong(key->rx_iv_low);
1647 for(i = 0, p = (UBYTE *)&n + 2; i < 2; i++)
1648 nonce_block[12 + i] = p[i];
1650 *(UWORD *)(nonce_block + 14) = MakeBEWord(size);
1652 /* Initialise MIC block from nonce block */
1654 AESEncrypt((ULONG *)nonce_block, mic_block, key->stream, base);
1656 /* Integrate AAD into MIC */
1658 for(i = 0, p = aad_blocks; i < 2; i++, p += 16)
1660 EOREncrypt((ULONG *)p, mic_block, mic_block, base);
1661 AESEncrypt(mic_block, mic_block, key->stream, base);
1664 /* Decrypt data and calculate MIC */
1666 nonce_block[0] = 0x01;
1667 block_count = (size - 1) / 16 + 1;
1669 for(i = 1, j = size, p = data, q = buffer; i <= block_count; i++,
1670 p += 16, q += 16, j -= 16)
1672 /* Decrypt next block */
1674 *(UWORD *)(nonce_block + 14) = MakeBEWord(i);
1675 AESEncrypt((ULONG *)nonce_block, key_block, key->stream, base);
1676 EOREncrypt((ULONG *)p, (ULONG *)q, key_block, base);
1678 /* Update MIC */
1680 if(j < 16)
1682 data_block[0] = 0;
1683 data_block[1] = 0;
1684 data_block[2] = 0;
1685 data_block[3] = 0;
1686 CopyMem(q, data_block, j);
1688 else
1690 CopyMem(q, data_block, 16);
1692 EOREncrypt(data_block, mic_block, mic_block, base);
1693 AESEncrypt(mic_block, mic_block, key->stream, base);
1696 /* Extract and check MIC */
1698 *(UWORD *)(nonce_block + 14) = 0;
1699 AESEncrypt((ULONG *)nonce_block, key_block, key->stream, base);
1700 EOREncrypt(mic_block, mic_block, key_block, base);
1701 CopyMem(data + size, mic_block + MIC_SIZE / sizeof(ULONG), MIC_SIZE);
1702 if(mic_block[0] != mic_block[2] || mic_block[1] != mic_block[3])
1703 success = FALSE;
1705 return success;
1710 /****i* prism2.device/UpdateMIC ********************************************
1712 * NAME
1713 * UpdateMIC -- Include new data into a Michael MIC value.
1715 * SYNOPSIS
1716 * UpdateMIC(left, right, data, count)
1718 * VOID UpdateMIC(ULONG *, ULONG *, ULONG *, ULONG);
1720 ****************************************************************************
1724 VOID UpdateMIC(ULONG *left, ULONG *right, const ULONG *data,
1725 ULONG count)
1727 ULONG l = *left, r = *right, i;
1729 for(i = 0; i < count; i++)
1731 l ^= LELong(*data++);
1732 r ^= l << 17 | l >> (32 - 17);
1733 l += r;
1734 r ^= ((l & 0x00ff00ff) << 8) | ((l & 0xff00ff00) >> 8);
1735 l += r;
1736 r ^= l << 3 | l >> (32 - 3);
1737 l += r;
1738 r ^= l >> 2 | l << (32 - 2);
1739 l += r;
1742 *left = l;
1743 *right = r;
1745 return;
1750 /****i* prism2.device/TKIPKeyMix1 ******************************************
1752 * NAME
1753 * TKIPKeyMix1 -- Apply phase 1 of the TKIP key-mixing function.
1755 * SYNOPSIS
1756 * TKIPKeyMix1(ttak, tk, ta, iv_high)
1758 * VOID TKIPKeyMix1(UWORD *, UWORD *, UWORD *, ULONG);
1760 ****************************************************************************
1764 static VOID TKIPKeyMix1(UWORD *ttak, const UWORD *tk, const UWORD *ta,
1765 ULONG iv_high, struct DevBase *base)
1767 const UWORD *p;
1768 UWORD i, *q, *r, a;
1770 ttak[0] = iv_high;
1771 ttak[1] = iv_high >> 16;
1772 ttak[2] = LEWord(ta[0]);
1773 ttak[3] = LEWord(ta[1]);
1774 ttak[4] = LEWord(ta[2]);
1776 for(i = 0; i < 8; i++)
1778 p = tk + (i & 1);
1779 q = ttak;
1780 r = ttak + 4;
1781 a = *p++;
1782 *q++ += SBox(*r ^ a);
1783 r = ttak;
1784 *q++ += SBox(*r++ ^ *++p);
1785 p += 2;
1786 *q++ += SBox(*r++ ^ *p++);
1787 *q++ += SBox(*r++ ^ *++p);
1788 *q += SBox(*r++ ^ a) + i;
1791 return;
1796 /****i* prism2.device/TKIPKeyMix2 ******************************************
1798 * NAME
1799 * TKIPKeyMix2 -- Apply phase 2 of the TKIP key-mixing function.
1801 * SYNOPSIS
1802 * TKIPKeyMix2(rc4_seed, ttak, tk, iv16)
1804 * VOID TKIPKeyMix2(UBYTE *, UWORD *, UWORD *, UWORD);
1806 ****************************************************************************
1810 VOID TKIPKeyMix2(UBYTE *rc4_seed, const UWORD *ttak, const UWORD *tk,
1811 UWORD iv16, struct DevBase *base)
1813 const UWORD *p = ttak;
1814 UWORD i, temp_key[6], *q = temp_key, *r, a;
1816 for(i = 0; i < 5; i++)
1817 *q++ = *p++;
1818 a = *q++ = ttak[4] + iv16;
1820 p = tk;
1821 r = q = temp_key;
1822 *q++ += SBox(a ^ *p++);
1823 *q++ += SBox(*r++ ^ *p++);
1824 *q++ += SBox(*r++ ^ *p++);
1825 *q++ += SBox(*r++ ^ *p++);
1826 *q++ += SBox(*r++ ^ *p++);
1827 *q++ += SBox(*r++ ^ *p++);
1829 q = temp_key;
1830 a = *r++ ^ *p++;
1831 *q++ += a << 15 | a >> 1;
1832 r = temp_key;
1833 a = *r++ ^ *p++;
1834 *q++ += a << 15 | a >> 1;
1835 a = *r++;
1836 *q++ += a << 15 | a >> 1;
1837 a = *r++;
1838 *q++ += a << 15 | a >> 1;
1839 a = *r++;
1840 *q++ += a << 15 | a >> 1;
1841 a = *r;
1842 *q += a << 15 | a >> 1;
1844 *rc4_seed++ = iv16 >> 8;
1845 *rc4_seed++ = (iv16 >> 8 | 0x20) & 0x7f;
1846 *rc4_seed++ = iv16;
1847 *rc4_seed++ = (*q ^ tk[0]) >> 1;
1848 q = temp_key;
1849 for(i = 0; i < 6; i++)
1851 a = *q++;
1852 *rc4_seed++ = a;
1853 *rc4_seed++ = a >> 8;
1856 return;
1861 /****i* prism2.device/RC4Encrypt *******************************************
1863 * NAME
1864 * RC4Encrypt -- Encrypt data using the RC4 cipher, and append CRC.
1866 * SYNOPSIS
1867 * RC4Encrypt(unit, data, size, buffer, seed)
1869 * VOID RC4Encrypt(struct DevUnit *, UBYTE *, UWORD, UBYTE *, UBYTE *);
1871 * NOTES
1872 * The input data may overlap the output buffer as long as the output
1873 * address is not higher than the input address.
1875 ****************************************************************************
1879 VOID RC4Encrypt(struct DevUnit *unit, const UBYTE *data, UWORD size,
1880 UBYTE *buffer, UBYTE *seed, struct DevBase *base)
1882 UWORD i, j, k;
1883 ULONG crc = ~0;
1884 const UBYTE *p;
1885 UBYTE s[256], *q, a, b, c;
1887 /* Initialise RC4 state */
1889 for(i = 0; i < 256; i++)
1890 s[i] = i;
1891 for(j = i = 0; i < 256; i++)
1893 a = s[i];
1894 j = j + seed[i & 0xf] + a & 0xff;
1895 s[i] = s[j];
1896 s[j] = a;
1899 /* Encrypt data and CRC */
1901 for(p = data, q = buffer, k = j = i = 0; k < size + 4; k++)
1903 if(k == size)
1905 *(ULONG *)q = MakeLELong(~crc);
1906 p = q;
1908 i = i + 1 & 0xff;
1909 a = s[i];
1910 j = j + a & 0xff;
1911 s[i] = b = s[j];
1912 s[j] = a;
1913 c = *p++;
1914 *q++ = c ^ s[a + b & 0xff];
1915 crc = crc32[(crc ^ c) & 0xff] ^ crc >> 8;
1918 return;
1922 /****i* prism2.device/RC4Decrypt *******************************************
1924 * NAME
1925 * RC4Decrypt -- Decrypt data using the RC4 cipher, and check CRC.
1927 * SYNOPSIS
1928 * success = RC4Encrypt(unit, data, size, buffer, seed)
1930 * BOOL RC4Decrypt(struct DevUnit *, UBYTE *, UWORD, UBYTE *, UBYTE *);
1932 * NOTES
1933 * The input data may overlap the output buffer as long as the output
1934 * address is not higher than the input address.
1936 * The output buffer must be at least as big as the input data.
1938 ****************************************************************************
1942 BOOL RC4Decrypt(struct DevUnit *unit, const UBYTE *data, UWORD size,
1943 UBYTE *buffer, UBYTE *seed, struct DevBase *base)
1945 UWORD i, j, k;
1946 ULONG crc = ~0;
1947 const UBYTE *p;
1948 UBYTE s[256], *q, a, b, c;
1950 /* Initialise RC4 state */
1952 for(i = 0; i < 256; i++)
1953 s[i] = i;
1954 for(j = i = 0; i < 256; i++)
1956 a = s[i];
1957 j = j + seed[i & 0xf] + s[i] & 0xff;
1958 s[i] = s[j];
1959 s[j] = a;
1962 /* Decrypt data and CRC */
1964 for(p = data, q = buffer, k = j = i = 0; k < size; k++)
1966 i = i + 1 & 0xff;
1967 a = s[i];
1968 j = j + a & 0xff;
1969 b = s[j];
1970 s[j] = a;
1971 s[i] = b;
1972 c = *p++ ^ s[a + b & 0xff];
1973 if(k < size - 4)
1974 crc = crc32[(crc ^ c) & 0xff] ^ crc >> 8;
1975 *q++ = c;
1978 /* Check CRC */
1980 return ~crc == LELong(*(ULONG *)(q - 4));
1984 /****i* prism2.device/EOREncrypt *******************************************
1986 * NAME
1987 * EOREncrypt -- Apply exclusive-or to a block.
1989 * SYNOPSIS
1990 * EOREncrypt(data, buffer, key)
1992 * VOID EOREncrypt(UBYTE *, UBYTE *, UBYTE *);
1994 * NOTES
1995 *# The input data may overlap the output buffer as long as the output
1996 *# address is not higher than the input address.
1998 ****************************************************************************
2002 VOID EOREncrypt(const ULONG *data, ULONG *buffer, ULONG *key,
2003 struct DevBase *base)
2005 *buffer++ = *data++ ^ *key++;
2006 *buffer++ = *data++ ^ *key++;
2007 *buffer++ = *data++ ^ *key++;
2008 *buffer++ = *data++ ^ *key++;
2013 /****i* prism2.device/AESKeyMix ********************************************
2015 * NAME
2016 * AESKeyMix -- Expand an AES key into a key stream.
2018 * SYNOPSIS
2019 * AESKeyMix(stream, key)
2021 * VOID AESKeyMix(struct DevUnit *, UBYTE *);
2023 ****************************************************************************
2027 static VOID AESKeyMix(ULONG *stream, const ULONG *key, struct DevBase *base)
2029 UWORD i;
2030 ULONG n;
2032 stream[0] = BELong(key[0]);
2033 stream[1] = BELong(key[1]);
2034 stream[2] = BELong(key[2]);
2035 stream[3] = BELong(key[3]);
2037 for(i = 0; i < 10; i++)
2039 n = stream[3];
2040 stream[4] = stream[0] ^ (te4[(n >> 16) & 0xff] & 0xff000000)
2041 ^ (te4[(n >> 8) & 0xff] & 0x00ff0000)
2042 ^ (te4[n & 0xff] & 0x0000ff00)
2043 ^ (te4[n >> 24] & 0x000000ff) ^ rcon[i];
2044 stream[5] = stream[1] ^ stream[4];
2045 stream[6] = stream[2] ^ stream[5];
2046 stream[7] = stream[3] ^ stream[6];
2047 stream += 4;
2053 /****i* prism2.device/AESEncrypt *******************************************
2055 * NAME
2056 * AESEncrypt -- Encrypt a block using the AES cipher.
2058 * SYNOPSIS
2059 * AESEncrypt(data, buffer, key)
2061 * VOID AESEncrypt(UBYTE *, UBYTE *, UBYTE *);
2063 ****************************************************************************
2067 VOID AESEncrypt(const ULONG *data, ULONG *buffer, ULONG *key,
2068 struct DevBase *base)
2070 UWORD i = 5;
2071 ULONG s0, s1, s2, s3, t0, t1, t2, t3;
2074 s0 = BELong(data[0]) ^ key[0];
2075 s1 = BELong(data[1]) ^ key[1];
2076 s2 = BELong(data[2]) ^ key[2];
2077 s3 = BELong(data[3]) ^ key[3];
2079 while(TRUE)
2081 t0 = te0[s0 >> 24] ^ te1[(s1 >> 16) & 0xff] ^ te2[(s2 >> 8) & 0xff]
2082 ^ te3[s3 & 0xff] ^ key[4];
2083 t1 = te0[s1 >> 24] ^ te1[(s2 >> 16) & 0xff] ^ te2[(s3 >> 8) & 0xff]
2084 ^ te3[s0 & 0xff] ^ key[5];
2085 t2 = te0[s2 >> 24] ^ te1[(s3 >> 16) & 0xff] ^ te2[(s0 >> 8) & 0xff]
2086 ^ te3[s1 & 0xff] ^ key[6];
2087 t3 = te0[s3 >> 24] ^ te1[(s0 >> 16) & 0xff] ^ te2[(s1 >> 8) & 0xff]
2088 ^ te3[s2 & 0xff] ^ key[7];
2090 key += 8;
2091 if(--i == 0)
2092 break;
2094 s0 = te0[t0 >> 24] ^ te1[(t1 >> 16) & 0xff] ^ te2[(t2 >> 8) & 0xff]
2095 ^ te3[t3 & 0xff] ^ key[0];
2096 s1 = te0[t1 >> 24] ^ te1[(t2 >> 16) & 0xff] ^ te2[(t3 >> 8) & 0xff]
2097 ^ te3[t0 & 0xff] ^ key[1];
2098 s2 = te0[t2 >> 24] ^ te1[(t3 >> 16) & 0xff] ^ te2[(t0 >> 8) & 0xff]
2099 ^ te3[t1 & 0xff] ^ key[2];
2100 s3 = te0[t3 >> 24] ^ te1[(t0 >> 16) & 0xff] ^ te2[(t1 >> 8) & 0xff]
2101 ^ te3[t2 & 0xff] ^ key[3];
2104 s0 = (te4[t0 >> 24] & 0xff000000) ^ (te4[(t1 >> 16) & 0xff] & 0x00ff0000)
2105 ^ (te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (te4[t3 & 0xff] & 0x000000ff)
2106 ^ key[0];
2107 buffer[0] = MakeBELong(s0);
2108 s1 = (te4[t1 >> 24] & 0xff000000) ^ (te4[(t2 >> 16) & 0xff] & 0x00ff0000)
2109 ^ (te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (te4[t0 & 0xff] & 0x000000ff)
2110 ^ key[1];
2111 buffer[1] = MakeBELong(s1);
2112 s2 = (te4[t2 >> 24] & 0xff000000) ^ (te4[(t3 >> 16) & 0xff] & 0x00ff0000)
2113 ^ (te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (te4[t1 & 0xff] & 0x000000ff)
2114 ^ key[2];
2115 buffer[2] = MakeBELong(s2);
2116 s3 = (te4[t3 >> 24] & 0xff000000) ^ (te4[(t0 >> 16) & 0xff] & 0x00ff0000)
2117 ^ (te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (te4[t2 & 0xff] & 0x000000ff)
2118 ^ key[3];
2119 buffer[3] = MakeBELong(s3);
2121 return;