summaryrefslogtreecommitdiffstats
path: root/contrib/wpa/hostapd/wpa.c
diff options
context:
space:
mode:
authorrpaulo <rpaulo@FreeBSD.org>2010-06-14 15:37:48 +0000
committerrpaulo <rpaulo@FreeBSD.org>2010-06-14 15:37:48 +0000
commitce9c8f380b1fae326c166456a15ae504dce5c1d1 (patch)
tree14bf596282a14863f779d075d7a8f7e60c25f0a8 /contrib/wpa/hostapd/wpa.c
parentda0290f8d3606ed387adb04fec5d24de81a39032 (diff)
parent60c44471bf25f9e84d8701afe1bbcbcc88e18c89 (diff)
downloadFreeBSD-src-ce9c8f380b1fae326c166456a15ae504dce5c1d1.zip
FreeBSD-src-ce9c8f380b1fae326c166456a15ae504dce5c1d1.tar.gz
MFV hostapd & wpa_supplicant 0.6.10.
Diffstat (limited to 'contrib/wpa/hostapd/wpa.c')
-rw-r--r--contrib/wpa/hostapd/wpa.c71
1 files changed, 54 insertions, 17 deletions
diff --git a/contrib/wpa/hostapd/wpa.c b/contrib/wpa/hostapd/wpa.c
index cf285b6..19b11d5 100644
--- a/contrib/wpa/hostapd/wpa.c
+++ b/contrib/wpa/hostapd/wpa.c
@@ -1,6 +1,6 @@
/*
* hostapd - IEEE 802.11i-2004 / WPA Authenticator
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -44,6 +44,8 @@ static void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx);
static void wpa_group_sm_step(struct wpa_authenticator *wpa_auth,
struct wpa_group *group);
static void wpa_request_new_ptk(struct wpa_state_machine *sm);
+static int wpa_gtk_update(struct wpa_authenticator *wpa_auth,
+ struct wpa_group *group);
static const u32 dot11RSNAConfigGroupUpdateCount = 4;
static const u32 dot11RSNAConfigPairwiseUpdateCount = 4;
@@ -286,21 +288,9 @@ static void wpa_auth_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
}
-static struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth,
- int vlan_id)
+static void wpa_group_set_key_len(struct wpa_group *group, int cipher)
{
- struct wpa_group *group;
- u8 buf[ETH_ALEN + 8 + sizeof(group)];
- u8 rkey[32];
-
- group = os_zalloc(sizeof(struct wpa_group));
- if (group == NULL)
- return NULL;
-
- group->GTKAuthenticator = TRUE;
- group->vlan_id = vlan_id;
-
- switch (wpa_auth->conf.wpa_group) {
+ switch (cipher) {
case WPA_CIPHER_CCMP:
group->GTK_len = 16;
break;
@@ -314,6 +304,24 @@ static struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth,
group->GTK_len = 5;
break;
}
+}
+
+
+static struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth,
+ int vlan_id)
+{
+ struct wpa_group *group;
+ u8 buf[ETH_ALEN + 8 + sizeof(group)];
+ u8 rkey[32];
+
+ group = os_zalloc(sizeof(struct wpa_group));
+ if (group == NULL)
+ return NULL;
+
+ group->GTKAuthenticator = TRUE;
+ group->vlan_id = vlan_id;
+
+ wpa_group_set_key_len(group, wpa_auth->conf.wpa_group);
/* Counter = PRF-256(Random number, "Init Counter",
* Local MAC Address || Time)
@@ -451,6 +459,7 @@ void wpa_deinit(struct wpa_authenticator *wpa_auth)
int wpa_reconfig(struct wpa_authenticator *wpa_auth,
struct wpa_auth_config *conf)
{
+ struct wpa_group *group;
if (wpa_auth == NULL)
return 0;
@@ -460,6 +469,17 @@ int wpa_reconfig(struct wpa_authenticator *wpa_auth,
return -1;
}
+ /*
+ * Reinitialize GTK to make sure it is suitable for the new
+ * configuration.
+ */
+ group = wpa_auth->group;
+ wpa_group_set_key_len(group, wpa_auth->conf.wpa_group);
+ group->GInit = TRUE;
+ wpa_group_sm_step(wpa_auth, group);
+ group->GInit = FALSE;
+ wpa_group_sm_step(wpa_auth, group);
+
return 0;
}
@@ -619,6 +639,22 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
return;
}
+ if (sm->wpa == WPA_VERSION_WPA2) {
+ if (key->type != EAPOL_KEY_TYPE_RSN) {
+ wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with "
+ "unexpected type %d in RSN mode",
+ key->type);
+ return;
+ }
+ } else {
+ if (key->type != EAPOL_KEY_TYPE_WPA) {
+ wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with "
+ "unexpected type %d in WPA mode",
+ key->type);
+ return;
+ }
+ }
+
/* FIX: verify that the EAPOL-Key frame was encrypted if pairwise keys
* are set */
@@ -1403,14 +1439,15 @@ SM_STATE(WPA_PTK, PTKSTART)
static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *pmk,
struct wpa_ptk *ptk)
{
+ size_t ptk_len = sm->pairwise == WPA_CIPHER_CCMP ? 48 : 64;
#ifdef CONFIG_IEEE80211R
if (wpa_key_mgmt_ft(sm->wpa_key_mgmt))
- return wpa_auth_derive_ptk_ft(sm, pmk, ptk);
+ return wpa_auth_derive_ptk_ft(sm, pmk, ptk, ptk_len);
#endif /* CONFIG_IEEE80211R */
wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion",
sm->wpa_auth->addr, sm->addr, sm->ANonce, sm->SNonce,
- (u8 *) ptk, sizeof(*ptk),
+ (u8 *) ptk, ptk_len,
wpa_key_mgmt_sha256(sm->wpa_key_mgmt));
return 0;
OpenPOWER on IntegriCloud