Skip to content

Commit c5ab9ee

Browse files
Vasanthakumar Thiagarajangregkh
authored andcommitted
ath10k: rebuild crypto header in rx data frames
commit 7eccb73 upstream. Rx data frames notified through HTT_T2H_MSG_TYPE_RX_IND and HTT_T2H_MSG_TYPE_RX_FRAG_IND expect PN/TSC check to be done on host (mac80211) rather than firmware. Rebuild cipher header in every received data frames (that are notified through those HTT interfaces) from the rx_hdr_status tlv available in the rx descriptor of the first msdu. Skip setting RX_FLAG_IV_STRIPPED flag for the packets which requires mac80211 PN/TSC check support and set appropriate RX_FLAG for stripped crypto tail. Hw QCA988X, QCA9887, QCA99X0, QCA9984, QCA9888 and QCA4019 currently need the rebuilding of cipher header to perform PN/TSC check for replay attack. Please note that removing crypto tail for CCMP-256, GCMP and GCMP-256 ciphers in raw mode needs to be fixed. Since Rx with these ciphers in raw mode does not work in the current form even without this patch and removing crypto tail for these chipers needs clean up, raw mode related issues in CCMP-256, GCMP and GCMP-256 can be addressed in follow up patches. Tested-by: Manikanta Pubbisetty <[email protected]> Signed-off-by: Vasanthakumar Thiagarajan <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 234c8e6 commit c5ab9ee

File tree

2 files changed

+92
-16
lines changed

2 files changed

+92
-16
lines changed

drivers/net/wireless/ath/ath10k/htt_rx.c

Lines changed: 89 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,11 @@ static int ath10k_htt_rx_crypto_param_len(struct ath10k *ar,
548548
return IEEE80211_TKIP_IV_LEN;
549549
case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2:
550550
return IEEE80211_CCMP_HDR_LEN;
551+
case HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2:
552+
return IEEE80211_CCMP_256_HDR_LEN;
553+
case HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2:
554+
case HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2:
555+
return IEEE80211_GCMP_HDR_LEN;
551556
case HTT_RX_MPDU_ENCRYPT_WEP128:
552557
case HTT_RX_MPDU_ENCRYPT_WAPI:
553558
break;
@@ -573,6 +578,11 @@ static int ath10k_htt_rx_crypto_tail_len(struct ath10k *ar,
573578
return IEEE80211_TKIP_ICV_LEN;
574579
case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2:
575580
return IEEE80211_CCMP_MIC_LEN;
581+
case HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2:
582+
return IEEE80211_CCMP_256_MIC_LEN;
583+
case HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2:
584+
case HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2:
585+
return IEEE80211_GCMP_MIC_LEN;
576586
case HTT_RX_MPDU_ENCRYPT_WEP128:
577587
case HTT_RX_MPDU_ENCRYPT_WAPI:
578588
break;
@@ -1024,9 +1034,21 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar,
10241034
hdr = (void *)msdu->data;
10251035

10261036
/* Tail */
1027-
if (status->flag & RX_FLAG_IV_STRIPPED)
1037+
if (status->flag & RX_FLAG_IV_STRIPPED) {
10281038
skb_trim(msdu, msdu->len -
10291039
ath10k_htt_rx_crypto_tail_len(ar, enctype));
1040+
} else {
1041+
/* MIC */
1042+
if ((status->flag & RX_FLAG_MIC_STRIPPED) &&
1043+
enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2)
1044+
skb_trim(msdu, msdu->len - 8);
1045+
1046+
/* ICV */
1047+
if (status->flag & RX_FLAG_ICV_STRIPPED &&
1048+
enctype != HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2)
1049+
skb_trim(msdu, msdu->len -
1050+
ath10k_htt_rx_crypto_tail_len(ar, enctype));
1051+
}
10301052

10311053
/* MMIC */
10321054
if ((status->flag & RX_FLAG_MMIC_STRIPPED) &&
@@ -1048,14 +1070,16 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar,
10481070
static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
10491071
struct sk_buff *msdu,
10501072
struct ieee80211_rx_status *status,
1051-
const u8 first_hdr[64])
1073+
const u8 first_hdr[64],
1074+
enum htt_rx_mpdu_encrypt_type enctype)
10521075
{
10531076
struct ieee80211_hdr *hdr;
10541077
struct htt_rx_desc *rxd;
10551078
size_t hdr_len;
10561079
u8 da[ETH_ALEN];
10571080
u8 sa[ETH_ALEN];
10581081
int l3_pad_bytes;
1082+
int bytes_aligned = ar->hw_params.decap_align_bytes;
10591083

10601084
/* Delivered decapped frame:
10611085
* [nwifi 802.11 header] <-- replaced with 802.11 hdr
@@ -1084,6 +1108,14 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
10841108
/* push original 802.11 header */
10851109
hdr = (struct ieee80211_hdr *)first_hdr;
10861110
hdr_len = ieee80211_hdrlen(hdr->frame_control);
1111+
1112+
if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
1113+
memcpy(skb_push(msdu,
1114+
ath10k_htt_rx_crypto_param_len(ar, enctype)),
1115+
(void *)hdr + round_up(hdr_len, bytes_aligned),
1116+
ath10k_htt_rx_crypto_param_len(ar, enctype));
1117+
}
1118+
10871119
memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
10881120

10891121
/* original 802.11 header has a different DA and in
@@ -1144,6 +1176,7 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
11441176
u8 sa[ETH_ALEN];
11451177
int l3_pad_bytes;
11461178
struct htt_rx_desc *rxd;
1179+
int bytes_aligned = ar->hw_params.decap_align_bytes;
11471180

11481181
/* Delivered decapped frame:
11491182
* [eth header] <-- replaced with 802.11 hdr & rfc1042/llc
@@ -1172,6 +1205,14 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
11721205
/* push original 802.11 header */
11731206
hdr = (struct ieee80211_hdr *)first_hdr;
11741207
hdr_len = ieee80211_hdrlen(hdr->frame_control);
1208+
1209+
if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
1210+
memcpy(skb_push(msdu,
1211+
ath10k_htt_rx_crypto_param_len(ar, enctype)),
1212+
(void *)hdr + round_up(hdr_len, bytes_aligned),
1213+
ath10k_htt_rx_crypto_param_len(ar, enctype));
1214+
}
1215+
11751216
memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
11761217

11771218
/* original 802.11 header has a different DA and in
@@ -1185,12 +1226,14 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
11851226
static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar,
11861227
struct sk_buff *msdu,
11871228
struct ieee80211_rx_status *status,
1188-
const u8 first_hdr[64])
1229+
const u8 first_hdr[64],
1230+
enum htt_rx_mpdu_encrypt_type enctype)
11891231
{
11901232
struct ieee80211_hdr *hdr;
11911233
size_t hdr_len;
11921234
int l3_pad_bytes;
11931235
struct htt_rx_desc *rxd;
1236+
int bytes_aligned = ar->hw_params.decap_align_bytes;
11941237

11951238
/* Delivered decapped frame:
11961239
* [amsdu header] <-- replaced with 802.11 hdr
@@ -1206,6 +1249,14 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar,
12061249

12071250
hdr = (struct ieee80211_hdr *)first_hdr;
12081251
hdr_len = ieee80211_hdrlen(hdr->frame_control);
1252+
1253+
if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
1254+
memcpy(skb_push(msdu,
1255+
ath10k_htt_rx_crypto_param_len(ar, enctype)),
1256+
(void *)hdr + round_up(hdr_len, bytes_aligned),
1257+
ath10k_htt_rx_crypto_param_len(ar, enctype));
1258+
}
1259+
12091260
memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
12101261
}
12111262

@@ -1240,13 +1291,15 @@ static void ath10k_htt_rx_h_undecap(struct ath10k *ar,
12401291
is_decrypted);
12411292
break;
12421293
case RX_MSDU_DECAP_NATIVE_WIFI:
1243-
ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr);
1294+
ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr,
1295+
enctype);
12441296
break;
12451297
case RX_MSDU_DECAP_ETHERNET2_DIX:
12461298
ath10k_htt_rx_h_undecap_eth(ar, msdu, status, first_hdr, enctype);
12471299
break;
12481300
case RX_MSDU_DECAP_8023_SNAP_LLC:
1249-
ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr);
1301+
ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr,
1302+
enctype);
12501303
break;
12511304
}
12521305
}
@@ -1289,7 +1342,8 @@ static void ath10k_htt_rx_h_csum_offload(struct sk_buff *msdu)
12891342

12901343
static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
12911344
struct sk_buff_head *amsdu,
1292-
struct ieee80211_rx_status *status)
1345+
struct ieee80211_rx_status *status,
1346+
bool fill_crypt_header)
12931347
{
12941348
struct sk_buff *first;
12951349
struct sk_buff *last;
@@ -1299,7 +1353,6 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
12991353
enum htt_rx_mpdu_encrypt_type enctype;
13001354
u8 first_hdr[64];
13011355
u8 *qos;
1302-
size_t hdr_len;
13031356
bool has_fcs_err;
13041357
bool has_crypto_err;
13051358
bool has_tkip_err;
@@ -1324,15 +1377,17 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
13241377
* decapped header. It'll be used for undecapping of each MSDU.
13251378
*/
13261379
hdr = (void *)rxd->rx_hdr_status;
1327-
hdr_len = ieee80211_hdrlen(hdr->frame_control);
1328-
memcpy(first_hdr, hdr, hdr_len);
1380+
memcpy(first_hdr, hdr, RX_HTT_HDR_STATUS_LEN);
13291381

13301382
/* Each A-MSDU subframe will use the original header as the base and be
13311383
* reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl.
13321384
*/
13331385
hdr = (void *)first_hdr;
1334-
qos = ieee80211_get_qos_ctl(hdr);
1335-
qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
1386+
1387+
if (ieee80211_is_data_qos(hdr->frame_control)) {
1388+
qos = ieee80211_get_qos_ctl(hdr);
1389+
qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
1390+
}
13361391

13371392
/* Some attention flags are valid only in the last MSDU. */
13381393
last = skb_peek_tail(amsdu);
@@ -1379,9 +1434,14 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
13791434
status->flag |= RX_FLAG_DECRYPTED;
13801435

13811436
if (likely(!is_mgmt))
1382-
status->flag |= RX_FLAG_IV_STRIPPED |
1383-
RX_FLAG_MMIC_STRIPPED;
1384-
}
1437+
status->flag |= RX_FLAG_MMIC_STRIPPED;
1438+
1439+
if (fill_crypt_header)
1440+
status->flag |= RX_FLAG_MIC_STRIPPED |
1441+
RX_FLAG_ICV_STRIPPED;
1442+
else
1443+
status->flag |= RX_FLAG_IV_STRIPPED;
1444+
}
13851445

13861446
skb_queue_walk(amsdu, msdu) {
13871447
ath10k_htt_rx_h_csum_offload(msdu);
@@ -1397,6 +1457,9 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
13971457
if (is_mgmt)
13981458
continue;
13991459

1460+
if (fill_crypt_header)
1461+
continue;
1462+
14001463
hdr = (void *)msdu->data;
14011464
hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
14021465
}
@@ -1407,6 +1470,9 @@ static void ath10k_htt_rx_h_deliver(struct ath10k *ar,
14071470
struct ieee80211_rx_status *status)
14081471
{
14091472
struct sk_buff *msdu;
1473+
struct sk_buff *first_subframe;
1474+
1475+
first_subframe = skb_peek(amsdu);
14101476

14111477
while ((msdu = __skb_dequeue(amsdu))) {
14121478
/* Setup per-MSDU flags */
@@ -1415,6 +1481,13 @@ static void ath10k_htt_rx_h_deliver(struct ath10k *ar,
14151481
else
14161482
status->flag |= RX_FLAG_AMSDU_MORE;
14171483

1484+
if (msdu == first_subframe) {
1485+
first_subframe = NULL;
1486+
status->flag &= ~RX_FLAG_ALLOW_SAME_PN;
1487+
} else {
1488+
status->flag |= RX_FLAG_ALLOW_SAME_PN;
1489+
}
1490+
14181491
ath10k_process_rx(ar, status, msdu);
14191492
}
14201493
}
@@ -1557,7 +1630,7 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt)
15571630
ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff);
15581631
ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0);
15591632
ath10k_htt_rx_h_filter(ar, &amsdu, rx_status);
1560-
ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status);
1633+
ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true);
15611634
ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status);
15621635

15631636
return num_msdus;
@@ -1892,7 +1965,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
18921965
num_msdus += skb_queue_len(&amsdu);
18931966
ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id);
18941967
ath10k_htt_rx_h_filter(ar, &amsdu, status);
1895-
ath10k_htt_rx_h_mpdu(ar, &amsdu, status);
1968+
ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false);
18961969
ath10k_htt_rx_h_deliver(ar, &amsdu, status);
18971970
break;
18981971
case -EAGAIN:

drivers/net/wireless/ath/ath10k/rx_desc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ enum htt_rx_mpdu_encrypt_type {
239239
HTT_RX_MPDU_ENCRYPT_WAPI = 5,
240240
HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2 = 6,
241241
HTT_RX_MPDU_ENCRYPT_NONE = 7,
242+
HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2 = 8,
243+
HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2 = 9,
244+
HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2 = 10,
242245
};
243246

244247
#define RX_MPDU_START_INFO0_PEER_IDX_MASK 0x000007ff

0 commit comments

Comments
 (0)