untrusted comment: signature from openbsd 5.9 base secret key
RWQJVNompF3pwRnXy6ewNE7pRc2vGApi4XnLBELfzJC1Fkkw4Py0N4JkxWf1gg//VxX8gLex+mLkUItFa9wLT5OefiHcu6Wv9ws=

OpenBSD 5.9 errata 35, Mar 1, 2017:

WiFi clients using WPA1 or WPA2 are vulnerable to a man-in-the-middle attack
by rogue access points.

This is version 2 of the patch file.

Apply by doing:
   signify -Vep /etc/signify/openbsd-59-base.pub -x 035_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.168
diff -u -p -r1.168 ieee80211_input.c
--- sys/net80211/ieee80211_input.c      12 Feb 2016 10:12:42 -0000      1.168
+++ sys/net80211/ieee80211_input.c      1 Mar 2017 18:27:50 -0000
@@ -2345,6 +2345,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.59
diff -u -p -r1.59 ieee80211_node.h
--- sys/net80211/ieee80211_node.h       11 Feb 2016 17:15:43 -0000      1.59
+++ sys/net80211/ieee80211_node.h       1 Mar 2017 18:27:50 -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:56 -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.26
diff -u -p -r1.26 ieee80211_pae_output.c
--- sys/net80211/ieee80211_pae_output.c 25 Nov 2015 03:10:00 -0000      1.26
+++ sys/net80211/ieee80211_pae_output.c 1 Mar 2017 18:27:50 -0000
@@ -320,6 +320,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 :
@@ -448,6 +449,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.64
diff -u -p -r1.64 ieee80211_proto.c
--- sys/net80211/ieee80211_proto.c      8 Feb 2016 01:00:47 -0000       1.64
+++ sys/net80211/ieee80211_proto.c      2 Mar 2017 08:57:06 -0000
@@ -362,8 +362,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

@@ -372,6 +372,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
@@ -724,6 +725,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:
@@ -890,6 +895,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;
@@ -900,6 +906,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
@@ -942,6 +949,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"));