summaryrefslogtreecommitdiff
path: root/net/mac80211/wpa.c
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2016-05-03 15:59:44 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-05-16 11:06:46 +0300
commit6de1fabb6cbcf3203e4dc831c230ef23df0c0079 (patch)
tree6bfe89d0da5db6aa60adad1f12c90622ce57e24c /net/mac80211/wpa.c
parent706e58e319087f02267208b160af584c09c36dfd (diff)
downloadlinux-6de1fabb6cbcf3203e4dc831c230ef23df0c0079.tar.xz
mac80211: allow same PN for AMSDU sub-frames
commit f631a77ba920f7153a1094d09cd8f2ebbffd0328 upstream. 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> Cc: Sriram R <srirrama@codeaurora.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/mac80211/wpa.c')
-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 b09072749499..c0567a866fdd 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -523,12 +523,16 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
return RX_DROP_UNUSABLE;
if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
+ int res;
+
ccmp_hdr2pn(pn, skb->data + hdrlen);
queue = rx->security_idx;
- if (memcmp(pn, key->u.ccmp.rx_pn[queue],
- IEEE80211_CCMP_PN_LEN) <= 0) {
+ res = memcmp(pn, key->u.ccmp.rx_pn[queue],
+ IEEE80211_CCMP_PN_LEN);
+ if (res < 0 ||
+ (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
key->u.ccmp.replays++;
return RX_DROP_UNUSABLE;
}
@@ -749,12 +753,16 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
return RX_DROP_UNUSABLE;
if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
+ int res;
+
gcmp_hdr2pn(pn, skb->data + hdrlen);
queue = rx->security_idx;
- if (memcmp(pn, key->u.gcmp.rx_pn[queue],
- IEEE80211_GCMP_PN_LEN) <= 0) {
+ res = memcmp(pn, key->u.gcmp.rx_pn[queue],
+ IEEE80211_GCMP_PN_LEN);
+ if (res < 0 ||
+ (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
key->u.gcmp.replays++;
return RX_DROP_UNUSABLE;
}