Allow hostapd AP to advertise Transition Disable KDE

The new hostapd configuration parameter transition_disable can now be
used to configure the AP to advertise that use of a transition mode is
disabled. This allows stations to automatically disable transition mode
by disabling less secure network profile parameters.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2020-03-26 00:08:26 +02:00 committed by Jouni Malinen
parent 3eb9ddc658
commit 82cc0b0cc2
6 changed files with 45 additions and 3 deletions

View file

@ -4462,6 +4462,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
conf->rssi_reject_assoc_timeout = atoi(pos); conf->rssi_reject_assoc_timeout = atoi(pos);
} else if (os_strcmp(buf, "pbss") == 0) { } else if (os_strcmp(buf, "pbss") == 0) {
bss->pbss = atoi(pos); bss->pbss = atoi(pos);
} else if (os_strcmp(buf, "transition_disable") == 0) {
bss->transition_disable = strtol(pos, NULL, 16);
#ifdef CONFIG_AIRTIME_POLICY #ifdef CONFIG_AIRTIME_POLICY
} else if (os_strcmp(buf, "airtime_mode") == 0) { } else if (os_strcmp(buf, "airtime_mode") == 0) {
int val = atoi(pos); int val = atoi(pos);

View file

@ -1905,6 +1905,23 @@ own_ip_addr=127.0.0.1
# default: 30 TUs (= 30.72 milliseconds) # default: 30 TUs (= 30.72 milliseconds)
#fils_hlp_wait_time=30 #fils_hlp_wait_time=30
# Transition Disable indication
# The AP can notify authenticated stations to disable transition mode in their
# network profiles when the network has completed transition steps, i.e., once
# sufficiently large number of APs in the ESS have been updated to support the
# more secure alternative. When this indication is used, the stations are
# expected to automatically disable transition mode and less secure security
# options. This includes use of WEP, TKIP (including use of TKIP as the group
# cipher), and connections without PMF.
# Bitmap bits:
# bit 0 (0x01): WPA3-Personal (i.e., disable WPA2-Personal = WPA-PSK and only
# allow SAE to be used)
# bit 1 (0x02): SAE-PK (disable SAE without use of SAE-PK)
# bit 2 (0x04): WPA3-Enterprise (move to requiring PMF)
# bit 3 (0x08): Enhanced Open (disable use of open network; require OWE)
# (default: 0 = do not include Transition Disable KDE)
#transition_disable=0x01
##### IEEE 802.11r configuration ############################################## ##### IEEE 802.11r configuration ##############################################
# Mobility Domain identifier (dot11FTMobilityDomainID, MDID) # Mobility Domain identifier (dot11FTMobilityDomainID, MDID)

View file

@ -756,6 +756,8 @@ struct hostapd_bss_config {
u8 send_probe_response; u8 send_probe_response;
u8 transition_disable;
#define BACKHAUL_BSS 1 #define BACKHAUL_BSS 1
#define FRONTHAUL_BSS 2 #define FRONTHAUL_BSS 2
int multi_ap; /* bitmap of BACKHAUL_BSS, FRONTHAUL_BSS */ int multi_ap; /* bitmap of BACKHAUL_BSS, FRONTHAUL_BSS */

View file

@ -2712,8 +2712,13 @@ static struct wpabuf * fils_prepare_plainbuf(struct wpa_state_machine *sm,
u8 *gtk, dummy_gtk[32]; u8 *gtk, dummy_gtk[32];
size_t gtk_len; size_t gtk_len;
struct wpa_group *gsm; struct wpa_group *gsm;
size_t plain_len;
struct wpa_auth_config *conf = &sm->wpa_auth->conf;
plain = wpabuf_alloc(1000 + ieee80211w_kde_len(sm)); plain_len = 1000 + ieee80211w_kde_len(sm);
if (conf->transition_disable)
plain_len += 2 + RSN_SELECTOR_LEN + 1;
plain = wpabuf_alloc(plain_len);
if (!plain) if (!plain)
return NULL; return NULL;
@ -2766,6 +2771,13 @@ static struct wpabuf * fils_prepare_plainbuf(struct wpa_state_machine *sm,
tmp2 = ieee80211w_kde_add(sm, tmp); tmp2 = ieee80211w_kde_add(sm, tmp);
wpabuf_put(plain, tmp2 - tmp); wpabuf_put(plain, tmp2 - tmp);
if (conf->transition_disable) {
tmp = wpabuf_put(plain, 0);
tmp2 = wpa_add_kde(tmp, WFA_KEY_DATA_TRANSITION_DISABLE,
&conf->transition_disable, 1, NULL, 0);
wpabuf_put(plain, tmp2 - tmp);
}
*len = (u8 *) wpabuf_put(plain, 0) - len - 1; *len = (u8 *) wpabuf_put(plain, 0) - len - 1;
#ifdef CONFIG_OCV #ifdef CONFIG_OCV
@ -3276,6 +3288,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
int secure, gtkidx, encr = 0; int secure, gtkidx, encr = 0;
u8 *wpa_ie_buf = NULL, *wpa_ie_buf2 = NULL; u8 *wpa_ie_buf = NULL, *wpa_ie_buf2 = NULL;
u8 hdr[2]; u8 hdr[2];
struct wpa_auth_config *conf = &sm->wpa_auth->conf;
SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk); SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk);
sm->TimeoutEvt = FALSE; sm->TimeoutEvt = FALSE;
@ -3400,6 +3413,10 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
if (WPA_GET_BE32(sm->ip_addr) > 0) if (WPA_GET_BE32(sm->ip_addr) > 0)
kde_len += 2 + RSN_SELECTOR_LEN + 3 * 4; kde_len += 2 + RSN_SELECTOR_LEN + 3 * 4;
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
if (conf->transition_disable)
kde_len += 2 + RSN_SELECTOR_LEN + 1;
kde = os_malloc(kde_len); kde = os_malloc(kde_len);
if (kde == NULL) if (kde == NULL)
goto done; goto done;
@ -3442,9 +3459,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
#ifdef CONFIG_IEEE80211R_AP #ifdef CONFIG_IEEE80211R_AP
if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
int res; int res;
struct wpa_auth_config *conf;
conf = &sm->wpa_auth->conf;
if (sm->assoc_resp_ftie && if (sm->assoc_resp_ftie &&
kde + kde_len - pos >= 2 + sm->assoc_resp_ftie[1]) { kde + kde_len - pos >= 2 + sm->assoc_resp_ftie[1]) {
os_memcpy(pos, sm->assoc_resp_ftie, os_memcpy(pos, sm->assoc_resp_ftie,
@ -3493,6 +3508,10 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
} }
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
if (conf->transition_disable)
pos = wpa_add_kde(pos, WFA_KEY_DATA_TRANSITION_DISABLE,
&conf->transition_disable, 1, NULL, 0);
wpa_send_eapol(sm->wpa_auth, sm, wpa_send_eapol(sm->wpa_auth, sm,
(secure ? WPA_KEY_INFO_SECURE : 0) | (secure ? WPA_KEY_INFO_SECURE : 0) |
(wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len) ? (wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len) ?

View file

@ -251,6 +251,7 @@ struct wpa_auth_config {
#endif /* CONFIG_FILS */ #endif /* CONFIG_FILS */
int sae_pwe; int sae_pwe;
int owe_ptk_workaround; int owe_ptk_workaround;
u8 transition_disable;
}; };
typedef enum { typedef enum {

View file

@ -195,6 +195,7 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
#ifdef CONFIG_OWE #ifdef CONFIG_OWE
wconf->owe_ptk_workaround = conf->owe_ptk_workaround; wconf->owe_ptk_workaround = conf->owe_ptk_workaround;
#endif /* CONFIG_OWE */ #endif /* CONFIG_OWE */
wconf->transition_disable = conf->transition_disable;
} }