FT: Clean up wpa_sm_set_ft_params() by using common parse
authorJouni Malinen <j@w1.fi>
Sat, 10 Apr 2010 08:36:35 +0000 (11:36 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 10 Apr 2010 08:36:35 +0000 (11:36 +0300)
Instead of parsing the IEs in the callers, use the already existing
parser in wpa_ft.c to handle MDIE and FTIE from initial MD association
response. In addition, this provides more complete access to association
response IEs to FT code which will be needed to fix FT 4-way handshake
message 2/4.

src/rsn_supp/wpa.h
src/rsn_supp/wpa_ft.c
wpa_supplicant/events.c
wpa_supplicant/mlme.c
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant.c

index 0d4405b..72bf8f4 100644 (file)
@@ -278,9 +278,7 @@ static inline int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer)
 
 #ifdef CONFIG_IEEE80211R
 
-int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *mobility_domain,
-                        const u8 *r0kh_id, size_t r0kh_id_len,
-                        const u8 *r1kh_id);
+int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len);
 int wpa_ft_prepare_auth_request(struct wpa_sm *sm, const u8 *mdie);
 int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
                            int ft_action, const u8 *target_ap,
index 50f48ed..d3051f8 100644 (file)
 
 #ifdef CONFIG_IEEE80211R
 
+struct wpa_ft_ies {
+       const u8 *mdie;
+       size_t mdie_len;
+       const u8 *ftie;
+       size_t ftie_len;
+       const u8 *r1kh_id;
+       const u8 *gtk;
+       size_t gtk_len;
+       const u8 *r0kh_id;
+       size_t r0kh_id_len;
+       const u8 *rsn;
+       size_t rsn_len;
+       const u8 *rsn_pmkid;
+       const u8 *tie;
+       size_t tie_len;
+       const u8 *igtk;
+       size_t igtk_len;
+       const u8 *ric;
+       size_t ric_len;
+};
+
+static int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
+                           struct wpa_ft_ies *parse);
+
+
 int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
                      const struct wpa_eapol_key *key,
                      struct wpa_ptk *ptk, size_t ptk_len)
@@ -62,34 +87,40 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
 /**
  * wpa_sm_set_ft_params - Set FT (IEEE 802.11r) parameters
  * @sm: Pointer to WPA state machine data from wpa_sm_init()
- * @mobility_domain: Mobility domain identifier (2 octets + 1 octet)
- * @r0kh_id: PMK-R0 key holder identity (1-48 octets)
- * @r0kh_id_len: R0KH-ID length (1-48)
- * @r1kh_id: PMK-R1 key holder identity (16 octets)
+ * @ies: Association Response IEs or %NULL to clear FT parameters
+ * @ies_len: Length of ies buffer in octets
  * Returns: 0 on success, -1 on failure
  */
-int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *mobility_domain,
-                        const u8 *r0kh_id, size_t r0kh_id_len,
-                        const u8 *r1kh_id)
+int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len)
 {
-       if (sm && mobility_domain) {
+       struct wpa_ft_ies ft;
+
+       if (sm == NULL)
+               return 0;
+
+       if (wpa_ft_parse_ies(ies, ies_len, &ft) < 0)
+               return -1;
+
+       if (ft.mdie && ft.mdie_len < MOBILITY_DOMAIN_ID_LEN + 1)
+               return -1;
+
+       if (ft.mdie) {
                wpa_hexdump(MSG_DEBUG, "FT: Mobility domain",
-                           mobility_domain, MOBILITY_DOMAIN_ID_LEN);
-               os_memcpy(sm->mobility_domain, mobility_domain,
+                           ft.mdie, MOBILITY_DOMAIN_ID_LEN);
+               os_memcpy(sm->mobility_domain, ft.mdie,
                          MOBILITY_DOMAIN_ID_LEN);
-               sm->mdie_ft_capab = mobility_domain[MOBILITY_DOMAIN_ID_LEN];
+               sm->mdie_ft_capab = ft.mdie[MOBILITY_DOMAIN_ID_LEN];
                wpa_printf(MSG_DEBUG, "FT: Capability and Policy: 0x%02x",
                           sm->mdie_ft_capab);
-       } else if (sm)
+       } else
                os_memset(sm->mobility_domain, 0, MOBILITY_DOMAIN_ID_LEN);
 
-       if (sm && r0kh_id) {
-               if (r0kh_id_len > FT_R0KH_ID_MAX_LEN)
-                       return -1;
-               wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID", r0kh_id, r0kh_id_len);
-               os_memcpy(sm->r0kh_id, r0kh_id, r0kh_id_len);
-               sm->r0kh_id_len = r0kh_id_len;
-       } else if (sm) {
+       if (ft.r0kh_id) {
+               wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID",
+                           ft.r0kh_id, ft.r0kh_id_len);
+               os_memcpy(sm->r0kh_id, ft.r0kh_id, ft.r0kh_id_len);
+               sm->r0kh_id_len = ft.r0kh_id_len;
+       } else {
                /* FIX: When should R0KH-ID be cleared? We need to keep the
                 * old R0KH-ID in order to be able to use this during FT. */
                /*
@@ -98,10 +129,11 @@ int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *mobility_domain,
                 */
        }
 
-       if (sm && r1kh_id) {
-               wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID", r1kh_id, FT_R1KH_ID_LEN);
-               os_memcpy(sm->r1kh_id, r1kh_id, FT_R1KH_ID_LEN);
-       } else if (sm)
+       if (ft.r1kh_id) {
+               wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID",
+                           ft.r1kh_id, FT_R1KH_ID_LEN);
+               os_memcpy(sm->r1kh_id, ft.r1kh_id, FT_R1KH_ID_LEN);
+       } else
                os_memset(sm->r1kh_id, 0, FT_R1KH_ID_LEN);
 
        return 0;
@@ -296,28 +328,6 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
 }
 
 
-struct wpa_ft_ies {
-       const u8 *mdie;
-       size_t mdie_len;
-       const u8 *ftie;
-       size_t ftie_len;
-       const u8 *r1kh_id;
-       const u8 *gtk;
-       size_t gtk_len;
-       const u8 *r0kh_id;
-       size_t r0kh_id_len;
-       const u8 *rsn;
-       size_t rsn_len;
-       const u8 *rsn_pmkid;
-       const u8 *tie;
-       size_t tie_len;
-       const u8 *igtk;
-       size_t igtk_len;
-       const u8 *ric;
-       size_t ric_len;
-};
-
-
 static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
                             struct wpa_ft_ies *parse)
 {
index afd06b4..d43a172 100644 (file)
@@ -956,58 +956,11 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_NO_SCAN_PROCESSING */
 
 
-#ifdef CONFIG_IEEE80211R
-static void wpa_assoc_set_ft_params(struct wpa_supplicant *wpa_s,
-                                   const u8 *ftie, const u8 *mdie)
-{
-       const u8 *mobility_domain = NULL;
-       const u8 *r0kh_id = NULL;
-       size_t r0kh_id_len = 0;
-       const u8 *r1kh_id = NULL;
-       struct rsn_ftie *hdr;
-       const u8 *pos, *end;
-
-       if (mdie == NULL || ftie == NULL)
-               return;
-
-       if (mdie[1] >= MOBILITY_DOMAIN_ID_LEN) {
-               mobility_domain = mdie + 2;
-#ifdef CONFIG_SME
-               wpa_s->sme.ft_used = 1;
-               os_memcpy(wpa_s->sme.mobility_domain, mobility_domain, 2);
-#endif /* CONFIG_SME */
-       }
-       if (ftie[1] >= sizeof(struct rsn_ftie)) {
-               end = ftie + 2 + ftie[1];
-               hdr = (struct rsn_ftie *) (ftie + 2);
-               pos = (const u8 *) (hdr + 1);
-               while (pos + 1 < end) {
-                       if (pos + 2 + pos[1] > end)
-                               break;
-                       if (pos[0] == FTIE_SUBELEM_R1KH_ID &&
-                           pos[1] == FT_R1KH_ID_LEN)
-                               r1kh_id = pos + 2;
-                       else if (pos[0] == FTIE_SUBELEM_R0KH_ID &&
-                                pos[1] >= 1 && pos[1] <= FT_R0KH_ID_MAX_LEN) {
-                               r0kh_id = pos + 2;
-                               r0kh_id_len = pos[1];
-                       }
-                       pos += 2 + pos[1];
-               }
-       }
-       wpa_sm_set_ft_params(wpa_s->wpa, mobility_domain, r0kh_id,
-                            r0kh_id_len, r1kh_id);
-}
-#endif /* CONFIG_IEEE80211R */
-
 static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
                                          union wpa_event_data *data)
 {
        int l, len, found = 0, wpa_found, rsn_found;
        const u8 *p;
-#ifdef CONFIG_IEEE80211R
-       const u8 *mdie = NULL, *ftie = NULL;
-#endif /* CONFIG_IEEE80211R */
 
        wpa_printf(MSG_DEBUG, "Association info event");
        if (data->assoc_info.req_ies)
@@ -1065,12 +1018,11 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
                        return -1;
                }
        }
-#endif /* CONFIG_SME */
 
        p = data->assoc_info.resp_ies;
        l = data->assoc_info.resp_ies_len;
 
-       /* Go through the IEs and make a copy of the FT/MD IE, if present. */
+       /* Go through the IEs and make a copy of the MDIE, if present. */
        while (p && l >= 2) {
                len = p[1] + 2;
                if (len > l) {
@@ -1078,15 +1030,20 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
                                    p, l);
                        break;
                }
-               if (p[0] == WLAN_EID_FAST_BSS_TRANSITION)
-                       ftie = p;
-               else if (p[0] == WLAN_EID_MOBILITY_DOMAIN)
-                       mdie = p;
+               if (p[0] == WLAN_EID_MOBILITY_DOMAIN &&
+                   p[1] >= MOBILITY_DOMAIN_ID_LEN) {
+                       wpa_s->sme.ft_used = 1;
+                       os_memcpy(wpa_s->sme.mobility_domain, p + 2,
+                                 MOBILITY_DOMAIN_ID_LEN);
+                       break;
+               }
                l -= len;
                p += len;
        }
+#endif /* CONFIG_SME */
 
-       wpa_assoc_set_ft_params(wpa_s, ftie, mdie);
+       wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies,
+                            data->assoc_info.resp_ies_len);
 #endif /* CONFIG_IEEE80211R */
 
        /* WPA/RSN IE from Beacon/ProbeResp */
index b013a74..c9a1c28 100644 (file)
@@ -996,45 +996,6 @@ static void ieee80211_rx_mgmt_disassoc(struct wpa_supplicant *wpa_s,
 }
 
 
-static int ieee80211_ft_assoc_resp(struct wpa_supplicant *wpa_s,
-                                  struct ieee802_11_elems *elems)
-{
-#ifdef CONFIG_IEEE80211R
-       const u8 *mobility_domain = NULL;
-       const u8 *r0kh_id = NULL;
-       size_t r0kh_id_len = 0;
-       const u8 *r1kh_id = NULL;
-       struct rsn_ftie *hdr;
-       const u8 *pos, *end;
-
-       if (elems->mdie && elems->mdie_len >= MOBILITY_DOMAIN_ID_LEN)
-               mobility_domain = elems->mdie;
-       if (elems->ftie && elems->ftie_len >= sizeof(struct rsn_ftie)) {
-               end = elems->ftie + elems->ftie_len;
-               hdr = (struct rsn_ftie *) elems->ftie;
-               pos = (const u8 *) (hdr + 1);
-               while (pos + 1 < end) {
-                       if (pos + 2 + pos[1] > end)
-                               break;
-                       if (pos[0] == FTIE_SUBELEM_R1KH_ID &&
-                           pos[1] == FT_R1KH_ID_LEN)
-                               r1kh_id = pos + 2;
-                       else if (pos[0] == FTIE_SUBELEM_R0KH_ID &&
-                                pos[1] >= 1 && pos[1] <= FT_R0KH_ID_MAX_LEN) {
-                               r0kh_id = pos + 2;
-                               r0kh_id_len = pos[1];
-                       }
-                       pos += 2 + pos[1];
-               }
-       }
-       return wpa_sm_set_ft_params(wpa_s->wpa, mobility_domain, r0kh_id,
-                                   r0kh_id_len, r1kh_id);
-#else /* CONFIG_IEEE80211R */
-       return 0;
-#endif /* CONFIG_IEEE80211R */
-}
-
-
 static void ieee80211_build_tspec(struct wpabuf *buf)
 {
        struct wmm_tspec_element *tspec;
@@ -1194,7 +1155,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s,
                                   "Resp failed");
                        return;
                }
-       } else if (ieee80211_ft_assoc_resp(wpa_s, &elems) < 0)
+       } else if (wpa_sm_set_ft_params(wpa_s->wpa, pos,
+                                       len - (pos - (u8 *) mgmt)) < 0)
                return;
 
        wpa_printf(MSG_DEBUG, "MLME: associated");
index 800731d..a31f2db 100644 (file)
@@ -160,7 +160,7 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
        ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
        if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
                md = ie + 2;
-       wpa_sm_set_ft_params(wpa_s->wpa, md, NULL, 0, NULL);
+       wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
        if (md) {
                /* Prepare for the next transition */
                wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
index c5387bf..0eba4a0 100644 (file)
@@ -1037,7 +1037,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
                ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
                if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
                        md = ie + 2;
-               wpa_sm_set_ft_params(wpa_s->wpa, md, NULL, 0, NULL);
+               wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
                if (md) {
                        /* Prepare for the next transition */
                        wpa_ft_prepare_auth_request(wpa_s->wpa, ie);