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, >k[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, >k[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;
