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_wep.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 /*      $NetBSD: ieee80211_crypto_wep.c,v 1.13 2020/11/03 15:06:50 mlelstv Exp $        */
    2 
    3 /*
    4  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. The name of the author may not be used to endorse or promote products
   16  *    derived from this software without specific prior written permission.
   17  *
   18  * Alternatively, this software may be distributed under the terms of the
   19  * GNU General Public License ("GPL") version 2 as published by the Free
   20  * Software Foundation.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 #ifdef __FreeBSD__
   36 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_wep.c,v 1.7 2005/06/10 16:11:24 sam Exp $");
   37 #endif
   38 #ifdef __NetBSD__
   39 __KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_wep.c,v 1.13 2020/11/03 15:06:50 mlelstv Exp $");
   40 #endif
   41 
   42 /*
   43  * IEEE 802.11 WEP crypto support.
   44  */
   45 #include <sys/param.h>
   46 #include <sys/systm.h>
   47 #include <sys/mbuf.h>
   48 #include <sys/kmem.h>
   49 #include <sys/kernel.h>
   50 #include <sys/endian.h>
   51 
   52 #include <sys/socket.h>
   53 
   54 #include <net/if.h>
   55 #include <net/if_ether.h>
   56 #include <net/if_media.h>
   57 
   58 #include <net80211/ieee80211_var.h>
   59 
   60 static  void *wep_attach(struct ieee80211com *, struct ieee80211_key *);
   61 static  void wep_detach(struct ieee80211_key *);
   62 static  int wep_setkey(struct ieee80211_key *);
   63 static  int wep_encap(struct ieee80211_key *, struct mbuf *, u_int8_t keyid);
   64 static  int wep_decap(struct ieee80211_key *, struct mbuf *, int hdrlen);
   65 static  int wep_enmic(struct ieee80211_key *, struct mbuf *, int);
   66 static  int wep_demic(struct ieee80211_key *, struct mbuf *, int);
   67 
   68 const struct ieee80211_cipher ieee80211_cipher_wep = {
   69         .ic_name        = "WEP",
   70         .ic_cipher      = IEEE80211_CIPHER_WEP,
   71         .ic_header      = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN,
   72         .ic_trailer     = IEEE80211_WEP_CRCLEN,
   73         .ic_miclen      = 0,
   74         .ic_attach      = wep_attach,
   75         .ic_detach      = wep_detach,
   76         .ic_setkey      = wep_setkey,
   77         .ic_encap       = wep_encap,
   78         .ic_decap       = wep_decap,
   79         .ic_enmic       = wep_enmic,
   80         .ic_demic       = wep_demic,
   81 };
   82 
   83 #define wep     ieee80211_cipher_wep
   84 
   85 static  int wep_encrypt(struct ieee80211_key *, struct mbuf *, int hdrlen);
   86 static  int wep_decrypt(struct ieee80211_key *, struct mbuf *, int hdrlen);
   87 
   88 struct wep_ctx {
   89         struct ieee80211com *wc_ic;     /* for diagnostics */
   90         u_int32_t       wc_iv;          /* initial vector for crypto */
   91 };
   92 
   93 static void *
   94 wep_attach(struct ieee80211com *ic, struct ieee80211_key *k)
   95 {
   96         struct wep_ctx *ctx;
   97 
   98         ctx = kmem_intr_zalloc(sizeof(struct wep_ctx), KM_NOSLEEP);
   99         if (ctx == NULL) {
  100                 ic->ic_stats.is_crypto_nomem++;
  101                 return NULL;
  102         }
  103 
  104         ctx->wc_ic = ic;
  105         get_random_bytes(&ctx->wc_iv, sizeof(ctx->wc_iv));
  106         return ctx;
  107 }
  108 
  109 static void
  110 wep_detach(struct ieee80211_key *k)
  111 {
  112         struct wep_ctx *ctx = k->wk_private;
  113 
  114         kmem_intr_free(ctx, sizeof(struct wep_ctx));
  115 }
  116 
  117 static int
  118 wep_setkey(struct ieee80211_key *k)
  119 {
  120         return k->wk_keylen >= 40/NBBY;
  121 }
  122 
  123 /*
  124  * Add privacy headers appropriate for the specified key.
  125  */
  126 static int
  127 wep_encap(struct ieee80211_key *k, struct mbuf *m, u_int8_t keyid)
  128 {
  129         struct wep_ctx *ctx = k->wk_private;
  130         struct ieee80211com *ic = ctx->wc_ic;
  131         u_int32_t iv;
  132         u_int8_t *ivp;
  133         int hdrlen;
  134 
  135         hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
  136         ivp = mtod(m, u_int8_t *) + hdrlen;
  137 
  138         /*
  139          * XXX
  140          * IV must not duplicate during the lifetime of the key.
  141          * But no mechanism to renew keys is defined in IEEE 802.11
  142          * for WEP.  And the IV may be duplicated at other stations
  143          * because the session key itself is shared.  So we use a
  144          * pseudo random IV for now, though it is not the right way.
  145          *
  146          * NB: Rather than use a strictly random IV we select a
  147          * random one to start and then increment the value for
  148          * each frame.  This is an explicit tradeoff between
  149          * overhead and security.  Given the basic insecurity of
  150          * WEP this seems worthwhile.
  151          */
  152 
  153         /*
  154          * Skip 'bad' IVs from Fluhrer/Mantin/Shamir:
  155          * (B, 255, N) with 3 <= B < 16 and 0 <= N <= 255
  156          */
  157         iv = ctx->wc_iv;
  158         if ((iv & 0xff00) == 0xff00) {
  159                 int B = (iv & 0xff0000) >> 16;
  160                 if (3 <= B && B < 16)
  161                         iv += 0x0100;
  162         }
  163         ctx->wc_iv = iv + 1;
  164 
  165         /*
  166          * NB: Preserve byte order of IV for packet
  167          *     sniffers; it doesn't matter otherwise.
  168          */
  169 #if _BYTE_ORDER == _BIG_ENDIAN
  170         ivp[0] = iv >> 0;
  171         ivp[1] = iv >> 8;
  172         ivp[2] = iv >> 16;
  173 #else
  174         ivp[2] = iv >> 0;
  175         ivp[1] = iv >> 8;
  176         ivp[0] = iv >> 16;
  177 #endif
  178         ivp[3] = keyid;
  179 
  180         /*
  181          * Finally, do software encrypt if neeed.
  182          */
  183         if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) &&
  184             !wep_encrypt(k, m, hdrlen))
  185                 return 0;
  186 
  187         return 1;
  188 }
  189 
  190 /*
  191  * Add MIC to the frame as needed.
  192  */
  193 static int
  194 wep_enmic(struct ieee80211_key *k, struct mbuf *m, int force)
  195 {
  196 
  197         return 1;
  198 }
  199 
  200 /*
  201  * Validate and strip privacy headers (and trailer) for a
  202  * received frame.  If necessary, decrypt the frame using
  203  * the specified key.
  204  */
  205 static int
  206 wep_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
  207 {
  208         struct wep_ctx *ctx = k->wk_private;
  209         struct ieee80211_frame *wh;
  210 
  211         wh = mtod(m, struct ieee80211_frame *);
  212 
  213         /*
  214          * Check if the device handled the decrypt in hardware.
  215          * If so we just strip the header; otherwise we need to
  216          * handle the decrypt in software.
  217          */
  218         if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) &&
  219             !wep_decrypt(k, m, hdrlen)) {
  220                 IEEE80211_DPRINTF(ctx->wc_ic, IEEE80211_MSG_CRYPTO,
  221                     "[%s] WEP ICV mismatch on decrypt\n",
  222                     ether_sprintf(wh->i_addr2));
  223                 ctx->wc_ic->ic_stats.is_rx_wepfail++;
  224                 return 0;
  225         }
  226 
  227         /*
  228          * Copy up 802.11 header and strip crypto bits.
  229          */
  230         memmove(mtod(m, u_int8_t *) + wep.ic_header, mtod(m, void *), hdrlen);
  231         m_adj(m, wep.ic_header);
  232         m_adj(m, -wep.ic_trailer);
  233 
  234         return 1;
  235 }
  236 
  237 /*
  238  * Verify and strip MIC from the frame.
  239  */
  240 static int
  241 wep_demic(struct ieee80211_key *k, struct mbuf *skb,
  242     int force)
  243 {
  244         return 1;
  245 }
  246 
  247 static const uint32_t crc32_table[256] = {
  248         0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
  249         0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
  250         0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
  251         0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  252         0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
  253         0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
  254         0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
  255         0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
  256         0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
  257         0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
  258         0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
  259         0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  260         0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
  261         0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
  262         0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
  263         0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
  264         0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
  265         0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
  266         0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
  267         0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  268         0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
  269         0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
  270         0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
  271         0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
  272         0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
  273         0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
  274         0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
  275         0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  276         0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
  277         0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
  278         0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
  279         0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
  280         0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
  281         0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
  282         0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
  283         0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
  284         0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
  285         0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
  286         0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
  287         0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
  288         0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
  289         0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
  290         0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
  291         0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
  292         0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
  293         0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
  294         0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
  295         0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
  296         0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
  297         0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
  298         0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
  299         0x2d02ef8dL
  300 };
  301 
  302 static int
  303 wep_encrypt(struct ieee80211_key *key, struct mbuf *m0, int hdrlen)
  304 {
  305 #define S_SWAP(a,b) do { uint8_t t = S[a]; S[a] = S[b]; S[b] = t; } while(0)
  306         struct wep_ctx *ctx = key->wk_private;
  307         struct mbuf *m = m0;
  308         u_int8_t rc4key[IEEE80211_WEP_IVLEN + IEEE80211_KEYBUF_SIZE];
  309         uint8_t icv[IEEE80211_WEP_CRCLEN];
  310         uint32_t i, j, k, crc;
  311         size_t buflen, data_len;
  312         uint8_t S[256];
  313         uint8_t *pos;
  314         u_int off, keylen;
  315 
  316         ctx->wc_ic->ic_stats.is_crypto_wep++;
  317 
  318         /*
  319          * NB: this assumes the header was pulled up; it was done in
  320          * ieee80211_crypto_encap().
  321          */
  322         memcpy(rc4key, mtod(m, u_int8_t *) + hdrlen, IEEE80211_WEP_IVLEN);
  323         memcpy(rc4key + IEEE80211_WEP_IVLEN, key->wk_key, key->wk_keylen);
  324 
  325         /* Setup RC4 state */
  326         for (i = 0; i < 256; i++)
  327                 S[i] = i;
  328         j = 0;
  329         keylen = key->wk_keylen + IEEE80211_WEP_IVLEN;
  330         for (i = 0; i < 256; i++) {
  331                 j = (j + S[i] + rc4key[i % keylen]) & 0xff;
  332                 S_SWAP(i, j);
  333         }
  334 
  335         off = hdrlen + wep.ic_header;
  336         data_len = m->m_pkthdr.len - off;
  337 
  338         /* Compute CRC32 over unencrypted data and apply RC4 to data */
  339         crc = ~0;
  340         i = j = 0;
  341         pos = mtod(m, uint8_t *) + off;
  342         buflen = m->m_len - off;
  343         for (;;) {
  344                 if (buflen > data_len)
  345                         buflen = data_len;
  346                 data_len -= buflen;
  347                 for (k = 0; k < buflen; k++) {
  348                         crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8);
  349                         i = (i + 1) & 0xff;
  350                         j = (j + S[i]) & 0xff;
  351                         S_SWAP(i, j);
  352                         *pos++ ^= S[(S[i] + S[j]) & 0xff];
  353                 }
  354                 if (m->m_next == NULL) {
  355                         if (data_len != 0) {            /* out of data */
  356                                 IEEE80211_DPRINTF(ctx->wc_ic,
  357                                     IEEE80211_MSG_CRYPTO,
  358                                     "[%s] out of data for WEP (data_len %zu)\n",
  359                                     ether_sprintf(mtod(m0,
  360                                         struct ieee80211_frame *)->i_addr2),
  361                                     data_len);
  362                                 return 0;
  363                         }
  364                         break;
  365                 }
  366                 m = m->m_next;
  367                 pos = mtod(m, uint8_t *);
  368                 buflen = m->m_len;
  369         }
  370         crc = ~crc;
  371 
  372         /* Append little-endian CRC32 and encrypt it to produce ICV */
  373         icv[0] = crc;
  374         icv[1] = crc >> 8;
  375         icv[2] = crc >> 16;
  376         icv[3] = crc >> 24;
  377         for (k = 0; k < IEEE80211_WEP_CRCLEN; k++) {
  378                 i = (i + 1) & 0xff;
  379                 j = (j + S[i]) & 0xff;
  380                 S_SWAP(i, j);
  381                 icv[k] ^= S[(S[i] + S[j]) & 0xff];
  382         }
  383         return m_append(m0, IEEE80211_WEP_CRCLEN, icv);
  384 #undef S_SWAP
  385 }
  386 
  387 static int
  388 wep_decrypt(struct ieee80211_key *key, struct mbuf *m0, int hdrlen)
  389 {
  390 #define S_SWAP(a,b) do { uint8_t t = S[a]; S[a] = S[b]; S[b] = t; } while(0)
  391         struct wep_ctx *ctx = key->wk_private;
  392         struct mbuf *m = m0;
  393         u_int8_t rc4key[IEEE80211_WEP_IVLEN + IEEE80211_KEYBUF_SIZE];
  394         uint8_t icv[IEEE80211_WEP_CRCLEN];
  395         uint32_t i, j, k, crc;
  396         size_t buflen, data_len;
  397         uint8_t S[256];
  398         uint8_t *pos;
  399         u_int off, keylen;
  400 
  401         ctx->wc_ic->ic_stats.is_crypto_wep++;
  402 
  403         /* NB: this assumes the header was pulled up */
  404         memcpy(rc4key, mtod(m, u_int8_t *) + hdrlen, IEEE80211_WEP_IVLEN);
  405         memcpy(rc4key + IEEE80211_WEP_IVLEN, key->wk_key, key->wk_keylen);
  406 
  407         /* Setup RC4 state */
  408         for (i = 0; i < 256; i++)
  409                 S[i] = i;
  410         j = 0;
  411         keylen = key->wk_keylen + IEEE80211_WEP_IVLEN;
  412         for (i = 0; i < 256; i++) {
  413                 j = (j + S[i] + rc4key[i % keylen]) & 0xff;
  414                 S_SWAP(i, j);
  415         }
  416 
  417         off = hdrlen + wep.ic_header;
  418         data_len = m->m_pkthdr.len - (off + wep.ic_trailer);
  419 
  420         /* Compute CRC32 over unencrypted data and apply RC4 to data */
  421         crc = ~0;
  422         i = j = 0;
  423         pos = mtod(m, uint8_t *) + off;
  424         buflen = m->m_len - off;
  425         for (;;) {
  426                 if (buflen > data_len)
  427                         buflen = data_len;
  428                 data_len -= buflen;
  429                 for (k = 0; k < buflen; k++) {
  430                         i = (i + 1) & 0xff;
  431                         j = (j + S[i]) & 0xff;
  432                         S_SWAP(i, j);
  433                         *pos ^= S[(S[i] + S[j]) & 0xff];
  434                         crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8);
  435                         pos++;
  436                 }
  437                 m = m->m_next;
  438                 if (m == NULL) {
  439                         if (data_len != 0) {            /* out of data */
  440                                 IEEE80211_DPRINTF(ctx->wc_ic,
  441                                     IEEE80211_MSG_CRYPTO,
  442                                     "[%s] out of data for WEP (data_len %zu)\n",
  443                                     ether_sprintf(mtod(m0,
  444                                         struct ieee80211_frame *)->i_addr2),
  445                                     data_len);
  446                                 return 0;
  447                         }
  448                         break;
  449                 }
  450                 pos = mtod(m, uint8_t *);
  451                 buflen = m->m_len;
  452         }
  453         crc = ~crc;
  454 
  455         /*
  456          * Encrypt little-endian CRC32 and verify that it matches with
  457          * received ICV
  458          */
  459         icv[0] = crc;
  460         icv[1] = crc >> 8;
  461         icv[2] = crc >> 16;
  462         icv[3] = crc >> 24;
  463         for (k = 0; k < IEEE80211_WEP_CRCLEN; k++) {
  464                 i = (i + 1) & 0xff;
  465                 j = (j + S[i]) & 0xff;
  466                 S_SWAP(i, j);
  467                 /* XXX assumes ICV is contiguous in mbuf */
  468                 if ((icv[k] ^ S[(S[i] + S[j]) & 0xff]) != *pos++) {
  469                         /* ICV mismatch - drop frame */
  470                         return 0;
  471                 }
  472         }
  473         return 1;
  474 #undef S_SWAP
  475 }
  476 
  477 IEEE80211_CRYPTO_SETUP(wep_register)
  478 {
  479         ieee80211_crypto_register(&wep);
  480 }

Cache object: 310fa3bfb1ed41aa9490f218ef0b128e


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