diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 6c26e8ba8..d55d8e8f5 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -2942,6 +2942,40 @@ static int wpa_cipher_to_cipher_suites(unsigned int ciphers, u32 suites[], } +static int wpa_key_mgmt_to_suites(unsigned int key_mgmt_suites, u32 suites[], + int max_suites) +{ + int num_suites = 0; + +#define __AKM(a, b) \ + if (num_suites < max_suites && \ + (key_mgmt_suites & (WPA_KEY_MGMT_ ## a))) \ + suites[num_suites++] = (RSN_AUTH_KEY_MGMT_ ## b) + __AKM(IEEE8021X, UNSPEC_802_1X); + __AKM(PSK, PSK_OVER_802_1X); + __AKM(FT_IEEE8021X, FT_802_1X); + __AKM(FT_PSK, FT_PSK); + __AKM(IEEE8021X_SHA256, 802_1X_SHA256); + __AKM(PSK_SHA256, PSK_SHA256); + __AKM(SAE, SAE); + __AKM(FT_SAE, FT_SAE); + __AKM(CCKM, CCKM); + __AKM(OSEN, OSEN); + __AKM(IEEE8021X_SUITE_B, 802_1X_SUITE_B); + __AKM(IEEE8021X_SUITE_B_192, 802_1X_SUITE_B_192); + __AKM(FILS_SHA256, FILS_SHA256); + __AKM(FILS_SHA384, FILS_SHA384); + __AKM(FT_FILS_SHA256, FT_FILS_SHA256); + __AKM(FT_FILS_SHA384, FT_FILS_SHA384); + __AKM(OWE, OWE); + __AKM(DPP, DPP); + __AKM(FT_IEEE8021X_SHA384, FT_802_1X_SHA384); +#undef __AKM + + return num_suites; +} + + #ifdef CONFIG_DRIVER_NL80211_QCA static int issue_key_mgmt_set_key(struct wpa_driver_nl80211_data *drv, const u8 *key, size_t key_len) @@ -4102,7 +4136,7 @@ static int wpa_driver_nl80211_set_ap(void *priv, int ret = -ENOBUFS; int beacon_set; int num_suites; - u32 suites[10], suite; + u32 suites[20], suite; u32 ver; #ifdef CONFIG_MESH struct wpa_driver_mesh_bss_params mesh_params; @@ -4196,14 +4230,15 @@ static int wpa_driver_nl80211_set_ap(void *priv, wpa_printf(MSG_DEBUG, "nl80211: key_mgmt_suites=0x%x", params->key_mgmt_suites); - num_suites = 0; - if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X) - suites[num_suites++] = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X; - if (params->key_mgmt_suites & WPA_KEY_MGMT_PSK) - suites[num_suites++] = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X; - if (num_suites && - nla_put(msg, NL80211_ATTR_AKM_SUITES, num_suites * sizeof(u32), - suites)) + num_suites = wpa_key_mgmt_to_suites(params->key_mgmt_suites, + suites, ARRAY_SIZE(suites)); + if (num_suites > NL80211_MAX_NR_AKM_SUITES) + wpa_printf(MSG_WARNING, + "nl80211: Not enough room for all AKM suites (num_suites=%d > NL80211_MAX_NR_AKM_SUITES)", + num_suites); + else if (num_suites && + nla_put(msg, NL80211_ATTR_AKM_SUITES, num_suites * sizeof(u32), + suites)) goto fail; if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X_NO_WPA &&