aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-05-08 05:34:10 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-11 15:23:55 -0400
commit0c7c10c7cc6bc890d23c8c62b81b4feccd92124b (patch)
treeb6efb9424fd436e64802b332d1b59eb40c92c1ff /net/mac80211
parent782571f46fc7d2bbb0288ab0d676c47a88449a5c (diff)
mac80211: Drop unencrypted frames based on key setup
When using nl80211, we do not have a mechanism to set sdata->drop_unencrypted. Currently, this breaks code that is supposed to drop unencrypted frames when protection is expected since ieee80211_rx_h_decrypt() is optimized to not set rx->key when the frame is not protected. This patch modifies ieee80211_rx_h_decrypt() to set rx->key for all frames and only skip decryption if the frame is not protected. This allows ieee80211_drop_unencrypted() to correctly drop frames even if drop_unencrypted is not set. The changes here are not enough to handle all cases, though. Additional patches will be needed to implement proper IEEE 802.1X PAE for station mode (currently, this is only used for AP mode) and some additional rules are needed for MFP to drop unprotected Robust Action frames prior to having PTK and IGTK configured. In theory, the unprotected frames could and should be dropped in ieee80211_rx_h_decrypt(). However, due to the special case with EAPOL frames that have to be allowed to be received unprotected even when keys are set, it is simpler to only set rx->key and allow the ieee80211_frame_allowed() function to handle the actual dropping of data frames after 802.11->802.3 header conversion. In addition, unprotected robust management frames are dropped before they are processed. Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/rx.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index d052f4004829..bf21e92a6b9c 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -630,15 +630,6 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
630 * possible. 630 * possible.
631 */ 631 */
632 632
633 if (!ieee80211_has_protected(hdr->frame_control)) {
634 if (!ieee80211_is_mgmt(hdr->frame_control) ||
635 rx->sta == NULL || !test_sta_flags(rx->sta, WLAN_STA_MFP))
636 return RX_CONTINUE;
637 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
638 if (mmie_keyidx < 0)
639 return RX_CONTINUE;
640 }
641
642 /* 633 /*
643 * No point in finding a key and decrypting if the frame is neither 634 * No point in finding a key and decrypting if the frame is neither
644 * addressed to us nor a multicast frame. 635 * addressed to us nor a multicast frame.
@@ -649,8 +640,14 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
649 if (rx->sta) 640 if (rx->sta)
650 stakey = rcu_dereference(rx->sta->key); 641 stakey = rcu_dereference(rx->sta->key);
651 642
643 if (!ieee80211_has_protected(hdr->frame_control))
644 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
645
652 if (!is_multicast_ether_addr(hdr->addr1) && stakey) { 646 if (!is_multicast_ether_addr(hdr->addr1) && stakey) {
653 rx->key = stakey; 647 rx->key = stakey;
648 /* Skip decryption if the frame is not protected. */
649 if (!ieee80211_has_protected(hdr->frame_control))
650 return RX_CONTINUE;
654 } else if (mmie_keyidx >= 0) { 651 } else if (mmie_keyidx >= 0) {
655 /* Broadcast/multicast robust management frame / BIP */ 652 /* Broadcast/multicast robust management frame / BIP */
656 if ((rx->status->flag & RX_FLAG_DECRYPTED) && 653 if ((rx->status->flag & RX_FLAG_DECRYPTED) &&
@@ -661,6 +658,21 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
661 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) 658 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
662 return RX_DROP_MONITOR; /* unexpected BIP keyidx */ 659 return RX_DROP_MONITOR; /* unexpected BIP keyidx */
663 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); 660 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
661 } else if (!ieee80211_has_protected(hdr->frame_control)) {
662 /*
663 * The frame was not protected, so skip decryption. However, we
664 * need to set rx->key if there is a key that could have been
665 * used so that the frame may be dropped if encryption would
666 * have been expected.
667 */
668 struct ieee80211_key *key = NULL;
669 if (ieee80211_is_mgmt(hdr->frame_control) &&
670 is_multicast_ether_addr(hdr->addr1) &&
671 (key = rcu_dereference(rx->sdata->default_mgmt_key)))
672 rx->key = key;
673 else if ((key = rcu_dereference(rx->sdata->default_key)))
674 rx->key = key;
675 return RX_CONTINUE;
664 } else { 676 } else {
665 /* 677 /*
666 * The device doesn't give us the IV so we won't be 678 * The device doesn't give us the IV so we won't be