From 86f7b62a3315499c2efd25b3a57ea591a6e4fd7c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 13 Mar 2010 17:15:38 +0200 Subject: [PATCH] FT: Add a workaround to set PTK after reassociation If the PTK configuration prior to association fails, allow reassociation attempt to continue and configure PTK after association. This is a workaround for drivers that do not allow PTK to be configured before association (e.g., current cfg80211/mac80211). --- src/rsn_supp/wpa_ft.c | 37 ++++++++++++++++++++++++++++--------- src/rsn_supp/wpa_i.h | 1 + 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index 964977fce..556838b34 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -629,18 +629,29 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, } ret = wpa_ft_install_ptk(sm, bssid); + if (ret) { + /* + * Some drivers do not support key configuration when we are + * not associated with the target AP. Work around this by + * trying again after the following reassociation gets + * completed. + */ + wpa_printf(MSG_DEBUG, "FT: Failed to set PTK prior to " + "association - try again after reassociation"); + sm->set_ptk_after_assoc = 1; + } else + sm->set_ptk_after_assoc = 0; - if (ret == 0) { - sm->ft_completed = 1; - if (ft_action) { - /* TODO: trigger re-association to the Target AP; - * MLME is now doing this automatically, but it should - * really be done only if we get here successfully. */ - os_memcpy(sm->bssid, target_ap, ETH_ALEN); - } + sm->ft_completed = 1; + if (ft_action) { + /* + * The caller is expected trigger re-association with the + * Target AP. + */ + os_memcpy(sm->bssid, target_ap, ETH_ALEN); } - return ret; + return 0; } @@ -896,6 +907,14 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, return -1; #endif /* CONFIG_IEEE80211W */ + if (sm->set_ptk_after_assoc) { + wpa_printf(MSG_DEBUG, "FT: Try to set PTK again now that we " + "are associated"); + if (wpa_ft_install_ptk(sm, src_addr) < 0) + return -1; + sm->set_ptk_after_assoc = 0; + } + if (parse.ric) { wpa_hexdump(MSG_MSGDUMP, "FT: RIC Response", parse.ric, parse.ric_len); diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index f1dcfdd69..bb774f97d 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -106,6 +106,7 @@ struct wpa_sm { int ft_completed; int over_the_ds_in_progress; u8 target_ap[ETH_ALEN]; /* over-the-DS target AP */ + int set_ptk_after_assoc; #endif /* CONFIG_IEEE80211R */ };