diff mbox series

[1/2] Check driver support before selecting ciphers

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

Commit Message

Matthew Wang Feb. 7, 2024, 9:16 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.

Change-Id: I343b6656bd695d074ed2ac42d35378711ec1426e
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(-)

Comments

Matthew Wang Feb. 9, 2024, 5:33 p.m. UTC | #1
I'm not sure how faithfully drivers report this, but the second patch
checking the AKMs definitely doesn't work properly (I've found at
least one driver that supports an AKM that it doesn't advertise
support for), please ignore that one.

On Wed, Feb 7, 2024 at 10:16 PM Matthew Wang <matthewmwang@chromium.org> wrote:
>
> 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.
>
> Change-Id: I343b6656bd695d074ed2ac42d35378711ec1426e
> 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 --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;
>
> --
> 2.43.0.594.gd9cf4e227d-goog
>
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;