net80211; LinuxKPI 802.11: introduce IEEE80211_RX_F_ICV_STRIP

For TKIP with iwlwifi we are seeing
DECRYPTED | ICV_STRIPPED | MMIC_STRIPPED.

In tkip_decap() we however unconditionally stripped the ICV which
resulted in a short frame and Gtk handshake never finished.

Add IEEE80211_RX_F_ICV_STRIP to net80211.  Add the extra check to the
TKIP code.

While there correct a comment and leave another about contiguous data
assumptions.

In LinuxKPI 802.11 translate the new flag and sort them into STRIP
and FAIL while here.

Sponsored by:	The FreeBSD Foundation
Reviewed by:	adrian
Differential Revision: https://reviews.freebsd.org/D49880

(cherry picked from commit 731ff40069d28ddab206dee276fbbdf0f28a2124)
This commit is contained in:
Bjoern A. Zeeb 2025-04-17 19:33:59 +00:00
parent a638734e4a
commit 28c5a37f07
3 changed files with 12 additions and 8 deletions

View file

@ -6467,14 +6467,16 @@ lkpi_convert_rx_status(struct ieee80211_hw *hw, struct lkpi_sta *lsta,
if (rx_status->flag & RX_FLAG_PN_VALIDATED)
rx_stats->c_pktflags |= IEEE80211_RX_F_PN_VALIDATED;
}
if (rx_status->flag & RX_FLAG_IV_STRIPPED)
rx_stats->c_pktflags |= IEEE80211_RX_F_IV_STRIP;
if (rx_status->flag & RX_FLAG_ICV_STRIPPED)
rx_stats->c_pktflags |= IEEE80211_RX_F_ICV_STRIP;
if (rx_status->flag & RX_FLAG_MIC_STRIPPED)
rx_stats->c_pktflags |= IEEE80211_RX_F_MIC_STRIP;
if (rx_status->flag & RX_FLAG_MMIC_STRIPPED)
rx_stats->c_pktflags |= IEEE80211_RX_F_MMIC_STRIP;
if (rx_status->flag & RX_FLAG_MMIC_ERROR)
rx_stats->c_pktflags |= IEEE80211_RX_F_FAIL_MMIC;
if (rx_status->flag & RX_FLAG_MIC_STRIPPED)
rx_stats->c_pktflags |= IEEE80211_RX_F_MIC_STRIP;
if (rx_status->flag & RX_FLAG_IV_STRIPPED)
rx_stats->c_pktflags |= IEEE80211_RX_F_IV_STRIP;
if (rx_status->flag & RX_FLAG_FAILED_FCS_CRC)
rx_stats->c_pktflags |= IEEE80211_RX_F_FAIL_FCSCRC;
#endif

View file

@ -575,6 +575,7 @@ struct ieee80211_mimo_info {
#define IEEE80211_RX_F_VHT 0x00008000
#define IEEE80211_RX_F_PN_VALIDATED 0x00010000 /* Decrypted; PN validated */
#define IEEE80211_RX_F_MIC_STRIP 0x00020000 /* Decrypted; MIC stripped */
#define IEEE80211_RX_F_ICV_STRIP 0x00040000 /* Decrypted: ICV (ic_trailer) stripped */
/* Channel width */
#define IEEE80211_RX_FW_20MHZ 1

View file

@ -361,16 +361,17 @@ finish:
* are required to.
*/
if (! ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_IV_STRIP))) {
/* XXX this assumes the header + IV are contiguous in an mbuf. */
memmove(mtod(m, uint8_t *) + tkip.ic_header, mtod(m, void *),
hdrlen);
m_adj(m, tkip.ic_header);
}
/*
* XXX TODO: do we need an option to potentially not strip the
* WEP trailer? Does "MMIC_STRIP" also mean this? Or?
* Strip the ICV if hardware has not done so already.
*/
m_adj(m, -tkip.ic_trailer);
if (rxs != NULL && (rxs->c_pktflags & IEEE80211_RX_F_ICV_STRIP) == 0)
m_adj(m, -tkip.ic_trailer);
return 1;
}
@ -403,7 +404,7 @@ tkip_demic(struct ieee80211_key *k, struct mbuf *m, int force)
}
/*
* If IV has been stripped, we skip most of the below.
* If MMIC has been stripped, we skip most of the below.
*/
if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_MMIC_STRIP))
goto finish;