On Mon, Dec 07, 2020 at 10:55:29PM +0100, Stefan Sperling wrote:
> When announcing RSN (WPA2) capabilities in management frames such as
> association requests, we currently echo back all RSN (i.e. WPA2)
> capabilities which were announced by our peer.
> This is bad in case the peer announces features we don't support.
> One such feature is Management Frame Protection (MFP). If we announce this
> capability then the peer sends us encrypted management frames which won't be
> processed. One symptom of this is that we fail to negotiate 11n block ack
> with APs that enable MFP if the client announces support for MFP (problem
> found by sthen@).
> With this patch we only echo the RSN capalibities which we actually support.
> I am handling MFP and PBAR bits here as done elsewhere, but note that
> neither of these features is enabled yet at run-time.
> (We do have code for MFP; but it is untested, and disabled in all of our
> wifi drivers. That's for another day...)
> ok?
I've been running this with my iwn wireless all night with no regression.
(AP is a Unifi AC Lite).
ok kmos
> diff 18e888c6238d4d2767f9b9d181633c8a9b33b1a3 /usr/src
> blob - 1610fbf508ab3f6fb12721ee5c1ba7f56c0a94b3
> file + sys/net80211/ieee80211_output.c
> --- sys/net80211/ieee80211_output.c
> +++ sys/net80211/ieee80211_output.c
> @@ -941,7 +941,7 @@ ieee80211_add_rsn_body(u_int8_t *frm, struct ieee80211
> {
> const u_int8_t *oui = wpa ? MICROSOFT_OUI : IEEE80211_OUI;
> u_int8_t *pcount;
> - u_int16_t count;
> + u_int16_t count, rsncaps;
>
> /* write Version field */
> LE_WRITE_2(frm, 1); frm += 2;
> @@ -1017,7 +1017,16 @@ ieee80211_add_rsn_body(u_int8_t *frm, struct ieee80211
> return frm;
>
> /* write RSN Capabilities field */
> - LE_WRITE_2(frm, ni->ni_rsncaps); frm += 2;
> + rsncaps = (ni->ni_rsncaps & (IEEE80211_RSNCAP_PTKSA_RCNT_MASK |
> + IEEE80211_RSNCAP_GTKSA_RCNT_MASK));
> + if (ic->ic_caps & IEEE80211_C_MFP) {
> + rsncaps |= IEEE80211_RSNCAP_MFPC;
> + if (ic->ic_flags & IEEE80211_F_MFPR)
> + rsncaps |= IEEE80211_RSNCAP_MFPR;
> + }
> + if (ic->ic_flags & IEEE80211_F_PBAR)
> + rsncaps |= IEEE80211_RSNCAP_PBAC;
> + LE_WRITE_2(frm, rsncaps); frm += 2;
>
> if (ni->ni_flags & IEEE80211_NODE_PMKID) {
> /* write PMKID Count field */
>
>