Browse Source

SAE: Add option to require MFP for SAE associations

The new hostapd.conf parameter sae_require_pmf=<0/1> can now be used to
enforce negotiation of MFP for all associations that negotiate use of
SAE. This is used in cases where SAE-capable devices are known to be
MFP-capable and the BSS is configured with optional MFP (ieee80211w=1)
for legacy support. The non-SAE stations can connect without MFP while
SAE stations are required to negotiate MFP if sae_require_mfp=1.

Signed-off-by: Jouni Malinen <j@w1.fi>
Jouni Malinen 7 years ago
parent
commit
ba3d435fe4
6 changed files with 23 additions and 0 deletions
  1. 2 0
      hostapd/config_file.c
  2. 8 0
      hostapd/hostapd.conf
  3. 1 0
      src/ap/ap_config.h
  4. 1 0
      src/ap/wpa_auth.h
  5. 1 0
      src/ap/wpa_auth_glue.c
  6. 10 0
      src/ap/wpa_auth_ie.c

+ 2 - 0
hostapd/config_file.c

@@ -3643,6 +3643,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 				   line, pos);
 			return 1;
 		}
+	} else if (os_strcmp(buf, "sae_require_mfp") == 0) {
+		bss->sae_require_mfp = atoi(pos);
 	} else if (os_strcmp(buf, "local_pwr_constraint") == 0) {
 		int val = atoi(pos);
 		if (val < 0 || val > 255) {

+ 8 - 0
hostapd/hostapd.conf

@@ -1443,6 +1443,14 @@ own_ip_addr=127.0.0.1
 # http://www.iana.org/assignments/ipsec-registry/ipsec-registry.xml#ipsec-registry-9
 #sae_groups=19 20 21 25 26
 
+# Require MFP for all associations using SAE
+# This parameter can be used to enforce negotiation of MFP for all associations
+# that negotiate use of SAE. This is used in cases where SAE-capable devices are
+# known to be MFP-capable and the BSS is configured with optional MFP
+# (ieee80211w=1) for legacy support. The non-SAE stations can connect without
+# MFP while SAE stations are required to negotiate MFP if sae_require_mfp=1.
+#sae_require_mfp=0
+
 # FILS Cache Identifier (16-bit value in hexdump format)
 #fils_cache_id=0011
 

+ 1 - 0
src/ap/ap_config.h

@@ -585,6 +585,7 @@ struct hostapd_bss_config {
 
 	unsigned int sae_anti_clogging_threshold;
 	unsigned int sae_sync;
+	int sae_require_mfp;
 	int *sae_groups;
 	char *sae_password;
 

+ 1 - 0
src/ap/wpa_auth.h

@@ -177,6 +177,7 @@ struct wpa_auth_config {
 #ifdef CONFIG_IEEE80211W
 	enum mfp_options ieee80211w;
 	int group_mgmt_cipher;
+	int sae_require_mfp;
 #endif /* CONFIG_IEEE80211W */
 #ifdef CONFIG_IEEE80211R_AP
 	u8 ssid[SSID_MAX_LEN];

+ 1 - 0
src/ap/wpa_auth_glue.c

@@ -59,6 +59,7 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
 #ifdef CONFIG_IEEE80211W
 	wconf->ieee80211w = conf->ieee80211w;
 	wconf->group_mgmt_cipher = conf->group_mgmt_cipher;
+	wconf->sae_require_mfp = conf->sae_require_mfp;
 #endif /* CONFIG_IEEE80211W */
 #ifdef CONFIG_IEEE80211R_AP
 	wconf->ssid_len = conf->ssid.ssid_len;

+ 10 - 0
src/ap/wpa_auth_ie.c

@@ -725,6 +725,16 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
 		}
 	}
 
+#ifdef CONFIG_SAE
+	if (wpa_auth->conf.ieee80211w == MGMT_FRAME_PROTECTION_OPTIONAL &&
+	    wpa_key_mgmt_sae(sm->wpa_key_mgmt) &&
+	    !(data.capabilities & WPA_CAPABILITY_MFPC)) {
+		wpa_printf(MSG_DEBUG,
+			   "Management frame protection required with SAE, but client did not enable it");
+		return WPA_MGMT_FRAME_PROTECTION_VIOLATION;
+	}
+#endif /* CONFIG_SAE */
+
 	if (wpa_auth->conf.ieee80211w == NO_MGMT_FRAME_PROTECTION ||
 	    !(data.capabilities & WPA_CAPABILITY_MFPC))
 		sm->mgmt_frame_prot = 0;