diff options
author | rpaulo <rpaulo@FreeBSD.org> | 2010-06-14 15:37:48 +0000 |
---|---|---|
committer | rpaulo <rpaulo@FreeBSD.org> | 2010-06-14 15:37:48 +0000 |
commit | ce9c8f380b1fae326c166456a15ae504dce5c1d1 (patch) | |
tree | 14bf596282a14863f779d075d7a8f7e60c25f0a8 /contrib/wpa/hostapd/wpa.c | |
parent | da0290f8d3606ed387adb04fec5d24de81a39032 (diff) | |
parent | 60c44471bf25f9e84d8701afe1bbcbcc88e18c89 (diff) | |
download | FreeBSD-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.c | 71 |
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; |