diff --git a/hostapd/ChangeLog b/hostapd/ChangeLog index 5a2ac6971..d79623a6e 100644 --- a/hostapd/ChangeLog +++ b/hostapd/ChangeLog @@ -15,6 +15,9 @@ ChangeLog for hostapd * fixed TNC with EAP-TTLS * fixed IEEE 802.11r key derivation function to match with the standard (note: this breaks interoperability with previous version) [Bug 303] + * fixed SHA-256 based key derivation function to match with the + standard when using CCMP (for IEEE 802.11r and IEEE 802.11w) + (note: this breaks interoperability with previous version) [Bug 307] 2009-01-06 - v0.6.7 * added support for Wi-Fi Protected Setup (WPS) diff --git a/hostapd/wpa.c b/hostapd/wpa.c index d88f6218f..64bc6b39d 100644 --- a/hostapd/wpa.c +++ b/hostapd/wpa.c @@ -1405,14 +1405,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; diff --git a/hostapd/wpa_auth_i.h b/hostapd/wpa_auth_i.h index bcaeda5dc..925d3ee45 100644 --- a/hostapd/wpa_auth_i.h +++ b/hostapd/wpa_auth_i.h @@ -213,7 +213,7 @@ void wpa_smk_m3(struct wpa_authenticator *wpa_auth, #ifdef CONFIG_IEEE80211R int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len); int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk, - struct wpa_ptk *ptk); + struct wpa_ptk *ptk, size_t ptk_len); struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void); void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache); #endif /* CONFIG_IEEE80211R */ diff --git a/hostapd/wpa_ft.c b/hostapd/wpa_ft.c index 8c5217664..bc86bd0cc 100644 --- a/hostapd/wpa_ft.c +++ b/hostapd/wpa_ft.c @@ -344,7 +344,7 @@ static int wpa_ft_pull_pmk_r1(struct wpa_authenticator *wpa_auth, int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk, - struct wpa_ptk *ptk) + struct wpa_ptk *ptk, size_t ptk_len) { u8 pmk_r0[PMK_LEN], pmk_r0_name[WPA_PMK_NAME_LEN]; u8 pmk_r1[PMK_LEN], pmk_r1_name[WPA_PMK_NAME_LEN]; @@ -377,8 +377,8 @@ int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk, wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr, sm->wpa_auth->addr, pmk_r1_name, - (u8 *) ptk, sizeof(*ptk), ptk_name); - wpa_hexdump_key(MSG_DEBUG, "FT: PTK", (u8 *) ptk, sizeof(*ptk)); + (u8 *) ptk, ptk_len, ptk_name); + wpa_hexdump_key(MSG_DEBUG, "FT: PTK", (u8 *) ptk, ptk_len); wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN); return 0; @@ -889,7 +889,7 @@ static u16 wpa_ft_process_auth_req(struct wpa_state_machine *sm, u8 ptk_name[WPA_PMK_NAME_LEN]; struct wpa_auth_config *conf; struct wpa_ft_ies parse; - size_t buflen; + size_t buflen, ptk_len; int ret; u8 *pos, *end; @@ -979,11 +979,12 @@ static u16 wpa_ft_process_auth_req(struct wpa_state_machine *sm, wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce", sm->ANonce, WPA_NONCE_LEN); + ptk_len = sm->pairwise == WPA_CIPHER_CCMP ? 48 : 64; wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr, sm->wpa_auth->addr, pmk_r1_name, - (u8 *) &sm->PTK, sizeof(sm->PTK), ptk_name); + (u8 *) &sm->PTK, ptk_len, ptk_name); wpa_hexdump_key(MSG_DEBUG, "FT: PTK", - (u8 *) &sm->PTK, sizeof(sm->PTK)); + (u8 *) &sm->PTK, ptk_len); wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN); wpa_ft_install_ptk(sm); diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 3bcb6ab7c..bedc0c481 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -360,14 +360,15 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr, const struct wpa_eapol_key *key, struct wpa_ptk *ptk) { + size_t ptk_len = sm->pairwise_cipher == WPA_CIPHER_CCMP ? 48 : 64; #ifdef CONFIG_IEEE80211R if (wpa_key_mgmt_ft(sm->key_mgmt)) - return wpa_derive_ptk_ft(sm, src_addr, key, ptk); + return wpa_derive_ptk_ft(sm, src_addr, key, ptk, ptk_len); #endif /* CONFIG_IEEE80211R */ wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion", sm->own_addr, sm->bssid, sm->snonce, key->key_nonce, - (u8 *) ptk, sizeof(*ptk), + (u8 *) ptk, ptk_len, wpa_key_mgmt_sha256(sm->key_mgmt)); return 0; } diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index aa77a3d12..9a39ed249 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -26,7 +26,7 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, const struct wpa_eapol_key *key, - struct wpa_ptk *ptk) + struct wpa_ptk *ptk, size_t ptk_len) { u8 pmk_r1_name[WPA_PMK_NAME_LEN]; u8 ptk_name[WPA_PMK_NAME_LEN]; @@ -51,8 +51,8 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", pmk_r1_name, WPA_PMK_NAME_LEN); wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->snonce, anonce, sm->own_addr, sm->bssid, pmk_r1_name, - (u8 *) ptk, sizeof(*ptk), ptk_name); - wpa_hexdump_key(MSG_DEBUG, "FT: PTK", (u8 *) ptk, sizeof(*ptk)); + (u8 *) ptk, ptk_len, ptk_name); + wpa_hexdump_key(MSG_DEBUG, "FT: PTK", (u8 *) ptk, ptk_len); wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN); return 0; @@ -520,7 +520,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, const u8 *ric_ies, size_t ric_ies_len) { u8 *ft_ies; - size_t ft_ies_len; + size_t ft_ies_len, ptk_len; struct wpa_ft_ies parse; struct rsn_mdie *mdie; struct rsn_ftie *ftie; @@ -611,11 +611,12 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, sm->pmk_r1_name, WPA_PMK_NAME_LEN); bssid = target_ap; + ptk_len = sm->pairwise_cipher == WPA_CIPHER_CCMP ? 48 : 64; wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->snonce, ftie->anonce, sm->own_addr, bssid, sm->pmk_r1_name, - (u8 *) &sm->ptk, sizeof(sm->ptk), ptk_name); + (u8 *) &sm->ptk, ptk_len, ptk_name); wpa_hexdump_key(MSG_DEBUG, "FT: PTK", - (u8 *) &sm->ptk, sizeof(sm->ptk)); + (u8 *) &sm->ptk, ptk_len); wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN); ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, ftie->anonce, diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 95348da8a..e0dc6bd41 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -240,6 +240,6 @@ int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst, int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, const struct wpa_eapol_key *key, - struct wpa_ptk *ptk); + struct wpa_ptk *ptk, size_t ptk_len); #endif /* WPA_I_H */ diff --git a/wpa_supplicant/ChangeLog b/wpa_supplicant/ChangeLog index 795194dda..bae055b21 100644 --- a/wpa_supplicant/ChangeLog +++ b/wpa_supplicant/ChangeLog @@ -22,6 +22,9 @@ ChangeLog for wpa_supplicant and association commands (e.g., mac80211-based Linux drivers with nl80211; SME in wpa_supplicant); this allows over-the-air FT protocol to be used (IEEE 802.11r) + * fixed SHA-256 based key derivation function to match with the + standard when using CCMP (for IEEE 802.11r and IEEE 802.11w) + (note: this breaks interoperability with previous version) [Bug 307] 2009-01-06 - v0.6.7 * added support for Wi-Fi Protected Setup (WPS)