mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-01 12:19:28 +00:00
- 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)
This commit is contained in:
parent
a7d6757c3e
commit
5d766a09da
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=209636
@ -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)
|
||||
|
||||
|
@ -226,14 +226,8 @@ ccmp_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
|
||||
}
|
||||
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.
|
||||
*/
|
||||
|
@ -281,14 +281,8 @@ tkip_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
@ -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_alg alg,
|
||||
}
|
||||
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 char *ifname)
|
||||
__func__, strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
drv->opmode = get80211opmode(drv);
|
||||
|
||||
return drv;
|
||||
fail:
|
||||
|
Loading…
Reference in New Issue
Block a user