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 *
 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
 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
 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
 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
 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
 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
 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
 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
 342 RotR1(uint16_t val)
 343 {
 344         return ((val >> 1) | (val << 15));
 345 }
 346 
 347 static uint8_t
 348 Lo8(uint16_t val)
 349 {
 350         return (val & 0xff);
 351 }
 352 
 353 static uint8_t
 354 Hi8(uint16_t val)
 355 {
 356         return (val >> 8);
 357 }
 358 
 359 static uint16_t
 360 Lo16(uint32_t val)
 361 {
 362         return (val & 0xffff);
 363 }
 364 
 365 static uint16_t
 366 Hi16(uint32_t val)
 367 {
 368         return (val >> 16);
 369 }
 370 
 371 static uint16_t
 372 Mk16(uint8_t hi, uint8_t lo)
 373 {
 374         return (lo | (((uint16_t)hi) << 8));
 375 }
 376 
 377 static uint16_t
 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
 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
 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
 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
 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
 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
 557 rotl(uint32_t val, int bits)
 558 {
 559         return ((val << bits) | (val >> (32 - bits)));
 560 }
 561 
 562 
 563 static uint32_t
 564 rotr(uint32_t val, int bits)
 565 {
 566         return ((val >> bits) | (val << (32 - bits)));
 567 }
 568 
 569 
 570 static uint32_t
 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
 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
 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
 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
 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
 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
 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
 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 }