]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Handle AKM suite selectors for AP configuration
authorJouni Malinen <jouni@codeaurora.org>
Mon, 17 Feb 2020 15:43:11 +0000 (17:43 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 17 Feb 2020 15:47:34 +0000 (17:47 +0200)
Previously only couple of AKM suite selectors were converted into
NL80211_ATTR_AKM_SUITES. Add rest of the AKM suites here. However, since
the current kernel interface has a very small limit
(NL80211_MAX_NR_AKM_SUITES = 2), add the attribute only when no more
than that limit entries are included. cfg80211 would reject the command
with any more entries listed.

This needs to be extended in cfg80211/nl80211 in a backwards compatible
manner, so this seems to be the best that can be done for now in user
space. Many drivers do not use this attribute, so must not reject the
configuration completely when larger number of AKM suites is configured.
Such cases may not work properly with drivers that depend on
NL80211_ATTR_AKM_SUITES value.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/drivers/driver_nl80211.c

index 6c26e8ba893ae4bd621b1f1a3fddec78dee2bd9e..d55d8e8f5559ace19fcba919f79ae2dcf7b2c96c 100644 (file)
@@ -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 &&