Skip to content

Commit

Permalink
ath10k: fix pmf for action frames
Browse files Browse the repository at this point in the history
Fix sending and receiveing protected managment frames.
Lack of protected flag for received protected action frames
causes report these frames as unprotected robust action frames.
If the driver in AP mode sent frame with protected flag and
CCMP header using IEEE80211_KEY_FLAG_SW_MGMT_TX flag,
the FW encrypted frames once again. From user side all
received SA Query Requests and Responses were skipped and
all protected action frames were sent as malformed packets.

Signed-off-by: Marek Kwaczynski <marek.kwaczynski@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
  • Loading branch information
Marek Kwaczynski authored and Kalle Valo committed May 16, 2014
1 parent a6a2f74 commit eeab266
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
5 changes: 4 additions & 1 deletion drivers/net/wireless/ath/ath10k/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
switch (key->cipher) {
case WLAN_CIPHER_SUITE_CCMP:
arg.key_cipher = WMI_CIPHER_AES_CCM;
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
if (arvif->vdev_type == WMI_VDEV_TYPE_AP)
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
else
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
break;
case WLAN_CIPHER_SUITE_TKIP:
arg.key_cipher = WMI_CIPHER_TKIP;
Expand Down
24 changes: 20 additions & 4 deletions drivers/net/wireless/ath/ath10k/wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb)
struct sk_buff *wmi_skb;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int len;
u32 buf_len = skb->len;
u16 fc;

hdr = (struct ieee80211_hdr *)skb->data;
Expand All @@ -648,6 +649,15 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb)
return -EINVAL;

len = sizeof(cmd->hdr) + skb->len;

if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
ieee80211_is_disassoc(hdr->frame_control)) &&
ieee80211_has_protected(hdr->frame_control)) {
len += IEEE80211_CCMP_MIC_LEN;
buf_len += IEEE80211_CCMP_MIC_LEN;
}

len = round_up(len, 4);

wmi_skb = ath10k_wmi_alloc_skb(len);
Expand All @@ -659,7 +669,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb)
cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(skb)->vdev_id);
cmd->hdr.tx_rate = 0;
cmd->hdr.tx_power = 0;
cmd->hdr.buf_len = __cpu_to_le32((u32)(skb->len));
cmd->hdr.buf_len = __cpu_to_le32(buf_len);

memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN);
memcpy(cmd->buf, skb->data, skb->len);
Expand Down Expand Up @@ -957,10 +967,16 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
* frames with Protected Bit set. */
if (ieee80211_has_protected(hdr->frame_control) &&
!ieee80211_is_auth(hdr->frame_control)) {
status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED |
RX_FLAG_MMIC_STRIPPED;
hdr->frame_control = __cpu_to_le16(fc &
status->flag |= RX_FLAG_DECRYPTED;

if (!ieee80211_is_action(hdr->frame_control) &&
!ieee80211_is_deauth(hdr->frame_control) &&
!ieee80211_is_disassoc(hdr->frame_control)) {
status->flag |= RX_FLAG_IV_STRIPPED |
RX_FLAG_MMIC_STRIPPED;
hdr->frame_control = __cpu_to_le16(fc &
~IEEE80211_FCTL_PROTECTED);
}
}

ath10k_dbg(ATH10K_DBG_MGMT,
Expand Down

0 comments on commit eeab266

Please sign in to comment.