The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net80211/ieee80211_crypto_tkip.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

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

Cache object: f7217d94066cc2b6b0fd630497b3f9b9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.