diff mbox series

[RESEND] Check driver support before selecting ciphers

Message ID 20240311143846.3574071-1-matthewmwang@chromium.org
State New
Headers show
Series [RESEND] Check driver support before selecting ciphers | expand

Commit Message

Matthew Wang March 11, 2024, 2:38 p.m. UTC
We currently don't check driver support before selecting pairwise and
group ciphers. Check that the driver supports a cipher before selecting
it, otherwise fall back.

Signed-off-by: Matthew Wang <matthewmwang@chromium.org>
---
 wpa_supplicant/wpa_supplicant.c   | 41 ++++++++++++++++++++++++++-----
 wpa_supplicant/wpa_supplicant_i.h |  1 +
 2 files changed, 36 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 172a863cb..bec2c9037 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1747,10 +1747,10 @@  int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 	wpa_s->group_cipher = WPA_CIPHER_NONE;
 	wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
 #else /* CONFIG_NO_WPA */
-	sel = ie.group_cipher & ssid->group_cipher;
+	sel = ie.group_cipher & ssid->group_cipher & wpa_s->drv_ciphers;
 	wpa_dbg(wpa_s, MSG_DEBUG,
-		"WPA: AP group 0x%x network profile group 0x%x; available group 0x%x",
-		ie.group_cipher, ssid->group_cipher, sel);
+		"WPA: AP group 0x%x network profile group 0x%x driver supported ciphers 0x%x; available group 0x%x",
+		ie.group_cipher, ssid->group_cipher, wpa_s->drv_ciphers, sel);
 	wpa_s->group_cipher = wpa_pick_group_cipher(sel);
 	if (wpa_s->group_cipher < 0) {
 		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
@@ -1760,10 +1760,11 @@  int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 	wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
 		wpa_cipher_txt(wpa_s->group_cipher));
 
-	sel = ie.pairwise_cipher & ssid->pairwise_cipher;
+	sel = ie.pairwise_cipher & ssid->pairwise_cipher & wpa_s->drv_ciphers;
 	wpa_dbg(wpa_s, MSG_DEBUG,
-		"WPA: AP pairwise 0x%x network profile pairwise 0x%x; available pairwise 0x%x",
-		ie.pairwise_cipher, ssid->pairwise_cipher, sel);
+		"WPA: AP pairwise 0x%x network profile pairwise 0x%x driver supported ciphers 0x%x; available pairwise 0x%x",
+		ie.pairwise_cipher, ssid->pairwise_cipher, wpa_s->drv_ciphers,
+		sel);
 	wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
 	if (wpa_s->pairwise_cipher < 0) {
 		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
@@ -7040,6 +7041,33 @@  static void wpas_gas_server_tx(void *ctx, int freq, const u8 *da,
 
 #endif /* CONFIG_GAS_SERVER */
 
+static unsigned int wpas_drv_enc_to_ciphers(unsigned int drv_enc)
+{
+	unsigned int ciphers = 0;
+	if (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40)
+		ciphers |= WPA_CIPHER_WEP40;
+	if (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104)
+		ciphers |= WPA_CIPHER_WEP104;
+	if (drv_enc & WPA_DRIVER_CAPA_ENC_TKIP)
+		ciphers |= WPA_CIPHER_TKIP;
+	if (drv_enc & WPA_DRIVER_CAPA_ENC_CCMP)
+		ciphers |= WPA_CIPHER_CCMP;
+	if (drv_enc & WPA_DRIVER_CAPA_ENC_GCMP)
+		ciphers |= WPA_CIPHER_GCMP;
+	if (drv_enc & WPA_DRIVER_CAPA_ENC_GCMP_256)
+		ciphers |= WPA_CIPHER_GCMP_256;
+	if (drv_enc & WPA_DRIVER_CAPA_ENC_CCMP_256)
+		ciphers |= WPA_CIPHER_CCMP_256;
+	if (drv_enc & WPA_DRIVER_CAPA_ENC_BIP_GMAC_128)
+		ciphers |= WPA_CIPHER_BIP_GMAC_128;
+	if (drv_enc & WPA_DRIVER_CAPA_ENC_BIP_GMAC_256)
+		ciphers |= WPA_CIPHER_BIP_GMAC_256;
+	if (drv_enc & WPA_DRIVER_CAPA_ENC_BIP_CMAC_256)
+		ciphers |= WPA_CIPHER_BIP_CMAC_256;
+	return ciphers;
+}
+
+
 static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
 				     const struct wpa_interface *iface)
 {
@@ -7224,6 +7252,7 @@  static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
 		wpa_s->drv_flags = capa.flags;
 		wpa_s->drv_flags2 = capa.flags2;
 		wpa_s->drv_enc = capa.enc;
+		wpa_s->drv_ciphers = wpas_drv_enc_to_ciphers(wpa_s->drv_enc);
 		wpa_s->drv_rrm_flags = capa.rrm_flags;
 		wpa_s->drv_max_acl_mac_addrs = capa.max_acl_mac_addrs;
 		wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 933fc3626..55929e667 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -920,6 +920,7 @@  struct wpa_supplicant {
 	u64 drv_flags;
 	u64 drv_flags2;
 	unsigned int drv_enc;
+	unsigned int drv_ciphers;
 	unsigned int drv_rrm_flags;
 	unsigned int drv_max_acl_mac_addrs;