Browse Source

FILS: Set TK after association (AP)

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Jouni Malinen 9 years ago
parent
commit
da24c5aa1c
3 changed files with 37 additions and 1 deletions
  1. 12 0
      src/ap/ieee802_11.c
  2. 24 1
      src/ap/wpa_auth.c
  3. 1 0
      src/ap/wpa_auth.h

+ 12 - 0
src/ap/ieee802_11.c

@@ -3258,6 +3258,18 @@ static void handle_assoc_cb(struct hostapd_data *hapd,
 	hapd->new_assoc_sta_cb(hapd, sta, !new_assoc);
 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
 
+#ifdef CONFIG_FILS
+	if ((sta->auth_alg == WLAN_AUTH_FILS_SK ||
+	     sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
+	     sta->auth_alg == WLAN_AUTH_FILS_PK) &&
+	    fils_set_tk(sta->wpa_sm) < 0) {
+		wpa_printf(MSG_DEBUG, "FILS: TK configuration failed");
+		ap_sta_disconnect(hapd, sta, sta->addr,
+				  WLAN_REASON_UNSPECIFIED);
+		return;
+	}
+#endif /* CONFIG_FILS */
+
 	if (sta->pending_eapol_rx) {
 		struct os_reltime now, age;
 

+ 24 - 1
src/ap/wpa_auth.c

@@ -1759,7 +1759,8 @@ int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event)
 		remove_ptk = 0;
 #endif /* CONFIG_IEEE80211W */
 #ifdef CONFIG_FILS
-	if (wpa_key_mgmt_fils(sm->wpa_key_mgmt) && event == WPA_AUTH)
+	if (wpa_key_mgmt_fils(sm->wpa_key_mgmt) &&
+	    (event == WPA_AUTH || event == WPA_ASSOC))
 		remove_ptk = 0;
 #endif /* CONFIG_FILS */
 
@@ -2395,6 +2396,28 @@ int fils_encrypt_assoc(struct wpa_state_machine *sm, u8 *buf,
 	return current_len;
 }
 
+
+int fils_set_tk(struct wpa_state_machine *sm)
+{
+	enum wpa_alg alg;
+	int klen;
+
+	if (!sm || !sm->PTK_valid)
+		return -1;
+
+	alg = wpa_cipher_to_alg(sm->pairwise);
+	klen = wpa_cipher_key_len(sm->pairwise);
+
+	wpa_printf(MSG_DEBUG, "FILS: Configure TK to the driver");
+	if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
+			     sm->PTK.tk, klen)) {
+		wpa_printf(MSG_DEBUG, "FILS: Failed to set TK to the driver");
+		return -1;
+	}
+
+	return 0;
+}
+
 #endif /* CONFIG_FILS */
 
 

+ 1 - 0
src/ap/wpa_auth.h

@@ -355,5 +355,6 @@ int fils_decrypt_assoc(struct wpa_state_machine *sm, const u8 *fils_session,
 		       u8 *pos, size_t left);
 int fils_encrypt_assoc(struct wpa_state_machine *sm, u8 *buf,
 		       size_t current_len, size_t max_len);
+int fils_set_tk(struct wpa_state_machine *sm);
 
 #endif /* WPA_AUTH_H */