Author: bschmidt
Date: Thu Jul  1 20:50:12 2010
New Revision: 209636
URL: http://svn.freebsd.org/changeset/base/209636

Log:
  - Introduce IEEE80211_KEY_NOREPLAY, a per-key flag to ignore replay
    violations.
  - Use SIOCGIFMEDIA to determine VAP's opmode, cache it and set
    IEEE80211_KEY_NOREPLAY for AHDEMO and IBSS.
  
  Approved by:  rpaulo (mentor)

Modified:
  head/sys/net80211/ieee80211_crypto.h
  head/sys/net80211/ieee80211_crypto_ccmp.c
  head/sys/net80211/ieee80211_crypto_tkip.c
  head/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c

Modified: head/sys/net80211/ieee80211_crypto.h
==============================================================================
--- head/sys/net80211/ieee80211_crypto.h        Thu Jul  1 18:59:05 2010        
(r209635)
+++ head/sys/net80211/ieee80211_crypto.h        Thu Jul  1 20:50:12 2010        
(r209636)
@@ -78,6 +78,7 @@ struct ieee80211_key {
 #define        IEEE80211_KEY_XMIT      0x0001  /* key used for xmit */
 #define        IEEE80211_KEY_RECV      0x0002  /* key used for recv */
 #define        IEEE80211_KEY_GROUP     0x0004  /* key used for WPA group 
operation */
+#define        IEEE80211_KEY_NOREPLAY  0x0008  /* ignore replay failures */
 #define        IEEE80211_KEY_SWENCRYPT 0x0010  /* host-based encrypt */
 #define        IEEE80211_KEY_SWDECRYPT 0x0020  /* host-based decrypt */
 #define        IEEE80211_KEY_SWENMIC   0x0040  /* host-based enmic */
@@ -98,7 +99,8 @@ struct ieee80211_key {
        uint8_t         wk_macaddr[IEEE80211_ADDR_LEN];
 };
 #define        IEEE80211_KEY_COMMON            /* common flags passed in by 
apps */\
-       (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP)
+       (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP | \
+        IEEE80211_KEY_NOREPLAY)
 #define        IEEE80211_KEY_DEVICE            /* flags owned by device driver 
*/\
        (IEEE80211_KEY_DEVKEY|IEEE80211_KEY_CIPHER0|IEEE80211_KEY_CIPHER1)
 

Modified: head/sys/net80211/ieee80211_crypto_ccmp.c
==============================================================================
--- head/sys/net80211/ieee80211_crypto_ccmp.c   Thu Jul  1 18:59:05 2010        
(r209635)
+++ head/sys/net80211/ieee80211_crypto_ccmp.c   Thu Jul  1 20:50:12 2010        
(r209636)
@@ -226,14 +226,8 @@ ccmp_decap(struct ieee80211_key *k, stru
        }
        tid = ieee80211_gettid(wh);
        pn = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]);
-       /*
-        * NB: Multiple stations are using the same key in
-        * IBSS mode, there is currently no way to sync keyrsc
-        * counters without discarding too many frames.
-        */
-       if (vap->iv_opmode != IEEE80211_M_IBSS &&
-           vap->iv_opmode != IEEE80211_M_AHDEMO &&
-           pn <= k->wk_keyrsc[tid]) {
+       if (pn <= k->wk_keyrsc[tid] &&
+           (k->wk_flags & IEEE80211_KEY_NOREPLAY) == 0) {
                /*
                 * Replay violation.
                 */

Modified: head/sys/net80211/ieee80211_crypto_tkip.c
==============================================================================
--- head/sys/net80211/ieee80211_crypto_tkip.c   Thu Jul  1 18:59:05 2010        
(r209635)
+++ head/sys/net80211/ieee80211_crypto_tkip.c   Thu Jul  1 20:50:12 2010        
(r209636)
@@ -281,14 +281,8 @@ tkip_decap(struct ieee80211_key *k, stru
 
        tid = ieee80211_gettid(wh);
        ctx->rx_rsc = READ_6(ivp[2], ivp[0], ivp[4], ivp[5], ivp[6], ivp[7]);
-       /*
-        * NB: Multiple stations are using the same key in
-        * IBSS mode, there is currently no way to sync keyrsc
-        * counters without discarding too many frames.
-        */
-       if (vap->iv_opmode != IEEE80211_M_IBSS &&
-           vap->iv_opmode != IEEE80211_M_AHDEMO &&
-           ctx->rx_rsc <= k->wk_keyrsc[tid]) {
+       if (ctx->rx_rsc <= k->wk_keyrsc[tid] &&
+           (k->wk_flags & IEEE80211_KEY_NOREPLAY) == 0) {
                /*
                 * Replay violation; notify upper layer.
                 */

Modified: head/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c
==============================================================================
--- head/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c   Thu Jul  1 18:59:05 
2010        (r209635)
+++ head/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c   Thu Jul  1 20:50:12 
2010        (r209636)
@@ -29,6 +29,7 @@
 
 #include <sys/socket.h>
 #include <net/if.h>
+#include <net/if_media.h>
 #include <net/ethernet.h>
 
 #include <net80211/ieee80211_ioctl.h>
@@ -47,8 +48,34 @@ struct wpa_driver_bsd_data {
        int     lastssid_len;
        uint32_t drivercaps;            /* general driver capabilities */
        uint32_t cryptocaps;            /* hardware crypto support */
+       enum ieee80211_opmode opmode;   /* operation mode */
 };
 
+static enum ieee80211_opmode
+get80211opmode(struct wpa_driver_bsd_data *drv)
+{
+       struct ifmediareq ifmr;
+
+       (void) memset(&ifmr, 0, sizeof(ifmr));
+       (void) strncpy(ifmr.ifm_name, drv->ifname, sizeof(ifmr.ifm_name));
+
+       if (ioctl(drv->sock, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0) {
+               if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) {
+                       if (ifmr.ifm_current & IFM_FLAG0)
+                               return IEEE80211_M_AHDEMO;
+                       else
+                               return IEEE80211_M_IBSS;
+               }
+               if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP)
+                       return IEEE80211_M_HOSTAP;
+               if (ifmr.ifm_current & IFM_IEEE80211_MONITOR)
+                       return IEEE80211_M_MONITOR;
+               if (ifmr.ifm_current & IFM_IEEE80211_MBSS)
+                       return IEEE80211_M_MBSS;
+       }
+       return IEEE80211_M_STA;
+}
+
 static int
 set80211var(struct wpa_driver_bsd_data *drv, int op, const void *arg, int 
arg_len)
 {
@@ -332,6 +359,12 @@ wpa_driver_bsd_set_key(void *priv, wpa_a
        }
        if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx)
                wk.ik_flags |= IEEE80211_KEY_DEFAULT;
+       /*
+        * Ignore replay failures in IBSS and AHDEMO mode.
+        */
+       if (drv->opmode == IEEE80211_M_IBSS ||
+           drv->opmode == IEEE80211_M_AHDEMO)
+               wk.ik_flags |= IEEE80211_KEY_NOREPLAY;
        wk.ik_keylen = key_len;
        memcpy(&wk.ik_keyrsc, seq, seq_len);
        wk.ik_keyrsc = le64toh(wk.ik_keyrsc);
@@ -861,6 +894,7 @@ wpa_driver_bsd_init(void *ctx, const cha
                           __func__, strerror(errno));
                goto fail;
        }
+       drv->opmode = get80211opmode(drv);
 
        return drv;
 fail:
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to