* 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)
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;
#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 */
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];
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;
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;
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);
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;
}
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];
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;
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;
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,
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 */
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)