From: Michael Braun Date: Wed, 24 Feb 2016 11:53:36 +0000 (+0100) Subject: Defer passphrase-to-PSK hashing out of 802.11 authentication ACL check X-Git-Tag: hostap_2_6~797 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f8e09bc57e95c14e68ae0af1c3b1854a3f3ac22e;p=thirdparty%2Fhostap.git Defer passphrase-to-PSK hashing out of 802.11 authentication ACL check Hashing takes quite some time (can be about one second on a low-power CPU for each passphrase provided), so hostapd can easily hit the 900 ms Wi-Fi client authentication deadline (mac80211 uses 3x 300 ms). This can be fixed by storing the passphrase instead of PSK with the STA and defer the hashing into the WPA/RSN 4-way handshake, when enumerating all PSKs. This applies for the case where a RADIUS server is used to store the per-STA passphrases and this passphrase is delivered as part of the MAC ACL check during IEEE 802.11 Authentication frame processing. Signed-off-by: Michael Braun --- diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 9afca48be..90405b4e3 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -128,9 +128,12 @@ struct hostapd_vlan { }; #define PMK_LEN 32 +#define MAX_PASSPHRASE_LEN 63 struct hostapd_sta_wpa_psk_short { struct hostapd_sta_wpa_psk_short *next; + unsigned int is_passphrase:1; u8 psk[PMK_LEN]; + char passphrase[MAX_PASSPHRASE_LEN + 1]; }; struct hostapd_wpa_psk { diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c index f28070982..6afdc5db2 100644 --- a/src/ap/ieee802_11_auth.c +++ b/src/ap/ieee802_11_auth.c @@ -15,7 +15,6 @@ #include "utils/common.h" #include "utils/eloop.h" -#include "crypto/sha1.h" #include "radius/radius.h" #include "radius/radius_client.h" #include "hostapd.h" @@ -443,7 +442,7 @@ static void decode_tunnel_passwords(struct hostapd_data *hapd, struct hostapd_cached_radius_acl *cache) { int passphraselen; - char *passphrase, *strpassphrase; + char *passphrase; size_t i; struct hostapd_sta_wpa_psk_short *psk; @@ -464,19 +463,16 @@ static void decode_tunnel_passwords(struct hostapd_data *hapd, * passphrase does not contain the NULL termination. * Add it here as pbkdf2_sha1() requires it. */ - strpassphrase = os_zalloc(passphraselen + 1); psk = os_zalloc(sizeof(struct hostapd_sta_wpa_psk_short)); - if (strpassphrase && psk) { - os_memcpy(strpassphrase, passphrase, passphraselen); - pbkdf2_sha1(strpassphrase, - hapd->conf->ssid.ssid, - hapd->conf->ssid.ssid_len, 4096, - psk->psk, PMK_LEN); + if (psk) { + if (passphraselen > MAX_PASSPHRASE_LEN) + passphraselen = MAX_PASSPHRASE_LEN; + os_memcpy(psk->passphrase, passphrase, passphraselen); + psk->is_passphrase = 1; psk->next = cache->psk; cache->psk = psk; psk = NULL; } - os_free(strpassphrase); os_free(psk); os_free(passphrase); } diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index fb830e918..e92415a82 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -12,6 +12,7 @@ #include "common/ieee802_11_defs.h" #include "common/sae.h" #include "common/wpa_ctrl.h" +#include "crypto/sha1.h" #include "eapol_auth/eapol_auth_sm.h" #include "eapol_auth/eapol_auth_sm_i.h" #include "eap_server/eap.h" @@ -246,6 +247,13 @@ static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr, struct hostapd_sta_wpa_psk_short *pos; psk = sta->psk->psk; for (pos = sta->psk; pos; pos = pos->next) { + if (pos->is_passphrase) { + pbkdf2_sha1(pos->passphrase, + hapd->conf->ssid.ssid, + hapd->conf->ssid.ssid_len, 4096, + pos->psk, PMK_LEN); + pos->is_passphrase = 0; + } if (pos->psk == prev_psk) { psk = pos->next ? pos->next->psk : NULL; break;