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.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) 2001 Atsushi Onoe
    3  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. The name of the author may not be used to endorse or promote products
   15  *    derived from this software without specific prior written permission.
   16  *
   17  * Alternatively, this software may be distributed under the terms of the
   18  * GNU General Public License ("GPL") version 2 as published by the Free
   19  * Software Foundation.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD: releng/6.2/sys/net80211/ieee80211_crypto.c 149772 2005-09-03 22:40:02Z sam $");
   35 
   36 /*
   37  * IEEE 802.11 generic crypto support.
   38  */
   39 #include <sys/param.h>
   40 #include <sys/mbuf.h>   
   41 
   42 #include <sys/socket.h>
   43 
   44 #include <net/if.h>
   45 #include <net/if_media.h>
   46 #include <net/ethernet.h>               /* XXX ETHER_HDR_LEN */
   47 
   48 #include <net80211/ieee80211_var.h>
   49 
   50 /*
   51  * Table of registered cipher modules.
   52  */
   53 static  const struct ieee80211_cipher *ciphers[IEEE80211_CIPHER_MAX];
   54 
   55 static  int _ieee80211_crypto_delkey(struct ieee80211com *,
   56                 struct ieee80211_key *);
   57 
   58 /*
   59  * Default "null" key management routines.
   60  */
   61 static int
   62 null_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *k,
   63         ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
   64 {
   65         if (!(&ic->ic_nw_keys[0] <= k &&
   66              k < &ic->ic_nw_keys[IEEE80211_WEP_NKID])) {
   67                 /*
   68                  * Not in the global key table, the driver should handle this
   69                  * by allocating a slot in the h/w key table/cache.  In
   70                  * lieu of that return key slot 0 for any unicast key
   71                  * request.  We disallow the request if this is a group key.
   72                  * This default policy does the right thing for legacy hardware
   73                  * with a 4 key table.  It also handles devices that pass
   74                  * packets through untouched when marked with the WEP bit
   75                  * and key index 0.
   76                  */
   77                 if (k->wk_flags & IEEE80211_KEY_GROUP)
   78                         return 0;
   79                 *keyix = 0;     /* NB: use key index 0 for ucast key */
   80         } else {
   81                 *keyix = k - ic->ic_nw_keys;
   82         }
   83         *rxkeyix = IEEE80211_KEYIX_NONE;        /* XXX maybe *keyix? */
   84         return 1;
   85 }
   86 static int
   87 null_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k)
   88 {
   89         return 1;
   90 }
   91 static  int
   92 null_key_set(struct ieee80211com *ic, const struct ieee80211_key *k,
   93              const u_int8_t mac[IEEE80211_ADDR_LEN])
   94 {
   95         return 1;
   96 }
   97 static void null_key_update(struct ieee80211com *ic) {}
   98 
   99 /*
  100  * Write-arounds for common operations.
  101  */
  102 static __inline void
  103 cipher_detach(struct ieee80211_key *key)
  104 {
  105         key->wk_cipher->ic_detach(key);
  106 }
  107 
  108 static __inline void *
  109 cipher_attach(struct ieee80211com *ic, struct ieee80211_key *key)
  110 {
  111         return key->wk_cipher->ic_attach(ic, key);
  112 }
  113 
  114 /* 
  115  * Wrappers for driver key management methods.
  116  */
  117 static __inline int
  118 dev_key_alloc(struct ieee80211com *ic,
  119         const struct ieee80211_key *key,
  120         ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
  121 {
  122         return ic->ic_crypto.cs_key_alloc(ic, key, keyix, rxkeyix);
  123 }
  124 
  125 static __inline int
  126 dev_key_delete(struct ieee80211com *ic,
  127         const struct ieee80211_key *key)
  128 {
  129         return ic->ic_crypto.cs_key_delete(ic, key);
  130 }
  131 
  132 static __inline int
  133 dev_key_set(struct ieee80211com *ic, const struct ieee80211_key *key,
  134         const u_int8_t mac[IEEE80211_ADDR_LEN])
  135 {
  136         return ic->ic_crypto.cs_key_set(ic, key, mac);
  137 }
  138 
  139 /*
  140  * Setup crypto support.
  141  */
  142 void
  143 ieee80211_crypto_attach(struct ieee80211com *ic)
  144 {
  145         struct ieee80211_crypto_state *cs = &ic->ic_crypto;
  146         int i;
  147 
  148         /* NB: we assume everything is pre-zero'd */
  149         cs->cs_def_txkey = IEEE80211_KEYIX_NONE;
  150         cs->cs_max_keyix = IEEE80211_WEP_NKID;
  151         ciphers[IEEE80211_CIPHER_NONE] = &ieee80211_cipher_none;
  152         for (i = 0; i < IEEE80211_WEP_NKID; i++)
  153                 ieee80211_crypto_resetkey(ic, &cs->cs_nw_keys[i],
  154                         IEEE80211_KEYIX_NONE);
  155         /*
  156          * Initialize the driver key support routines to noop entries.
  157          * This is useful especially for the cipher test modules.
  158          */
  159         cs->cs_key_alloc = null_key_alloc;
  160         cs->cs_key_set = null_key_set;
  161         cs->cs_key_delete = null_key_delete;
  162         cs->cs_key_update_begin = null_key_update;
  163         cs->cs_key_update_end = null_key_update;
  164 }
  165 
  166 /*
  167  * Teardown crypto support.
  168  */
  169 void
  170 ieee80211_crypto_detach(struct ieee80211com *ic)
  171 {
  172         ieee80211_crypto_delglobalkeys(ic);
  173 }
  174 
  175 /*
  176  * Register a crypto cipher module.
  177  */
  178 void
  179 ieee80211_crypto_register(const struct ieee80211_cipher *cip)
  180 {
  181         if (cip->ic_cipher >= IEEE80211_CIPHER_MAX) {
  182                 printf("%s: cipher %s has an invalid cipher index %u\n",
  183                         __func__, cip->ic_name, cip->ic_cipher);
  184                 return;
  185         }
  186         if (ciphers[cip->ic_cipher] != NULL && ciphers[cip->ic_cipher] != cip) {
  187                 printf("%s: cipher %s registered with a different template\n",
  188                         __func__, cip->ic_name);
  189                 return;
  190         }
  191         ciphers[cip->ic_cipher] = cip;
  192 }
  193 
  194 /*
  195  * Unregister a crypto cipher module.
  196  */
  197 void
  198 ieee80211_crypto_unregister(const struct ieee80211_cipher *cip)
  199 {
  200         if (cip->ic_cipher >= IEEE80211_CIPHER_MAX) {
  201                 printf("%s: cipher %s has an invalid cipher index %u\n",
  202                         __func__, cip->ic_name, cip->ic_cipher);
  203                 return;
  204         }
  205         if (ciphers[cip->ic_cipher] != NULL && ciphers[cip->ic_cipher] != cip) {
  206                 printf("%s: cipher %s registered with a different template\n",
  207                         __func__, cip->ic_name);
  208                 return;
  209         }
  210         /* NB: don't complain about not being registered */
  211         /* XXX disallow if references */
  212         ciphers[cip->ic_cipher] = NULL;
  213 }
  214 
  215 int
  216 ieee80211_crypto_available(u_int cipher)
  217 {
  218         return cipher < IEEE80211_CIPHER_MAX && ciphers[cipher] != NULL;
  219 }
  220 
  221 /* XXX well-known names! */
  222 static const char *cipher_modnames[] = {
  223         "wlan_wep",     /* IEEE80211_CIPHER_WEP */
  224         "wlan_tkip",    /* IEEE80211_CIPHER_TKIP */
  225         "wlan_aes_ocb", /* IEEE80211_CIPHER_AES_OCB */
  226         "wlan_ccmp",    /* IEEE80211_CIPHER_AES_CCM */
  227         "wlan_ckip",    /* IEEE80211_CIPHER_CKIP */
  228 };
  229 
  230 /*
  231  * Establish a relationship between the specified key and cipher
  232  * and, if necessary, allocate a hardware index from the driver.
  233  * Note that when a fixed key index is required it must be specified
  234  * and we blindly assign it w/o consulting the driver (XXX).
  235  *
  236  * This must be the first call applied to a key; all the other key
  237  * routines assume wk_cipher is setup.
  238  *
  239  * Locking must be handled by the caller using:
  240  *      ieee80211_key_update_begin(ic);
  241  *      ieee80211_key_update_end(ic);
  242  */
  243 int
  244 ieee80211_crypto_newkey(struct ieee80211com *ic,
  245         int cipher, int flags, struct ieee80211_key *key)
  246 {
  247 #define N(a)    (sizeof(a) / sizeof(a[0]))
  248         const struct ieee80211_cipher *cip;
  249         ieee80211_keyix keyix, rxkeyix;
  250         void *keyctx;
  251         int oflags;
  252 
  253         /*
  254          * Validate cipher and set reference to cipher routines.
  255          */
  256         if (cipher >= IEEE80211_CIPHER_MAX) {
  257                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  258                         "%s: invalid cipher %u\n", __func__, cipher);
  259                 ic->ic_stats.is_crypto_badcipher++;
  260                 return 0;
  261         }
  262         cip = ciphers[cipher];
  263         if (cip == NULL) {
  264                 /*
  265                  * Auto-load cipher module if we have a well-known name
  266                  * for it.  It might be better to use string names rather
  267                  * than numbers and craft a module name based on the cipher
  268                  * name; e.g. wlan_cipher_<cipher-name>.
  269                  */
  270                 if (cipher < N(cipher_modnames)) {
  271                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  272                                 "%s: unregistered cipher %u, load module %s\n",
  273                                 __func__, cipher, cipher_modnames[cipher]);
  274                         ieee80211_load_module(cipher_modnames[cipher]);
  275                         /*
  276                          * If cipher module loaded it should immediately
  277                          * call ieee80211_crypto_register which will fill
  278                          * in the entry in the ciphers array.
  279                          */
  280                         cip = ciphers[cipher];
  281                 }
  282                 if (cip == NULL) {
  283                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  284                                 "%s: unable to load cipher %u, module %s\n",
  285                                 __func__, cipher,
  286                                 cipher < N(cipher_modnames) ?
  287                                         cipher_modnames[cipher] : "<unknown>");
  288                         ic->ic_stats.is_crypto_nocipher++;
  289                         return 0;
  290                 }
  291         }
  292 
  293         oflags = key->wk_flags;
  294         flags &= IEEE80211_KEY_COMMON;
  295         /*
  296          * If the hardware does not support the cipher then
  297          * fallback to a host-based implementation.
  298          */
  299         if ((ic->ic_caps & (1<<cipher)) == 0) {
  300                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  301                     "%s: no h/w support for cipher %s, falling back to s/w\n",
  302                     __func__, cip->ic_name);
  303                 flags |= IEEE80211_KEY_SWCRYPT;
  304         }
  305         /*
  306          * Hardware TKIP with software MIC is an important
  307          * combination; we handle it by flagging each key,
  308          * the cipher modules honor it.
  309          */
  310         if (cipher == IEEE80211_CIPHER_TKIP &&
  311             (ic->ic_caps & IEEE80211_C_TKIPMIC) == 0) {
  312                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  313                     "%s: no h/w support for TKIP MIC, falling back to s/w\n",
  314                     __func__);
  315                 flags |= IEEE80211_KEY_SWMIC;
  316         }
  317 
  318         /*
  319          * Bind cipher to key instance.  Note we do this
  320          * after checking the device capabilities so the
  321          * cipher module can optimize space usage based on
  322          * whether or not it needs to do the cipher work.
  323          */
  324         if (key->wk_cipher != cip || key->wk_flags != flags) {
  325 again:
  326                 /*
  327                  * Fillin the flags so cipher modules can see s/w
  328                  * crypto requirements and potentially allocate
  329                  * different state and/or attach different method
  330                  * pointers.
  331                  *
  332                  * XXX this is not right when s/w crypto fallback
  333                  *     fails and we try to restore previous state.
  334                  */
  335                 key->wk_flags = flags;
  336                 keyctx = cip->ic_attach(ic, key);
  337                 if (keyctx == NULL) {
  338                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  339                                 "%s: unable to attach cipher %s\n",
  340                                 __func__, cip->ic_name);
  341                         key->wk_flags = oflags; /* restore old flags */
  342                         ic->ic_stats.is_crypto_attachfail++;
  343                         return 0;
  344                 }
  345                 cipher_detach(key);
  346                 key->wk_cipher = cip;           /* XXX refcnt? */
  347                 key->wk_private = keyctx;
  348         }
  349         /*
  350          * Commit to requested usage so driver can see the flags.
  351          */
  352         key->wk_flags = flags;
  353 
  354         /*
  355          * Ask the driver for a key index if we don't have one.
  356          * Note that entries in the global key table always have
  357          * an index; this means it's safe to call this routine
  358          * for these entries just to setup the reference to the
  359          * cipher template.  Note also that when using software
  360          * crypto we also call the driver to give us a key index.
  361          */
  362         if (key->wk_keyix == IEEE80211_KEYIX_NONE) {
  363                 if (!dev_key_alloc(ic, key, &keyix, &rxkeyix)) {
  364                         /*
  365                          * Driver has no room; fallback to doing crypto
  366                          * in the host.  We change the flags and start the
  367                          * procedure over.  If we get back here then there's
  368                          * no hope and we bail.  Note that this can leave
  369                          * the key in a inconsistent state if the caller
  370                          * continues to use it.
  371                          */
  372                         if ((key->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) {
  373                                 ic->ic_stats.is_crypto_swfallback++;
  374                                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  375                                     "%s: no h/w resources for cipher %s, "
  376                                     "falling back to s/w\n", __func__,
  377                                     cip->ic_name);
  378                                 oflags = key->wk_flags;
  379                                 flags |= IEEE80211_KEY_SWCRYPT;
  380                                 if (cipher == IEEE80211_CIPHER_TKIP)
  381                                         flags |= IEEE80211_KEY_SWMIC;
  382                                 goto again;
  383                         }
  384                         ic->ic_stats.is_crypto_keyfail++;
  385                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  386                             "%s: unable to setup cipher %s\n",
  387                             __func__, cip->ic_name);
  388                         return 0;
  389                 }
  390                 key->wk_keyix = keyix;
  391                 key->wk_rxkeyix = rxkeyix;
  392         }
  393         return 1;
  394 #undef N
  395 }
  396 
  397 /*
  398  * Remove the key (no locking, for internal use).
  399  */
  400 static int
  401 _ieee80211_crypto_delkey(struct ieee80211com *ic, struct ieee80211_key *key)
  402 {
  403         ieee80211_keyix keyix;
  404 
  405         KASSERT(key->wk_cipher != NULL, ("No cipher!"));
  406 
  407         IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  408             "%s: %s keyix %u flags 0x%x rsc %ju tsc %ju len %u\n",
  409             __func__, key->wk_cipher->ic_name,
  410             key->wk_keyix, key->wk_flags,
  411             key->wk_keyrsc, key->wk_keytsc, key->wk_keylen);
  412 
  413         keyix = key->wk_keyix;
  414         if (keyix != IEEE80211_KEYIX_NONE) {
  415                 /*
  416                  * Remove hardware entry.
  417                  */
  418                 /* XXX key cache */
  419                 if (!dev_key_delete(ic, key)) {
  420                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  421                             "%s: driver did not delete key index %u\n",
  422                             __func__, keyix);
  423                         ic->ic_stats.is_crypto_delkey++;
  424                         /* XXX recovery? */
  425                 }
  426         }
  427         cipher_detach(key);
  428         memset(key, 0, sizeof(*key));
  429         ieee80211_crypto_resetkey(ic, key, IEEE80211_KEYIX_NONE);
  430         return 1;
  431 }
  432 
  433 /*
  434  * Remove the specified key.
  435  */
  436 int
  437 ieee80211_crypto_delkey(struct ieee80211com *ic, struct ieee80211_key *key)
  438 {
  439         int status;
  440 
  441         ieee80211_key_update_begin(ic);
  442         status = _ieee80211_crypto_delkey(ic, key);
  443         ieee80211_key_update_end(ic);
  444         return status;
  445 }
  446 
  447 /*
  448  * Clear the global key table.
  449  */
  450 void
  451 ieee80211_crypto_delglobalkeys(struct ieee80211com *ic)
  452 {
  453         int i;
  454 
  455         ieee80211_key_update_begin(ic);
  456         for (i = 0; i < IEEE80211_WEP_NKID; i++)
  457                 (void) _ieee80211_crypto_delkey(ic, &ic->ic_nw_keys[i]);
  458         ieee80211_key_update_end(ic);
  459 }
  460 
  461 /*
  462  * Set the contents of the specified key.
  463  *
  464  * Locking must be handled by the caller using:
  465  *      ieee80211_key_update_begin(ic);
  466  *      ieee80211_key_update_end(ic);
  467  */
  468 int
  469 ieee80211_crypto_setkey(struct ieee80211com *ic, struct ieee80211_key *key,
  470                 const u_int8_t macaddr[IEEE80211_ADDR_LEN])
  471 {
  472         const struct ieee80211_cipher *cip = key->wk_cipher;
  473 
  474         KASSERT(cip != NULL, ("No cipher!"));
  475 
  476         IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  477             "%s: %s keyix %u flags 0x%x mac %s rsc %ju tsc %ju len %u\n",
  478             __func__, cip->ic_name, key->wk_keyix,
  479             key->wk_flags, ether_sprintf(macaddr),
  480             key->wk_keyrsc, key->wk_keytsc, key->wk_keylen);
  481 
  482         /*
  483          * Give cipher a chance to validate key contents.
  484          * XXX should happen before modifying state.
  485          */
  486         if (!cip->ic_setkey(key)) {
  487                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  488                     "%s: cipher %s rejected key index %u len %u flags 0x%x\n",
  489                     __func__, cip->ic_name, key->wk_keyix,
  490                     key->wk_keylen, key->wk_flags);
  491                 ic->ic_stats.is_crypto_setkey_cipher++;
  492                 return 0;
  493         }
  494         if (key->wk_keyix == IEEE80211_KEYIX_NONE) {
  495                 /* XXX nothing allocated, should not happen */
  496                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  497                     "%s: no key index; should not happen!\n", __func__);
  498                 ic->ic_stats.is_crypto_setkey_nokey++;
  499                 return 0;
  500         }
  501         return dev_key_set(ic, key, macaddr);
  502 }
  503 
  504 /*
  505  * Add privacy headers appropriate for the specified key.
  506  */
  507 struct ieee80211_key *
  508 ieee80211_crypto_encap(struct ieee80211com *ic,
  509         struct ieee80211_node *ni, struct mbuf *m)
  510 {
  511         struct ieee80211_key *k;
  512         struct ieee80211_frame *wh;
  513         const struct ieee80211_cipher *cip;
  514         u_int8_t keyid;
  515 
  516         /*
  517          * Multicast traffic always uses the multicast key.
  518          * Otherwise if a unicast key is set we use that and
  519          * it is always key index 0.  When no unicast key is
  520          * set we fall back to the default transmit key.
  521          */
  522         wh = mtod(m, struct ieee80211_frame *);
  523         if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
  524             ni->ni_ucastkey.wk_cipher == &ieee80211_cipher_none) {
  525                 if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE) {
  526                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  527                             "[%s] no default transmit key (%s) deftxkey %u\n",
  528                             ether_sprintf(wh->i_addr1), __func__,
  529                             ic->ic_def_txkey);
  530                         ic->ic_stats.is_tx_nodefkey++;
  531                         return NULL;
  532                 }
  533                 keyid = ic->ic_def_txkey;
  534                 k = &ic->ic_nw_keys[ic->ic_def_txkey];
  535         } else {
  536                 keyid = 0;
  537                 k = &ni->ni_ucastkey;
  538         }
  539         cip = k->wk_cipher;
  540         return (cip->ic_encap(k, m, keyid<<6) ? k : NULL);
  541 }
  542 
  543 /*
  544  * Validate and strip privacy headers (and trailer) for a
  545  * received frame that has the WEP/Privacy bit set.
  546  */
  547 struct ieee80211_key *
  548 ieee80211_crypto_decap(struct ieee80211com *ic,
  549         struct ieee80211_node *ni, struct mbuf *m, int hdrlen)
  550 {
  551 #define IEEE80211_WEP_HDRLEN    (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN)
  552 #define IEEE80211_WEP_MINLEN \
  553         (sizeof(struct ieee80211_frame) + \
  554         IEEE80211_WEP_HDRLEN + IEEE80211_WEP_CRCLEN)
  555         struct ieee80211_key *k;
  556         struct ieee80211_frame *wh;
  557         const struct ieee80211_cipher *cip;
  558         const u_int8_t *ivp;
  559         u_int8_t keyid;
  560 
  561         /* NB: this minimum size data frame could be bigger */
  562         if (m->m_pkthdr.len < IEEE80211_WEP_MINLEN) {
  563                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
  564                         "%s: WEP data frame too short, len %u\n",
  565                         __func__, m->m_pkthdr.len);
  566                 ic->ic_stats.is_rx_tooshort++;  /* XXX need unique stat? */
  567                 return NULL;
  568         }
  569 
  570         /*
  571          * Locate the key. If unicast and there is no unicast
  572          * key then we fall back to the key id in the header.
  573          * This assumes unicast keys are only configured when
  574          * the key id in the header is meaningless (typically 0).
  575          */
  576         wh = mtod(m, struct ieee80211_frame *);
  577         ivp = mtod(m, const u_int8_t *) + hdrlen;       /* XXX contig */
  578         keyid = ivp[IEEE80211_WEP_IVLEN];
  579         if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
  580             ni->ni_ucastkey.wk_cipher == &ieee80211_cipher_none)
  581                 k = &ic->ic_nw_keys[keyid >> 6];
  582         else
  583                 k = &ni->ni_ucastkey;
  584 
  585         /*
  586          * Insure crypto header is contiguous for all decap work.
  587          */
  588         cip = k->wk_cipher;
  589         if (m->m_len < hdrlen + cip->ic_header &&
  590             (m = m_pullup(m, hdrlen + cip->ic_header)) == NULL) {
  591                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  592                     "[%s] unable to pullup %s header\n",
  593                     ether_sprintf(wh->i_addr2), cip->ic_name);
  594                 ic->ic_stats.is_rx_wepfail++;   /* XXX */
  595                 return 0;
  596         }
  597 
  598         return (cip->ic_decap(k, m, hdrlen) ? k : NULL);
  599 #undef IEEE80211_WEP_MINLEN
  600 #undef IEEE80211_WEP_HDRLEN
  601 }

Cache object: 55eced930a4807baf44001c30ed1aea7


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