]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
mesh: Fix mesh SAE auth on low spec devices
authorMasashi Honma <masashi.honma@gmail.com>
Wed, 8 Jul 2015 13:41:36 +0000 (22:41 +0900)
committerJouni Malinen <j@w1.fi>
Sun, 2 Aug 2015 18:37:10 +0000 (21:37 +0300)
The mesh SAE auth often fails with master branch. By bisect I found
commit eb5fee0bf50444419ac12d3c7f38f27a47523a47 ('SAE: Add side-channel
protection to PWE derivation with ECC') 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 makes 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@gmail.com>
src/ap/hostapd.h
src/ap/ieee802_11.c
wpa_supplicant/config.c
wpa_supplicant/config.h
wpa_supplicant/config_file.c
wpa_supplicant/mesh.c
wpa_supplicant/wpa_cli.c

index d28a02a53a6cc3ac7d1baa61cc3267e1d1ad2a92..5c94bc1bd4f8a65394e844bce77e61d91bf622dd 100644 (file)
@@ -269,6 +269,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
index 1ca31c04a385b29e5c4d74fbdce08e41c3b1bbe2..2a3041108ac812d3ece6a0fc3eae28b5dcee0164 100644 (file)
@@ -316,7 +316,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 */
 
 
@@ -499,12 +498,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:
@@ -530,7 +531,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);
 }
 
index d6bdb33c905c051767471fb371b7baf2abebfea9..4841646f375dc047023f36c6cbb34faf947b29fd 100644 (file)
@@ -3517,6 +3517,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;
@@ -4130,6 +4132,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 },
index 54a79f49e68931541fa91e6162d40877d2513447..0bc8fecc97ded3e90877ca13399b1c2ec036b710 100644 (file)
 #define DEFAULT_USER_MPM 1
 #define DEFAULT_MAX_PEER_LINKS 99
 #define DEFAULT_MESH_MAX_INACTIVITY 300
+/*
+ * The default dot11RSNASAERetransPeriod is defined as 40 ms in the standard,
+ * but use 1000 ms in practice to avoid issues on low power CPUs.
+ */
+#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
@@ -1160,6 +1165,15 @@ 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 Authentication frame.
+        * By default: 1000 milliseconds.
+        */
+       int dot11RSNASAERetransPeriod;
+
        /**
         * passive_scan - Whether to force passive scan for network connection
         *
index ae34f1027fd729a1b0c0d1d25d0c5d5695df609b..5bab821a6bc372eefe417db2f7da75325a14ce7f 100644 (file)
@@ -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);
 
index ca012e25383329b2b42def5840c68c9532812125..ac0eb5cbe8c5ac51b452bbe930f5330f9dd6d8a7 100644 (file)
@@ -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);
index 48897d4f2290cfe89fcf8392209ba4f34b82ac0a..dbe653c2b166b4588c9aa53e0e01357e4423b589 100644 (file)
@@ -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",