FT: Use correct BSSID when deriving PTK and verifying MIC

The old version was using struct wpa_sm::bssid which is not necessarily
updated to point to the correct target address when doing over-the-air FT
since the address is used before the association has actually been
completed.
This commit is contained in:
Jouni Malinen 2008-03-12 11:20:20 +02:00
parent 58a98fb027
commit 658d166297
3 changed files with 10 additions and 7 deletions

View file

@ -280,7 +280,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
int ft_action, const u8 *target_ap); int ft_action, const u8 *target_ap);
int wpa_ft_is_completed(struct wpa_sm *sm); int wpa_ft_is_completed(struct wpa_sm *sm);
int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
size_t ies_len); size_t ies_len, const u8 *src_addr);
int wpa_ft_start_over_ds(struct wpa_sm *sm, const u8 *target_ap); int wpa_ft_start_over_ds(struct wpa_sm *sm, const u8 *target_ap);
#else /* CONFIG_IEEE80211R */ #else /* CONFIG_IEEE80211R */
@ -310,7 +310,8 @@ static inline int wpa_ft_is_completed(struct wpa_sm *sm)
} }
static inline int static inline int
wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, size_t ies_len) wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
const u8 *src_addr)
{ {
return -1; return -1;
} }

View file

@ -536,7 +536,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name",
sm->pmk_r1_name, WPA_PMK_NAME_LEN); sm->pmk_r1_name, WPA_PMK_NAME_LEN);
bssid = ft_action ? sm->target_ap : sm->bssid; bssid = target_ap;
wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->snonce, ftie->anonce, sm->own_addr, wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->snonce, ftie->anonce, sm->own_addr,
bssid, sm->pmk_r1_name, bssid, sm->pmk_r1_name,
(u8 *) &sm->ptk, sizeof(sm->ptk), ptk_name); (u8 *) &sm->ptk, sizeof(sm->ptk), ptk_name);
@ -582,7 +582,7 @@ int wpa_ft_is_completed(struct wpa_sm *sm)
int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
size_t ies_len) size_t ies_len, const u8 *src_addr)
{ {
struct wpa_ft_ies parse; struct wpa_ft_ies parse;
struct rsn_mdie *mdie; struct rsn_mdie *mdie;
@ -665,7 +665,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
return -1; return -1;
} }
if (wpa_ft_mic(sm->ptk.kck, sm->own_addr, sm->bssid, 6, if (wpa_ft_mic(sm->ptk.kck, sm->own_addr, src_addr, 6,
parse.mdie - 2, parse.mdie_len + 2, parse.mdie - 2, parse.mdie_len + 2,
parse.ftie - 2, parse.ftie_len + 2, parse.ftie - 2, parse.ftie_len + 2,
parse.rsn - 2, parse.rsn_len + 2, NULL, 0, parse.rsn - 2, parse.rsn_len + 2, NULL, 0,

View file

@ -356,7 +356,7 @@ static void ieee80211_sta_wmm_params(struct wpa_supplicant *wpa_s,
static void ieee80211_set_associated(struct wpa_supplicant *wpa_s, int assoc) static void ieee80211_set_associated(struct wpa_supplicant *wpa_s, int assoc)
{ {
if (wpa_s->mlme.associated == assoc) if (wpa_s->mlme.associated == assoc && !assoc)
return; return;
wpa_s->mlme.associated = assoc; wpa_s->mlme.associated = assoc;
@ -1051,6 +1051,7 @@ static void ieee80211_rx_mgmt_auth(struct wpa_supplicant *wpa_s,
data.ft_ies.ies = mgmt->u.auth.variable; data.ft_ies.ies = mgmt->u.auth.variable;
data.ft_ies.ies_len = len - data.ft_ies.ies_len = len -
(mgmt->u.auth.variable - (u8 *) mgmt); (mgmt->u.auth.variable - (u8 *) mgmt);
os_memcpy(data.ft_ies.target_ap, wpa_s->bssid, ETH_ALEN);
wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &data); wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &data);
ieee80211_auth_completed(wpa_s); ieee80211_auth_completed(wpa_s);
break; break;
@ -1258,7 +1259,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s,
return; return;
} }
if (wpa_ft_validate_reassoc_resp( if (wpa_ft_validate_reassoc_resp(
wpa_s->wpa, pos, len - (pos - (u8 *) mgmt)) < 0) { wpa_s->wpa, pos, len - (pos - (u8 *) mgmt),
mgmt->sa) < 0) {
wpa_printf(MSG_DEBUG, "MLME: FT validation of Reassoc" wpa_printf(MSG_DEBUG, "MLME: FT validation of Reassoc"
"Resp failed"); "Resp failed");
return; return;