svn commit: r336485 - vendor/wpa/dist/src/ap

Cy Schubert cy at FreeBSD.org
Thu Jul 19 14:35:30 UTC 2018


Author: cy
Date: Thu Jul 19 14:35:27 2018
New Revision: 336485
URL: https://svnweb.freebsd.org/changeset/base/336485

Log:
  Import upline hostapd-avoid-key-reinstallation security patch.
  
  Obtained from:	https://w1.fi/security/2017-1/\
  		rebased-v2.6-0001-hostapd-Avoid-key-\
  		reinstallation-in-FT-handshake.patch

Modified:
  vendor/wpa/dist/src/ap/ieee802_11.c
  vendor/wpa/dist/src/ap/wpa_auth.c
  vendor/wpa/dist/src/ap/wpa_auth.h
  vendor/wpa/dist/src/ap/wpa_auth_ft.c
  vendor/wpa/dist/src/ap/wpa_auth_i.h

Modified: vendor/wpa/dist/src/ap/ieee802_11.c
==============================================================================
--- vendor/wpa/dist/src/ap/ieee802_11.c	Thu Jul 19 14:24:48 2018	(r336484)
+++ vendor/wpa/dist/src/ap/ieee802_11.c	Thu Jul 19 14:35:27 2018	(r336485)
@@ -1841,6 +1841,7 @@ static int add_associated_sta(struct hostapd_data *hap
 {
 	struct ieee80211_ht_capabilities ht_cap;
 	struct ieee80211_vht_capabilities vht_cap;
+	int set = 1;
 
 	/*
 	 * Remove the STA entry to ensure the STA PS state gets cleared and
@@ -1848,9 +1849,18 @@ static int add_associated_sta(struct hostapd_data *hap
 	 * FT-over-the-DS, where a station re-associates back to the same AP but
 	 * skips the authentication flow, or if working with a driver that
 	 * does not support full AP client state.
+	 *
+	 * Skip this if the STA has already completed FT reassociation and the
+	 * TK has been configured since the TX/RX PN must not be reset to 0 for
+	 * the same key.
 	 */
-	if (!sta->added_unassoc)
+	if (!sta->added_unassoc &&
+	    (!(sta->flags & WLAN_STA_AUTHORIZED) ||
+	     !wpa_auth_sta_ft_tk_already_set(sta->wpa_sm))) {
 		hostapd_drv_sta_remove(hapd, sta->addr);
+		wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED);
+		set = 0;
+	}
 
 #ifdef CONFIG_IEEE80211N
 	if (sta->flags & WLAN_STA_HT)
@@ -1873,11 +1883,11 @@ static int add_associated_sta(struct hostapd_data *hap
 			    sta->flags & WLAN_STA_VHT ? &vht_cap : NULL,
 			    sta->flags | WLAN_STA_ASSOC, sta->qosinfo,
 			    sta->vht_opmode, sta->p2p_ie ? 1 : 0,
-			    sta->added_unassoc)) {
+			    set)) {
 		hostapd_logger(hapd, sta->addr,
 			       HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE,
 			       "Could not %s STA to kernel driver",
-			       sta->added_unassoc ? "set" : "add");
+			       set ? "set" : "add");
 
 		if (sta->added_unassoc) {
 			hostapd_drv_sta_remove(hapd, sta->addr);

Modified: vendor/wpa/dist/src/ap/wpa_auth.c
==============================================================================
--- vendor/wpa/dist/src/ap/wpa_auth.c	Thu Jul 19 14:24:48 2018	(r336484)
+++ vendor/wpa/dist/src/ap/wpa_auth.c	Thu Jul 19 14:35:27 2018	(r336485)
@@ -1745,6 +1745,9 @@ int wpa_auth_sm_event(struct wpa_state_machine *sm, en
 #else /* CONFIG_IEEE80211R */
 		break;
 #endif /* CONFIG_IEEE80211R */
+	case WPA_DRV_STA_REMOVED:
+		sm->tk_already_set = FALSE;
+		return 0;
 	}
 
 #ifdef CONFIG_IEEE80211R
@@ -3247,6 +3250,14 @@ int wpa_auth_sta_wpa_version(struct wpa_state_machine 
 	if (sm == NULL)
 		return 0;
 	return sm->wpa;
+}
+
+
+int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm)
+{
+	if (!sm || !wpa_key_mgmt_ft(sm->wpa_key_mgmt))
+		return 0;
+	return sm->tk_already_set;
 }
 
 

Modified: vendor/wpa/dist/src/ap/wpa_auth.h
==============================================================================
--- vendor/wpa/dist/src/ap/wpa_auth.h	Thu Jul 19 14:24:48 2018	(r336484)
+++ vendor/wpa/dist/src/ap/wpa_auth.h	Thu Jul 19 14:35:27 2018	(r336485)
@@ -267,7 +267,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
 		 u8 *data, size_t data_len);
 enum wpa_event {
 	WPA_AUTH, WPA_ASSOC, WPA_DISASSOC, WPA_DEAUTH, WPA_REAUTH,
-	WPA_REAUTH_EAPOL, WPA_ASSOC_FT
+	WPA_REAUTH_EAPOL, WPA_ASSOC_FT, WPA_DRV_STA_REMOVED
 };
 void wpa_remove_ptk(struct wpa_state_machine *sm);
 int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event);
@@ -280,6 +280,7 @@ int wpa_auth_pairwise_set(struct wpa_state_machine *sm
 int wpa_auth_get_pairwise(struct wpa_state_machine *sm);
 int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm);
 int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm);
+int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm);
 int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
 			     struct rsn_pmksa_cache_entry *entry);
 struct rsn_pmksa_cache_entry *

Modified: vendor/wpa/dist/src/ap/wpa_auth_ft.c
==============================================================================
--- vendor/wpa/dist/src/ap/wpa_auth_ft.c	Thu Jul 19 14:24:48 2018	(r336484)
+++ vendor/wpa/dist/src/ap/wpa_auth_ft.c	Thu Jul 19 14:35:27 2018	(r336485)
@@ -780,6 +780,14 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm)
 		return;
 	}
 
+	if (sm->tk_already_set) {
+		/* Must avoid TK reconfiguration to prevent clearing of TX/RX
+		 * PN in the driver */
+		wpa_printf(MSG_DEBUG,
+			   "FT: Do not re-install same PTK to the driver");
+		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. This function will be called
@@ -792,6 +800,7 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm)
 
 	/* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
 	sm->pairwise_set = TRUE;
+	sm->tk_already_set = TRUE;
 }
 
 
@@ -898,6 +907,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_ma
 
 	sm->pairwise = pairwise;
 	sm->PTK_valid = TRUE;
+	sm->tk_already_set = FALSE;
 	wpa_ft_install_ptk(sm);
 
 	buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +

Modified: vendor/wpa/dist/src/ap/wpa_auth_i.h
==============================================================================
--- vendor/wpa/dist/src/ap/wpa_auth_i.h	Thu Jul 19 14:24:48 2018	(r336484)
+++ vendor/wpa/dist/src/ap/wpa_auth_i.h	Thu Jul 19 14:35:27 2018	(r336485)
@@ -65,6 +65,7 @@ struct wpa_state_machine {
 	struct wpa_ptk PTK;
 	Boolean PTK_valid;
 	Boolean pairwise_set;
+	Boolean tk_already_set;
 	int keycount;
 	Boolean Pair;
 	struct wpa_key_replay_counter {


More information about the svn-src-all mailing list