aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2024-04-17 01:53:52 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2025-04-29 10:49:28 +0000
commitcaebab19e711d0f5c12070ae4c2b74d2d13d5cb3 (patch)
treefe1e8ad7a3f3bf7503780aea9aa7e2b0798bfce5
parent0ed97681a30d968c03c5526739948da29d3f2215 (diff)
net80211: add a new field specifically for announcing specific ciphers
This dates way, way back with the original net80211 support w/ atheros chips. The earliest chip (AR5210) had limitations supporting software encryption. It only had the four WEP slots, and not any keycache entries. So when trying to do CCMP/TKIP encryption would be enabled and the key slots would have nothing useful in them, resulting in garbage encryption/decryption. I changed this back in 2012 to disable supporting hardware WEP for AR5210 so if_ath(4) / net80211 crypto is all done in software and yes, I could do CCMP/TKIP on AR5210 in software. Fast-forward to newer-ish hardware - the Qualcomm 11ac hardware. Those also don't support pass-through keycache slots! Well, the hardware does at that layer, but then there's a whole offload data path encap/decap layer that's turning the frames from raw wifi into ethernet frames (for "dumb" AP behaviours) or "wifi direct" frames (ie, "windows".) This hides a bunch of header frame contents required for doing the software encryption / decryption path. But then if you enable the raw transmit/receive frame format it ALSO bypasses the hardware encryption/decryption engine! So for those NICs: * If you want to do encryption, you can only use the firmware supported ciphers w/ wifi direct or ethernet; * If you want to use software encrypt/decrypt, you MUST disable all encryption and instead use 100% software encryption. The wpa_supplicant bsd driver code has a specific comment about this and flips on supporting WEP/TKIP/CCMP, which is understandable but it doesn't fix the ACTUAL intention of all of this stuff. So: * create a new field, ic_sw_cryptocaps * populate it with the default supported set of ciphers for net80211 (right now wep, tkip, ccmp) * Communicate the combination of both ic_sw_cryptocaps and ic_cryptocaps to wpa_supplicant via the relevant devcap ioctl. * Update manpage. I'll follow this up with a driver_bsd.c change in wpa_supplicant to trust this again, and then start adding the other cipher support there. Differential Revision: https://reviews.freebsd.org/D44820 Adjusted for MFC by moving the new field to a spare. Sponsored by: The FreeBSD Foundation (cherry picked from commit 1116e8b95c601ddaac2feb4ab0904f77801a520f)
-rw-r--r--share/man/man9/ieee80211.94
-rw-r--r--sys/net80211/ieee80211_crypto.c12
-rw-r--r--sys/net80211/ieee80211_ioctl.c6
-rw-r--r--sys/net80211/ieee80211_ioctl.h4
-rw-r--r--sys/net80211/ieee80211_var.h8
5 files changed, 28 insertions, 6 deletions
diff --git a/share/man/man9/ieee80211.9 b/share/man/man9/ieee80211.9
index 100b4e7540a5..40c8c243a77c 100644
--- a/share/man/man9/ieee80211.9
+++ b/share/man/man9/ieee80211.9
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd January 26, 2021
+.Dd April 24, 2024
.Dt IEEE80211 9
.Os
.Sh NAME
@@ -514,6 +514,8 @@ General capabilities are specified by
.Vt ic_caps .
Hardware cryptographic capabilities are specified by
.Vt ic_cryptocaps .
+Software cryptographic capabilities are specified by
+.Vt ic_sw_cryptocaps .
802.11n capabilities, if any, are specified by
.Vt ic_htcaps .
The
diff --git a/sys/net80211/ieee80211_crypto.c b/sys/net80211/ieee80211_crypto.c
index bb7a612ac36c..fef63390c27b 100644
--- a/sys/net80211/ieee80211_crypto.c
+++ b/sys/net80211/ieee80211_crypto.c
@@ -142,6 +142,18 @@ ieee80211_crypto_attach(struct ieee80211com *ic)
{
/* NB: we assume everything is pre-zero'd */
ciphers[IEEE80211_CIPHER_NONE] = &ieee80211_cipher_none;
+
+ /*
+ * Default set of net80211 supported ciphers.
+ *
+ * These are the default set that all drivers are expected to
+ * support, either/or in hardware and software.
+ *
+ * Drivers can add their own support to this and the
+ * hardware cipher list (ic_cryptocaps.)
+ */
+ ic->ic_sw_cryptocaps = IEEE80211_CRYPTO_WEP |
+ IEEE80211_CRYPTO_TKIP | IEEE80211_CRYPTO_AES_CCM;
}
/*
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index 8432bf4bcbfd..3b57e7d8cd8e 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -709,7 +709,11 @@ ieee80211_ioctl_getdevcaps(struct ieee80211com *ic,
if (dc == NULL)
return ENOMEM;
dc->dc_drivercaps = ic->ic_caps;
- dc->dc_cryptocaps = ic->ic_cryptocaps;
+ /*
+ * Announce the set of both hardware and software supported
+ * ciphers.
+ */
+ dc->dc_cryptocaps = ic->ic_cryptocaps | ic->ic_sw_cryptocaps;
dc->dc_htcaps = ic->ic_htcaps;
dc->dc_vhtcaps = ic->ic_vht_cap.vht_cap_info;
ci = &dc->dc_chaninfo;
diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h
index 58080025b5a9..18152495c499 100644
--- a/sys/net80211/ieee80211_ioctl.h
+++ b/sys/net80211/ieee80211_ioctl.h
@@ -551,13 +551,13 @@ struct ieee80211_regdomain_req {
IEEE80211_REGDOMAIN_SIZE((_req)->chaninfo.ic_nchans)
/*
- * Get driver capabilities. Driver, hardware crypto, and
+ * Get driver capabilities. Driver, hardware/software crypto, and
* HT/802.11n capabilities, and a table that describes what
* the radio can do.
*/
struct ieee80211_devcaps_req {
uint32_t dc_drivercaps; /* general driver caps */
- uint32_t dc_cryptocaps; /* hardware crypto support */
+ uint32_t dc_cryptocaps; /* software + hardware crypto support */
uint32_t dc_htcaps; /* HT/802.11n support */
uint32_t dc_vhtcaps; /* VHT/802.11ac capabilities */
struct ieee80211req_chaninfo dc_chaninfo;
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 3e7ad7942de7..dd6737aedb66 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -163,7 +163,7 @@ struct ieee80211com {
uint32_t ic_caps; /* capabilities */
uint32_t ic_htcaps; /* HT capabilities */
uint32_t ic_htextcaps; /* HT extended capabilities */
- uint32_t ic_cryptocaps; /* crypto capabilities */
+ uint32_t ic_cryptocaps; /* hardware crypto caps */
/* set of mode capabilities */
uint8_t ic_modecaps[IEEE80211_MODE_BYTES];
uint8_t ic_promisc; /* vap's needing promisc mode */
@@ -375,7 +375,11 @@ struct ieee80211com {
void (*ic_update_chw)(struct ieee80211com *);
const struct debugnet80211_methods *ic_debugnet_meth;
- uint64_t ic_spare[7];
+ /* driver-supported software crypto caps */
+ uint32_t ic_sw_cryptocaps;
+
+ uint32_t ic_spare1;
+ uint64_t ic_spare[6];
};
struct ieee80211_aclator;