aboutsummaryrefslogtreecommitdiffstats
path: root/src/rsn_supp
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-01 09:04:36 (GMT)
commitc0a6190815ce37450fc348d4d09b2a0153478fc0 (patch)
treefde0953e0c4a7c54a29e76f8e45ee39ae88c4147 /src/rsn_supp
parentd61f48ba1da01ed501026e5fa1b6bfefa6d5c93a (diff)
downloadhostap-c0a6190815ce37450fc348d4d09b2a0153478fc0.zip
hostap-c0a6190815ce37450fc348d4d09b2a0153478fc0.tar.gz
hostap-c0a6190815ce37450fc348d4d09b2a0153478fc0.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]
Diffstat (limited to 'src/rsn_supp')
-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
3 files changed, 11 insertions, 9 deletions
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 3bcb6ab..bedc0c4 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 aa77a3d..9a39ed2 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 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 */