Cache hashed passphrase in RADIUS-based PSK delivery

Instead of copying the full struct hostapd_sta_wpa_psk_short, share the
existing entry and use reference counting to check when it needs to be
freed. This allows caching of PSKs derived from passphrases to avoid
having to perform the heavy hashing operation multiple times.

Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
This commit is contained in:
Michael Braun 2016-02-24 12:53:37 +01:00 committed by Jouni Malinen
parent f8e09bc57e
commit d8912fd80e
2 changed files with 13 additions and 16 deletions

View File

@ -134,6 +134,7 @@ struct hostapd_sta_wpa_psk_short {
unsigned int is_passphrase:1; unsigned int is_passphrase:1;
u8 psk[PMK_LEN]; u8 psk[PMK_LEN];
char passphrase[MAX_PASSPHRASE_LEN + 1]; char passphrase[MAX_PASSPHRASE_LEN + 1];
int ref; /* (number of references held) - 1 */
}; };
struct hostapd_wpa_psk { struct hostapd_wpa_psk {

View File

@ -76,23 +76,13 @@ static void hostapd_acl_cache_free(struct hostapd_cached_radius_acl *acl_cache)
static void copy_psk_list(struct hostapd_sta_wpa_psk_short **psk, static void copy_psk_list(struct hostapd_sta_wpa_psk_short **psk,
struct hostapd_sta_wpa_psk_short *src) struct hostapd_sta_wpa_psk_short *src)
{ {
struct hostapd_sta_wpa_psk_short **copy_to; if (!psk)
struct hostapd_sta_wpa_psk_short *copy_from; return;
/* Copy PSK linked list */ if (src)
copy_to = psk; src->ref++;
copy_from = src;
while (copy_from && copy_to) { *psk = src;
*copy_to = os_zalloc(sizeof(struct hostapd_sta_wpa_psk_short));
if (*copy_to == NULL)
break;
os_memcpy(*copy_to, copy_from,
sizeof(struct hostapd_sta_wpa_psk_short));
copy_from = copy_from->next;
copy_to = &((*copy_to)->next);
}
if (copy_to)
*copy_to = NULL;
} }
@ -667,6 +657,12 @@ void hostapd_acl_deinit(struct hostapd_data *hapd)
void hostapd_free_psk_list(struct hostapd_sta_wpa_psk_short *psk) void hostapd_free_psk_list(struct hostapd_sta_wpa_psk_short *psk)
{ {
if (psk && psk->ref) {
/* This will be freed when the last reference is dropped. */
psk->ref--;
return;
}
while (psk) { while (psk) {
struct hostapd_sta_wpa_psk_short *prev = psk; struct hostapd_sta_wpa_psk_short *prev = psk;
psk = psk->next; psk = psk->next;