FT: Fix PTK configuration in authenticator

Must update sm->pairwise when fetching PMK-R1 SA.
Add a workaround for drivers that cannot set keys before association
(e.g., cfg80211/mac80211): retry PTK configuration after association.
This commit is contained in:
Jouni Malinen 2010-03-13 21:11:26 +02:00
parent 2a7e7f4e4a
commit 0e84c25434
3 changed files with 15 additions and 4 deletions

View File

@ -1210,6 +1210,11 @@ int wpa_auth_sm_event(struct wpa_state_machine *sm, wpa_event event)
break; break;
case WPA_ASSOC_FT: case WPA_ASSOC_FT:
#ifdef CONFIG_IEEE80211R #ifdef CONFIG_IEEE80211R
if (!sm->pairwise_set) {
wpa_printf(MSG_DEBUG, "FT: Retry PTK configuration "
"after association");
wpa_ft_install_ptk(sm);
}
/* Using FT protocol, not WPA auth state machine */ /* Using FT protocol, not WPA auth state machine */
sm->ft_completed = 1; sm->ft_completed = 1;
return 0; return 0;

View File

@ -852,7 +852,7 @@ static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
} }
static void wpa_ft_install_ptk(struct wpa_state_machine *sm) void wpa_ft_install_ptk(struct wpa_state_machine *sm)
{ {
enum wpa_alg alg; enum wpa_alg alg;
int klen; int klen;
@ -864,13 +864,17 @@ static void wpa_ft_install_ptk(struct wpa_state_machine *sm)
} else if (sm->pairwise == WPA_CIPHER_CCMP) { } else if (sm->pairwise == WPA_CIPHER_CCMP) {
alg = WPA_ALG_CCMP; alg = WPA_ALG_CCMP;
klen = 16; klen = 16;
} else } else {
wpa_printf(MSG_DEBUG, "FT: Unknown pairwise alg 0x%x - skip "
"PTK configuration", sm->pairwise);
return; return;
}
/* FIX: add STA entry to kernel/driver here? The set_key will fail /* FIX: add STA entry to kernel/driver here? The set_key will fail
* most likely without this.. At the moment, STA entry is added only * most likely without this.. At the moment, STA entry is added only
* after association has been completed. Alternatively, could * after association has been completed. This function will be called
* re-configure PTK at that point(?). * again after association to get the PTK configured, but that could be
* optimized by adding the STA entry earlier.
*/ */
if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0, if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
sm->PTK.tk1, klen)) sm->PTK.tk1, klen))
@ -990,6 +994,7 @@ static u16 wpa_ft_process_auth_req(struct wpa_state_machine *sm,
(u8 *) &sm->PTK, ptk_len); (u8 *) &sm->PTK, ptk_len);
wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN); wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
sm->pairwise = pairwise;
wpa_ft_install_ptk(sm); wpa_ft_install_ptk(sm);
buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) + buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +

View File

@ -216,6 +216,7 @@ int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
struct wpa_ptk *ptk, size_t ptk_len); struct wpa_ptk *ptk, size_t ptk_len);
struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void); struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void);
void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache); void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache);
void wpa_ft_install_ptk(struct wpa_state_machine *sm);
#endif /* CONFIG_IEEE80211R */ #endif /* CONFIG_IEEE80211R */
#endif /* WPA_AUTH_I_H */ #endif /* WPA_AUTH_I_H */