1 /*
2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /*
7 * Copyright (c) 2001 Atsushi Onoe
8 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * Alternatively, this software may be distributed under the terms of the
23 * GNU General Public License ("GPL") version 2 as published by the Free
24 * Software Foundation.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 /*
39 * IEEE 802.11i TKIP crypto support.
40 *
41 * Part of this module is derived from similar code in the Host
42 * AP driver. The code is used with the consent of the author and
43 * it's license is included below.
44 */
45
46 #include <sys/byteorder.h>
47 #include <sys/crypto/common.h>
48 #include <sys/crypto/api.h>
49 #include <sys/crc32.h>
50 #include <sys/random.h>
51 #include <sys/strsun.h>
52 #include "net80211_impl.h"
53
54 static void *tkip_attach(struct ieee80211com *, struct ieee80211_key *);
55 static void tkip_detach(struct ieee80211_key *);
56 static int tkip_setkey(struct ieee80211_key *);
57 static int tkip_encap(struct ieee80211_key *, mblk_t *, uint8_t);
58 static int tkip_decap(struct ieee80211_key *, mblk_t *, int);
59 static int tkip_enmic(struct ieee80211_key *, mblk_t *, int);
60 static int tkip_demic(struct ieee80211_key *, mblk_t *, int);
61
62 const struct ieee80211_cipher tkip = {
63 "TKIP",
64 IEEE80211_CIPHER_TKIP,
65 IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
66 IEEE80211_WEP_EXTIVLEN,
67 IEEE80211_WEP_CRCLEN,
68 IEEE80211_WEP_MICLEN,
69 tkip_attach,
70 tkip_detach,
71 tkip_setkey,
72 tkip_encap,
73 tkip_decap,
74 tkip_enmic,
75 tkip_demic,
76 };
77
78 struct tkip_ctx {
79 struct ieee80211com *tc_ic; /* for diagnostics */
80 uint16_t tx_ttak[5];
81 int tx_phase1_done;
82 uint8_t tx_rc4key[16];
83 uint16_t rx_ttak[5];
84 int rx_phase1_done;
85 uint8_t rx_rc4key[16];
86 uint64_t rx_rsc; /* held until MIC verified */
87 };
88
89 static void michael_mic(struct tkip_ctx *, const uint8_t *,
90 mblk_t *, uint_t, size_t, uint8_t[]);
91 static int tkip_encrypt(struct tkip_ctx *, struct ieee80211_key *,
92 mblk_t *, int);
93 static int tkip_decrypt(struct tkip_ctx *, struct ieee80211_key *,
94 mblk_t *, int);
95
96 extern int rc4_init(crypto_context_t *, const uint8_t *, int);
97 extern int rc4_crypt(crypto_context_t, const uint8_t *, uint8_t *, int);
98 extern int rc4_final(crypto_context_t, uint8_t *, int);
99
100 /* ARGSUSED */
101 static void *
tkip_attach(struct ieee80211com * ic,struct ieee80211_key * k)102 tkip_attach(struct ieee80211com *ic, struct ieee80211_key *k)
103 {
104 struct tkip_ctx *ctx;
105
106 ctx = kmem_zalloc(sizeof (struct tkip_ctx), KM_SLEEP);
107 if (ctx == NULL)
108 return (NULL);
109
110 ctx->tc_ic = ic;
111 return (ctx);
112 }
113
114 static void
tkip_detach(struct ieee80211_key * k)115 tkip_detach(struct ieee80211_key *k)
116 {
117 struct tkip_ctx *ctx = k->wk_private;
118
119 if (ctx != NULL)
120 kmem_free(ctx, sizeof (struct tkip_ctx));
121 }
122
123 static int
tkip_setkey(struct ieee80211_key * k)124 tkip_setkey(struct ieee80211_key *k)
125 {
126 if (k->wk_keylen != (128/NBBY))
127 return (0);
128
129 k->wk_keytsc = 1; /* TSC starts at 1 */
130 return (1);
131 }
132
133 /*
134 * Add privacy headers appropriate for the specified key.
135 */
136 static int
tkip_encap(struct ieee80211_key * k,mblk_t * mp,uint8_t keyid)137 tkip_encap(struct ieee80211_key *k, mblk_t *mp, uint8_t keyid)
138 {
139 struct tkip_ctx *ctx = k->wk_private;
140 struct ieee80211com *ic = ctx->tc_ic;
141 uint8_t *ivp;
142 int hdrlen;
143
144 /*
145 * Handle TKIP counter measures requirement.
146 */
147 if (ic->ic_flags & IEEE80211_F_COUNTERM)
148 return (0);
149
150 hdrlen = ieee80211_hdrspace(ic, mp->b_rptr);
151 /*
152 * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
153 */
154 ivp = mp->b_rptr;
155 ivp += hdrlen;
156
157 ivp[0] = k->wk_keytsc >> 8; /* TSC1 */
158 ivp[1] = (ivp[0] | 0x20) & 0x7f; /* WEP seed */
159 ivp[2] = k->wk_keytsc >> 0; /* TSC0 */
160 ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */
161 ivp[4] = k->wk_keytsc >> 16; /* TSC2 */
162 ivp[5] = k->wk_keytsc >> 24; /* TSC3 */
163 ivp[6] = k->wk_keytsc >> 32; /* TSC4 */
164 ivp[7] = k->wk_keytsc >> 40; /* TSC5 */
165
166 /*
167 * Finally, do software encrypt if neeed.
168 */
169 if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
170 if (!tkip_encrypt(ctx, k, mp, hdrlen))
171 return (0);
172 } else
173 k->wk_keytsc++; /* wrap at 48 bits */
174
175 return (1);
176 }
177
178 uint64_t
ieee80211_read_6(uint8_t b0,uint8_t b1,uint8_t b2,uint8_t b3,uint8_t b4,uint8_t b5)179 ieee80211_read_6(uint8_t b0, uint8_t b1, uint8_t b2,
180 uint8_t b3, uint8_t b4, uint8_t b5)
181 {
182 uint32_t iv32 = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24);
183 uint16_t iv16 = (b4 << 0) | (b5 << 8);
184 return ((((uint64_t)iv16) << 32) | iv32);
185 }
186
187 /*
188 * Validate and strip privacy headers (and trailer) for a
189 * received frame. If necessary, decrypt the frame using
190 * the specified key.
191 */
192 static int
tkip_decap(struct ieee80211_key * k,mblk_t * mp,int hdrlen)193 tkip_decap(struct ieee80211_key *k, mblk_t *mp, int hdrlen)
194 {
195 struct tkip_ctx *ctx = k->wk_private;
196 struct ieee80211com *ic = ctx->tc_ic;
197 uint8_t *ivp;
198 uint64_t pn;
199
200 /*
201 * Header should have extended IV and sequence number;
202 * verify the former and validate the latter.
203 */
204 ivp = mp->b_rptr + hdrlen;
205 if ((ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) == 0) {
206 /*
207 * No extended IV; discard frame.
208 */
209 return (0);
210 }
211 /*
212 * Handle TKIP counter measures requirement.
213 */
214 if (ic->ic_flags & IEEE80211_F_COUNTERM)
215 return (0);
216
217 /* NB: assume IEEEE80211_WEP_MINLEN covers the extended IV */
218 pn = ieee80211_read_6(ivp[2], ivp[0], ivp[4], ivp[5], ivp[6], ivp[7]);
219 ctx->rx_rsc = pn;
220 if (ctx->rx_rsc <= k->wk_keyrsc)
221 return (0);
222 /*
223 * NB: We can't update the rsc in the key until MIC is verified.
224 *
225 * We assume we are not preempted between doing the check above
226 * and updating wk_keyrsc when stripping the MIC in tkip_demic.
227 * Otherwise we might process another packet and discard it as
228 * a replay.
229 */
230
231 /*
232 * Check if the device handled the decrypt in hardware.
233 * If so we just strip the header; otherwise we need to
234 * handle the decrypt in software.
235 */
236 if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
237 if (!tkip_decrypt(ctx, k, mp, hdrlen))
238 return (0);
239 }
240
241 /*
242 * Copy up 802.11 header and strip crypto bits.
243 */
244 (void) memmove(mp->b_rptr + tkip.ic_header, mp->b_rptr, hdrlen);
245 mp->b_rptr += tkip.ic_header;
246 mp->b_wptr -= tkip.ic_trailer;
247
248 return (1);
249 }
250
251 /*
252 * Add MIC to the frame as needed.
253 */
254 static int
tkip_enmic(struct ieee80211_key * k,mblk_t * mp,int force)255 tkip_enmic(struct ieee80211_key *k, mblk_t *mp, int force)
256 {
257 struct tkip_ctx *ctx = k->wk_private;
258
259 if (force || (k->wk_flags & IEEE80211_KEY_SWMIC)) {
260 int hdrlen;
261 uint8_t *mic;
262
263 hdrlen = ieee80211_hdrspace(ctx->tc_ic, mp->b_rptr);
264 mic = mp->b_wptr;
265 mp->b_wptr += tkip.ic_miclen;
266
267 if ((int)(MBLKL(mp) -
268 (hdrlen + tkip.ic_header + tkip.ic_miclen)) < 0)
269 return (0); /* dead packet */
270
271 michael_mic(ctx, k->wk_txmic, mp, (hdrlen + tkip.ic_header),
272 MBLKL(mp) -
273 (hdrlen + tkip.ic_header + tkip.ic_miclen), mic);
274 }
275 return (1);
276 }
277
278 /*
279 * Verify and strip MIC from the frame.
280 */
281 /* ARGSUSED */
282 static int
tkip_demic(struct ieee80211_key * k,mblk_t * mp,int force)283 tkip_demic(struct ieee80211_key *k, mblk_t *mp, int force)
284 {
285 struct tkip_ctx *ctx = k->wk_private;
286
287 if (force || (k->wk_flags & IEEE80211_KEY_SWMIC)) {
288 int hdrlen = ieee80211_hdrspace(ctx->tc_ic, mp->b_rptr);
289 uint8_t mic[IEEE80211_WEP_MICLEN];
290 uint8_t mic0[IEEE80211_WEP_MICLEN];
291
292 michael_mic(ctx, k->wk_rxmic,
293 mp, hdrlen,
294 MBLKL(mp) - (hdrlen + tkip.ic_miclen),
295 mic);
296 bcopy(mp->b_wptr - tkip.ic_miclen, mic0, tkip.ic_miclen);
297 if (bcmp(mic, mic0, tkip.ic_miclen)) {
298 ieee80211_dbg(IEEE80211_MSG_CRYPTO,
299 "tkip_demic() mic mismatch\n");
300 return (0);
301 }
302 }
303 /*
304 * Strip MIC from the tail.
305 */
306 mp->b_wptr -= tkip.ic_miclen;
307 /*
308 * Ok to update rsc now that MIC has been verified.
309 */
310 k->wk_keyrsc = ctx->rx_rsc;
311 return (1);
312 }
313
314 /*
315 * For the avoidance of doubt, except that if any license choice other
316 * than GPL or LGPL is available it will apply instead, Sun elects to
317 * use only the General Public License version 2 (GPLv2) at this time
318 * for any software where a choice of GPL license versions is made
319 * available with the language indicating that GPLv2 or any later
320 * version may be used, or where a choice of which version of the GPL
321 * is applied is otherwise unspecified.
322 */
323
324 /*
325 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
326 *
327 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
328 *
329 * This program is free software; you can redistribute it and/or modify
330 * it under the terms of the GNU General Public License version 2 as
331 * published by the Free Software Foundation. See README and COPYING for
332 * more details.
333 *
334 * Alternatively, this software may be distributed under the terms of BSD
335 * license.
336 */
337
338 /* Table of CRCs of all 8-bit messages */
339 static uint32_t crc_table[] = { CRC32_TABLE };
340
341 static uint16_t
RotR1(uint16_t val)342 RotR1(uint16_t val)
343 {
344 return ((val >> 1) | (val << 15));
345 }
346
347 static uint8_t
Lo8(uint16_t val)348 Lo8(uint16_t val)
349 {
350 return (val & 0xff);
351 }
352
353 static uint8_t
Hi8(uint16_t val)354 Hi8(uint16_t val)
355 {
356 return (val >> 8);
357 }
358
359 static uint16_t
Lo16(uint32_t val)360 Lo16(uint32_t val)
361 {
362 return (val & 0xffff);
363 }
364
365 static uint16_t
Hi16(uint32_t val)366 Hi16(uint32_t val)
367 {
368 return (val >> 16);
369 }
370
371 static uint16_t
Mk16(uint8_t hi,uint8_t lo)372 Mk16(uint8_t hi, uint8_t lo)
373 {
374 return (lo | (((uint16_t)hi) << 8));
375 }
376
377 static uint16_t
Mk16_le(const uint16_t * v)378 Mk16_le(const uint16_t *v)
379 {
380 return (LE_16(*v));
381 }
382
383 static const uint16_t Sbox[256] = {
384 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
385 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
386 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
387 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
388 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
389 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
390 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
391 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
392 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
393 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
394 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
395 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
396 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
397 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
398 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
399 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
400 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
401 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
402 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
403 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
404 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
405 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
406 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
407 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
408 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
409 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
410 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
411 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
412 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
413 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
414 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
415 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
416 };
417
418 static uint16_t
_S_(uint16_t v)419 _S_(uint16_t v)
420 {
421 uint16_t t = Sbox[Hi8(v)];
422 return (Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8)));
423 }
424
425 #define PHASE1_LOOP_COUNT 8
426
427 static void
tkip_mixing_phase1(uint16_t * TTAK,const uint8_t * TK,const uint8_t * TA,uint32_t IV32)428 tkip_mixing_phase1(uint16_t *TTAK, const uint8_t *TK,
429 const uint8_t *TA, uint32_t IV32)
430 {
431 int i, j;
432
433 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
434 TTAK[0] = Lo16(IV32);
435 TTAK[1] = Hi16(IV32);
436 TTAK[2] = Mk16(TA[1], TA[0]);
437 TTAK[3] = Mk16(TA[3], TA[2]);
438 TTAK[4] = Mk16(TA[5], TA[4]);
439
440 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
441 j = 2 * (i & 1);
442 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
443 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
444 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
445 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
446 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
447 }
448 }
449
450 static void
tkip_mixing_phase2(uint8_t * WEPSeed,const uint8_t * TK,const uint16_t * TTAK,uint16_t IV16)451 tkip_mixing_phase2(uint8_t *WEPSeed, const uint8_t *TK,
452 const uint16_t *TTAK, uint16_t IV16)
453 {
454 /*
455 * Make temporary area overlap WEP seed so that the final copy can be
456 * avoided on little endian hosts.
457 */
458 uint16_t *PPK = (uint16_t *)&WEPSeed[4];
459
460 /* Step 1 - make copy of TTAK and bring in TSC */
461 PPK[0] = TTAK[0];
462 PPK[1] = TTAK[1];
463 PPK[2] = TTAK[2];
464 PPK[3] = TTAK[3];
465 PPK[4] = TTAK[4];
466 PPK[5] = TTAK[4] + IV16;
467
468 /* Step 2 - 96-bit bijective mixing using S-box */
469 PPK[0] += _S_(PPK[5] ^ Mk16_le((const uint16_t *) &TK[0]));
470 PPK[1] += _S_(PPK[0] ^ Mk16_le((const uint16_t *) &TK[2]));
471 PPK[2] += _S_(PPK[1] ^ Mk16_le((const uint16_t *) &TK[4]));
472 PPK[3] += _S_(PPK[2] ^ Mk16_le((const uint16_t *) &TK[6]));
473 PPK[4] += _S_(PPK[3] ^ Mk16_le((const uint16_t *) &TK[8]));
474 PPK[5] += _S_(PPK[4] ^ Mk16_le((const uint16_t *) &TK[10]));
475
476 PPK[0] += RotR1(PPK[5] ^ Mk16_le((const uint16_t *) &TK[12]));
477 PPK[1] += RotR1(PPK[0] ^ Mk16_le((const uint16_t *) &TK[14]));
478 PPK[2] += RotR1(PPK[1]);
479 PPK[3] += RotR1(PPK[2]);
480 PPK[4] += RotR1(PPK[3]);
481 PPK[5] += RotR1(PPK[4]);
482
483 /*
484 * Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
485 * WEPSeed[0..2] is transmitted as WEP IV
486 */
487 WEPSeed[0] = Hi8(IV16);
488 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
489 WEPSeed[2] = Lo8(IV16);
490 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((const uint16_t *) &TK[0])) >> 1);
491
492 #ifdef _BIG_ENDIAN
493 int i;
494 for (i = 0; i < 6; i++)
495 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
496 #endif
497 }
498
499 static int
wep_encrypt(uint8_t * key,mblk_t * mp,uint_t off,size_t data_len,uint8_t icv[IEEE80211_WEP_CRCLEN])500 wep_encrypt(uint8_t *key, mblk_t *mp, uint_t off, size_t data_len,
501 uint8_t icv[IEEE80211_WEP_CRCLEN])
502 {
503 uint8_t crcbuf[IEEE80211_WEP_CRCLEN];
504 uint32_t crc;
505 crypto_context_t ctx;
506 int rv;
507
508 ctx = NULL;
509 rv = rc4_init(&ctx, (const uint8_t *)key, 16);
510 if (rv != CRYPTO_SUCCESS)
511 return (0);
512
513 /* calculate CRC over unencrypted data */
514 CRC32(crc, mp->b_rptr + off, data_len, -1U, crc_table);
515
516 /* encrypt data */
517 (void) rc4_crypt(ctx, mp->b_rptr + off, mp->b_rptr + off, data_len);
518
519 /* tack on ICV */
520 *(uint32_t *)crcbuf = LE_32(~crc);
521 (void) rc4_crypt(ctx, crcbuf, icv, IEEE80211_WEP_CRCLEN);
522
523 (void) rc4_final(ctx, icv, IEEE80211_WEP_CRCLEN);
524
525 return (1);
526 }
527
528 static int
wep_decrypt(uint8_t * key,mblk_t * mp,uint_t off,size_t data_len)529 wep_decrypt(uint8_t *key, mblk_t *mp, uint_t off, size_t data_len)
530 {
531 uint8_t crcbuf[IEEE80211_WEP_CRCLEN];
532 uint8_t *icv;
533 uint32_t crc;
534 crypto_context_t ctx;
535 int rv;
536
537 ctx = NULL;
538 rv = rc4_init(&ctx, (const uint8_t *)key, 16);
539 if (rv != CRYPTO_SUCCESS)
540 return (0);
541
542 /* decrypt data */
543 (void) rc4_crypt(ctx, mp->b_rptr + off, mp->b_rptr + off, data_len);
544
545 /* calculate CRC over unencrypted data */
546 CRC32(crc, mp->b_rptr + off, data_len, -1U, crc_table);
547
548 /* decrypt ICV and compare to CRC */
549 icv = mp->b_wptr - IEEE80211_WEP_CRCLEN;
550 (void) rc4_crypt(ctx, icv, crcbuf, IEEE80211_WEP_CRCLEN);
551 (void) rc4_final(ctx, crcbuf, IEEE80211_WEP_CRCLEN);
552
553 return (crc == ~LE_32(*(uint32_t *)crcbuf));
554 }
555
556 static uint32_t
rotl(uint32_t val,int bits)557 rotl(uint32_t val, int bits)
558 {
559 return ((val << bits) | (val >> (32 - bits)));
560 }
561
562
563 static uint32_t
rotr(uint32_t val,int bits)564 rotr(uint32_t val, int bits)
565 {
566 return ((val >> bits) | (val << (32 - bits)));
567 }
568
569
570 static uint32_t
xswap(uint32_t val)571 xswap(uint32_t val)
572 {
573 return (((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8));
574 }
575
576
577 #define michael_block(l, r) \
578 do { \
579 r ^= rotl(l, 17); \
580 l += r; \
581 r ^= xswap(l); \
582 l += r; \
583 r ^= rotl(l, 3); \
584 l += r; \
585 r ^= rotr(l, 2); \
586 l += r; \
587 _NOTE(CONSTANTCONDITION)\
588 } while (0)
589
590
591 static uint32_t
get_le32_split(uint8_t b0,uint8_t b1,uint8_t b2,uint8_t b3)592 get_le32_split(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3)
593 {
594 return (b0 | (b1 << 8) | (b2 << 16) | (b3 << 24));
595 }
596
597 static uint32_t
get_le32(const uint8_t * p)598 get_le32(const uint8_t *p)
599 {
600 return (get_le32_split(p[0], p[1], p[2], p[3]));
601 }
602
603
604 static void
put_le32(uint8_t * p,uint32_t v)605 put_le32(uint8_t *p, uint32_t v)
606 {
607 p[0] = (uint8_t)v;
608 p[1] = v >> 8;
609 p[2] = v >> 16;
610 p[3] = v >> 24;
611 }
612
613 /*
614 * Craft pseudo header used to calculate the MIC.
615 */
616 static void
michael_mic_hdr(const struct ieee80211_frame * wh0,uint8_t hdr[16])617 michael_mic_hdr(const struct ieee80211_frame *wh0, uint8_t hdr[16])
618 {
619 const struct ieee80211_frame_addr4 *wh =
620 (const struct ieee80211_frame_addr4 *)wh0;
621
622 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
623 case IEEE80211_FC1_DIR_NODS:
624 IEEE80211_ADDR_COPY(hdr, wh->i_addr1); /* DA */
625 IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr2);
626 break;
627 case IEEE80211_FC1_DIR_TODS:
628 IEEE80211_ADDR_COPY(hdr, wh->i_addr3); /* DA */
629 IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr2);
630 break;
631 case IEEE80211_FC1_DIR_FROMDS:
632 IEEE80211_ADDR_COPY(hdr, wh->i_addr1); /* DA */
633 IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr3);
634 break;
635 case IEEE80211_FC1_DIR_DSTODS:
636 IEEE80211_ADDR_COPY(hdr, wh->i_addr3); /* DA */
637 IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr4);
638 break;
639 }
640
641 if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
642 const struct ieee80211_qosframe *qwh =
643 (const struct ieee80211_qosframe *)wh;
644 hdr[12] = qwh->i_qos[0] & IEEE80211_QOS_TID;
645 } else
646 hdr[12] = 0;
647 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
648 }
649
650 /* ARGSUSED */
651 static void
michael_mic(struct tkip_ctx * ctx,const uint8_t * key,mblk_t * mp,uint_t off,size_t data_len,uint8_t mic[IEEE80211_WEP_MICLEN])652 michael_mic(struct tkip_ctx *ctx, const uint8_t *key,
653 mblk_t *mp, uint_t off, size_t data_len,
654 uint8_t mic[IEEE80211_WEP_MICLEN])
655 {
656 uint8_t hdr[16];
657 uint32_t l, r;
658 const uint8_t *data;
659 int i, blocks, last;
660
661 michael_mic_hdr((struct ieee80211_frame *)mp->b_rptr, hdr);
662
663 l = get_le32(key);
664 r = get_le32(key + 4);
665
666 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
667 l ^= get_le32(hdr);
668 michael_block(l, r);
669 l ^= get_le32(&hdr[4]);
670 michael_block(l, r);
671 l ^= get_le32(&hdr[8]);
672 michael_block(l, r);
673 l ^= get_le32(&hdr[12]);
674 michael_block(l, r);
675
676 /* first buffer has special handling */
677 data = mp->b_rptr + off;
678
679 blocks = data_len / 4;
680 last = data_len % 4;
681
682 for (i = 0; i < blocks; i++) {
683 l ^= get_le32(&data[4 * i]);
684 michael_block(l, r);
685 }
686
687 /* Last block and padding (0x5a, 4..7 x 0) */
688 switch (last) {
689 case 0:
690 l ^= 0x5a;
691 break;
692 case 1:
693 l ^= data[4 * i] | 0x5a00;
694 break;
695 case 2:
696 l ^= data[4 * i] | (data[4 * i + 1] << 8) | 0x5a0000;
697 break;
698 case 3:
699 l ^= data[4 * i] | (data[4 * i + 1] << 8) |
700 (data[4 * i + 2] << 16) | 0x5a000000;
701 break;
702 }
703 michael_block(l, r);
704 /* l ^= 0; */
705 michael_block(l, r);
706
707 put_le32(mic, l);
708 put_le32(mic + 4, r);
709 }
710
711 static int
tkip_encrypt(struct tkip_ctx * ctx,struct ieee80211_key * key,mblk_t * mp,int hdrlen)712 tkip_encrypt(struct tkip_ctx *ctx, struct ieee80211_key *key,
713 mblk_t *mp, int hdrlen)
714 {
715 struct ieee80211_frame *wh;
716 uint8_t *icv;
717
718 wh = (struct ieee80211_frame *)mp->b_rptr;
719 if (!ctx->tx_phase1_done) {
720 tkip_mixing_phase1(ctx->tx_ttak, key->wk_key, wh->i_addr2,
721 (uint32_t)(key->wk_keytsc >> 16));
722 ctx->tx_phase1_done = 1;
723 }
724 tkip_mixing_phase2(ctx->tx_rc4key, key->wk_key, ctx->tx_ttak,
725 (uint16_t)key->wk_keytsc);
726
727 icv = mp->b_wptr;
728 mp->b_wptr += tkip.ic_trailer;
729
730 (void) wep_encrypt(ctx->tx_rc4key,
731 mp, hdrlen + tkip.ic_header,
732 MBLKL(mp) -
733 (hdrlen + tkip.ic_header + tkip.ic_trailer),
734 icv);
735
736 key->wk_keytsc++;
737 if ((uint16_t)(key->wk_keytsc) == 0)
738 ctx->tx_phase1_done = 0;
739 return (1);
740 }
741
742 static int
tkip_decrypt(struct tkip_ctx * ctx,struct ieee80211_key * key,mblk_t * mp,int hdrlen)743 tkip_decrypt(struct tkip_ctx *ctx, struct ieee80211_key *key,
744 mblk_t *mp, int hdrlen)
745 {
746 struct ieee80211_frame *wh;
747 uint32_t iv32;
748 uint16_t iv16;
749
750 wh = (struct ieee80211_frame *)mp->b_rptr;
751 /* tkip_decap already verified header and left seq in rx_rsc */
752 iv16 = (uint16_t)ctx->rx_rsc;
753 iv32 = (uint32_t)(ctx->rx_rsc >> 16);
754
755 if (iv32 != (uint32_t)(key->wk_keyrsc >> 16) || !ctx->rx_phase1_done) {
756 tkip_mixing_phase1(ctx->rx_ttak, key->wk_key,
757 wh->i_addr2, iv32);
758 ctx->rx_phase1_done = 0; /* DHCP */
759 }
760 tkip_mixing_phase2(ctx->rx_rc4key, key->wk_key, ctx->rx_ttak, iv16);
761
762 /* m is unstripped; deduct headers + ICV to get payload */
763 if (!wep_decrypt(ctx->rx_rc4key,
764 mp, hdrlen + tkip.ic_header,
765 MBLKL(mp) -
766 (hdrlen + tkip.ic_header + tkip.ic_trailer))) {
767 if (iv32 != (uint32_t)(key->wk_keyrsc >> 16)) {
768 /*
769 * Previously cached Phase1 result was already lost, so
770 * it needs to be recalculated for the next packet.
771 */
772 ctx->rx_phase1_done = 0;
773 }
774 ieee80211_dbg(IEEE80211_MSG_CRYPTO, "tkip_decrypt() error\n");
775 return (0);
776 }
777 return (1);
778 }
779