From: stsp Date: Mon, 19 Apr 2021 14:27:25 +0000 (+0000) Subject: Multicast decryption fixes for iwx(4). X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=ac84d6f044bdad5b5c559957b2cae7964d452e55;p=openbsd Multicast decryption fixes for iwx(4). Pick the correct key for multicast frames in iwx_ccmp_decap(). Comparing the PN of a multicast frame against the last-seen PN of the pairwise key is obviously wrong. We need to check the multicast frame's PN against the last-seen PN of the group key. Update crypto-offloading checks in iwx_rx_frame() to match recent WPA1/TKIP groupcipher fixes made in athn(4). The code inherited from iwm(4) only looked at the pairwise key, and unlike iwx(4) and athn(4), iwm(4) only offloads pairwise crypto. Found while investigating a question from zxystd at OpenIntelWireless. --- diff --git a/sys/dev/pci/if_iwx.c b/sys/dev/pci/if_iwx.c index b634fded702..cdb3bafe26a 100644 --- a/sys/dev/pci/if_iwx.c +++ b/sys/dev/pci/if_iwx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwx.c,v 1.51 2021/04/14 18:38:54 stsp Exp $ */ +/* $OpenBSD: if_iwx.c,v 1.52 2021/04/19 14:27:25 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh @@ -3252,7 +3252,7 @@ int iwx_ccmp_decap(struct iwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni) { struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_key *k = &ni->ni_pairwise_key; + struct ieee80211_key *k; struct ieee80211_frame *wh; uint64_t pn, *prsc; uint8_t *ivp; @@ -3263,6 +3263,11 @@ iwx_ccmp_decap(struct iwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni) hdrlen = ieee80211_get_hdrlen(wh); ivp = (uint8_t *)wh + hdrlen; + /* find key for decryption */ + k = ieee80211_get_rxkey(ic, m, ni); + if (k == NULL || k->k_cipher != IEEE80211_CIPHER_CCMP) + return 1; + /* Check that ExtIV bit is be set. */ if (!(ivp[3] & IEEE80211_WEP_EXTIV)) return 1; @@ -3327,7 +3332,10 @@ iwx_rx_frame(struct iwx_softc *sc, struct mbuf *m, int chanidx, if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL) && (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) && (ni->ni_flags & IEEE80211_NODE_RXPROT) && - ni->ni_pairwise_key.k_cipher == IEEE80211_CIPHER_CCMP) { + ((!IEEE80211_IS_MULTICAST(wh->i_addr1) && + ni->ni_rsncipher == IEEE80211_CIPHER_CCMP) || + (IEEE80211_IS_MULTICAST(wh->i_addr1) && + ni->ni_rsngroupcipher == IEEE80211_CIPHER_CCMP))) { if ((rx_pkt_status & IWX_RX_MPDU_RES_STATUS_SEC_ENC_MSK) != IWX_RX_MPDU_RES_STATUS_SEC_CCM_ENC) { ic->ic_stats.is_ccmp_dec_errs++;