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"));