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 <michael-dev@fami-braun.de>
This commit is contained in:
parent
cc9c805a51
commit
f8e09bc57e
3 changed files with 17 additions and 10 deletions
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue