]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Fix SHA-256-based KDF when using CCMP as the pairwise cipher
authorJouni Malinen <jouni.malinen@atheros.com>
Wed, 1 Apr 2009 09:04:36 +0000 (12:04 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 1 Apr 2009 09:04:36 +0000 (12:04 +0300)
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]

hostapd/ChangeLog
hostapd/wpa.c
hostapd/wpa_auth_i.h
hostapd/wpa_ft.c
src/rsn_supp/wpa.c
src/rsn_supp/wpa_ft.c
src/rsn_supp/wpa_i.h
wpa_supplicant/ChangeLog

index 5a2ac6971b5c3ecc1065c1e2cb127f28d12c78de..d79623a6e9c4c23dae076de12e9fffdcd0834be0 100644 (file)
@@ -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)
index d88f6218f126f52fe90b3efcacab65fd6808a74d..64bc6b39d9114bce7c2dc84427a5d57848bcd1fb 100644 (file)
@@ -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;
index bcaeda5dcb08c901e164cdf34e5bfd559f0d53bd..925d3ee459ce17f7c3e99c35039bd2f3931cd07a 100644 (file)
@@ -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 */
index 8c52176647a55512ea0e1989b061f45cdc033664..bc86bd0ccb10576651e53bdfcb3702e61ca2f72c 100644 (file)
@@ -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);
index 3bcb6ab7c0f3ae377e8539c1da86c7bafa84f5ea..bedc0c481bd85c676a1b20877c23fa2eab11508c 100644 (file)
@@ -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;
 }
index aa77a3d1290fbdefd7b39910f0ce807e773da007..9a39ed24998d5472f347be93c42faa740dc03afe 100644 (file)
@@ -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,
index 95348da8a996053d5692901f155c83e15f1acb37..e0dc6bd414e8cfb856a5597031531ac92e681cc8 100644 (file)
@@ -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 */
index 795194dda5eb719535a0e279b7fb5fc675c2356c..bae055b21ecc906c3688776d60d263f6bc29160b 100644 (file)
@@ -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)