[PATCH 30/44] Move password hashing out of 802.11 authentication path

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Michael Braun <michael-dev@xxxxxxxxxxxxx>

Hashing takes quite some time (about 1s here for each passphrase provided),
so hostapd easily hits the 900ms Wi-Fi client authentication deadline
(mac80211 uses 3x 300ms). This can be fixed by storing the passphrase with
the sta (instead of psk) and defer the hashing into the WPA handshake, when
enumerating all PSKs.

Signed-off-by: Michael Braun <michael-dev@xxxxxxxxxxxxx>
---
 src/ap/ap_config.h       |  3 +++
 src/ap/ieee802_11_auth.c | 19 +++++++++----------
 src/ap/wpa_auth_glue.c   |  8 ++++++++
 3 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index a2b36c3..9b09c16 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -131,9 +131,12 @@ struct hostapd_vlan {
 };
 
 #define PMK_LEN 32
+#define PASSPHRASE_LEN (2 * PMK_LEN)
 struct hostapd_sta_wpa_psk_short {
 	struct hostapd_sta_wpa_psk_short *next;
+	int ispassphrase;
 	u8 psk[PMK_LEN];
+	char passphrase[PASSPHRASE_LEN];
 };
 
 struct hostapd_wpa_psk {
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
index ebc971c..e007a73 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"
@@ -454,7 +453,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;
 
@@ -475,19 +474,19 @@ 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 > PASSPHRASE_LEN - 1)
+				os_memcpy(psk->passphrase, passphrase,
+					  PASSPHRASE_LEN - 1);
+			else
+				os_memcpy(psk->passphrase, passphrase,
+					  passphraselen);
+			psk->ispassphrase = 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 e7fc46a..116c4fb 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -27,6 +27,7 @@
 #include "ap_config.h"
 #include "wpa_auth.h"
 #include "wpa_auth_glue.h"
+#include "crypto/sha1.h"
 #include <stdlib.h>
 
 #ifdef CONFIG_IEEE80211R
@@ -260,6 +261,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->ispassphrase) {
+				pbkdf2_sha1(pos->passphrase,
+					    hapd->conf->ssid.ssid,
+					    hapd->conf->ssid.ssid_len, 4096,
+					    pos->psk, PMK_LEN);
+				pos->ispassphrase = 0;
+			}
 			if (pos->psk == prev_psk) {
 				psk = pos->next ? pos->next->psk : NULL;
 				break;
-- 
1.9.1


_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux