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

Cache object: d9e2d6b036eb200ce6193861950cbd76


[ 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.