@@ -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 {
@@ -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);
}
@@ -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;