diff mbox series

[2/2] Check driver support when selecting AKMs

Message ID 20240207211620.3917804-2-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 select an AKM even if the driver doesn't support it. Check
driver support before selecting an AKM, otherwise fall back.

Change-Id: Ib5b13cffa6d993a69db33c2a2cb81480d619bd79
Signed-off-by: Matthew Wang <matthewmwang@chromium.org>
---
 wpa_supplicant/wpa_supplicant.c   | 64 +++++++++++++++++++++----------
 wpa_supplicant/wpa_supplicant_i.h |  1 +
 2 files changed, 44 insertions(+), 21 deletions(-)
diff mbox series

Patch

diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index bec2c9037..9c5955c2b 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1795,7 +1795,8 @@  int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 #ifdef CONFIG_IEEE80211R
 #ifdef CONFIG_SHA384
 	} else if ((sel & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) &&
-		   os_strcmp(wpa_supplicant_get_eap_mode(wpa_s), "LEAP") != 0) {
+		   os_strcmp(wpa_supplicant_get_eap_mode(wpa_s), "LEAP") != 0 &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_802_1X_SHA384)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
 		wpa_dbg(wpa_s, MSG_DEBUG,
 			"WPA: using KEY_MGMT FT/802.1X-SHA384");
@@ -1810,44 +1811,52 @@  int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_SHA384 */
 #endif /* CONFIG_IEEE80211R */
 #ifdef CONFIG_SUITEB192
-	} else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
+	} else if ((sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
 		wpa_dbg(wpa_s, MSG_DEBUG,
 			"WPA: using KEY_MGMT 802.1X with Suite B (192-bit)");
 #endif /* CONFIG_SUITEB192 */
 #ifdef CONFIG_SUITEB
-	} else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
+	} else if ((sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
 		wpa_dbg(wpa_s, MSG_DEBUG,
 			"WPA: using KEY_MGMT 802.1X with Suite B");
 #endif /* CONFIG_SUITEB */
 #ifdef CONFIG_SHA384
-	} else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA384) {
+	} else if ((sel & WPA_KEY_MGMT_IEEE8021X_SHA384) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA384;
 		wpa_dbg(wpa_s, MSG_DEBUG,
 			"WPA: using KEY_MGMT 802.1X with SHA384");
 #endif /* CONFIG_SHA384 */
 #ifdef CONFIG_FILS
 #ifdef CONFIG_IEEE80211R
-	} else if (sel & WPA_KEY_MGMT_FT_FILS_SHA384) {
+	} else if ((sel & WPA_KEY_MGMT_FT_FILS_SHA384) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_FILS_SHA384;
 		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT-FILS-SHA384");
 #endif /* CONFIG_IEEE80211R */
-	} else if (sel & WPA_KEY_MGMT_FILS_SHA384) {
+	} else if ((sel & WPA_KEY_MGMT_FILS_SHA384) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_FILS_SHA384;
 		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FILS-SHA384");
 #ifdef CONFIG_IEEE80211R
-	} else if (sel & WPA_KEY_MGMT_FT_FILS_SHA256) {
+	} else if ((sel & WPA_KEY_MGMT_FT_FILS_SHA256) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_FILS_SHA256;
 		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT-FILS-SHA256");
 #endif /* CONFIG_IEEE80211R */
-	} else if (sel & WPA_KEY_MGMT_FILS_SHA256) {
+	} else if ((sel & WPA_KEY_MGMT_FILS_SHA256) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_FILS_SHA256;
 		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FILS-SHA256");
 #endif /* CONFIG_FILS */
 #ifdef CONFIG_IEEE80211R
 	} else if ((sel & WPA_KEY_MGMT_FT_IEEE8021X) &&
-		   os_strcmp(wpa_supplicant_get_eap_mode(wpa_s), "LEAP") != 0) {
+		   os_strcmp(wpa_supplicant_get_eap_mode(wpa_s), "LEAP") != 0 &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
 		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
 		if (!ssid->ft_eap_pmksa_caching &&
@@ -1860,54 +1869,66 @@  int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 		}
 #endif /* CONFIG_IEEE80211R */
 #ifdef CONFIG_DPP
-	} else if (sel & WPA_KEY_MGMT_DPP) {
+	} else if ((sel & WPA_KEY_MGMT_DPP) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_DPP;
 		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT DPP");
 #endif /* CONFIG_DPP */
 #ifdef CONFIG_SAE
-	} else if (sel & WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
+	} else if ((sel & WPA_KEY_MGMT_FT_SAE_EXT_KEY) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE_EXT_KEY)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE_EXT_KEY;
 		wpa_dbg(wpa_s, MSG_DEBUG,
 			"RSN: using KEY_MGMT FT/SAE (ext key)");
-	} else if (sel & WPA_KEY_MGMT_SAE_EXT_KEY) {
+	} else if ((sel & WPA_KEY_MGMT_SAE_EXT_KEY) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE_EXT_KEY)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_SAE_EXT_KEY;
 		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE (ext key)");
-	} else if (sel & WPA_KEY_MGMT_FT_SAE) {
+	} else if ((sel & WPA_KEY_MGMT_FT_SAE) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
 		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
-	} else if (sel & WPA_KEY_MGMT_SAE) {
+	} else if ((sel & WPA_KEY_MGMT_SAE) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
 		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
 #endif /* CONFIG_SAE */
 #ifdef CONFIG_IEEE80211R
-	} else if (sel & WPA_KEY_MGMT_FT_PSK) {
+	} else if ((sel & WPA_KEY_MGMT_FT_PSK) &&
+		   wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
 		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
 #endif /* CONFIG_IEEE80211R */
-	} else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
+	} else if ((sel & WPA_KEY_MGMT_IEEE8021X_SHA256) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_802_1X_SHA256)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
 		wpa_dbg(wpa_s, MSG_DEBUG,
 			"WPA: using KEY_MGMT 802.1X with SHA256");
-	} else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
+	} else if ((sel & WPA_KEY_MGMT_PSK_SHA256) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_PSK_SHA256)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
 		wpa_dbg(wpa_s, MSG_DEBUG,
 			"WPA: using KEY_MGMT PSK with SHA256");
-	} else if (sel & WPA_KEY_MGMT_IEEE8021X) {
+	} else if ((sel & WPA_KEY_MGMT_IEEE8021X) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
 		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
-	} else if (sel & WPA_KEY_MGMT_PSK) {
+	} else if ((sel & WPA_KEY_MGMT_PSK) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
 		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
 	} else if (sel & WPA_KEY_MGMT_WPA_NONE) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
 		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
 #ifdef CONFIG_HS20
-	} else if (sel & WPA_KEY_MGMT_OSEN) {
+	} else if ((sel & WPA_KEY_MGMT_OSEN) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OSEN)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_OSEN;
 		wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using KEY_MGMT OSEN");
 #endif /* CONFIG_HS20 */
 #ifdef CONFIG_OWE
-	} else if (sel & WPA_KEY_MGMT_OWE) {
+	} else if ((sel & WPA_KEY_MGMT_OWE) &&
+		   (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE)) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_OWE;
 		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT OWE");
 #endif /* CONFIG_OWE */
@@ -7253,6 +7274,7 @@  static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
 		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_key_mgmt = capa.key_mgmt;
 		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 55929e667..d5490e513 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -921,6 +921,7 @@  struct wpa_supplicant {
 	u64 drv_flags2;
 	unsigned int drv_enc;
 	unsigned int drv_ciphers;
+	unsigned int drv_key_mgmt;
 	unsigned int drv_rrm_flags;
 	unsigned int drv_max_acl_mac_addrs;