aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2009-09-06 10:55:01 (GMT)
committerJouni Malinen <j@w1.fi>2009-11-22 18:49:24 (GMT)
commit63ca22309b88cd07feed58eb327cc230ce554698 (patch)
tree3123ab6af9649f0fc3b581a7043b119d02ae2cb6
parentf9c7b1e06cef6c02a6056896f19740a21c1726de (diff)
downloadhostap-06-63ca22309b88cd07feed58eb327cc230ce554698.zip
hostap-06-63ca22309b88cd07feed58eb327cc230ce554698.tar.gz
hostap-06-63ca22309b88cd07feed58eb327cc230ce554698.tar.bz2
Fix WPA reconfiguration to update GTK
The group key state machine needs to be re-initialized with possible updated GTK length when restarting WPA (e.g., when WPS was used to reconfigure the AP). (cherry picked from commit e6965d4e5daf00f5d7910fbade1681e0e6ad85e2)
-rw-r--r--hostapd/wpa.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/hostapd/wpa.c b/hostapd/wpa.c
index bbfaa0c..19b11d5 100644
--- a/hostapd/wpa.c
+++ b/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;
}