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
This commit is contained in:
Cy Schubert 2018-07-19 14:35:27 +00:00
parent 256810032c
commit 190650c714
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/wpa/dist/; revision=336485
5 changed files with 37 additions and 4 deletions

View File

@ -1841,6 +1841,7 @@ static int add_associated_sta(struct hostapd_data *hapd,
{
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 *hapd,
* 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 *hapd,
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);

View File

@ -1745,6 +1745,9 @@ int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event)
#else /* CONFIG_IEEE80211R */
break;
#endif /* CONFIG_IEEE80211R */
case WPA_DRV_STA_REMOVED:
sm->tk_already_set = FALSE;
return 0;
}
#ifdef CONFIG_IEEE80211R
@ -3250,6 +3253,14 @@ int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm)
}
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;
}
int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
struct rsn_pmksa_cache_entry *entry)
{

View File

@ -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 *

View File

@ -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_machine *sm,
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) +

View File

@ -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 {