[PATCH] mesh: Fix mesh SAE auth on low spec devices

Masashi Honma masashi.honma
Wed Jul 8 06:41:36 PDT 2015


The mesh SAE auth often fails with master branch. By bisect I found
commit eb5fee0bf50444419ac12d3c7f38f27a47523a47 causes this issue. This does not
mean the commit has a bug. This is just a CPU resource issue.

After the commit, sae_derive_pwe_ecc() spends 101(msec) on my PC (Intel Atom
N270 1.6GHz). But dot11RSNASAERetransPeriod is 40(msec). So
auth_sae_retransmit_timer() is always called and it can causes continuous frame
exchanges. Before the commit, it was 23(msec).

On the IEEE 802.11 spec, the default value of dot11RSNASAERetransPeriod is
defined as 40(msec). But it looks short because generally mesh functionality
will be used on low spec devices. Indeed Raspberry Pi B+
(ARM ARM1176JZF-S 700MHz) requires 287(msec) for new sae_derive_pwe_ecc().

So this patch makes the default to 1000(msec) and it configurable.

This issue does not occur on infrastructure SAE because the
dot11RSNASAERetransPeriod is not used on it.

Signed-off-by: Masashi Honma <masashi.honma at gmail.com>
---
 src/ap/hostapd.h             |  1 +
 src/ap/ieee802_11.c          |  9 +++++----
 wpa_supplicant/config.c      |  3 +++
 wpa_supplicant/config.h      | 10 ++++++++++
 wpa_supplicant/config_file.c |  5 +++++
 wpa_supplicant/mesh.c        |  2 ++
 wpa_supplicant/wpa_cli.c     |  1 +
 7 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index be5c7a8..07e98f5 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -268,6 +268,7 @@ struct hostapd_data {
 	/** Key used for generating SAE anti-clogging tokens */
 	u8 sae_token_key[8];
 	struct os_reltime last_sae_token_key_update;
+	int dot11RSNASAERetransPeriod; /* msec */
 #endif /* CONFIG_SAE */
 
 #ifdef CONFIG_TESTING_OPTIONS
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index db20c86..5e81b54 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -313,7 +313,6 @@ static void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid,
 
 #ifdef CONFIG_SAE
 
-#define dot11RSNASAERetransPeriod 40	/* msec */
 #define dot11RSNASAESync 5		/* attempts */
 
 
@@ -496,12 +495,14 @@ static void auth_sae_retransmit_timer(void *eloop_ctx, void *eloop_data)
 	switch (sta->sae->state) {
 	case SAE_COMMITTED:
 		ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0);
-		eloop_register_timeout(0, dot11RSNASAERetransPeriod * 1000,
+		eloop_register_timeout(0,
+				       hapd->dot11RSNASAERetransPeriod * 1000,
 				       auth_sae_retransmit_timer, hapd, sta);
 		break;
 	case SAE_CONFIRMED:
 		ret = auth_sae_send_confirm(hapd, sta, hapd->own_addr);
-		eloop_register_timeout(0, dot11RSNASAERetransPeriod * 1000,
+		eloop_register_timeout(0,
+				       hapd->dot11RSNASAERetransPeriod * 1000,
 				       auth_sae_retransmit_timer, hapd, sta);
 		break;
 	default:
@@ -527,7 +528,7 @@ static void sae_set_retransmit_timer(struct hostapd_data *hapd,
 		return;
 
 	eloop_cancel_timeout(auth_sae_retransmit_timer, hapd, sta);
-	eloop_register_timeout(0, dot11RSNASAERetransPeriod * 1000,
+	eloop_register_timeout(0, hapd->dot11RSNASAERetransPeriod * 1000,
 			       auth_sae_retransmit_timer, hapd, sta);
 }
 
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 4d801cc..2e48be9 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -3515,6 +3515,8 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
 	config->user_mpm = DEFAULT_USER_MPM;
 	config->max_peer_links = DEFAULT_MAX_PEER_LINKS;
 	config->mesh_max_inactivity = DEFAULT_MESH_MAX_INACTIVITY;
+	config->dot11RSNASAERetransPeriod =
+		DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD;
 	config->fast_reauth = DEFAULT_FAST_REAUTH;
 	config->p2p_go_intent = DEFAULT_P2P_GO_INTENT;
 	config->p2p_intra_bss = DEFAULT_P2P_INTRA_BSS;
@@ -4128,6 +4130,7 @@ static const struct global_parse_data global_fields[] = {
 	{ INT(user_mpm), 0 },
 	{ INT_RANGE(max_peer_links, 0, 255), 0 },
 	{ INT(mesh_max_inactivity), 0 },
+	{ INT(dot11RSNASAERetransPeriod), 0 },
 #endif /* CONFIG_MESH */
 	{ INT(disable_scan_offload), 0 },
 	{ INT(fast_reauth), 0 },
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index d8ca054..27d5d98 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -18,6 +18,8 @@
 #define DEFAULT_USER_MPM 1
 #define DEFAULT_MAX_PEER_LINKS 99
 #define DEFAULT_MESH_MAX_INACTIVITY 300
+/* The default is defined as 40 in spec. But use 1000 in practice. */
+#define DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD 1000
 #define DEFAULT_FAST_REAUTH 1
 #define DEFAULT_P2P_GO_INTENT 7
 #define DEFAULT_P2P_INTRA_BSS 1
@@ -1161,6 +1163,14 @@ struct wpa_config {
 	int mesh_max_inactivity;
 
 	/**
+	 * dot11RSNASAERetransPeriod - Timeout to retransmit SAE auth frame
+	 *
+	 * This timeout value is used in mesh STA to retransmit SAE auth frame.
+	 * By default: 1000 milli seconds.
+	 */
+	int dot11RSNASAERetransPeriod;
+
+	/**
 	 * passive_scan - Whether to force passive scan for network connection
 	 *
 	 * This parameter can be used to force only passive scanning to be used
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index ae34f10..5bab821 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1282,6 +1282,11 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
 		fprintf(f, "mesh_max_inactivity=%d\n",
 			config->mesh_max_inactivity);
 
+	if (config->dot11RSNASAERetransPeriod !=
+	    DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD)
+		fprintf(f, "dot11RSNASAERetransPeriod=%d\n",
+			config->dot11RSNASAERetransPeriod);
+
 	if (config->passive_scan)
 		fprintf(f, "passive_scan=%d\n", config->passive_scan);
 
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index ca012e2..ac0eb5c 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -171,6 +171,8 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
 	ifmsh->conf = conf;
 
 	ifmsh->bss[0]->max_plinks = wpa_s->conf->max_peer_links;
+	ifmsh->bss[0]->dot11RSNASAERetransPeriod =
+		wpa_s->conf->dot11RSNASAERetransPeriod;
 	os_strlcpy(bss->conf->iface, wpa_s->ifname, sizeof(bss->conf->iface));
 
 	mconf = mesh_config_create(ssid);
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index c5d8333..82d2563 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -618,6 +618,7 @@ static char ** wpa_cli_complete_set(const char *str, int pos)
 		"eapol_version", "ap_scan", "bgscan",
 #ifdef CONFIG_MESH
 		"user_mpm", "max_peer_links", "mesh_max_inactivity",
+		"dot11RSNASAERetransPeriod",
 #endif /* CONFIG_MESH */
 		"disable_scan_offload", "fast_reauth", "opensc_engine_path",
 		"pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
-- 
2.1.4




More information about the Hostap mailing list