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/dev/ath/if_ath_keycache.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-2009 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  *    without modification.
   11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
   13  *    redistribution must be conditioned upon including a substantially
   14  *    similar Disclaimer requirement for further binary redistribution.
   15  *
   16  * NO WARRANTY
   17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
   20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
   22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   27  * THE POSSIBILITY OF SUCH DAMAGES.
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD$");
   32 
   33 /*
   34  * Driver for the Atheros Wireless LAN controller.
   35  *
   36  * This software is derived from work of Atsushi Onoe; his contribution
   37  * is greatly appreciated.
   38  */
   39 
   40 #include "opt_inet.h"
   41 #include "opt_ath.h"
   42 #include "opt_wlan.h"
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/sysctl.h>
   47 #include <sys/mbuf.h>
   48 #include <sys/malloc.h>
   49 #include <sys/lock.h>
   50 #include <sys/mutex.h>
   51 #include <sys/kernel.h>
   52 #include <sys/socket.h>
   53 #include <sys/sockio.h>
   54 #include <sys/errno.h>
   55 #include <sys/callout.h>
   56 #include <sys/bus.h>
   57 #include <sys/endian.h>
   58 #include <sys/kthread.h>
   59 #include <sys/taskqueue.h>
   60 #include <sys/priv.h>
   61 
   62 #include <machine/bus.h>
   63 
   64 #include <net/if.h>
   65 #include <net/if_dl.h>
   66 #include <net/if_media.h>
   67 #include <net/if_types.h>
   68 #include <net/if_arp.h>
   69 #include <net/ethernet.h>
   70 #include <net/if_llc.h>
   71 
   72 #include <net80211/ieee80211_var.h>
   73 
   74 #include <net/bpf.h>
   75 
   76 #include <dev/ath/if_athvar.h>
   77 
   78 #include <dev/ath/if_ath_debug.h>
   79 #include <dev/ath/if_ath_keycache.h>
   80 
   81 #ifdef ATH_DEBUG
   82 static void
   83 ath_keyprint(struct ath_softc *sc, const char *tag, u_int ix,
   84         const HAL_KEYVAL *hk, const u_int8_t mac[IEEE80211_ADDR_LEN])
   85 {
   86         static const char *ciphers[] = {
   87                 "WEP",
   88                 "AES-OCB",
   89                 "AES-CCM",
   90                 "CKIP",
   91                 "TKIP",
   92                 "CLR",
   93         };
   94         int i, n;
   95 
   96         printf("%s: [%02u] %-7s ", tag, ix, ciphers[hk->kv_type]);
   97         for (i = 0, n = hk->kv_len; i < n; i++)
   98                 printf("%02x", hk->kv_val[i]);
   99         printf(" mac %s", ether_sprintf(mac));
  100         if (hk->kv_type == HAL_CIPHER_TKIP) {
  101                 printf(" %s ", sc->sc_splitmic ? "mic" : "rxmic");
  102                 for (i = 0; i < sizeof(hk->kv_mic); i++)
  103                         printf("%02x", hk->kv_mic[i]);
  104                 if (!sc->sc_splitmic) {
  105                         printf(" txmic ");
  106                         for (i = 0; i < sizeof(hk->kv_txmic); i++)
  107                                 printf("%02x", hk->kv_txmic[i]);
  108                 }
  109         }
  110         printf("\n");
  111 }
  112 #endif
  113 
  114 /*
  115  * Set a TKIP key into the hardware.  This handles the
  116  * potential distribution of key state to multiple key
  117  * cache slots for TKIP.
  118  */
  119 static int
  120 ath_keyset_tkip(struct ath_softc *sc, const struct ieee80211_key *k,
  121         HAL_KEYVAL *hk, const u_int8_t mac[IEEE80211_ADDR_LEN])
  122 {
  123 #define IEEE80211_KEY_XR        (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV)
  124         static const u_int8_t zerobssid[IEEE80211_ADDR_LEN];
  125         struct ath_hal *ah = sc->sc_ah;
  126 
  127         KASSERT(k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP,
  128                 ("got a non-TKIP key, cipher %u", k->wk_cipher->ic_cipher));
  129         if ((k->wk_flags & IEEE80211_KEY_XR) == IEEE80211_KEY_XR) {
  130                 if (sc->sc_splitmic) {
  131                         /*
  132                          * TX key goes at first index, RX key at the rx index.
  133                          * The hal handles the MIC keys at index+64.
  134                          */
  135                         memcpy(hk->kv_mic, k->wk_txmic, sizeof(hk->kv_mic));
  136                         KEYPRINTF(sc, k->wk_keyix, hk, zerobssid);
  137                         if (!ath_hal_keyset(ah, k->wk_keyix, hk, zerobssid))
  138                                 return 0;
  139 
  140                         memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic));
  141                         KEYPRINTF(sc, k->wk_keyix+32, hk, mac);
  142                         /* XXX delete tx key on failure? */
  143                         return ath_hal_keyset(ah, k->wk_keyix+32, hk, mac);
  144                 } else {
  145                         /*
  146                          * Room for both TX+RX MIC keys in one key cache
  147                          * slot, just set key at the first index; the hal
  148                          * will handle the rest.
  149                          */
  150                         memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic));
  151                         memcpy(hk->kv_txmic, k->wk_txmic, sizeof(hk->kv_txmic));
  152                         KEYPRINTF(sc, k->wk_keyix, hk, mac);
  153                         return ath_hal_keyset(ah, k->wk_keyix, hk, mac);
  154                 }
  155         } else if (k->wk_flags & IEEE80211_KEY_XMIT) {
  156                 if (sc->sc_splitmic) {
  157                         /*
  158                          * NB: must pass MIC key in expected location when
  159                          * the keycache only holds one MIC key per entry.
  160                          */
  161                         memcpy(hk->kv_mic, k->wk_txmic, sizeof(hk->kv_txmic));
  162                 } else
  163                         memcpy(hk->kv_txmic, k->wk_txmic, sizeof(hk->kv_txmic));
  164                 KEYPRINTF(sc, k->wk_keyix, hk, mac);
  165                 return ath_hal_keyset(ah, k->wk_keyix, hk, mac);
  166         } else if (k->wk_flags & IEEE80211_KEY_RECV) {
  167                 memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic));
  168                 KEYPRINTF(sc, k->wk_keyix, hk, mac);
  169                 return ath_hal_keyset(ah, k->wk_keyix, hk, mac);
  170         }
  171         return 0;
  172 #undef IEEE80211_KEY_XR
  173 }
  174 
  175 /*
  176  * Set a net80211 key into the hardware.  This handles the
  177  * potential distribution of key state to multiple key
  178  * cache slots for TKIP with hardware MIC support.
  179  */
  180 int
  181 ath_keyset(struct ath_softc *sc, const struct ieee80211_key *k,
  182         struct ieee80211_node *bss)
  183 {
  184 #define N(a)    (sizeof(a)/sizeof(a[0]))
  185         static const u_int8_t ciphermap[] = {
  186                 HAL_CIPHER_WEP,         /* IEEE80211_CIPHER_WEP */
  187                 HAL_CIPHER_TKIP,        /* IEEE80211_CIPHER_TKIP */
  188                 HAL_CIPHER_AES_OCB,     /* IEEE80211_CIPHER_AES_OCB */
  189                 HAL_CIPHER_AES_CCM,     /* IEEE80211_CIPHER_AES_CCM */
  190                 (u_int8_t) -1,          /* 4 is not allocated */
  191                 HAL_CIPHER_CKIP,        /* IEEE80211_CIPHER_CKIP */
  192                 HAL_CIPHER_CLR,         /* IEEE80211_CIPHER_NONE */
  193         };
  194         struct ath_hal *ah = sc->sc_ah;
  195         const struct ieee80211_cipher *cip = k->wk_cipher;
  196         u_int8_t gmac[IEEE80211_ADDR_LEN];
  197         const u_int8_t *mac;
  198         HAL_KEYVAL hk;
  199 
  200         memset(&hk, 0, sizeof(hk));
  201         /*
  202          * Software crypto uses a "clear key" so non-crypto
  203          * state kept in the key cache are maintained and
  204          * so that rx frames have an entry to match.
  205          */
  206         if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) {
  207                 KASSERT(cip->ic_cipher < N(ciphermap),
  208                         ("invalid cipher type %u", cip->ic_cipher));
  209                 hk.kv_type = ciphermap[cip->ic_cipher];
  210                 hk.kv_len = k->wk_keylen;
  211                 memcpy(hk.kv_val, k->wk_key, k->wk_keylen);
  212         } else
  213                 hk.kv_type = HAL_CIPHER_CLR;
  214 
  215         if ((k->wk_flags & IEEE80211_KEY_GROUP) && sc->sc_mcastkey) {
  216                 /*
  217                  * Group keys on hardware that supports multicast frame
  218                  * key search use a MAC that is the sender's address with
  219                  * the multicast bit set instead of the app-specified address.
  220                  */
  221                 IEEE80211_ADDR_COPY(gmac, bss->ni_macaddr);
  222                 gmac[0] |= 0x01;
  223                 mac = gmac;
  224         } else
  225                 mac = k->wk_macaddr;
  226 
  227         if (hk.kv_type == HAL_CIPHER_TKIP &&
  228             (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) {
  229                 return ath_keyset_tkip(sc, k, &hk, mac);
  230         } else {
  231                 KEYPRINTF(sc, k->wk_keyix, &hk, mac);
  232                 return ath_hal_keyset(ah, k->wk_keyix, &hk, mac);
  233         }
  234 #undef N
  235 }
  236 
  237 /*
  238  * Allocate tx/rx key slots for TKIP.  We allocate two slots for
  239  * each key, one for decrypt/encrypt and the other for the MIC.
  240  */
  241 static u_int16_t
  242 key_alloc_2pair(struct ath_softc *sc,
  243         ieee80211_keyix *txkeyix, ieee80211_keyix *rxkeyix)
  244 {
  245 #define N(a)    (sizeof(a)/sizeof(a[0]))
  246         u_int i, keyix;
  247 
  248         KASSERT(sc->sc_splitmic, ("key cache !split"));
  249         /* XXX could optimize */
  250         for (i = 0; i < N(sc->sc_keymap)/4; i++) {
  251                 u_int8_t b = sc->sc_keymap[i];
  252                 if (b != 0xff) {
  253                         /*
  254                          * One or more slots in this byte are free.
  255                          */
  256                         keyix = i*NBBY;
  257                         while (b & 1) {
  258                 again:
  259                                 keyix++;
  260                                 b >>= 1;
  261                         }
  262                         /* XXX IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV */
  263                         if (isset(sc->sc_keymap, keyix+32) ||
  264                             isset(sc->sc_keymap, keyix+64) ||
  265                             isset(sc->sc_keymap, keyix+32+64)) {
  266                                 /* full pair unavailable */
  267                                 /* XXX statistic */
  268                                 if (keyix == (i+1)*NBBY) {
  269                                         /* no slots were appropriate, advance */
  270                                         continue;
  271                                 }
  272                                 goto again;
  273                         }
  274                         setbit(sc->sc_keymap, keyix);
  275                         setbit(sc->sc_keymap, keyix+64);
  276                         setbit(sc->sc_keymap, keyix+32);
  277                         setbit(sc->sc_keymap, keyix+32+64);
  278                         DPRINTF(sc, ATH_DEBUG_KEYCACHE,
  279                                 "%s: key pair %u,%u %u,%u\n",
  280                                 __func__, keyix, keyix+64,
  281                                 keyix+32, keyix+32+64);
  282                         *txkeyix = keyix;
  283                         *rxkeyix = keyix+32;
  284                         return 1;
  285                 }
  286         }
  287         DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: out of pair space\n", __func__);
  288         return 0;
  289 #undef N
  290 }
  291 
  292 /*
  293  * Allocate tx/rx key slots for TKIP.  We allocate two slots for
  294  * each key, one for decrypt/encrypt and the other for the MIC.
  295  */
  296 static u_int16_t
  297 key_alloc_pair(struct ath_softc *sc,
  298         ieee80211_keyix *txkeyix, ieee80211_keyix *rxkeyix)
  299 {
  300 #define N(a)    (sizeof(a)/sizeof(a[0]))
  301         u_int i, keyix;
  302 
  303         KASSERT(!sc->sc_splitmic, ("key cache split"));
  304         /* XXX could optimize */
  305         for (i = 0; i < N(sc->sc_keymap)/4; i++) {
  306                 u_int8_t b = sc->sc_keymap[i];
  307                 if (b != 0xff) {
  308                         /*
  309                          * One or more slots in this byte are free.
  310                          */
  311                         keyix = i*NBBY;
  312                         while (b & 1) {
  313                 again:
  314                                 keyix++;
  315                                 b >>= 1;
  316                         }
  317                         if (isset(sc->sc_keymap, keyix+64)) {
  318                                 /* full pair unavailable */
  319                                 /* XXX statistic */
  320                                 if (keyix == (i+1)*NBBY) {
  321                                         /* no slots were appropriate, advance */
  322                                         continue;
  323                                 }
  324                                 goto again;
  325                         }
  326                         setbit(sc->sc_keymap, keyix);
  327                         setbit(sc->sc_keymap, keyix+64);
  328                         DPRINTF(sc, ATH_DEBUG_KEYCACHE,
  329                                 "%s: key pair %u,%u\n",
  330                                 __func__, keyix, keyix+64);
  331                         *txkeyix = *rxkeyix = keyix;
  332                         return 1;
  333                 }
  334         }
  335         DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: out of pair space\n", __func__);
  336         return 0;
  337 #undef N
  338 }
  339 
  340 /*
  341  * Allocate a single key cache slot.
  342  */
  343 static int
  344 key_alloc_single(struct ath_softc *sc,
  345         ieee80211_keyix *txkeyix, ieee80211_keyix *rxkeyix)
  346 {
  347 #define N(a)    (sizeof(a)/sizeof(a[0]))
  348         u_int i, keyix;
  349 
  350         /* XXX try i,i+32,i+64,i+32+64 to minimize key pair conflicts */
  351         for (i = 0; i < N(sc->sc_keymap); i++) {
  352                 u_int8_t b = sc->sc_keymap[i];
  353                 if (b != 0xff) {
  354                         /*
  355                          * One or more slots are free.
  356                          */
  357                         keyix = i*NBBY;
  358                         while (b & 1)
  359                                 keyix++, b >>= 1;
  360                         setbit(sc->sc_keymap, keyix);
  361                         DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: key %u\n",
  362                                 __func__, keyix);
  363                         *txkeyix = *rxkeyix = keyix;
  364                         return 1;
  365                 }
  366         }
  367         DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: out of space\n", __func__);
  368         return 0;
  369 #undef N
  370 }
  371 
  372 /*
  373  * Allocate one or more key cache slots for a uniacst key.  The
  374  * key itself is needed only to identify the cipher.  For hardware
  375  * TKIP with split cipher+MIC keys we allocate two key cache slot
  376  * pairs so that we can setup separate TX and RX MIC keys.  Note
  377  * that the MIC key for a TKIP key at slot i is assumed by the
  378  * hardware to be at slot i+64.  This limits TKIP keys to the first
  379  * 64 entries.
  380  */
  381 int
  382 ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
  383         ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
  384 {
  385         struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
  386 
  387         /*
  388          * Group key allocation must be handled specially for
  389          * parts that do not support multicast key cache search
  390          * functionality.  For those parts the key id must match
  391          * the h/w key index so lookups find the right key.  On
  392          * parts w/ the key search facility we install the sender's
  393          * mac address (with the high bit set) and let the hardware
  394          * find the key w/o using the key id.  This is preferred as
  395          * it permits us to support multiple users for adhoc and/or
  396          * multi-station operation.
  397          */
  398         if (k->wk_keyix != IEEE80211_KEYIX_NONE) {
  399                 /*
  400                  * Only global keys should have key index assigned.
  401                  */
  402                 if (!(&vap->iv_nw_keys[0] <= k &&
  403                       k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) {
  404                         /* should not happen */
  405                         DPRINTF(sc, ATH_DEBUG_KEYCACHE,
  406                                 "%s: bogus group key\n", __func__);
  407                         return 0;
  408                 }
  409                 if (vap->iv_opmode != IEEE80211_M_HOSTAP ||
  410                     !(k->wk_flags & IEEE80211_KEY_GROUP) ||
  411                     !sc->sc_mcastkey) {
  412                         /*
  413                          * XXX we pre-allocate the global keys so
  414                          * have no way to check if they've already
  415                          * been allocated.
  416                          */
  417                         *keyix = *rxkeyix = k - vap->iv_nw_keys;
  418                         return 1;
  419                 }
  420                 /*
  421                  * Group key and device supports multicast key search.
  422                  */
  423                 k->wk_keyix = IEEE80211_KEYIX_NONE;
  424         }
  425 
  426         /*
  427          * We allocate two pair for TKIP when using the h/w to do
  428          * the MIC.  For everything else, including software crypto,
  429          * we allocate a single entry.  Note that s/w crypto requires
  430          * a pass-through slot on the 5211 and 5212.  The 5210 does
  431          * not support pass-through cache entries and we map all
  432          * those requests to slot 0.
  433          */
  434         if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
  435                 return key_alloc_single(sc, keyix, rxkeyix);
  436         } else if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP &&
  437             (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) {
  438                 if (sc->sc_splitmic)
  439                         return key_alloc_2pair(sc, keyix, rxkeyix);
  440                 else
  441                         return key_alloc_pair(sc, keyix, rxkeyix);
  442         } else {
  443                 return key_alloc_single(sc, keyix, rxkeyix);
  444         }
  445 }
  446 
  447 /*
  448  * Delete an entry in the key cache allocated by ath_key_alloc.
  449  */
  450 int
  451 ath_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
  452 {
  453         struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
  454         struct ath_hal *ah = sc->sc_ah;
  455         const struct ieee80211_cipher *cip = k->wk_cipher;
  456         u_int keyix = k->wk_keyix;
  457 
  458         DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: delete key %u\n", __func__, keyix);
  459 
  460         ath_hal_keyreset(ah, keyix);
  461         /*
  462          * Handle split tx/rx keying required for TKIP with h/w MIC.
  463          */
  464         if (cip->ic_cipher == IEEE80211_CIPHER_TKIP &&
  465             (k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && sc->sc_splitmic)
  466                 ath_hal_keyreset(ah, keyix+32);         /* RX key */
  467         if (keyix >= IEEE80211_WEP_NKID) {
  468                 /*
  469                  * Don't touch keymap entries for global keys so
  470                  * they are never considered for dynamic allocation.
  471                  */
  472                 clrbit(sc->sc_keymap, keyix);
  473                 if (cip->ic_cipher == IEEE80211_CIPHER_TKIP &&
  474                     (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) {
  475                         clrbit(sc->sc_keymap, keyix+64);        /* TX key MIC */
  476                         if (sc->sc_splitmic) {
  477                                 /* +32 for RX key, +32+64 for RX key MIC */
  478                                 clrbit(sc->sc_keymap, keyix+32);
  479                                 clrbit(sc->sc_keymap, keyix+32+64);
  480                         }
  481                 }
  482         }
  483         return 1;
  484 }
  485 
  486 /*
  487  * Set the key cache contents for the specified key.  Key cache
  488  * slot(s) must already have been allocated by ath_key_alloc.
  489  */
  490 int
  491 ath_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k,
  492         const u_int8_t mac[IEEE80211_ADDR_LEN])
  493 {
  494         struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
  495 
  496         return ath_keyset(sc, k, vap->iv_bss);
  497 }

Cache object: 23a39cb72909fce4e54db44c4e752ad9


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