untrusted comment: signature from openbsd 6.0 base secret key RWSho3oKSqgLQ23A0xOCp400PktTZDUBix4+WeFGbvgFpT0syqTQuVCngviXTDrfBjkHEtJf4NmhIhDL44A9T2UnLSaoMOVPyAc= OpenBSD 6.0 errata 18, Mar 1, 2017: WiFi clients using WPA1 or WPA2 are vulnerable to a man-in-the-middle attack by rouge access points. This is version 2 of the patch file. Apply by doing: signify -Vep /etc/signify/openbsd-60-base.pub -x 018_net80211.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install a new kernel: cd /usr/src/sys/arch/`machine`/conf KK=`sysctl -n kern.osversion | cut -d# -f1` config $KK cd ../compile/$KK make make install Index: sys/net80211/ieee80211_input.c =================================================================== RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v retrieving revision 1.178 diff -u -p -r1.178 ieee80211_input.c --- sys/net80211/ieee80211_input.c 18 May 2016 08:15:28 -0000 1.178 +++ sys/net80211/ieee80211_input.c 1 Mar 2017 18:24:55 -0000 @@ -2299,6 +2299,7 @@ ieee80211_recv_assoc_resp(struct ieee802 */ if (ic->ic_flags & IEEE80211_F_RSNON) { /* XXX ic->ic_mgt_timer = 5; */ + ni->ni_rsn_supp_state = RSNA_SUPP_PTKSTART; } else if (ic->ic_flags & IEEE80211_F_WEPON) ni->ni_flags |= IEEE80211_NODE_TXRXPROT; Index: sys/net80211/ieee80211_node.h =================================================================== RCS file: /cvs/src/sys/net80211/ieee80211_node.h,v retrieving revision 1.60 diff -u -p -r1.60 ieee80211_node.h --- sys/net80211/ieee80211_node.h 28 Apr 2016 08:18:10 -0000 1.60 +++ sys/net80211/ieee80211_node.h 1 Mar 2017 18:24:55 -0000 @@ -99,6 +99,14 @@ enum { RSNA_KEYERROR }; +/* Supplicant state machine: 4-Way Handshake (not documented in standard) */ +enum { + RSNA_SUPP_INITIALIZE, /* not expecting any messages */ + RSNA_SUPP_PTKSTART, /* awaiting handshake message 1 */ + RSNA_SUPP_PTKNEGOTIATING, /* got message 1 and derived PTK */ + RNSA_SUPP_PTKDONE /* got message 3 and authenticated AP */ +}; + struct ieee80211_rxinfo { u_int32_t rxi_flags; u_int32_t rxi_tstamp; @@ -205,6 +213,7 @@ struct ieee80211_node { /* RSN */ struct timeout ni_eapol_to; u_int ni_rsn_state; + u_int ni_rsn_supp_state; u_int ni_rsn_gstate; u_int ni_rsn_retries; u_int ni_rsnprotos; Index: sys/net80211/ieee80211_pae_input.c =================================================================== RCS file: /cvs/src/sys/net80211/ieee80211_pae_input.c,v retrieving revision 1.25 diff -u -p -r1.25 ieee80211_pae_input.c --- sys/net80211/ieee80211_pae_input.c 15 Jul 2015 22:16:42 -0000 1.25 +++ sys/net80211/ieee80211_pae_input.c 2 Mar 2017 09:00:08 -0000 @@ -193,6 +193,15 @@ ieee80211_recv_4way_msg1(struct ieee8021 ic->ic_opmode != IEEE80211_M_IBSS) return; #endif + /* + * Message 1 is always expected while RSN is active since some + * APs will rekey the PTK by sending Msg1/4 after some time. + */ + if (ni->ni_rsn_supp_state == RSNA_SUPP_INITIALIZE) { + DPRINTF(("unexpected in state: %d\n", ni->ni_rsn_supp_state)); + return; + } + /* enforce monotonicity of key request replay counter */ if (ni->ni_replaycnt_ok && BE_READ_8(key->replaycnt) <= ni->ni_replaycnt) { ic->ic_stats.is_rx_eapol_replay++; @@ -343,6 +352,13 @@ ieee80211_recv_4way_msg3(struct ieee8021 ic->ic_opmode != IEEE80211_M_IBSS) return; #endif + /* discard if we're not expecting this message */ + if (ni->ni_rsn_supp_state != RSNA_SUPP_PTKNEGOTIATING && + ni->ni_rsn_supp_state != RNSA_SUPP_PTKDONE) { + DPRINTF(("unexpected in state: %d\n", ni->ni_rsn_supp_state)); + return; + } + /* enforce monotonicity of key request replay counter */ if (ni->ni_replaycnt_ok && BE_READ_8(key->replaycnt) <= ni->ni_replaycnt) { ic->ic_stats.is_rx_eapol_replay++; @@ -737,6 +753,12 @@ ieee80211_recv_rsn_group_msg1(struct iee ic->ic_opmode != IEEE80211_M_IBSS) return; #endif + /* discard if we're not expecting this message */ + if (ni->ni_rsn_supp_state != RNSA_SUPP_PTKDONE) { + DPRINTF(("unexpected in state: %d\n", ni->ni_rsn_supp_state)); + return; + } + /* enforce monotonicity of key request replay counter */ if (BE_READ_8(key->replaycnt) <= ni->ni_replaycnt) { ic->ic_stats.is_rx_eapol_replay++; return; @@ -883,6 +905,12 @@ ieee80211_recv_wpa_group_msg1(struct iee ic->ic_opmode != IEEE80211_M_IBSS) return; #endif + /* discard if we're not expecting this message */ + if (ni->ni_rsn_supp_state != RNSA_SUPP_PTKDONE) { + DPRINTF(("unexpected in state: %d\n", ni->ni_rsn_supp_state)); + return; + } + /* enforce monotonicity of key request replay counter */ if (BE_READ_8(key->replaycnt) <= ni->ni_replaycnt) { ic->ic_stats.is_rx_eapol_replay++; return; @@ -975,6 +1003,7 @@ ieee80211_recv_group_msg2(struct ieee802 ni->ni_rsn_gstate)); return; } + /* enforce monotonicity of key request replay counter */ if (BE_READ_8(key->replaycnt) != ni->ni_replaycnt) { ic->ic_stats.is_rx_eapol_replay++; return; @@ -1019,6 +1048,11 @@ ieee80211_recv_eapol_key_req(struct ieee ic->ic_opmode != IEEE80211_M_IBSS) return; + /* discard if we're not expecting this message */ + if (ni->ni_rsn_state != RSNA_PTKINITDONE) { + DPRINTF(("unexpected in state: %d\n", ni->ni_rsn_state)); + return; + } /* enforce monotonicity of key request replay counter */ if (ni->ni_reqreplaycnt_ok && BE_READ_8(key->replaycnt) <= ni->ni_reqreplaycnt) { Index: sys/net80211/ieee80211_pae_output.c =================================================================== RCS file: /cvs/src/sys/net80211/ieee80211_pae_output.c,v retrieving revision 1.27 diff -u -p -r1.27 ieee80211_pae_output.c --- sys/net80211/ieee80211_pae_output.c 12 Apr 2016 14:33:27 -0000 1.27 +++ sys/net80211/ieee80211_pae_output.c 1 Mar 2017 18:24:55 -0000 @@ -310,6 +310,7 @@ ieee80211_send_4way_msg2(struct ieee8021 u_int16_t info; u_int8_t *frm; + ni->ni_rsn_supp_state = RSNA_SUPP_PTKNEGOTIATING; m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) ? 2 + IEEE80211_WPAIE_MAXLEN : @@ -438,6 +439,7 @@ ieee80211_send_4way_msg4(struct ieee8021 struct mbuf *m; u_int16_t info; + ni->ni_rsn_supp_state = RNSA_SUPP_PTKDONE; m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0); if (m == NULL) return ENOMEM; Index: sys/net80211/ieee80211_proto.c =================================================================== RCS file: /cvs/src/sys/net80211/ieee80211_proto.c,v retrieving revision 1.68 diff -u -p -r1.68 ieee80211_proto.c --- sys/net80211/ieee80211_proto.c 20 Jul 2016 15:40:27 -0000 1.68 +++ sys/net80211/ieee80211_proto.c 2 Mar 2017 08:57:50 -0000 @@ -358,8 +358,8 @@ ieee80211_set_shortslottime(struct ieee8 int ieee80211_keyrun(struct ieee80211com *ic, u_int8_t *macaddr) { + struct ieee80211_node *ni = ic->ic_bss; #ifndef IEEE80211_STA_ONLY - struct ieee80211_node *ni; struct ieee80211_pmk *pmk; #endif @@ -368,6 +368,7 @@ ieee80211_keyrun(struct ieee80211com *ic !(ic->ic_flags & IEEE80211_F_RSNON)) return ENETDOWN; + ni->ni_rsn_supp_state = RSNA_SUPP_PTKSTART; #ifndef IEEE80211_STA_ONLY if (ic->ic_opmode == IEEE80211_M_STA) #endif @@ -732,6 +733,10 @@ ieee80211_auth_open(struct ieee80211com } ieee80211_new_state(ic, IEEE80211_S_AUTH, wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); + + /* In IBSS mode no (re)association frames are sent. */ + if (ic->ic_flags & IEEE80211_F_RSNON) + ni->ni_rsn_supp_state = RSNA_SUPP_PTKSTART; break; case IEEE80211_M_AHDEMO: @@ -898,6 +903,7 @@ justcleanup: ieee80211_free_allnodes(ic); break; } + ni->ni_rsn_supp_state = RSNA_SUPP_INITIALIZE; break; case IEEE80211_S_SCAN: ic->ic_flags &= ~IEEE80211_F_SIBSS; @@ -908,6 +914,7 @@ justcleanup: ieee80211_chan2mode(ic, ni->ni_chan)]; ni->ni_associd = 0; ni->ni_rstamp = 0; + ni->ni_rsn_supp_state = RSNA_SUPP_INITIALIZE; switch (ostate) { case IEEE80211_S_INIT: #ifndef IEEE80211_STA_ONLY @@ -950,6 +957,7 @@ justcleanup: } break; case IEEE80211_S_AUTH: + ni->ni_rsn_supp_state = RSNA_SUPP_INITIALIZE; switch (ostate) { case IEEE80211_S_INIT: DPRINTF(("invalid transition\n"));