wifi: cfg80211: Increase akm_suites array size in cfg80211_crypto_settings
authorVeerendranath Jakkam <quic_vjakkam@quicinc.com>
Mon, 23 May 2022 13:25:58 +0000 (18:55 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 1 Jul 2022 10:07:08 +0000 (12:07 +0200)
Increase akm_suites array size in struct cfg80211_crypto_settings to 10
and advertise the capability to userspace. This allows userspace to send
more than two AKMs to driver in netlink commands such as
NL80211_CMD_CONNECT.

This capability is needed for implementing WPA3-Personal transition mode
correctly with any driver that handles roaming internally. Currently,
the possible AKMs for multi-AKM connect can include PSK, PSK-SHA-256,
SAE, FT-PSK and FT-SAE. Since the count is already 5, increasing
the akm_suites array size to 10 should be reasonable for future
usecases.

Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
Link: https://lore.kernel.org/r/1653312358-12321-1-git-send-email-quic_vjakkam@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/quantenna/qtnfmac/commands.c
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/core.c
net/wireless/nl80211.c

index 3d734a7..0fad536 100644 (file)
@@ -241,6 +241,7 @@ int qtnf_cmd_send_start_ap(struct qtnf_vif *vif,
        struct qlink_auth_encr *aen;
        int ret;
        int i;
+       int n;
 
        if (!qtnf_cmd_start_ap_can_fit(vif, s))
                return -E2BIG;
@@ -280,8 +281,9 @@ int qtnf_cmd_send_start_ap(struct qtnf_vif *vif,
        for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++)
                aen->ciphers_pairwise[i] =
                                cpu_to_le32(s->crypto.ciphers_pairwise[i]);
-       aen->n_akm_suites = cpu_to_le32(s->crypto.n_akm_suites);
-       for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++)
+       n = min(QLINK_MAX_NR_AKM_SUITES, s->crypto.n_akm_suites);
+       aen->n_akm_suites = cpu_to_le32(n);
+       for (i = 0; i < n; i++)
                aen->akm_suites[i] = cpu_to_le32(s->crypto.akm_suites[i]);
        aen->control_port = s->crypto.control_port;
        aen->control_port_no_encrypt = s->crypto.control_port_no_encrypt;
@@ -2076,6 +2078,7 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif,
        struct qlink_auth_encr *aen;
        int ret;
        int i;
+       int n;
        u32 connect_flags = 0;
 
        cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
@@ -2132,9 +2135,10 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif,
                aen->ciphers_pairwise[i] =
                        cpu_to_le32(sme->crypto.ciphers_pairwise[i]);
 
-       aen->n_akm_suites = cpu_to_le32(sme->crypto.n_akm_suites);
+       n = min(QLINK_MAX_NR_AKM_SUITES, sme->crypto.n_akm_suites);
+       aen->n_akm_suites = cpu_to_le32(n);
 
-       for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++)
+       for (i = 0; i < n; i++)
                aen->akm_suites[i] = cpu_to_le32(sme->crypto.akm_suites[i]);
 
        aen->control_port = sme->crypto.control_port;
index 87ebed6..6bc161d 100644 (file)
@@ -1063,6 +1063,7 @@ struct survey_info {
 };
 
 #define CFG80211_MAX_WEP_KEYS  4
+#define CFG80211_MAX_NUM_AKM_SUITES    10
 
 /**
  * struct cfg80211_crypto_settings - Crypto settings
@@ -1114,7 +1115,7 @@ struct cfg80211_crypto_settings {
        int n_ciphers_pairwise;
        u32 ciphers_pairwise[NL80211_MAX_NR_CIPHER_SUITES];
        int n_akm_suites;
-       u32 akm_suites[NL80211_MAX_NR_AKM_SUITES];
+       u32 akm_suites[CFG80211_MAX_NUM_AKM_SUITES];
        bool control_port;
        __be16 control_port_ethertype;
        bool control_port_no_encrypt;
@@ -5200,6 +5201,13 @@ struct wiphy_iftype_akm_suites {
  * @ema_max_profile_periodicity: maximum profile periodicity supported by
  *     the driver. Setting this field to a non-zero value indicates that the
  *     driver supports enhanced multi-BSSID advertisements (EMA AP).
+ * @max_num_akm_suites: maximum number of AKM suites allowed for
+ *     configuration through %NL80211_CMD_CONNECT, %NL80211_CMD_ASSOCIATE and
+ *     %NL80211_CMD_START_AP. Set to NL80211_MAX_NR_AKM_SUITES if not set by
+ *     driver. If set by driver minimum allowed value is
+ *     NL80211_MAX_NR_AKM_SUITES in order to avoid compatibility issues with
+ *     legacy userspace and maximum allowed value is
+ *     CFG80211_MAX_NUM_AKM_SUITES.
  */
 struct wiphy {
        struct mutex mtx;
@@ -5346,6 +5354,7 @@ struct wiphy {
 
        u8 mbssid_max_interfaces;
        u8 ema_max_profile_periodicity;
+       u16 max_num_akm_suites;
 
        char priv[] __aligned(NETDEV_ALIGN);
 };
index 89f64f4..279f971 100644 (file)
@@ -2694,6 +2694,13 @@ enum nl80211_commands {
  *     connection. Used with %NL80211_CMD_CONNECT. If this attribute is not
  *     included in NL80211_CMD_CONNECT drivers must not perform MLO connection.
  *
+ * @NL80211_ATTR_MAX_NUM_AKM_SUITES: U16 attribute. Indicates maximum number of
+ *     AKM suites allowed for %NL80211_CMD_CONNECT, %NL80211_CMD_ASSOCIATE and
+ *     %NL80211_CMD_START_AP in %NL80211_CMD_GET_WIPHY response. If this
+ *     attribute is not present userspace shall consider maximum number of AKM
+ *     suites allowed as %NL80211_MAX_NR_AKM_SUITES which is the legacy maximum
+ *     number prior to the introduction of this attribute.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3214,6 +3221,8 @@ enum nl80211_attrs {
 
        NL80211_ATTR_MLO_SUPPORT,
 
+       NL80211_ATTR_MAX_NUM_AKM_SUITES,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
@@ -3268,6 +3277,11 @@ enum nl80211_attrs {
 #define NL80211_HE_MIN_CAPABILITY_LEN           16
 #define NL80211_HE_MAX_CAPABILITY_LEN           54
 #define NL80211_MAX_NR_CIPHER_SUITES           5
+
+/*
+ * NL80211_MAX_NR_AKM_SUITES is obsolete when %NL80211_ATTR_MAX_NUM_AKM_SUITES
+ * present in %NL80211_CMD_GET_WIPHY response.
+ */
 #define NL80211_MAX_NR_AKM_SUITES              2
 #define NL80211_EHT_MIN_CAPABILITY_LEN          13
 #define NL80211_EHT_MAX_CAPABILITY_LEN          51
index 3e5d120..6b5321b 100644 (file)
@@ -913,6 +913,12 @@ int wiphy_register(struct wiphy *wiphy)
                return -EINVAL;
 #endif
 
+       if (!wiphy->max_num_akm_suites)
+               wiphy->max_num_akm_suites = NL80211_MAX_NR_AKM_SUITES;
+       else if (wiphy->max_num_akm_suites < NL80211_MAX_NR_AKM_SUITES ||
+                wiphy->max_num_akm_suites > CFG80211_MAX_NUM_AKM_SUITES)
+               return -EINVAL;
+
        /* check and set up bitrates */
        ieee80211_set_bitrate_flags(wiphy);
 
index b583a76..e2b6740 100644 (file)
@@ -798,6 +798,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
                NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS),
        [NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
        [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
+       [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
 };
 
 /* policy for the key attributes */
@@ -2932,6 +2933,10 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
                if (nl80211_put_mbssid_support(&rdev->wiphy, msg))
                        goto nla_put_failure;
 
+               if (nla_put_u16(msg, NL80211_ATTR_MAX_NUM_AKM_SUITES,
+                               rdev->wiphy.max_num_akm_suites))
+                       goto nla_put_failure;
+
                /* done */
                state->split_start = 0;
                break;
@@ -10431,7 +10436,7 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
                if (len % sizeof(u32))
                        return -EINVAL;
 
-               if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
+               if (settings->n_akm_suites > rdev->wiphy.max_num_akm_suites)
                        return -EINVAL;
 
                memcpy(settings->akm_suites, data, len);