summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2021-04-19 14:27:26 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2021-04-19 14:27:26 +0000
commitf3974ee7ff6d93ac824fb9caa58b2673fa7a73f6 (patch)
tree3a04168846b8eccf1534241ed49c32f24ae8c94f /sys
parentb0a38277d6ad477388e7164bb7297a4c753582ac (diff)
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_iwx.c14
1 files changed, 11 insertions, 3 deletions
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 <info@genua.de>
@@ -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++;