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