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