[RFC] drivers: add separate driver flags for 802.1X and WPA/WPA2-Personal

Submitted by Arend van Spriel on March 23, 2017, 7:56 p.m.

Details

Message ID 1490298999-16464-1-git-send-email-arend.vanspriel@broadcom.com
State New
Headers show

Commit Message

Arend van Spriel March 23, 2017, 7:56 p.m.
Allow drivers to indicate support for either 802.1X and/or WPA/WPA2-PSK
introducing two separate drivers flags.

Cc: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
In reply to RFC "driver_nl80211: Support 4-way HS offloading for 1X
and PSK" posted by Andrei I decided to post this follow-up RFC. Having
wpa_supplicant specifying drivers flags with this granularity seems to
have merit.

Not sure if I got all conditions checking the 4-way HS offload flag right.
The one under CONFIG_PEERKEY was assumed PSK offload but not sure if that
is true here.

Anyway, hope this will help decide which way to go with this.

Regards,
Arend
---
 src/drivers/driver.h              | 18 ++++++++++--------
 src/drivers/driver_common.c       |  3 ++-
 src/drivers/driver_nl80211.c      |  4 ++--
 src/drivers/driver_nl80211_capa.c |  7 ++++---
 src/drivers/driver_openbsd.c      |  3 ++-
 src/drivers/driver_wext.c         |  7 ++++---
 wpa_supplicant/events.c           |  4 ++--
 wpa_supplicant/wpa_supplicant.c   |  8 ++++----
 wpa_supplicant/wpas_glue.c        |  2 +-
 9 files changed, 31 insertions(+), 25 deletions(-)

Comments

Otcheretianski, Andrei March 28, 2017, 12:47 p.m.
> 
> diff --git a/src/drivers/driver_openbsd.c b/src/drivers/driver_openbsd.c index
> e94eda0..ae61d74 100644
> --- a/src/drivers/driver_openbsd.c
> +++ b/src/drivers/driver_openbsd.c
> @@ -62,7 +62,8 @@ static int
>  wpa_driver_openbsd_get_capa(void *priv, struct wpa_driver_capa *capa)  {
>  	os_memset(capa, 0, sizeof(*capa));
> -	capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
> +	capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK &
> +		      WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X;

I guess you meant | here.

>  	return 0;
>  }
>

[..]
>		if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)
> -			drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
> +			drv->capa.flags |= (WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK &
> +					    WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X);
> 		drv->capa.auth = WPA_DRIVER_AUTH_OPEN |

And here too.

Andrei
Arend van Spriel March 29, 2017, 7:27 a.m.
On 28-3-2017 14:47, Otcheretianski, Andrei wrote:
>>
>> diff --git a/src/drivers/driver_openbsd.c b/src/drivers/driver_openbsd.c index
>> e94eda0..ae61d74 100644
>> --- a/src/drivers/driver_openbsd.c
>> +++ b/src/drivers/driver_openbsd.c
>> @@ -62,7 +62,8 @@ static int
>>  wpa_driver_openbsd_get_capa(void *priv, struct wpa_driver_capa *capa)  {
>>  	os_memset(capa, 0, sizeof(*capa));
>> -	capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
>> +	capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK &
>> +		      WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X;
> 
> I guess you meant | here.

Ouch. That is bad! Let see how I can weasel out here... Nope, your
"guess" is obviously right :-p

Thanks,
Arend

Patch hide | download patch | download mbox

diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index fc2593e..fee91c2 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -865,10 +865,10 @@  struct wpa_driver_associate_params {
 	 * passphrase - RSN passphrase for PSK
 	 *
 	 * This value is made available only for WPA/WPA2-Personal (PSK) and
-	 * only for drivers that set WPA_DRIVER_FLAGS_4WAY_HANDSHAKE. This is
-	 * the 8..63 character ASCII passphrase, if available. Please note that
-	 * this can be %NULL if passphrase was not used to generate the PSK. In
-	 * that case, the psk field must be used to fetch the PSK.
+	 * only for drivers that set WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK. This
+	 * is the 8..63 character ASCII passphrase, if available. Please note
+	 * that this can be %NULL if passphrase was not used to generate the
+	 * PSK. In that case, the psk field must be used to fetch the PSK.
 	 */
 	const char *passphrase;
 
@@ -876,9 +876,9 @@  struct wpa_driver_associate_params {
 	 * psk - RSN PSK (alternative for passphrase for PSK)
 	 *
 	 * This value is made available only for WPA/WPA2-Personal (PSK) and
-	 * only for drivers that set WPA_DRIVER_FLAGS_4WAY_HANDSHAKE. This is
-	 * the 32-octet (256-bit) PSK, if available. The driver wrapper should
-	 * be prepared to handle %NULL value as an error.
+	 * only for drivers that set WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK. This
+	 * is the 32-octet (256-bit) PSK, if available. The driver wrapper
+	 * should be prepared to handle %NULL value as an error.
 	 */
 	const u8 *psk;
 
@@ -1364,7 +1364,7 @@  struct wpa_driver_capa {
 #define WPA_DRIVER_FLAGS_DFS_OFFLOAD			0x00000004
 /** Driver takes care of RSN 4-way handshake internally; PMK is configured with
  * struct wpa_driver_ops::set_key using alg = WPA_ALG_PMK */
-#define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE 0x00000008
+#define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X		0x00000008
 /** Driver is for a wired Ethernet interface */
 #define WPA_DRIVER_FLAGS_WIRED		0x00000010
 /** Driver provides separate commands for authentication and association (SME in
@@ -1469,6 +1469,8 @@  struct wpa_driver_capa {
 #define WPA_DRIVER_FLAGS_SCHED_SCAN_RELATIVE_RSSI	0x0001000000000000ULL
 /** Driver supports HE capabilities */
 #define WPA_DRIVER_FLAGS_HE_CAPABILITIES	0x0002000000000000ULL
+/** Driver support 4-way handshake offload for WPA-Personal */
+#define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK	0x0004000000000000ULL
 	u64 flags;
 
 #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \
diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c
index 220b7d4..89b2135 100644
--- a/src/drivers/driver_common.c
+++ b/src/drivers/driver_common.c
@@ -230,7 +230,8 @@  const char * driver_flag_to_string(u64 flag)
 	DF2S(DRIVER_IE);
 	DF2S(SET_KEYS_AFTER_ASSOC);
 	DF2S(DFS_OFFLOAD);
-	DF2S(4WAY_HANDSHAKE);
+	DF2S(4WAY_HANDSHAKE_PSK);
+	DF2S(4WAY_HANDSHAKE_8021X);
 	DF2S(WIRED);
 	DF2S(SME);
 	DF2S(AP);
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 1768522..669aa04 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -2825,7 +2825,7 @@  static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
 #endif /* CONFIG_DRIVER_NL80211_QCA */
 
 	if (alg == WPA_ALG_PMK &&
-	    (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
+	    (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X))
 		return wpa_driver_nl80211_set_pmk(drv, key, key_len, addr);
 
 	if (alg == WPA_ALG_NONE) {
@@ -5255,7 +5255,7 @@  static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
 
 	/* add psk in case of 4way handshake offload */
 	if (params->psk &&
-	    (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) {
+	    (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK)) {
 		wpa_printf(MSG_DEBUG, "Adding psk (len=32)");
 		wpa_hexdump_key(MSG_DEBUG, "PSK", params->psk, 32);
 		if (nla_put(msg, NL80211_ATTR_PMK, 32, params->psk))
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index 54f9a03..4b3327e 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -400,10 +400,11 @@  static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info,
 		capa->flags |= WPA_DRIVER_FLAGS_SCHED_SCAN_RELATIVE_RSSI;
 
 	if (ext_feature_isset(ext_features, len,
-			      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK) &&
-	    ext_feature_isset(ext_features, len,
+			      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK))
+		capa->flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK;
+	if (ext_feature_isset(ext_features, len,
 			      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
-		capa->flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
+		capa->flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X;
 }
 
 
diff --git a/src/drivers/driver_openbsd.c b/src/drivers/driver_openbsd.c
index e94eda0..ae61d74 100644
--- a/src/drivers/driver_openbsd.c
+++ b/src/drivers/driver_openbsd.c
@@ -62,7 +62,8 @@  static int
 wpa_driver_openbsd_get_capa(void *priv, struct wpa_driver_capa *capa)
 {
 	os_memset(capa, 0, sizeof(*capa));
-	capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
+	capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK &
+		      WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X;
 	return 0;
 }
 
diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c
index 47b90eb..f2bf012 100644
--- a/src/drivers/driver_wext.c
+++ b/src/drivers/driver_wext.c
@@ -470,7 +470,7 @@  static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv,
 				drv->assoc_resp_ies = NULL;
 				wpa_supplicant_event(drv->ctx, EVENT_DISASSOC,
 						     NULL);
-			
+
 			} else {
 				wpa_driver_wext_event_assoc_ies(drv);
 				wpa_supplicant_event(drv->ctx, EVENT_ASSOC,
@@ -1654,7 +1654,8 @@  static int wpa_driver_wext_get_range(void *priv)
 		if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP)
 			drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
 		if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)
-			drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
+			drv->capa.flags |= (WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK &
+					    WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X);
 		drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
 			WPA_DRIVER_AUTH_SHARED |
 			WPA_DRIVER_AUTH_LEAP;
@@ -1685,7 +1686,7 @@  static int wpa_driver_wext_set_psk(struct wpa_driver_wext_data *drv,
 
 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
 
-	if (!(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
+	if (!(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X))
 		return 0;
 
 	if (!psk)
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 4ef8e28..c93ee84 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2563,7 +2563,7 @@  static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
 	}
 	wpa_supplicant_cancel_scan(wpa_s);
 
-	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
+	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
 	    wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
 		/*
 		 * We are done; the driver will take care of RSN 4-way
@@ -2573,7 +2573,7 @@  static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
 		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
 		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
 		eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
-	} else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
+	} else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X) &&
 		   wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
 		/*
 		 * The driver will take care of RSN 4-way handshake, so we need
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index e65441d..6ea8519 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2572,7 +2572,7 @@  static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
 	}
 	params.wep_tx_keyidx = ssid->wep_tx_keyidx;
 
-	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
+	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
 	    (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
 	     params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
 		params.passphrase = ssid->passphrase;
@@ -3464,7 +3464,7 @@  void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
 #ifdef CONFIG_PEERKEY
 	if (wpa_s->wpa_state > WPA_ASSOCIATED && wpa_s->current_ssid &&
 	    wpa_s->current_ssid->peerkey &&
-	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
+	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
 	    wpa_sm_rx_eapol_peerkey(wpa_s->wpa, src_addr, buf, len) == 1) {
 		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: Processed PeerKey EAPOL-Key");
 		return;
@@ -3520,7 +3520,7 @@  void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
 	}
 
 	if (wpa_s->eapol_received == 0 &&
-	    (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
+	    (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) ||
 	     !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
 	     wpa_s->wpa_state != WPA_COMPLETED) &&
 	    (wpa_s->current_ssid == NULL ||
@@ -3585,7 +3585,7 @@  void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
 	    eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
 		return;
 	wpa_drv_poll(wpa_s);
-	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
+	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK))
 		wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
 	else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
 		/*
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 52904d3..a49d0c0 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -295,7 +295,7 @@  static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol,
 	}
 
 	if (result != EAPOL_SUPP_RESULT_SUCCESS ||
-	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
+	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X))
 		return;
 
 	if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt))