On Thu, 15 Aug 2019, richard.n.proc...@gmail.com wrote:

> Hi Stefan, 
> 
> On Wed, 14 Aug 2019, Stefan Sperling wrote:
> 
> > On Tue, Aug 13, 2019 at 10:47:24AM -0300, Martin Pieuchot wrote:
> > > if the crash is because of a missing key, put one :)
> > 
> > Yes, you've convinced me. With this patch we install the CCMP key
> > to both firmware and net80211. Until firmware confirms that the
> > key has been installed, we do software encrypt/decrypt.
> 
> I agree we should handle a missing key but suggest an alternative approach 
> below.

so:

m0 = NULL;
m_free(m0);

isn't so useful; fixed patch follows.

best, 
Richard. 

Index: net80211/ieee80211_crypto.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_crypto.c,v
retrieving revision 1.74
diff -u -p -u -p -r1.74 ieee80211_crypto.c
--- net80211/ieee80211_crypto.c 24 Sep 2018 20:14:59 -0000      1.74
+++ net80211/ieee80211_crypto.c 15 Aug 2019 03:44:12 -0000
@@ -157,6 +157,10 @@ ieee80211_set_key(struct ieee80211com *i
                /* should not get there */
                error = EINVAL;
        }
+
+       if (error == 0)
+               k->k_flags |= IEEE80211_KEY_SWCRYPTO;
+
        return error;
 }
 
@@ -280,6 +284,11 @@ ieee80211_decrypt(struct ieee80211com *i
                }
                k = &ic->ic_nw_keys[kid];
        }
+
+       if ((k->k_flags & IEEE80211_KEY_SWCRYPTO) == 0) {
+               goto err;
+       }
+
        switch (k->k_cipher) {
        case IEEE80211_CIPHER_WEP40:
        case IEEE80211_CIPHER_WEP104:
@@ -296,9 +305,15 @@ ieee80211_decrypt(struct ieee80211com *i
                break;
        default:
                /* key not defined */
-               m_freem(m0);
-               m0 = NULL;
+               goto err;
        }
+
+       return m0;
+
+err:
+       m_freem(m0);
+       m0 = NULL;
+
        return m0;
 }
 
Index: net80211/ieee80211_crypto.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_crypto.h,v
retrieving revision 1.25
diff -u -p -u -p -r1.25 ieee80211_crypto.h
--- net80211/ieee80211_crypto.h 18 Aug 2017 17:30:12 -0000      1.25
+++ net80211/ieee80211_crypto.h 15 Aug 2019 03:44:12 -0000
@@ -78,6 +78,7 @@ struct ieee80211_key {
 #define IEEE80211_KEY_GROUP    0x00000001      /* group data 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 */
 
        u_int                   k_len;
        u_int64_t               k_rsc[IEEE80211_NUM_TID];



> > 
> > Should the firmware fail to install the key for some reason, we will
> > just keep using our software fallback until the interface is reset.
> > 
> > This also fixes the race with incoming frames during WPA handshake,
> > i.e. while (ni->ni_flags & IEEE80211_NODE_RXPROT) == 0.
> > Such frames can be passed to net80211 and will be dropped there.
> > 
> > Lightly tested on a 7260 device.
> > 
> > Ok?
> > 
> > diff refs/heads/master refs/heads/ccmp-crash2
> > blob - 038e6a63dfff113b525bb1e9a30c935996535569
> > blob + 8afcce065eb0d85f4469a3f378cacba1513bc215
> > --- sys/dev/pci/if_iwm.c
> > +++ sys/dev/pci/if_iwm.c
> > @@ -3595,10 +3595,17 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct 
> > iwm_rx_pac
> >     rxi.rxi_rssi = rssi;
> >     rxi.rxi_tstamp = device_timestamp;
> >  
> > -   /* Handle hardware decryption. */
> > +   /*
> > +    * Handle hardware decryption.
> > +    *
> > +    * If the WPA handshake has completed but firmware is not yet ready
> > +    * to decrypt frames, fall back to software decryption in net80211. 
> > +    * net80211 will drop encrypted frames until the handshake completes.
> > +    */
> >     if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL)
> >         && (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
> >         !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
> > +       (sc->sc_flags & IWM_FLAG_CCMP_READY) &&
> >         (ni->ni_flags & IEEE80211_NODE_RXPROT) &&
> >         ni->ni_pairwise_key.k_cipher == IEEE80211_CIPHER_CCMP) {
> >             if ((rx_pkt_status & IWM_RX_MPDU_RES_STATUS_SEC_ENC_MSK) !=
> > @@ -4402,7 +4409,8 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ie
> >  
> >     if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
> >             k = ieee80211_get_txkey(ic, wh, ni);
> > -           if  (k->k_cipher != IEEE80211_CIPHER_CCMP) {
> > +           if  (k->k_cipher != IEEE80211_CIPHER_CCMP ||
> > +               (sc->sc_flags & IWM_FLAG_CCMP_READY) == 0) {
> >                     if ((m = ieee80211_encrypt(ic, m, k)) == NULL)
> >                             return ENOBUFS;
> >  
> > @@ -4418,7 +4426,8 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ie
> >     /* Copy 802.11 header in TX command. */
> >     memcpy(((uint8_t *)tx) + sizeof(*tx), wh, hdrlen);
> >  
> > -   if  (k != NULL && k->k_cipher == IEEE80211_CIPHER_CCMP) {
> > +   if  (k != NULL && k->k_cipher == IEEE80211_CIPHER_CCMP &&
> > +       (sc->sc_flags & IWM_FLAG_CCMP_READY)) {
> >             /* Trim 802.11 header and prepend CCMP IV. */
> >             m_adj(m, hdrlen - IEEE80211_CCMP_HDRLEN);
> >             ivp = mtod(m, u_int8_t *);
> > @@ -6090,6 +6099,7 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
> >  {
> >     struct iwm_softc *sc = ic->ic_softc;
> >     struct iwm_add_sta_key_cmd cmd = { 0 };
> > +   int err;
> >  
> >     if ((k->k_flags & IEEE80211_KEY_GROUP) ||
> >         k->k_cipher != IEEE80211_CIPHER_CCMP)  {
> > @@ -6097,6 +6107,8 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
> >             return (ieee80211_set_key(ic, ni, k));
> >     }
> >  
> > +   sc->sc_flags &= ~(IWM_FLAG_CCMP_READY | IWM_FLAG_CCMP_KEY_SENT);
> > +
> >     cmd.key_flags = htole16(IWM_STA_KEY_FLG_CCM |
> >         IWM_STA_KEY_FLG_WEP_KEY_MAP |
> >         ((k->k_id << IWM_STA_KEY_FLG_KEYID_POS) &
> > @@ -6108,8 +6120,15 @@ iwm_set_key(struct ieee80211com *ic, struct 
> > ieee80211_
> >     cmd.key_offset = 0;
> >     cmd.sta_id = IWM_STATION_ID;
> >  
> > -   return iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
> > -       sizeof(cmd), &cmd);
> > +   /* Allow for software CCMP encryption/decryption fallback. */
> > +   err = ieee80211_set_key(ic, ni, k);
> > +   if (!err) {
> > +           err = iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
> > +               sizeof(cmd), &cmd);
> > +           if (!err)
> > +                   sc->sc_flags |= IWM_FLAG_CCMP_KEY_SENT;
> > +   }
> > +   return err;
> >  }
> >  
> >  void
> > @@ -6135,6 +6154,10 @@ iwm_delete_key(struct ieee80211com *ic, struct 
> > ieee802
> >     cmd.sta_id = IWM_STATION_ID;
> >  
> >     iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC, sizeof(cmd), &cmd);
> > +   sc->sc_flags &= ~(IWM_FLAG_CCMP_KEY_SENT | IWM_FLAG_CCMP_READY);
> > +
> > +   /* Delete software fallback CCMP key. */
> > +        ieee80211_delete_key(ic, ni, k);
> >  }
> >  
> >  void
> > @@ -6846,6 +6869,7 @@ iwm_stop(struct ifnet *ifp)
> >     sc->sc_flags &= ~IWM_FLAG_TE_ACTIVE;
> >     sc->sc_flags &= ~IWM_FLAG_HW_ERR;
> >     sc->sc_flags &= ~IWM_FLAG_SHUTDOWN;
> > +   sc->sc_flags &= ~(IWM_FLAG_CCMP_KEY_SENT | IWM_FLAG_CCMP_READY);
> >  
> >     sc->sc_newstate(ic, IEEE80211_S_INIT, -1);
> >  
> > @@ -7331,6 +7355,12 @@ iwm_notif_intr(struct iwm_softc *sc)
> >                     break;
> >  
> >             case IWM_ADD_STA_KEY:
> > +                   if (sc->sc_flags & IWM_FLAG_CCMP_KEY_SENT) {
> > +                           sc->sc_flags |= IWM_FLAG_CCMP_READY;
> > +                           sc->sc_flags &= ~IWM_FLAG_CCMP_KEY_SENT;
> > +                   }
> > +                   break;
> > +
> >             case IWM_PHY_CONFIGURATION_CMD:
> >             case IWM_TX_ANT_CONFIGURATION_CMD:
> >             case IWM_ADD_STA:
> > blob - e6593fbc840833a36d5a792042faaa85e3ac9719
> > blob + 747616074f868d8679f9f01232dec4ce09474f93
> > --- sys/dev/pci/if_iwmvar.h
> > +++ sys/dev/pci/if_iwmvar.h
> > @@ -289,6 +289,8 @@ struct iwm_rx_ring {
> >  #define IWM_FLAG_HW_ERR            0x80    /* hardware error occurred */
> >  #define IWM_FLAG_SHUTDOWN  0x100   /* shutting down; new tasks forbidden */
> >  #define IWM_FLAG_BGSCAN            0x200   /* background scan in progress 
> > */
> > +#define IWM_FLAG_CCMP_KEY_SENT     0x400   /* CCMP key sent to firmware */
> > +#define IWM_FLAG_CCMP_READY        0x800   /* CCMP key installed in 
> > firmware */
> >  
> >  struct iwm_ucode_status {
> >     uint32_t uc_error_event_table;
> > 
> > 
> 

Reply via email to