summaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2016-05-03 08:59:44 -0400
committerJohannes Berg <johannes.berg@intel.com>2016-05-12 05:14:45 -0400
commitf631a77ba920f7153a1094d09cd8f2ebbffd0328 (patch)
treeb5baaab1e31664bf225c04581178efaf6e1f387a /net/mac80211
parent20eb7ea93f7ffaaa24b19b8bfc411b1f7605759f (diff)
mac80211: allow same PN for AMSDU sub-frames
Some hardware (iwlwifi an example) de-aggregate AMSDUs and copy the IV as is to the generated MPDUs, so the same PN appears in multiple packets without being a replay attack. Allow driver to explicitly indicate that a frame is allowed to have the same PN as the previous frame. Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/wpa.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 7e4f2652bca7..b48c1e13e281 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -519,12 +519,16 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
519 return RX_DROP_UNUSABLE; 519 return RX_DROP_UNUSABLE;
520 520
521 if (!(status->flag & RX_FLAG_PN_VALIDATED)) { 521 if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
522 int res;
523
522 ccmp_hdr2pn(pn, skb->data + hdrlen); 524 ccmp_hdr2pn(pn, skb->data + hdrlen);
523 525
524 queue = rx->security_idx; 526 queue = rx->security_idx;
525 527
526 if (memcmp(pn, key->u.ccmp.rx_pn[queue], 528 res = memcmp(pn, key->u.ccmp.rx_pn[queue],
527 IEEE80211_CCMP_PN_LEN) <= 0) { 529 IEEE80211_CCMP_PN_LEN);
530 if (res < 0 ||
531 (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
528 key->u.ccmp.replays++; 532 key->u.ccmp.replays++;
529 return RX_DROP_UNUSABLE; 533 return RX_DROP_UNUSABLE;
530 } 534 }
@@ -745,12 +749,16 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
745 return RX_DROP_UNUSABLE; 749 return RX_DROP_UNUSABLE;
746 750
747 if (!(status->flag & RX_FLAG_PN_VALIDATED)) { 751 if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
752 int res;
753
748 gcmp_hdr2pn(pn, skb->data + hdrlen); 754 gcmp_hdr2pn(pn, skb->data + hdrlen);
749 755
750 queue = rx->security_idx; 756 queue = rx->security_idx;
751 757
752 if (memcmp(pn, key->u.gcmp.rx_pn[queue], 758 res = memcmp(pn, key->u.gcmp.rx_pn[queue],
753 IEEE80211_GCMP_PN_LEN) <= 0) { 759 IEEE80211_GCMP_PN_LEN);
760 if (res < 0 ||
761 (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
754 key->u.gcmp.replays++; 762 key->u.gcmp.replays++;
755 return RX_DROP_UNUSABLE; 763 return RX_DROP_UNUSABLE;
756 } 764 }