mac80211: Beacon protection using the new BIGTK (STA)
This adds support for mac80211 to verify that received Beacon frames have a valid MME in station mode when a BIGTK is configured. Signed-off-by: Jouni Malinen <jouni@codeaurora.org> Link: https://lore.kernel.org/r/20200222132548.20835-6-jouni@codeaurora.org Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
0a3a84360b
commit
af2d14b01c
|
@ -983,7 +983,8 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
|
||||||
if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da))
|
if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!ieee80211_is_robust_mgmt_frame(skb))
|
if (!ieee80211_is_robust_mgmt_frame(skb) &&
|
||||||
|
!ieee80211_is_beacon(hdr->frame_control))
|
||||||
return -1; /* not a robust management frame */
|
return -1; /* not a robust management frame */
|
||||||
|
|
||||||
mmie = (struct ieee80211_mmie *)
|
mmie = (struct ieee80211_mmie *)
|
||||||
|
@ -1868,6 +1869,41 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
|
||||||
return RX_CONTINUE;
|
return RX_CONTINUE;
|
||||||
} /* ieee80211_rx_h_sta_process */
|
} /* ieee80211_rx_h_sta_process */
|
||||||
|
|
||||||
|
static struct ieee80211_key *
|
||||||
|
ieee80211_rx_get_bigtk(struct ieee80211_rx_data *rx, int idx)
|
||||||
|
{
|
||||||
|
struct ieee80211_key *key = NULL;
|
||||||
|
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||||
|
int idx2;
|
||||||
|
|
||||||
|
/* Make sure key gets set if either BIGTK key index is set so that
|
||||||
|
* ieee80211_drop_unencrypted_mgmt() can properly drop both unprotected
|
||||||
|
* Beacon frames and Beacon frames that claim to use another BIGTK key
|
||||||
|
* index (i.e., a key that we do not have).
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (idx < 0) {
|
||||||
|
idx = NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS;
|
||||||
|
idx2 = idx + 1;
|
||||||
|
} else {
|
||||||
|
if (idx == NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
|
||||||
|
idx2 = idx + 1;
|
||||||
|
else
|
||||||
|
idx2 = idx - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rx->sta)
|
||||||
|
key = rcu_dereference(rx->sta->gtk[idx]);
|
||||||
|
if (!key)
|
||||||
|
key = rcu_dereference(sdata->keys[idx]);
|
||||||
|
if (!key && rx->sta)
|
||||||
|
key = rcu_dereference(rx->sta->gtk[idx2]);
|
||||||
|
if (!key)
|
||||||
|
key = rcu_dereference(sdata->keys[idx2]);
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
static ieee80211_rx_result debug_noinline
|
static ieee80211_rx_result debug_noinline
|
||||||
ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
||||||
{
|
{
|
||||||
|
@ -1885,17 +1921,18 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
||||||
/*
|
/*
|
||||||
* Key selection 101
|
* Key selection 101
|
||||||
*
|
*
|
||||||
* There are four types of keys:
|
* There are five types of keys:
|
||||||
* - GTK (group keys)
|
* - GTK (group keys)
|
||||||
* - IGTK (group keys for management frames)
|
* - IGTK (group keys for management frames)
|
||||||
|
* - BIGTK (group keys for Beacon frames)
|
||||||
* - PTK (pairwise keys)
|
* - PTK (pairwise keys)
|
||||||
* - STK (station-to-station pairwise keys)
|
* - STK (station-to-station pairwise keys)
|
||||||
*
|
*
|
||||||
* When selecting a key, we have to distinguish between multicast
|
* When selecting a key, we have to distinguish between multicast
|
||||||
* (including broadcast) and unicast frames, the latter can only
|
* (including broadcast) and unicast frames, the latter can only
|
||||||
* use PTKs and STKs while the former always use GTKs and IGTKs.
|
* use PTKs and STKs while the former always use GTKs, IGTKs, and
|
||||||
* Unless, of course, actual WEP keys ("pre-RSNA") are used, then
|
* BIGTKs. Unless, of course, actual WEP keys ("pre-RSNA") are used,
|
||||||
* unicast frames can also use key indices like GTKs. Hence, if we
|
* then unicast frames can also use key indices like GTKs. Hence, if we
|
||||||
* don't have a PTK/STK we check the key index for a WEP key.
|
* don't have a PTK/STK we check the key index for a WEP key.
|
||||||
*
|
*
|
||||||
* Note that in a regular BSS, multicast frames are sent by the
|
* Note that in a regular BSS, multicast frames are sent by the
|
||||||
|
@ -1939,6 +1976,20 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
||||||
/* Skip decryption if the frame is not protected. */
|
/* Skip decryption if the frame is not protected. */
|
||||||
if (!ieee80211_has_protected(fc))
|
if (!ieee80211_has_protected(fc))
|
||||||
return RX_CONTINUE;
|
return RX_CONTINUE;
|
||||||
|
} else if (mmie_keyidx >= 0 && ieee80211_is_beacon(fc)) {
|
||||||
|
/* Broadcast/multicast robust management frame / BIP */
|
||||||
|
if ((status->flag & RX_FLAG_DECRYPTED) &&
|
||||||
|
(status->flag & RX_FLAG_IV_STRIPPED))
|
||||||
|
return RX_CONTINUE;
|
||||||
|
|
||||||
|
if (mmie_keyidx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS ||
|
||||||
|
mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS +
|
||||||
|
NUM_DEFAULT_BEACON_KEYS)
|
||||||
|
return RX_DROP_MONITOR; /* unexpected BIP keyidx */
|
||||||
|
|
||||||
|
rx->key = ieee80211_rx_get_bigtk(rx, mmie_keyidx);
|
||||||
|
if (!rx->key)
|
||||||
|
return RX_CONTINUE; /* Beacon protection not in use */
|
||||||
} else if (mmie_keyidx >= 0) {
|
} else if (mmie_keyidx >= 0) {
|
||||||
/* Broadcast/multicast robust management frame / BIP */
|
/* Broadcast/multicast robust management frame / BIP */
|
||||||
if ((status->flag & RX_FLAG_DECRYPTED) &&
|
if ((status->flag & RX_FLAG_DECRYPTED) &&
|
||||||
|
@ -1968,11 +2019,12 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
||||||
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (ieee80211_is_mgmt(fc) &&
|
if (ieee80211_is_beacon(fc)) {
|
||||||
is_multicast_ether_addr(hdr->addr1) &&
|
key = ieee80211_rx_get_bigtk(rx, -1);
|
||||||
(key = rcu_dereference(rx->sdata->default_mgmt_key)))
|
} else if (ieee80211_is_mgmt(fc) &&
|
||||||
rx->key = key;
|
is_multicast_ether_addr(hdr->addr1)) {
|
||||||
else {
|
key = rcu_dereference(rx->sdata->default_mgmt_key);
|
||||||
|
} else {
|
||||||
if (rx->sta) {
|
if (rx->sta) {
|
||||||
for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
|
for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
|
||||||
key = rcu_dereference(rx->sta->gtk[i]);
|
key = rcu_dereference(rx->sta->gtk[i]);
|
||||||
|
@ -1987,9 +2039,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (key)
|
|
||||||
rx->key = key;
|
|
||||||
}
|
}
|
||||||
|
if (key)
|
||||||
|
rx->key = key;
|
||||||
return RX_CONTINUE;
|
return RX_CONTINUE;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
@ -2358,6 +2410,9 @@ static int ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
|
||||||
rx->skb->len);
|
rx->skb->len);
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
}
|
}
|
||||||
|
if (unlikely(ieee80211_is_beacon(fc) && rx->key &&
|
||||||
|
ieee80211_get_mmie_keyidx(rx->skb) < 0))
|
||||||
|
return -EACCES;
|
||||||
/*
|
/*
|
||||||
* When using MFP, Action frames are not allowed prior to
|
* When using MFP, Action frames are not allowed prior to
|
||||||
* having configured keys.
|
* having configured keys.
|
||||||
|
|
Loading…
Reference in New Issue