cfg80211: Add support to configure SAE PWE value to drivers
authorRohan Dutta <drohan@codeaurora.org>
Tue, 27 Oct 2020 10:09:10 +0000 (12:09 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 6 Nov 2020 09:00:04 +0000 (10:00 +0100)
Add support to configure SAE PWE preference from userspace to drivers in
both AP and STA modes. This is needed for cases where the driver takes
care of Authentication frame processing (SME in the driver) so that
correct enforcement of the acceptable PWE derivation mechanism can be
performed.

The userspace applications can pass the sae_pwe value using the
NL80211_ATTR_SAE_PWE attribute in the NL80211_CMD_CONNECT and
NL80211_CMD_START_AP commands to the driver. This allows selection
between the hunting-and-pecking loop and hash-to-element options for PWE
derivation. For backwards compatibility, this new attribute is optional
and if not included, the driver is notified of the value being
unspecified.

Signed-off-by: Rohan Dutta <drohan@codeaurora.org>
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
Link: https://lore.kernel.org/r/20201027100910.22283-1-jouni@codeaurora.org
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/nl80211.c

index 661edfc8722e1cf205cceb836a851de40210e1a8..0ba8d1fa6eb94113645cedef826de8992a29ca9b 100644 (file)
@@ -1008,6 +1008,14 @@ struct survey_info {
  * @sae_pwd: password for SAE authentication (for devices supporting SAE
  *     offload)
  * @sae_pwd_len: length of SAE password (for devices supporting SAE offload)
+ * @sae_pwe: The mechanisms allowed for SAE PWE derivation
+ *     NL80211_SAE_PWE_UNSPECIFIED: Not-specified, used to indicate userspace
+ *             did not specify any preference. The driver should follow its
+ *             internal policy in such a scenario.
+ *     NL80211_SAE_PWE_HUNT_AND_PECK: Allow hunting-and-pecking loop only
+ *     NL80211_SAE_PWE_HASH_TO_ELEMENT: Allow hash-to-element only
+ *     NL80211_SAE_PWE_BOTH: Allow either hunting-and-pecking loop
+ *             or hash-to-element
  */
 struct cfg80211_crypto_settings {
        u32 wpa_versions;
@@ -1026,6 +1034,7 @@ struct cfg80211_crypto_settings {
        const u8 *psk;
        const u8 *sae_pwd;
        u8 sae_pwd_len;
+       enum nl80211_sae_pwe_mechanism sae_pwe;
 };
 
 /**
index 47700a2b9af962f387a7759af4092e2a6a04412a..2d733effcdaf1cec2c55c027d4562ad968f226e8 100644 (file)
@@ -2527,6 +2527,11 @@ enum nl80211_commands {
  *     override mask. Used with NL80211_ATTR_S1G_CAPABILITY in
  *     NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT.
  *
+ * @NL80211_ATTR_SAE_PWE: Indicates the mechanism(s) allowed for SAE PWE
+ *     derivation in WPA3-Personal networks which are using SAE authentication.
+ *     This is a u8 attribute that encapsulates one of the values from
+ *     &enum nl80211_sae_pwe_mechanism.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3016,6 +3021,8 @@ enum nl80211_attrs {
        NL80211_ATTR_S1G_CAPABILITY,
        NL80211_ATTR_S1G_CAPABILITY_MASK,
 
+       NL80211_ATTR_SAE_PWE,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
@@ -7124,4 +7131,23 @@ enum nl80211_unsol_bcast_probe_resp_attributes {
        NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX =
                __NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_LAST - 1
 };
+
+/**
+ * enum nl80211_sae_pwe_mechanism - The mechanism(s) allowed for SAE PWE
+ *     derivation. Applicable only when WPA3-Personal SAE authentication is
+ *     used.
+ *
+ * @NL80211_SAE_PWE_UNSPECIFIED: not specified, used internally to indicate that
+ *     attribute is not present from userspace.
+ * @NL80211_SAE_PWE_HUNT_AND_PECK: hunting-and-pecking loop only
+ * @NL80211_SAE_PWE_HASH_TO_ELEMENT: hash-to-element only
+ * @NL80211_SAE_PWE_BOTH: both hunting-and-pecking loop and hash-to-element
+ *     can be used.
+ */
+enum nl80211_sae_pwe_mechanism {
+       NL80211_SAE_PWE_UNSPECIFIED,
+       NL80211_SAE_PWE_HUNT_AND_PECK,
+       NL80211_SAE_PWE_HASH_TO_ELEMENT,
+       NL80211_SAE_PWE_BOTH,
+};
 #endif /* __LINUX_NL80211_H */
index 554796a6c6fe5dcb3461d688f12a08a19a4a92cf..0928ecbe5bd639a52793c625bdd3cc6f300d98b1 100644 (file)
@@ -715,6 +715,9 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
                NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
        [NL80211_ATTR_S1G_CAPABILITY_MASK] =
                NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
+       [NL80211_ATTR_SAE_PWE] =
+               NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
+                                NL80211_SAE_PWE_BOTH),
 };
 
 /* policy for the key attributes */
@@ -9731,6 +9734,12 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
                        nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
        }
 
+       if (info->attrs[NL80211_ATTR_SAE_PWE])
+               settings->sae_pwe =
+                       nla_get_u8(info->attrs[NL80211_ATTR_SAE_PWE]);
+       else
+               settings->sae_pwe = NL80211_SAE_PWE_UNSPECIFIED;
+
        return 0;
 }