Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Apr 2025 11:41:57 GMT
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: e2e40ccaf1a1 - stable/14 - LinuxKPI: 802.11: add the key mgmt for TKIP and extra checks for CCMP
Message-ID:  <202504291141.53TBfv3S046434@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=e2e40ccaf1a1312679b402f925f5d78f796bc43a

commit e2e40ccaf1a1312679b402f925f5d78f796bc43a
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2025-04-15 21:28:48 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2025-04-29 10:49:31 +0000

    LinuxKPI: 802.11: add the key mgmt for TKIP and extra checks for CCMP
    
    Set iv/icv_len for TKIP as well.
    Add checks for both TKIP and CCMP that we do not get any unexpected
    or unimplemented flags back from KEY_SET.
    
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit 92942717fd4cdcfac4c51a46accd3e5ed532cdb7)
    (cherry picked from commit 91716e8dc1a3452fecedc724e5ef0274413ce7a0)
---
 sys/compat/linuxkpi/common/src/linux_80211.c | 75 ++++++++++++++++++++++++++--
 1 file changed, 71 insertions(+), 4 deletions(-)

diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index 86a8286d66eb..d6eeaf01d56b 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -1352,6 +1352,7 @@ lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
 	struct ieee80211_node *ni;
 	struct ieee80211_key_conf *kc;
 	uint32_t lcipher;
+	uint16_t exp_flags;
 	int error;
 
 	ic = vap->iv_ic;
@@ -1390,8 +1391,8 @@ lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
 	    k->wk_cipher->ic_cipher, k->wk_keylen);
 	switch (lcipher) {
 	case WLAN_CIPHER_SUITE_CCMP:
-		break;
 	case WLAN_CIPHER_SUITE_TKIP:
+		break;
 	default:
 		ic_printf(ic, "%s: CIPHER SUITE %#x (%s) not supported\n",
 		    __func__, lcipher, lkpi_cipher_suite_to_name(lcipher));
@@ -1423,6 +1424,9 @@ lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
 		kc->icv_len = k->wk_cipher->ic_trailer;
 		break;
 	case WLAN_CIPHER_SUITE_TKIP:
+		kc->iv_len = k->wk_cipher->ic_header;
+		kc->icv_len = k->wk_cipher->ic_trailer;
+		break;
 	default:
 		/* currently UNREACH */
 		IMPROVE();
@@ -1460,6 +1464,53 @@ lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
 		    kc, kc->keyidx, kc->hw_key_idx, kc->flags, IEEE80211_KEY_FLAG_BITS);
 #endif
 
+	exp_flags = 0;
+	switch (kc->cipher) {
+	case WLAN_CIPHER_SUITE_TKIP:
+		exp_flags = (IEEE80211_KEY_FLAG_PAIRWISE |
+			IEEE80211_KEY_FLAG_PUT_IV_SPACE |
+			IEEE80211_KEY_FLAG_GENERATE_MMIC |
+			IEEE80211_KEY_FLAG_PUT_MIC_SPACE);
+#define	TKIP_INVAL_COMBINATION						\
+     (IEEE80211_KEY_FLAG_PUT_MIC_SPACE|IEEE80211_KEY_FLAG_GENERATE_MMIC)
+		if ((kc->flags & TKIP_INVAL_COMBINATION) == TKIP_INVAL_COMBINATION) {
+			ic_printf(ic, "%s: SET_KEY for %s returned invalid "
+			    "combination %b\n", __func__,
+			    lkpi_cipher_suite_to_name(kc->cipher),
+			    kc->flags, IEEE80211_KEY_FLAG_BITS);
+		}
+#undef	TKIP_INVAL_COMBINATION
+#ifdef __notyet__
+		/* Do flags surgery; special see linuxkpi_ieee80211_ifattach(). */
+		if ((kc->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) != 0) {
+			k->wk_flags &= ~(IEEE80211_KEY_NOMICMGT|IEEE80211_KEY_NOMIC);
+			k->wk_flags |= IEEE80211_KEY_SWMIC;
+			ic->ic_cryptocaps &= ~IEEE80211_CRYPTO_TKIPMIC
+		}
+#endif
+		break;
+	case WLAN_CIPHER_SUITE_CCMP:
+		exp_flags = (IEEE80211_KEY_FLAG_PAIRWISE |
+		    IEEE80211_KEY_FLAG_PUT_IV_SPACE |
+		    IEEE80211_KEY_FLAG_GENERATE_IV |
+		    IEEE80211_KEY_FLAG_GENERATE_IV_MGMT |	/* Only needs IV geeration for MGMT frames. */
+		    IEEE80211_KEY_FLAG_SW_MGMT_TX);		/* MFP in software */
+		break;
+	}
+	if ((kc->flags & ~exp_flags) != 0)
+		ic_printf(ic, "%s: SET_KEY for %s returned unexpected key flags: "
+		    " %#06x & ~%#06x = %b\n", __func__,
+		    lkpi_cipher_suite_to_name(kc->cipher), kc->flags, exp_flags,
+		    (kc->flags & ~exp_flags), IEEE80211_KEY_FLAG_BITS);
+
+#ifdef __notyet__
+	/* Do flags surgery. */
+	if ((kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) == 0)
+		k->wk_flags |= IEEE80211_KEY_NOIVMGT;
+	if ((kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV) == 0)
+		k->wk_flags |= IEEE80211_KEY_NOIV;
+#endif
+
 	ieee80211_free_node(ni);
 	return (1);
 }
@@ -5956,16 +6007,32 @@ linuxkpi_ieee80211_ifattach(struct ieee80211_hw *hw)
 		uint32_t hwciphers;
 
 		hwciphers = 0;
-		for (i = 0; i < hw->wiphy->n_cipher_suites; i++)
-			hwciphers |= lkpi_l80211_to_net80211_cyphers(
+		for (i = 0; i < hw->wiphy->n_cipher_suites; i++) {
+			uint32_t cs;
+
+			cs = lkpi_l80211_to_net80211_cyphers(
 			    ic, hw->wiphy->cipher_suites[i]);
+			if (cs == IEEE80211_CRYPTO_TKIP) {
+				/*
+				 * We do set this here.  We will only find out
+				 * when doing a SET_KEY operation depending on
+				 * what the driver returns.
+				 * net80211::ieee80211_crypto_newkey()
+				 * checks this so we will have to do flags
+				 * surgery later.
+				 */
+				cs |= IEEE80211_CRYPTO_TKIPMIC;
+			}
+			hwciphers |= cs;
+		}
 		/*
 		 * (20250415) nothing anywhere in the path checks we actually
 		 * support all these in net80211.
 		 * net80211 supports _256 variants but the ioctl does not.
 		 */
 		IMPROVE("as net80211 grows more support, enable them");
-		hwciphers &= (IEEE80211_CRYPTO_WEP | IEEE80211_CRYPTO_TKIP |
+		hwciphers &= (IEEE80211_CRYPTO_WEP |
+		    IEEE80211_CRYPTO_TKIP | IEEE80211_CRYPTO_TKIPMIC |
 		    IEEE80211_CRYPTO_AES_CCM | IEEE80211_CRYPTO_AES_GCM_128);
 		/* We only support CCMP here, so further filter. */
 		hwciphers &= IEEE80211_CRYPTO_AES_CCM;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202504291141.53TBfv3S046434>