On Mon, Jul 05, 2021 at 09:35:20AM +0200, Stefan Sperling wrote:
> On Sun, Jul 04, 2021 at 07:58:47PM -0700, Greg Steuck wrote:
> > I never see "iwx0: sending action to" after this.
> 
> And you still see status: "no network" in ifconfig at this point?
> This could mean we're failing to set the link UP after the WPA handshake
> has completed. But I cannot explain why.

And perhaps related:
Did you have this patch applied? Does it make any difference?
Details here: https://marc.info/?l=openbsd-tech&m=162513511620823&w=2

diff 86b3b873864f7e98e688c12d8e455803ff30eadb 
27f93922f2b250b31e9534b457665df3dcf58794
blob - ea245574f624ada1b8d0c9e8e8a0653fb2c3adc4
blob + 0bac2cda2290c4a44de8f5b8110a4399f75de88d
--- sys/dev/ic/bwfm.c
+++ sys/dev/ic/bwfm.c
@@ -2714,7 +2714,13 @@ bwfm_set_key_cb(struct bwfm_softc *sc, void *arg)
        wsec |= wsec_enable;
        bwfm_fwvar_var_set_int(sc, "wsec", wsec);
 
+       if ((k->k_flags & IEEE80211_KEY_GROUP) == 0 &&
+           ni->ni_rsn_supp_state == RSNA_SUPP_PTKNEGOTIATING)
+               ni->ni_rsn_supp_state = RSNA_SUPP_PTKDONE;
+
        if (sc->sc_key_tasks == 0) {
+               if (k->k_flags & IEEE80211_KEY_SECURE)
+                       ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
                DPRINTF(("%s: marking port %s valid\n", DEVNAME(sc),
                    ether_sprintf(cmd->ni->ni_macaddr)));
                cmd->ni->ni_port_valid = 1;
blob - bdf8ce3e1afa332f698e3dc56af77e6acb4f8689
blob + 5be1d92ee862f584df5901fe54ebe30e0c937d36
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -6747,12 +6747,17 @@ iwx_add_sta_key(struct iwx_softc *sc, int sta_id, stru
                return err;
        }
 
-       if (k->k_flags & IEEE80211_KEY_GROUP)
+       if (k->k_flags & IEEE80211_KEY_GROUP) {
                in->in_flags |= IWX_NODE_FLAG_HAVE_GROUP_KEY;
-       else
+       } else {
                in->in_flags |= IWX_NODE_FLAG_HAVE_PAIRWISE_KEY;
+               if (ni->ni_rsn_supp_state == RSNA_SUPP_PTKNEGOTIATING)
+                       ni->ni_rsn_supp_state = RSNA_SUPP_PTKDONE;
+       }
 
        if ((in->in_flags & want_keymask) == want_keymask) {
+               if (k->k_flags & IEEE80211_KEY_SECURE)
+                       ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
                DPRINTF(("marking port %s valid\n",
                    ether_sprintf(ni->ni_macaddr)));
                ni->ni_port_valid = 1;
blob - 08ffda8c9aaede9c901d97a43bf2873591e8df19
blob + 0c141fc5df7ba1a774af98a59a2b718bdcc721bb
--- sys/dev/usb/if_athn_usb.c
+++ sys/dev/usb/if_athn_usb.c
@@ -1662,7 +1662,12 @@ athn_usb_set_key_cb(struct athn_usb_softc *usc, void *
        s = splnet();
        athn_usb_write_barrier(&usc->sc_sc);
        athn_set_key(ic, cmd->ni, cmd->key);
+       if ((cmd->key->k_flags & IEEE80211_KEY_GROUP) == 0 &&
+           cmd->ni->ni_rsn_supp_state == RSNA_SUPP_PTKNEGOTIATING)
+               cmd->ni->ni_rsn_supp_state = RSNA_SUPP_PTKDONE;
        if (usc->sc_key_tasks == 0) {
+               if (cmd->key->k_flags & IEEE80211_KEY_SECURE)
+                       cmd->ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
                DPRINTF(("marking port %s valid\n",
                    ether_sprintf(cmd->ni->ni_macaddr)));
                cmd->ni->ni_port_valid = 1;
blob - bb220831ffc852347afdcda18c9bca0589d6d939
blob + 8e426e9cab0b389f2e1260139ad451b30e10287e
--- sys/dev/usb/if_otus.c
+++ sys/dev/usb/if_otus.c
@@ -2116,7 +2116,12 @@ otus_set_key_cb(struct otus_softc *sc, void *arg)
        memcpy(key.key, k->k_key + 16, 16);
        (void)otus_cmd(sc, AR_CMD_EKEY, &key, sizeof key, NULL);
 
+       if ((k->k_flags & IEEE80211_KEY_GROUP) == 0 &&
+           cmd->ni->ni_rsn_supp_state == RSNA_SUPP_PTKNEGOTIATING)
+               cmd->ni->ni_rsn_supp_state = RSNA_SUPP_PTKDONE;
        if (sc->sc_key_tasks == 0) {
+               if (k->k_flags & IEEE80211_KEY_SECURE)
+                       cmd->ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
                DPRINTF(("marking port %s valid\n",
                    ether_sprintf(cmd->ni->ni_macaddr)));
                cmd->ni->ni_port_valid = 1;
blob - 929d8f161d50cd294569dd74e0a4e2980e5607ca
blob + 5e30f1b680b1b58c020ba9627aa5a8776aa1b3a4
--- sys/dev/usb/if_rsu.c
+++ sys/dev/usb/if_rsu.c
@@ -940,7 +940,12 @@ rsu_set_key_cb(struct rsu_softc *sc, void *arg)
        memcpy(key.key, k->k_key, MIN(k->k_len, sizeof(key.key)));
        (void)rsu_fw_cmd(sc, R92S_CMD_SET_KEY, &key, sizeof(key));
 
+       if ((k->k_flags & IEEE80211_KEY_GROUP) == 0 &&
+           cmd->ni->ni_rsn_supp_state == RSNA_SUPP_PTKNEGOTIATING)
+               cmd->ni->ni_rsn_supp_state = RSNA_SUPP_PTKDONE;
        if (sc->sc_key_tasks == 0) {
+               if (k->k_flags & IEEE80211_KEY_SECURE)
+                       cmd->ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
                DPRINTF(("marking port %s valid\n",
                    ether_sprintf(cmd->ni->ni_macaddr)));
                cmd->ni->ni_port_valid = 1;
blob - 7759d6e0cea12b48a1373d90942b20a8d55bd7fb
blob + 70acde2498e9adcadac12fcf3c6886ca7a753ef9
--- sys/dev/usb/if_run.c
+++ sys/dev/usb/if_run.c
@@ -2017,7 +2017,12 @@ run_set_key_cb(struct run_softc *sc, void *arg)
                run_write(sc, RT2860_WCID_ATTR(wcid), attr);
        }
 
+       if ((k->k_flags & IEEE80211_KEY_GROUP) == 0 &&
+           cmd->ni->ni_rsn_supp_state == RSNA_SUPP_PTKNEGOTIATING)
+               cmd->ni->ni_rsn_supp_state = RSNA_SUPP_PTKDONE;
        if (sc->sc_key_tasks == 0) {
+               if (k->k_flags & IEEE80211_KEY_SECURE)
+                       cmd->ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
                cmd->ni->ni_port_valid = 1;
                ieee80211_set_link_state(ic, LINK_STATE_UP);
        }
blob - c2133041168e826909415759d2009bd74dd48aee
blob + 82c02d91a36e5ce5d91f78f230789f348c09f5dd
--- sys/dev/usb/if_urtwn.c
+++ sys/dev/usb/if_urtwn.c
@@ -1062,7 +1062,12 @@ urtwn_set_key_cb(struct urtwn_softc *sc, void *arg)
        sc->sc_key_tasks--;
 
        if (rtwn_set_key(ic, cmd->ni, &cmd->key) == 0) {
+               if ((cmd->key.k_flags & IEEE80211_KEY_GROUP) == 0 &&
+                   cmd->ni->ni_rsn_supp_state == RSNA_SUPP_PTKNEGOTIATING)
+                       cmd->ni->ni_rsn_supp_state = RSNA_SUPP_PTKDONE;
                if (sc->sc_key_tasks == 0) {
+                       if (cmd->key.k_flags & IEEE80211_KEY_SECURE)
+                               cmd->ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
                        DPRINTF(("marking port %s valid\n",
                            ether_sprintf(cmd->ni->ni_macaddr)));
                        cmd->ni->ni_port_valid = 1;
blob - 748b44b3f8c309dfd40b347ac408f234588b404b
blob + e14b46a0ff9c9b824b59a93c866b955ce3338c24
--- sys/net80211/ieee80211_crypto.h
+++ sys/net80211/ieee80211_crypto.h
@@ -79,6 +79,7 @@ struct ieee80211_key {
 #define IEEE80211_KEY_TX       0x00000002      /* Tx+Rx */
 #define IEEE80211_KEY_IGTK     0x00000004      /* integrity group key */
 #define IEEE80211_KEY_SWCRYPTO 0x00000080      /* loaded for software crypto */
+#define IEEE80211_KEY_SECURE   0x00000100      /* initial key exchange done */
 
        u_int                   k_len;
        u_int64_t               k_rsc[IEEE80211_NUM_TID];
blob - daf550f591fdf675e073f82a968efbdbb49fdb46
blob + 19413bef0b9c3e5df41bb3b8bcc17c88ae331e47
--- sys/net80211/ieee80211_pae_input.c
+++ sys/net80211/ieee80211_pae_input.c
@@ -564,9 +564,12 @@ ieee80211_recv_4way_msg3(struct ieee80211com *ic,
                k->k_rsc[0] = prsc;
                k->k_len = keylen;
                memcpy(k->k_key, ni->ni_ptk.tk, k->k_len);
+               if (info & (EAPOL_KEY_INSTALL | EAPOL_KEY_SECURE))
+                       k->k_flags |= IEEE80211_KEY_SECURE;
                /* install the PTK */
                switch ((*ic->ic_set_key)(ic, ni, k)) {
                case 0:
+                       ni->ni_rsn_supp_state = RSNA_SUPP_PTKDONE;
                        break;
                case EBUSY:
                        deferlink = 1;
@@ -576,8 +579,9 @@ ieee80211_recv_4way_msg3(struct ieee80211com *ic,
                        goto deauth;
                }
                ni->ni_flags &= ~IEEE80211_NODE_RSN_NEW_PTK;
-               ni->ni_flags &= ~IEEE80211_NODE_TXRXPROT;
-               ni->ni_flags |= IEEE80211_NODE_RXPROT;
+               ni->ni_flags &= ~IEEE80211_NODE_TXPROT;
+               if (deferlink == 0)
+                       ni->ni_flags |= IEEE80211_NODE_RXPROT;
        } else if (ni->ni_rsncipher != IEEE80211_CIPHER_USEGROUP)
                printf("%s: unexpected pairwise key update received from %s\n",
                    ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr));
@@ -604,6 +608,8 @@ ieee80211_recv_4way_msg3(struct ieee80211com *ic,
                        k->k_rsc[0] = LE_READ_6(key->rsc);
                        k->k_len = keylen;
                        memcpy(k->k_key, &gtk[8], k->k_len);
+                       if (info & EAPOL_KEY_SECURE)
+                               k->k_flags |= IEEE80211_KEY_SECURE;
                        /* install the GTK */
                        switch ((*ic->ic_set_key)(ic, ni, k)) {
                        case 0:
@@ -641,6 +647,8 @@ ieee80211_recv_4way_msg3(struct ieee80211com *ic,
                        k->k_mgmt_rsc = LE_READ_6(&igtk[8]);    /* IPN */
                        k->k_len = 16;
                        memcpy(k->k_key, &igtk[14], k->k_len);
+                       if (info & EAPOL_KEY_SECURE)
+                               k->k_flags |= IEEE80211_KEY_SECURE;
                        /* install the IGTK */
                        switch ((*ic->ic_set_key)(ic, ni, k)) {
                        case 0:
@@ -654,11 +662,9 @@ ieee80211_recv_4way_msg3(struct ieee80211com *ic,
                        }
                }
        }
-       if (info & EAPOL_KEY_INSTALL)
+       if (deferlink == 0 && (info & (EAPOL_KEY_INSTALL | EAPOL_KEY_SECURE)))
                ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
-
        if (info & EAPOL_KEY_SECURE) {
-               ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
 #ifndef IEEE80211_STA_ONLY
                if (ic->ic_opmode != IEEE80211_M_IBSS ||
                    ++ni->ni_key_count == 2)
@@ -814,7 +820,7 @@ ieee80211_recv_rsn_group_msg1(struct ieee80211com *ic,
        const u_int8_t *frm, *efrm;
        const u_int8_t *gtk, *igtk;
        u_int16_t info, kid, reason = 0;
-       int keylen;
+       int keylen, deferlink = 0;
 
 #ifndef IEEE80211_STA_ONLY
        if (ic->ic_opmode != IEEE80211_M_STA &&
@@ -897,10 +903,14 @@ ieee80211_recv_rsn_group_msg1(struct ieee80211com *ic,
                k->k_rsc[0] = LE_READ_6(key->rsc);
                k->k_len = keylen;
                memcpy(k->k_key, &gtk[8], k->k_len);
+               if (info & EAPOL_KEY_SECURE)
+                       k->k_flags |= IEEE80211_KEY_SECURE;
                /* install the GTK */
                switch ((*ic->ic_set_key)(ic, ni, k)) {
                case 0:
+                       break;
                case EBUSY:
+                       deferlink = 1;
                        break;
                default:
                        reason = IEEE80211_REASON_AUTH_LEAVE;
@@ -929,10 +939,14 @@ ieee80211_recv_rsn_group_msg1(struct ieee80211com *ic,
                        k->k_mgmt_rsc = LE_READ_6(&igtk[8]);    /* IPN */
                        k->k_len = 16;
                        memcpy(k->k_key, &igtk[14], k->k_len);
+                       if (info & EAPOL_KEY_SECURE)
+                               k->k_flags |= IEEE80211_KEY_SECURE;
                        /* install the IGTK */
                        switch ((*ic->ic_set_key)(ic, ni, k)) {
                        case 0:
+                               break;
                        case EBUSY:
+                               deferlink = 1;
                                break;
                        default:
                                reason = IEEE80211_REASON_AUTH_LEAVE;
@@ -946,10 +960,12 @@ ieee80211_recv_rsn_group_msg1(struct ieee80211com *ic,
                    ++ni->ni_key_count == 2)
 #endif
                {
-                       DPRINTF(("marking port %s valid\n",
-                           ether_sprintf(ni->ni_macaddr)));
-                       ni->ni_port_valid = 1;
-                       ieee80211_set_link_state(ic, LINK_STATE_UP);
+                       if (deferlink == 0) {
+                               DPRINTF(("marking port %s valid\n",
+                                   ether_sprintf(ni->ni_macaddr)));
+                               ni->ni_port_valid = 1;
+                               ieee80211_set_link_state(ic, LINK_STATE_UP);
+                       }
                        ni->ni_assoc_fail = 0;
                }
        }
@@ -979,7 +995,7 @@ ieee80211_recv_wpa_group_msg1(struct ieee80211com *ic,
        struct ieee80211_key *k;
        u_int16_t info;
        u_int8_t kid;
-       int keylen;
+       int keylen, deferlink = 0;
        const uint8_t *gtk;
 
 #ifndef IEEE80211_STA_ONLY
@@ -1037,10 +1053,14 @@ ieee80211_recv_wpa_group_msg1(struct ieee80211com *ic,
                k->k_rsc[0] = LE_READ_6(key->rsc);
                k->k_len = keylen;
                memcpy(k->k_key, gtk, k->k_len);
+               if (info & EAPOL_KEY_SECURE)
+                       k->k_flags |= IEEE80211_KEY_SECURE;
                /* install the GTK */
                switch ((*ic->ic_set_key)(ic, ni, k)) {
                case 0:
+                       break;
                case EBUSY:
+                       deferlink = 1;
                        break;
                default:
                        IEEE80211_SEND_MGMT(ic, ni, 
IEEE80211_FC0_SUBTYPE_DEAUTH,
@@ -1055,10 +1075,12 @@ ieee80211_recv_wpa_group_msg1(struct ieee80211com *ic,
                    ++ni->ni_key_count == 2)
 #endif
                {
-                       DPRINTF(("marking port %s valid\n",
-                           ether_sprintf(ni->ni_macaddr)));
-                       ni->ni_port_valid = 1;
-                       ieee80211_set_link_state(ic, LINK_STATE_UP);
+                       if (deferlink == 0) {
+                               DPRINTF(("marking port %s valid\n",
+                                   ether_sprintf(ni->ni_macaddr)));
+                               ni->ni_port_valid = 1;
+                               ieee80211_set_link_state(ic, LINK_STATE_UP);
+                       }
                        ni->ni_assoc_fail = 0;
                }
        }
blob - 35a00ff8b6b7315718558ad26178d8646308c6dc
blob + 2a48158c2c93da086e7860a69a01e944991797c9
--- sys/net80211/ieee80211_pae_output.c
+++ sys/net80211/ieee80211_pae_output.c
@@ -444,7 +444,6 @@ ieee80211_send_4way_msg4(struct ieee80211com *ic, stru
        struct mbuf *m;
        u_int16_t info;
 
-       ni->ni_rsn_supp_state = RSNA_SUPP_PTKDONE;
        m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0);
        if (m == NULL)
                return ENOMEM;

Reply via email to