cfg80211: Authentication offload to user space in AP mode
diff mbox series

Message ID 1544779909-27758-1-git-send-email-dasaris@codeaurora.org
State Superseded
Delegated to: Johannes Berg
Headers show
Series
  • cfg80211: Authentication offload to user space in AP mode
Related show

Commit Message

Srinivas Dasari Dec. 14, 2018, 9:31 a.m. UTC
'commit 40cbfa90218b ("cfg80211/nl80211: Optional authentication
offload to userspace")' introduces authentication offload to user
space by the host drivers in station mode. This commit extends
the same for the AP mode too.

Extend NL80211_ATTR_EXTERNAL_AUTH_SUPPORT to also claim the
support of external authentication from the user space in AP mode.
A new flag parameter is introduced in cfg80211_ap_settings to
intend the same while "start ap" .

Host driver to use NL80211_CMD_FRAME interface to transmit and
receive the authentication frames to / from the user space.

Host driver to indicate the flag NL80211_RXMGMT_FLAG_EXTERNAL_AUTH
while sending the authentication frame to the user space. This
intends to the user space that the driver wishes it to process
the authentication frame for certain protocols, though it had
initially advertised the support for SME functionality.

User space shall accordingly do the authentication and indicate
its final status through the command NL80211_CMD_EXTERNAL_AUTH.
Allow the command even if userspace doesn't include the attribute
NL80211_ATTR_SSID for AP interface.

Host driver shall continue with the association sequence and
indicate the STA connection status through cfg80211_new_sta.

To facilitate the host drivers in AP mode for matching the pmkid
by the stations during the association, NL80211_CMD_EXTERNAL_AUTH
is also enhanced to include the pmkid to drivers after
the authentication.
This pmkid can also be used in the STA mode to include in the
association request.
Also enhanced nl80211_external_auth to not mandate SSID in AP mode.

Signed-off-by: Srinivas Dasari <dasaris@codeaurora.org>
---
 include/net/cfg80211.h       | 15 +++++++++++++++
 include/uapi/linux/nl80211.h | 13 +++++++++----
 net/wireless/nl80211.c       | 26 +++++++++++++++++++-------
 3 files changed, 43 insertions(+), 11 deletions(-)

Comments

Johannes Berg Dec. 18, 2018, 1:28 p.m. UTC | #1
Hi,


> @@ -2813,6 +2826,7 @@ struct cfg80211_pmk_conf {
>   *	use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
>   *	the real status code for failures. Used only for the authentication
>   *	response command interface (user space to driver).
> + * @pmkid: The identifier to refer a PMKSA.
>   */
>  struct cfg80211_external_auth_params {
>  	enum nl80211_external_auth_action action;
> @@ -2820,6 +2834,7 @@ struct cfg80211_external_auth_params {
>  	struct cfg80211_ssid ssid;
>  	unsigned int key_mgmt_suite;
>  	u16 status;
> +	const u8 *pmkid;

So, interesting - Andrei also added the PMKID but also the PMK here, in
a separate patch:
https://patchwork.kernel.org/patch/10732093/

>   * @NL80211_ATTR_EXTERNAL_AUTH_SUPPORT: Flag attribute indicating that the user
> - *     space supports external authentication. This attribute shall be used
> - *     only with %NL80211_CMD_CONNECT request. The driver may offload
> - *     authentication processing to user space if this capability is indicated
> - *     in NL80211_CMD_CONNECT requests from the user space.
> + *	space supports external authentication. This attribute shall be used
> + *	with %NL80211_CMD_CONNECT and %NL80211_CMD_START_AP request. The driver
> + *	may offload authentication processing to user space if this capability
> + *	is indicated in the respective requests from the user space.

Thanks for indenting this properly.

> @@ -12981,7 +12984,10 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
>  	if (!rdev->ops->external_auth)
>  		return -EOPNOTSUPP;
>  
> -	if (!info->attrs[NL80211_ATTR_SSID])
> +	if (!info->attrs[NL80211_ATTR_SSID] &&
> +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
> +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
> +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
>  		return -EINVAL;

Hm. do we really expect this on AP_VLAN?

johannes
Otcheretianski, Andrei Dec. 18, 2018, 1:40 p.m. UTC | #2
> So, interesting - Andrei also added the PMKID but also the PMK here, in a
> separate patch:
> https://patchwork.kernel.org/patch/10732093/

Yeah, PMK is needed for the devices that offload 4way handshake.
>>[...]
> > -	if (!info->attrs[NL80211_ATTR_SSID])
> > +	if (!info->attrs[NL80211_ATTR_SSID] &&
> > +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
> > +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
> > +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
> >  		return -EINVAL;
> 
> Hm. do we really expect this on AP_VLAN?

Actually I'm not sure about GO neither. P2P doesn't use SAE etc..

Andrei
> 
> johannes
Srinivas Dasari Dec. 20, 2018, 11:07 a.m. UTC | #3
On 2018-12-18 19:10, Otcheretianski, Andrei wrote:
>> So, interesting - Andrei also added the PMKID but also the PMK here, 
>> in a
>> separate patch:
>> https://patchwork.kernel.org/patch/10732093/
> 
> Yeah, PMK is needed for the devices that offload 4way handshake.
Thanks. Fine with us too. Will have an updated patchset with the pmkid 
part removed, as this is already added with the patch by Andrei.

>>> [...]
>> > -	if (!info->attrs[NL80211_ATTR_SSID])
>> > +	if (!info->attrs[NL80211_ATTR_SSID] &&
>> > +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
>> > +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
>> > +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
>> >  		return -EINVAL;
>> 
>> Hm. do we really expect this on AP_VLAN?
> 
> Actually I'm not sure about GO neither. P2P doesn't use SAE etc..
> 
> Andrei
Since these vifs are similar to an AP, we have considered external 
authentication to be applicable for them as well. Please let me know if 
this is fine . I shall update the patch accordingly.

>> 
>> johannes

Thanks,
Srinivas
Johannes Berg Jan. 15, 2019, 1:26 p.m. UTC | #4
On Thu, 2018-12-20 at 16:37 +0530, dasaris@codeaurora.org wrote:
> On 2018-12-18 19:10, Otcheretianski, Andrei wrote:
> > > So, interesting - Andrei also added the PMKID but also the PMK here, 
> > > in a
> > > separate patch:
> > > https://patchwork.kernel.org/patch/10732093/
> > 
> > Yeah, PMK is needed for the devices that offload 4way handshake.
> 
> Thanks. Fine with us too. Will have an updated patchset with the pmkid 
> part removed, as this is already added with the patch by Andrei.

Well, we're still discussing the whole thing :)

You can add the PMKID here as well, and then Andrei just has to rebase
accordingly?

> > > > [...]
> > > > -	if (!info->attrs[NL80211_ATTR_SSID])
> > > > +	if (!info->attrs[NL80211_ATTR_SSID] &&
> > > > +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
> > > > +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
> > > > +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
> > > >  		return -EINVAL;
> > > 
> > > Hm. do we really expect this on AP_VLAN?
> > 
> > Actually I'm not sure about GO neither. P2P doesn't use SAE etc..
> > 
> > Andrei
> 
> Since these vifs are similar to an AP, we have considered external 
> authentication to be applicable for them as well. Please let me know if 
> this is fine . I shall update the patch accordingly.

Sure, I think it's fine. Even if P2P right now doesn't actually
specify/use WPA3/SAE we can still support it, right?

My question was really more about AP_VLAN, because I was expecting the
handshake to still happen on the AP interface, not on the AP_VLAN?

johannes
Srinivas Dasari Jan. 23, 2019, 12:28 p.m. UTC | #5
On 2019-01-15 18:56, Johannes Berg wrote:
> On Thu, 2018-12-20 at 16:37 +0530, dasaris@codeaurora.org wrote:
>> On 2018-12-18 19:10, Otcheretianski, Andrei wrote:
>> > > So, interesting - Andrei also added the PMKID but also the PMK here,
>> > > in a
>> > > separate patch:
>> > > https://patchwork.kernel.org/patch/10732093/
>> >
>> > Yeah, PMK is needed for the devices that offload 4way handshake.
>> 
>> Thanks. Fine with us too. Will have an updated patchset with the pmkid
>> part removed, as this is already added with the patch by Andrei.
> 
> Well, we're still discussing the whole thing :)
> 
> You can add the PMKID here as well, and then Andrei just has to rebase
> accordingly?

Sure, thanks. Will add this in v3. v2 was sent prior to this comment by 
you.
Please ignore v2.

> 
>> > > > [...]
>> > > > -	if (!info->attrs[NL80211_ATTR_SSID])
>> > > > +	if (!info->attrs[NL80211_ATTR_SSID] &&
>> > > > +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
>> > > > +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
>> > > > +	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
>> > > >  		return -EINVAL;
>> > >
>> > > Hm. do we really expect this on AP_VLAN?
>> >
>> > Actually I'm not sure about GO neither. P2P doesn't use SAE etc..
>> >
>> > Andrei
>> 
>> Since these vifs are similar to an AP, we have considered external
>> authentication to be applicable for them as well. Please let me know 
>> if
>> this is fine . I shall update the patch accordingly.
> 
> Sure, I think it's fine. Even if P2P right now doesn't actually
> specify/use WPA3/SAE we can still support it, right?
> 
> My question was really more about AP_VLAN, because I was expecting the
> handshake to still happen on the AP interface, not on the AP_VLAN?
> 
> johannes

Thanks for this input. We have considered P2P_GO in v3.

Patch
diff mbox series

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ede7fcd..c20d261 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -834,6 +834,17 @@  struct cfg80211_bitrate_mask {
 };
 
 /**
+ * enum cfg80211_ap_settings_flags - AP settings flags
+ *
+ * Used by cfg80211_ap_settings
+ *
+ * @AP_SETTINGS_EXTERNAL_AUTH_SUPPORT: AP supports external authentication
+ */
+enum cfg80211_ap_settings_flags {
+	AP_SETTINGS_EXTERNAL_AUTH_SUPPORT = BIT(0),
+};
+
+/**
  * struct cfg80211_ap_settings - AP configuration
  *
  * Used to configure an AP interface.
@@ -863,6 +874,7 @@  struct cfg80211_bitrate_mask {
  * @he_cap: HE capabilities (or %NULL if HE isn't enabled)
  * @ht_required: stations must support HT
  * @vht_required: stations must support VHT
+ * @flags: flags, as defined in enum cfg80211_ap_settings_flags
  */
 struct cfg80211_ap_settings {
 	struct cfg80211_chan_def chandef;
@@ -888,6 +900,7 @@  struct cfg80211_ap_settings {
 	const struct ieee80211_vht_cap *vht_cap;
 	const struct ieee80211_he_cap_elem *he_cap;
 	bool ht_required, vht_required;
+	u32 flags;
 };
 
 /**
@@ -2813,6 +2826,7 @@  struct cfg80211_pmk_conf {
  *	use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
  *	the real status code for failures. Used only for the authentication
  *	response command interface (user space to driver).
+ * @pmkid: The identifier to refer a PMKSA.
  */
 struct cfg80211_external_auth_params {
 	enum nl80211_external_auth_action action;
@@ -2820,6 +2834,7 @@  struct cfg80211_external_auth_params {
 	struct cfg80211_ssid ssid;
 	unsigned int key_mgmt_suite;
 	u16 status;
+	const u8 *pmkid;
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 51bd85b..1b8236e 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2253,10 +2253,10 @@  enum nl80211_commands {
  *     &enum nl80211_external_auth_action value). This is used with the
  *     %NL80211_CMD_EXTERNAL_AUTH request event.
  * @NL80211_ATTR_EXTERNAL_AUTH_SUPPORT: Flag attribute indicating that the user
- *     space supports external authentication. This attribute shall be used
- *     only with %NL80211_CMD_CONNECT request. The driver may offload
- *     authentication processing to user space if this capability is indicated
- *     in NL80211_CMD_CONNECT requests from the user space.
+ *	space supports external authentication. This attribute shall be used
+ *	with %NL80211_CMD_CONNECT and %NL80211_CMD_START_AP request. The driver
+ *	may offload authentication processing to user space if this capability
+ *	is indicated in the respective requests from the user space.
  *
  * @NL80211_ATTR_NSS: Station's New/updated  RX_NSS value notified using this
  *	u8 attribute. This is used with %NL80211_CMD_STA_OPMODE_CHANGED.
@@ -5599,9 +5599,14 @@  enum nl80211_crit_proto_id {
  * Used by cfg80211_rx_mgmt()
  *
  * @NL80211_RXMGMT_FLAG_ANSWERED: frame was answered by device/driver.
+ * @NL80211_RXMGMT_FLAG_EXTERNAL_AUTH: Host driver intends to offload
+ *	the authentication. Exclusively defined for host drivers that
+ *	advertises the SME functionality but would like the userspace
+ *	to handle certain authentication algorithms (e.g., SAE).
  */
 enum nl80211_rxmgmt_flags {
 	NL80211_RXMGMT_FLAG_ANSWERED = 1 << 0,
+	NL80211_RXMGMT_FLAG_EXTERNAL_AUTH = 1 << 1,
 };
 
 /*
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e20329b..f21b12d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4531,6 +4531,9 @@  static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
 
 	nl80211_calculate_ap_params(&params);
 
+	if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT]))
+		params.flags |= AP_SETTINGS_EXTERNAL_AUTH_SUPPORT;
+
 	wdev_lock(wdev);
 	err = rdev_start_ap(rdev, dev, &params);
 	if (!err) {
@@ -12981,7 +12984,10 @@  static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
 	if (!rdev->ops->external_auth)
 		return -EOPNOTSUPP;
 
-	if (!info->attrs[NL80211_ATTR_SSID])
+	if (!info->attrs[NL80211_ATTR_SSID] &&
+	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
 		return -EINVAL;
 
 	if (!info->attrs[NL80211_ATTR_BSSID])
@@ -12992,18 +12998,24 @@  static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
 
 	memset(&params, 0, sizeof(params));
 
-	params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
-	if (params.ssid.ssid_len == 0 ||
-	    params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
-		return -EINVAL;
-	memcpy(params.ssid.ssid, nla_data(info->attrs[NL80211_ATTR_SSID]),
-	       params.ssid.ssid_len);
+	if (info->attrs[NL80211_ATTR_SSID]) {
+		params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+		if (params.ssid.ssid_len == 0 ||
+		    params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
+			return -EINVAL;
+		memcpy(params.ssid.ssid,
+		       nla_data(info->attrs[NL80211_ATTR_SSID]),
+		       params.ssid.ssid_len);
+	}
 
 	memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
 	       ETH_ALEN);
 
 	params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
 
+	if (info->attrs[NL80211_ATTR_PMKID])
+		params.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
+
 	return rdev_external_auth(rdev, dev, &params);
 }