FT: Fix PTK configuration in authenticator
authorJouni Malinen <j@w1.fi>
Sat, 13 Mar 2010 19:11:26 +0000 (21:11 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 13 Mar 2010 19:11:26 +0000 (21:11 +0200)
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.

src/ap/wpa_auth.c
src/ap/wpa_auth_ft.c
src/ap/wpa_auth_i.h

index fd6dba5..93ccb76 100644 (file)
@@ -1210,6 +1210,11 @@ int wpa_auth_sm_event(struct wpa_state_machine *sm, wpa_event event)
                break;
        case WPA_ASSOC_FT:
 #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 */
                sm->ft_completed = 1;
                return 0;
index c3200b1..2bf646b 100644 (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;
        int klen;
@@ -864,13 +864,17 @@ static void wpa_ft_install_ptk(struct wpa_state_machine *sm)
        } else if (sm->pairwise == WPA_CIPHER_CCMP) {
                alg = WPA_ALG_CCMP;
                klen = 16;
-       } else
+       } else {
+               wpa_printf(MSG_DEBUG, "FT: Unknown pairwise alg 0x%x - skip "
+                          "PTK configuration", sm->pairwise);
                return;
+       }
 
        /* 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
-        * after association has been completed. Alternatively, could
-        * re-configure PTK at that point(?).
+        * after association has been completed. This function will be called
+        * 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,
                             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);
        wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
 
+       sm->pairwise = pairwise;
        wpa_ft_install_ptk(sm);
 
        buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +
index 925d3ee..86df3a4 100644 (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_ft_pmk_cache * wpa_ft_pmk_cache_init(void);
 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 /* WPA_AUTH_I_H */