From owner-svn-src-all@FreeBSD.ORG Thu Jul 1 20:50:12 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 802131065672; Thu, 1 Jul 2010 20:50:12 +0000 (UTC) (envelope-from bschmidt@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6EFC58FC0A; Thu, 1 Jul 2010 20:50:12 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o61KoCSH080826; Thu, 1 Jul 2010 20:50:12 GMT (envelope-from bschmidt@svn.freebsd.org) Received: (from bschmidt@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o61KoCG1080821; Thu, 1 Jul 2010 20:50:12 GMT (envelope-from bschmidt@svn.freebsd.org) Message-Id: <201007012050.o61KoCG1080821@svn.freebsd.org> From: Bernhard Schmidt Date: Thu, 1 Jul 2010 20:50:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r209636 - in head: sys/net80211 usr.sbin/wpa/wpa_supplicant X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Jul 2010 20:50:12 -0000 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 #include +#include #include #include @@ -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: