1 /* $NetBSD: ieee80211_crypto_tkip.c,v 1.17 2020/11/03 15:06:50 mlelstv Exp $ */
2
3 /*
4 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * Alternatively, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") version 2 as published by the Free
20 * Software Foundation.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <sys/cdefs.h>
35 #ifdef __FreeBSD__
36 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_tkip.c,v 1.10 2005/08/08 18:46:35 sam Exp $");
37 #endif
38 #ifdef __NetBSD__
39 __KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_tkip.c,v 1.17 2020/11/03 15:06:50 mlelstv Exp $");
40 #endif
41
42 /*
43 * IEEE 802.11i TKIP crypto support.
44 *
45 * Part of this module is derived from similar code in the Host
46 * AP driver. The code is used with the consent of the author and
47 * its license is included below.
48 */
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/mbuf.h>
52 #include <sys/kmem.h>
53 #include <sys/kernel.h>
54 #include <sys/endian.h>
55
56 #include <sys/socket.h>
57
58 #include <net/if.h>
59 #include <net/if_ether.h>
60 #include <net/if_media.h>
61
62 #include <net80211/ieee80211_var.h>
63
64 static void *tkip_attach(struct ieee80211com *, struct ieee80211_key *);
65 static void tkip_detach(struct ieee80211_key *);
66 static int tkip_setkey(struct ieee80211_key *);
67 static int tkip_encap(struct ieee80211_key *, struct mbuf *m, u_int8_t keyid);
68 static int tkip_enmic(struct ieee80211_key *, struct mbuf *, int);
69 static int tkip_decap(struct ieee80211_key *, struct mbuf *, int);
70 static int tkip_demic(struct ieee80211_key *, struct mbuf *, int);
71
72 const struct ieee80211_cipher ieee80211_cipher_tkip = {
73 .ic_name = "TKIP",
74 .ic_cipher = IEEE80211_CIPHER_TKIP,
75 .ic_header = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
76 IEEE80211_WEP_EXTIVLEN,
77 .ic_trailer = IEEE80211_WEP_CRCLEN,
78 .ic_miclen = IEEE80211_WEP_MICLEN,
79 .ic_attach = tkip_attach,
80 .ic_detach = tkip_detach,
81 .ic_setkey = tkip_setkey,
82 .ic_encap = tkip_encap,
83 .ic_decap = tkip_decap,
84 .ic_enmic = tkip_enmic,
85 .ic_demic = tkip_demic,
86 };
87
88 #define tkip ieee80211_cipher_tkip
89
90 typedef uint8_t u8;
91 typedef uint16_t u16;
92 typedef uint32_t __u32;
93 typedef uint32_t u32;
94
95 struct tkip_ctx {
96 struct ieee80211com *tc_ic; /* for diagnostics */
97
98 u16 tx_ttak[5];
99 int tx_phase1_done;
100 u8 tx_rc4key[16]; /* XXX for test module; make locals? */
101
102 u16 rx_ttak[5];
103 int rx_phase1_done;
104 u8 rx_rc4key[16]; /* XXX for test module; make locals? */
105 uint64_t rx_rsc; /* held until MIC verified */
106 };
107
108 static void michael_mic(struct tkip_ctx *, const u8 *key,
109 struct mbuf *m, u_int off, size_t data_len,
110 u8 mic[IEEE80211_WEP_MICLEN]);
111 static int tkip_encrypt(struct tkip_ctx *, struct ieee80211_key *,
112 struct mbuf *, int hdr_len);
113 static int tkip_decrypt(struct tkip_ctx *, struct ieee80211_key *,
114 struct mbuf *, int hdr_len);
115
116 static void *
117 tkip_attach(struct ieee80211com *ic, struct ieee80211_key *k)
118 {
119 struct tkip_ctx *ctx;
120
121 ctx = kmem_intr_zalloc(sizeof(struct tkip_ctx), KM_NOSLEEP);
122 if (ctx == NULL) {
123 ic->ic_stats.is_crypto_nomem++;
124 return NULL;
125 }
126
127 ctx->tc_ic = ic;
128 return ctx;
129 }
130
131 static void
132 tkip_detach(struct ieee80211_key *k)
133 {
134 struct tkip_ctx *ctx = k->wk_private;
135
136 kmem_intr_free(ctx, sizeof(struct tkip_ctx));
137 }
138
139 static int
140 tkip_setkey(struct ieee80211_key *k)
141 {
142 struct tkip_ctx *ctx = k->wk_private;
143
144 if (k->wk_keylen != (128/NBBY)) {
145 (void) ctx; /* XXX */
146 IEEE80211_DPRINTF(ctx->tc_ic, IEEE80211_MSG_CRYPTO,
147 "%s: Invalid key length %u, expecting %u\n",
148 __func__, k->wk_keylen, 128/NBBY);
149 return 0;
150 }
151 k->wk_keytsc = 1; /* TSC starts at 1 */
152 return 1;
153 }
154
155 /*
156 * Add privacy headers and do any s/w encryption required.
157 */
158 static int
159 tkip_encap(struct ieee80211_key *k, struct mbuf *m, u_int8_t keyid)
160 {
161 struct tkip_ctx *ctx = k->wk_private;
162 struct ieee80211com *ic = ctx->tc_ic;
163 u_int8_t *ivp;
164 int hdrlen;
165
166 /*
167 * Handle TKIP counter measures requirement.
168 */
169 if (ic->ic_flags & IEEE80211_F_COUNTERM) {
170 #ifdef IEEE80211_DEBUG
171 struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
172 #endif
173
174 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
175 "[%s] Discard frame due to countermeasures (%s)\n",
176 ether_sprintf(wh->i_addr2), __func__);
177 ic->ic_stats.is_crypto_tkipcm++;
178 return 0;
179 }
180
181 hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
182 ivp = mtod(m, u_int8_t *) + hdrlen;
183
184 ivp[0] = k->wk_keytsc >> 8; /* TSC1 */
185 ivp[1] = (ivp[0] | 0x20) & 0x7f; /* WEP seed */
186 ivp[2] = k->wk_keytsc >> 0; /* TSC0 */
187 ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */
188 ivp[4] = k->wk_keytsc >> 16; /* TSC2 */
189 ivp[5] = k->wk_keytsc >> 24; /* TSC3 */
190 ivp[6] = k->wk_keytsc >> 32; /* TSC4 */
191 ivp[7] = k->wk_keytsc >> 40; /* TSC5 */
192
193 /*
194 * Finally, do software encrypt if neeed.
195 */
196 if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
197 if (!tkip_encrypt(ctx, k, m, hdrlen))
198 return 0;
199 /* NB: tkip_encrypt handles wk_keytsc */
200 } else
201 k->wk_keytsc++;
202
203 return 1;
204 }
205
206 /*
207 * Add MIC to the frame as needed.
208 */
209 static int
210 tkip_enmic(struct ieee80211_key *k, struct mbuf *m, int force)
211 {
212 struct tkip_ctx *ctx = k->wk_private;
213
214 if (force || (k->wk_flags & IEEE80211_KEY_SWMIC)) {
215 struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
216 struct ieee80211com *ic = ctx->tc_ic;
217 int hdrlen;
218 uint8_t mic[IEEE80211_WEP_MICLEN];
219
220 ic->ic_stats.is_crypto_tkipenmic++;
221
222 hdrlen = ieee80211_hdrspace(ic, wh);
223
224 michael_mic(ctx, k->wk_txmic,
225 m, hdrlen, m->m_pkthdr.len - hdrlen, mic);
226 return m_append(m, tkip.ic_miclen, mic);
227 }
228 return 1;
229 }
230
231 static __inline uint64_t
232 READ_6(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5)
233 {
234 uint32_t iv32 = (b0 << 0) | (b1 << 8) | (b2 << 16) | ((u32)b3 << 24);
235 uint16_t iv16 = (b4 << 0) | (b5 << 8);
236 return (((uint64_t)iv16) << 32) | iv32;
237 }
238
239 /*
240 * Validate and strip privacy headers (and trailer) for a
241 * received frame. If necessary, decrypt the frame using
242 * the specified key.
243 */
244 static int
245 tkip_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
246 {
247 struct tkip_ctx *ctx = k->wk_private;
248 struct ieee80211com *ic = ctx->tc_ic;
249 struct ieee80211_frame *wh;
250 uint8_t *ivp;
251
252 /*
253 * Header should have extended IV and sequence number;
254 * verify the former and validate the latter.
255 */
256 wh = mtod(m, struct ieee80211_frame *);
257 ivp = mtod(m, uint8_t *) + hdrlen;
258 if ((ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) == 0) {
259 /*
260 * No extended IV; discard frame.
261 */
262 IEEE80211_DPRINTF(ctx->tc_ic, IEEE80211_MSG_CRYPTO,
263 "[%s] missing ExtIV for TKIP cipher\n",
264 ether_sprintf(wh->i_addr2));
265 ctx->tc_ic->ic_stats.is_rx_tkipformat++;
266 return 0;
267 }
268 /*
269 * Handle TKIP counter measures requirement.
270 */
271 if (ic->ic_flags & IEEE80211_F_COUNTERM) {
272 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
273 "[%s] discard frame due to countermeasures (%s)\n",
274 ether_sprintf(wh->i_addr2), __func__);
275 ic->ic_stats.is_crypto_tkipcm++;
276 return 0;
277 }
278
279 ctx->rx_rsc = READ_6(ivp[2], ivp[0], ivp[4], ivp[5], ivp[6], ivp[7]);
280 if (ctx->rx_rsc <= k->wk_keyrsc) {
281 /*
282 * Replay violation; notify upper layer.
283 */
284 ieee80211_notify_replay_failure(ctx->tc_ic, wh, k, ctx->rx_rsc);
285 ctx->tc_ic->ic_stats.is_rx_tkipreplay++;
286 return 0;
287 }
288 /*
289 * NB: We can't update the rsc in the key until MIC is verified.
290 *
291 * We assume we are not preempted between doing the check above
292 * and updating wk_keyrsc when stripping the MIC in tkip_demic.
293 * Otherwise we might process another packet and discard it as
294 * a replay.
295 */
296
297 /*
298 * Check if the device handled the decrypt in hardware.
299 * If so we just strip the header; otherwise we need to
300 * handle the decrypt in software.
301 */
302 if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) &&
303 !tkip_decrypt(ctx, k, m, hdrlen))
304 return 0;
305
306 /*
307 * Copy up 802.11 header and strip crypto bits.
308 */
309 memmove(mtod(m, uint8_t *) + tkip.ic_header, mtod(m, void *), hdrlen);
310 m_adj(m, tkip.ic_header);
311 m_adj(m, -tkip.ic_trailer);
312
313 return 1;
314 }
315
316 /*
317 * Verify and strip MIC from the frame.
318 */
319 static int
320 tkip_demic(struct ieee80211_key *k, struct mbuf *m, int force)
321 {
322 struct tkip_ctx *ctx = k->wk_private;
323
324 if (force || (k->wk_flags & IEEE80211_KEY_SWMIC)) {
325 struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
326 struct ieee80211com *ic = ctx->tc_ic;
327 int hdrlen = ieee80211_hdrspace(ic, wh);
328 u8 mic[IEEE80211_WEP_MICLEN];
329 u8 mic0[IEEE80211_WEP_MICLEN];
330
331 ic->ic_stats.is_crypto_tkipdemic++;
332
333 michael_mic(ctx, k->wk_rxmic,
334 m, hdrlen, m->m_pkthdr.len - (hdrlen + tkip.ic_miclen),
335 mic);
336 m_copydata(m, m->m_pkthdr.len - tkip.ic_miclen,
337 tkip.ic_miclen, mic0);
338 if (memcmp(mic, mic0, tkip.ic_miclen)) {
339 /* NB: 802.11 layer handles statistic and debug msg */
340 ieee80211_notify_michael_failure(ic, wh,
341 k->wk_rxkeyix != IEEE80211_KEYIX_NONE ?
342 k->wk_rxkeyix : k->wk_keyix);
343 return 0;
344 }
345 }
346 /*
347 * Strip MIC from the tail.
348 */
349 m_adj(m, -tkip.ic_miclen);
350
351 /*
352 * Ok to update rsc now that MIC has been verified.
353 */
354 k->wk_keyrsc = ctx->rx_rsc;
355
356 return 1;
357 }
358
359 /*
360 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
361 *
362 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
363 *
364 * This program is free software; you can redistribute it and/or modify
365 * it under the terms of the GNU General Public License version 2 as
366 * published by the Free Software Foundation. See README and COPYING for
367 * more details.
368 *
369 * Alternatively, this software may be distributed under the terms of BSD
370 * license.
371 */
372
373 static const __u32 crc32_table[256] = {
374 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
375 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
376 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
377 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
378 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
379 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
380 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
381 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
382 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
383 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
384 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
385 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
386 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
387 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
388 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
389 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
390 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
391 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
392 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
393 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
394 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
395 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
396 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
397 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
398 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
399 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
400 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
401 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
402 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
403 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
404 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
405 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
406 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
407 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
408 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
409 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
410 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
411 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
412 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
413 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
414 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
415 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
416 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
417 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
418 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
419 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
420 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
421 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
422 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
423 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
424 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
425 0x2d02ef8dL
426 };
427
428 static __inline u16 RotR1(u16 val)
429 {
430 return (val >> 1) | (val << 15);
431 }
432
433 static __inline u8 Lo8(u16 val)
434 {
435 return val & 0xff;
436 }
437
438 static __inline u8 Hi8(u16 val)
439 {
440 return val >> 8;
441 }
442
443 static __inline u16 Lo16(u32 val)
444 {
445 return val & 0xffff;
446 }
447
448 static __inline u16 Hi16(u32 val)
449 {
450 return val >> 16;
451 }
452
453 static __inline u16 Mk16(u8 hi, u8 lo)
454 {
455 return lo | (((u16) hi) << 8);
456 }
457
458 static __inline u16 Mk16_le(const u16 *v)
459 {
460 return le16toh(*v);
461 }
462
463 static const u16 Sbox[256] = {
464 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
465 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
466 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
467 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
468 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
469 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
470 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
471 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
472 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
473 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
474 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
475 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
476 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
477 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
478 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
479 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
480 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
481 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
482 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
483 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
484 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
485 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
486 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
487 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
488 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
489 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
490 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
491 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
492 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
493 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
494 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
495 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
496 };
497
498 static __inline u16 _S_(u16 v)
499 {
500 u16 t = Sbox[Hi8(v)];
501 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
502 }
503
504 #define PHASE1_LOOP_COUNT 8
505
506 static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
507 {
508 int i, j;
509
510 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
511 TTAK[0] = Lo16(IV32);
512 TTAK[1] = Hi16(IV32);
513 TTAK[2] = Mk16(TA[1], TA[0]);
514 TTAK[3] = Mk16(TA[3], TA[2]);
515 TTAK[4] = Mk16(TA[5], TA[4]);
516
517 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
518 j = 2 * (i & 1);
519 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
520 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
521 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
522 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
523 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
524 }
525 }
526
527 #ifndef _BYTE_ORDER
528 #error "Don't know native byte order"
529 #endif
530
531 static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
532 u16 IV16)
533 {
534 /* Make temporary area overlap WEP seed so that the final copy can be
535 * avoided on little endian hosts. */
536 u16 *PPK = (u16 *) &WEPSeed[4];
537
538 /* Step 1 - make copy of TTAK and bring in TSC */
539 PPK[0] = TTAK[0];
540 PPK[1] = TTAK[1];
541 PPK[2] = TTAK[2];
542 PPK[3] = TTAK[3];
543 PPK[4] = TTAK[4];
544 PPK[5] = TTAK[4] + IV16;
545
546 /* Step 2 - 96-bit bijective mixing using S-box */
547 PPK[0] += _S_(PPK[5] ^ Mk16_le((const u16 *) &TK[0]));
548 PPK[1] += _S_(PPK[0] ^ Mk16_le((const u16 *) &TK[2]));
549 PPK[2] += _S_(PPK[1] ^ Mk16_le((const u16 *) &TK[4]));
550 PPK[3] += _S_(PPK[2] ^ Mk16_le((const u16 *) &TK[6]));
551 PPK[4] += _S_(PPK[3] ^ Mk16_le((const u16 *) &TK[8]));
552 PPK[5] += _S_(PPK[4] ^ Mk16_le((const u16 *) &TK[10]));
553
554 PPK[0] += RotR1(PPK[5] ^ Mk16_le((const u16 *) &TK[12]));
555 PPK[1] += RotR1(PPK[0] ^ Mk16_le((const u16 *) &TK[14]));
556 PPK[2] += RotR1(PPK[1]);
557 PPK[3] += RotR1(PPK[2]);
558 PPK[4] += RotR1(PPK[3]);
559 PPK[5] += RotR1(PPK[4]);
560
561 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
562 * WEPSeed[0..2] is transmitted as WEP IV */
563 WEPSeed[0] = Hi8(IV16);
564 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
565 WEPSeed[2] = Lo8(IV16);
566 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((const u16 *) &TK[0])) >> 1);
567
568 #if _BYTE_ORDER == _BIG_ENDIAN
569 {
570 int i;
571 for (i = 0; i < 6; i++)
572 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
573 }
574 #endif
575 }
576
577 static void
578 wep_encrypt(u8 *key, struct mbuf *m0, u_int off, size_t data_len,
579 uint8_t icv[IEEE80211_WEP_CRCLEN])
580 {
581 u32 i, j, k, crc;
582 size_t buflen;
583 u8 S[256];
584 u8 *pos;
585 struct mbuf *m;
586 #define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0)
587
588 /* Setup RC4 state */
589 for (i = 0; i < 256; i++)
590 S[i] = i;
591 j = 0;
592 for (i = 0; i < 256; i++) {
593 j = (j + S[i] + key[i & 0x0f]) & 0xff;
594 S_SWAP(i, j);
595 }
596
597 /* Compute CRC32 over unencrypted data and apply RC4 to data */
598 crc = ~0;
599 i = j = 0;
600 m = m0;
601 pos = mtod(m, uint8_t *) + off;
602 buflen = m->m_len - off;
603 for (;;) {
604 if (buflen > data_len)
605 buflen = data_len;
606 data_len -= buflen;
607 for (k = 0; k < buflen; k++) {
608 crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8);
609 i = (i + 1) & 0xff;
610 j = (j + S[i]) & 0xff;
611 S_SWAP(i, j);
612 *pos++ ^= S[(S[i] + S[j]) & 0xff];
613 }
614 m = m->m_next;
615 if (m == NULL) {
616 IASSERT(data_len == 0,
617 ("out of buffers with data_len %zu\n", data_len));
618 break;
619 }
620 pos = mtod(m, uint8_t *);
621 buflen = m->m_len;
622 }
623 crc = ~crc;
624
625 /* Append little-endian CRC32 and encrypt it to produce ICV */
626 icv[0] = crc;
627 icv[1] = crc >> 8;
628 icv[2] = crc >> 16;
629 icv[3] = crc >> 24;
630 for (k = 0; k < IEEE80211_WEP_CRCLEN; k++) {
631 i = (i + 1) & 0xff;
632 j = (j + S[i]) & 0xff;
633 S_SWAP(i, j);
634 icv[k] ^= S[(S[i] + S[j]) & 0xff];
635 }
636 }
637
638 static int
639 wep_decrypt(u8 *key, struct mbuf *m, u_int off, size_t data_len)
640 {
641 u32 i, j, k, crc;
642 u8 S[256];
643 u8 *pos, icv[4];
644 size_t buflen;
645
646 /* Setup RC4 state */
647 for (i = 0; i < 256; i++)
648 S[i] = i;
649 j = 0;
650 for (i = 0; i < 256; i++) {
651 j = (j + S[i] + key[i & 0x0f]) & 0xff;
652 S_SWAP(i, j);
653 }
654
655 /* Apply RC4 to data and compute CRC32 over decrypted data */
656 crc = ~0;
657 i = j = 0;
658 pos = mtod(m, uint8_t *) + off;
659 buflen = m->m_len - off;
660 for (;;) {
661 if (buflen > data_len)
662 buflen = data_len;
663 data_len -= buflen;
664 for (k = 0; k < buflen; k++) {
665 i = (i + 1) & 0xff;
666 j = (j + S[i]) & 0xff;
667 S_SWAP(i, j);
668 *pos ^= S[(S[i] + S[j]) & 0xff];
669 crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8);
670 pos++;
671 }
672 m = m->m_next;
673 if (m == NULL) {
674 IASSERT(data_len == 0,
675 ("out of buffers with data_len %zu\n", data_len));
676 break;
677 }
678 pos = mtod(m, uint8_t *);
679 buflen = m->m_len;
680 }
681 crc = ~crc;
682
683 /* Encrypt little-endian CRC32 and verify that it matches with the
684 * received ICV */
685 icv[0] = crc;
686 icv[1] = crc >> 8;
687 icv[2] = crc >> 16;
688 icv[3] = crc >> 24;
689 for (k = 0; k < 4; k++) {
690 i = (i + 1) & 0xff;
691 j = (j + S[i]) & 0xff;
692 S_SWAP(i, j);
693 if ((icv[k] ^ S[(S[i] + S[j]) & 0xff]) != *pos++) {
694 /* ICV mismatch - drop frame */
695 return -1;
696 }
697 }
698
699 return 0;
700 }
701
702
703 static __inline u32 rotl(u32 val, int bits)
704 {
705 return (val << bits) | (val >> (32 - bits));
706 }
707
708
709 static __inline u32 rotr(u32 val, int bits)
710 {
711 return (val >> bits) | (val << (32 - bits));
712 }
713
714
715 static __inline u32 xswap(u32 val)
716 {
717 return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
718 }
719
720
721 #define michael_block(l, r) \
722 do { \
723 r ^= rotl(l, 17); \
724 l += r; \
725 r ^= xswap(l); \
726 l += r; \
727 r ^= rotl(l, 3); \
728 l += r; \
729 r ^= rotr(l, 2); \
730 l += r; \
731 } while (0)
732
733
734 static __inline u32 get_le32_split(u8 b0, u8 b1, u8 b2, u8 b3)
735 {
736 return b0 | (b1 << 8) | (b2 << 16) | ((u32)b3 << 24);
737 }
738
739 static __inline u32 get_le32(const u8 *p)
740 {
741 return get_le32_split(p[0], p[1], p[2], p[3]);
742 }
743
744
745 static __inline void put_le32(u8 *p, u32 v)
746 {
747 p[0] = v;
748 p[1] = v >> 8;
749 p[2] = v >> 16;
750 p[3] = v >> 24;
751 }
752
753 /*
754 * Craft pseudo header used to calculate the MIC.
755 */
756 static void
757 michael_mic_hdr(const struct ieee80211_frame *wh0, uint8_t hdr[16])
758 {
759 const struct ieee80211_frame_addr4 *wh =
760 (const struct ieee80211_frame_addr4 *) wh0;
761
762 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
763 case IEEE80211_FC1_DIR_NODS:
764 IEEE80211_ADDR_COPY(hdr, wh->i_addr1); /* DA */
765 IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr2);
766 break;
767 case IEEE80211_FC1_DIR_TODS:
768 IEEE80211_ADDR_COPY(hdr, wh->i_addr3); /* DA */
769 IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr2);
770 break;
771 case IEEE80211_FC1_DIR_FROMDS:
772 IEEE80211_ADDR_COPY(hdr, wh->i_addr1); /* DA */
773 IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr3);
774 break;
775 case IEEE80211_FC1_DIR_DSTODS:
776 IEEE80211_ADDR_COPY(hdr, wh->i_addr3); /* DA */
777 IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr4);
778 break;
779 }
780
781 if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
782 const struct ieee80211_qosframe *qwh =
783 (const struct ieee80211_qosframe *) wh;
784 hdr[12] = qwh->i_qos[0] & IEEE80211_QOS_TID;
785 } else
786 hdr[12] = 0;
787 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
788 }
789
790 static void
791 michael_mic(struct tkip_ctx *ctx, const u8 *key,
792 struct mbuf *m, u_int off, size_t data_len,
793 u8 mic[IEEE80211_WEP_MICLEN])
794 {
795 uint8_t hdr[16];
796 u32 l, r;
797 const uint8_t *data;
798 u_int space;
799 uint8_t spill[4];
800 int nspill = 0;
801
802 michael_mic_hdr(mtod(m, struct ieee80211_frame *), hdr);
803
804 l = get_le32(key);
805 r = get_le32(key + 4);
806
807 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
808 l ^= get_le32(hdr);
809 michael_block(l, r);
810 l ^= get_le32(&hdr[4]);
811 michael_block(l, r);
812 l ^= get_le32(&hdr[8]);
813 michael_block(l, r);
814 l ^= get_le32(&hdr[12]);
815 michael_block(l, r);
816
817 /* first buffer has special handling */
818 data = mtod(m, const uint8_t *) + off;
819 space = m->m_len - off;
820 for (;;) {
821 if (space > data_len)
822 space = data_len;
823 if (nspill) {
824 int n = uimin(4 - nspill, space);
825 memcpy(spill + nspill, data, n);
826 nspill += n;
827 data += n;
828 space -= n;
829 data_len -= n;
830 if (nspill == 4) {
831 l ^= get_le32(spill);
832 michael_block(l, r);
833 nspill = 0;
834 } else
835 goto next;
836 }
837 /* collect 32-bit blocks from current buffer */
838 while (space >= sizeof(uint32_t)) {
839 l ^= get_le32(data);
840 michael_block(l, r);
841 data += sizeof(uint32_t);
842 space -= sizeof(uint32_t);
843 data_len -= sizeof(uint32_t);
844 }
845 if (space) {
846 memcpy(spill, data, space);
847 nspill = space;
848 data_len -= space;
849 }
850 next:
851 if (!data_len)
852 break;
853 m = m->m_next;
854 KASSERT(m);
855 /*
856 * Setup for next buffer.
857 */
858 data = mtod(m, const uint8_t *);
859 space = m->m_len;
860 }
861 /* Last block and padding (0x5a, 4..7 x 0) */
862 spill[nspill++] = 0x5a;
863 for (; nspill < 4; nspill++)
864 spill[nspill] = 0;
865 l ^= get_le32(spill);
866 michael_block(l, r);
867 /* l ^= 0; */
868 michael_block(l, r);
869
870 put_le32(mic, l);
871 put_le32(mic + 4, r);
872 }
873
874 static int
875 tkip_encrypt(struct tkip_ctx *ctx, struct ieee80211_key *key,
876 struct mbuf *m, int hdrlen)
877 {
878 struct ieee80211_frame *wh;
879 uint8_t icv[IEEE80211_WEP_CRCLEN];
880
881 ctx->tc_ic->ic_stats.is_crypto_tkip++;
882
883 wh = mtod(m, struct ieee80211_frame *);
884 if (!ctx->tx_phase1_done) {
885 tkip_mixing_phase1(ctx->tx_ttak, key->wk_key, wh->i_addr2,
886 (u32)(key->wk_keytsc >> 16));
887 ctx->tx_phase1_done = 1;
888 }
889 tkip_mixing_phase2(ctx->tx_rc4key, key->wk_key, ctx->tx_ttak,
890 (u16)key->wk_keytsc);
891
892 wep_encrypt(ctx->tx_rc4key,
893 m, hdrlen + tkip.ic_header,
894 m->m_pkthdr.len - (hdrlen + tkip.ic_header),
895 icv);
896
897 if (!m_append(m, IEEE80211_WEP_CRCLEN, icv)) {
898 return 0;
899 }
900
901 key->wk_keytsc++;
902 if ((u16)(key->wk_keytsc) == 0)
903 ctx->tx_phase1_done = 0;
904
905 return 1;
906 }
907
908 static int
909 tkip_decrypt(struct tkip_ctx *ctx, struct ieee80211_key *key,
910 struct mbuf *m, int hdrlen)
911 {
912 struct ieee80211_frame *wh;
913 u32 iv32;
914 u16 iv16;
915
916 ctx->tc_ic->ic_stats.is_crypto_tkip++;
917
918 wh = mtod(m, struct ieee80211_frame *);
919 /* NB: tkip_decap already verified header and left seq in rx_rsc */
920 iv16 = (u16) ctx->rx_rsc;
921 iv32 = (u32) (ctx->rx_rsc >> 16);
922
923 if (iv32 != (u32)(key->wk_keyrsc >> 16) || !ctx->rx_phase1_done) {
924 tkip_mixing_phase1(ctx->rx_ttak, key->wk_key,
925 wh->i_addr2, iv32);
926 ctx->rx_phase1_done = 1;
927 }
928 tkip_mixing_phase2(ctx->rx_rc4key, key->wk_key, ctx->rx_ttak, iv16);
929
930 /* NB: m is unstripped; deduct headers + ICV to get payload */
931 if (wep_decrypt(ctx->rx_rc4key, m, hdrlen + tkip.ic_header,
932 m->m_pkthdr.len - (hdrlen + tkip.ic_header + tkip.ic_trailer))) {
933 if (iv32 != (u32)(key->wk_keyrsc >> 16)) {
934 /* Previously cached Phase1 result was already lost, so
935 * it needs to be recalculated for the next packet. */
936 ctx->rx_phase1_done = 0;
937 }
938 IEEE80211_DPRINTF(ctx->tc_ic, IEEE80211_MSG_CRYPTO,
939 "[%s] TKIP ICV mismatch on decrypt\n",
940 ether_sprintf(wh->i_addr2));
941 ctx->tc_ic->ic_stats.is_rx_tkipicv++;
942 return 0;
943 }
944
945 return 1;
946 }
947
948 IEEE80211_CRYPTO_SETUP(tkip_register)
949 {
950 ieee80211_crypto_register(&tkip);
951 }
Cache object: f7217d94066cc2b6b0fd630497b3f9b9
|