aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-04-01 09:04:36 (GMT)
committerJouni Malinen <j@w1.fi>2009-04-20 09:10:19 (GMT)
commit1d779732670112f852b6e028f62613d9ff0120a5 (patch)
tree14ab67c0de885da001d1b0a3d81742db1fb7c8e8
parente1a5cf26b158860578d2511e9c34d28ea9802de4 (diff)
downloadhostap-06-1d779732670112f852b6e028f62613d9ff0120a5.zip
hostap-06-1d779732670112f852b6e028f62613d9ff0120a5.tar.gz
hostap-06-1d779732670112f852b6e028f62613d9ff0120a5.tar.bz2
Fix SHA-256-based KDF when using CCMP as the pairwise cipher
IEEE 802.11r KDF uses key length in the derivation and as such, the PTK length must be specified correctly. The previous version was deriving using 512-bit PTK regardless of the negotiated cipher suite; this works for TKIP, but not for CCMP. Update the code to use proper PTK length based on the pairwise cipher. This fixed PTK derivation for both IEEE 802.11r and IEEE 802.11w (when using AKMP that specifies SHA-256-based key derivation). The fixed version does not interoperate with the previous versions. [Bug 307] (cherry picked from commit c0a6190815ce37450fc348d4d09b2a0153478fc0) Conflicts: wpa_supplicant/ChangeLog
-rw-r--r--hostapd/ChangeLog5
-rw-r--r--hostapd/wpa.c5
-rw-r--r--hostapd/wpa_auth_i.h2
-rw-r--r--hostapd/wpa_ft.c13
-rw-r--r--src/rsn_supp/wpa.c5
-rw-r--r--src/rsn_supp/wpa_ft.c13
-rw-r--r--src/rsn_supp/wpa_i.h2
-rw-r--r--wpa_supplicant/ChangeLog5
8 files changed, 32 insertions, 18 deletions
diff --git a/hostapd/ChangeLog b/hostapd/ChangeLog
index 51cd049..63023b1 100644
--- a/hostapd/ChangeLog
+++ b/hostapd/ChangeLog
@@ -1,5 +1,10 @@
ChangeLog for hostapd
+????-??-?? - v0.6.10
+ * 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-03-23 - v0.6.9
* driver_nl80211: fixed STA accounting data collection (TX/RX bytes
reported correctly; TX/RX packets not yet available from kernel)
diff --git a/hostapd/wpa.c b/hostapd/wpa.c
index cf285b6..ca08a02 100644
--- a/hostapd/wpa.c
+++ b/hostapd/wpa.c
@@ -1403,14 +1403,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 bcaeda5..925d3ee 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 9cf6713..3139105 100644
--- a/hostapd/wpa_ft.c
+++ b/hostapd/wpa_ft.c
@@ -321,7 +321,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];
@@ -354,8 +354,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;
@@ -714,7 +714,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;
@@ -804,11 +804,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 d1d0bec..2a6c8ca 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -358,14 +358,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 c89b89a..557b311 100644
--- a/src/rsn_supp/wpa_ft.c
+++ b/src/rsn_supp/wpa_ft.c
@@ -25,7 +25,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];
@@ -50,8 +50,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;
@@ -455,7 +455,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
int ft_action, const u8 *target_ap)
{
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;
@@ -545,11 +545,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 95348da..e0dc6bd 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 199a471..25d6335 100644
--- a/wpa_supplicant/ChangeLog
+++ b/wpa_supplicant/ChangeLog
@@ -1,5 +1,10 @@
ChangeLog for wpa_supplicant
+????-??-?? - v0.6.10
+ * 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-03-23 - v0.6.9
* driver_ndis: add PAE group address to the multicast address list to
fix wired IEEE 802.1X authentication