From 2f8529ec491389bdb41911edcf084bc643d7c9ee Mon Sep 17 00:00:00 2001 From: Chung-Hsien Hsu Date: Tue, 10 Dec 2019 14:03:57 -0600 Subject: [PATCH 09/49] AP: Support 4-way handshake offload for WPA/WPA2-PSK Add support for WPA/WPA2-PSK 4-way handshake offload in AP mode. In this case, the 4-way handshake is handled by driver instead of user space. Signed-off-by: Chung-Hsien Hsu --- src/ap/beacon.c | 10 ++++++++++ src/ap/hostapd.c | 8 +++++++- src/ap/wpa_auth.c | 16 ++++++++++++++++ src/ap/wpa_auth.h | 2 ++ src/ap/wpa_auth_glue.c | 4 ++++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 8cd1c4170..583b6836e 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -1753,6 +1753,16 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, } } + if ((hapd->iface->drv_flags2 & + WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK) && + (params->key_mgmt_suites & + (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_PSK_SHA256))) { + if (hapd->conf->ssid.wpa_passphrase) + params->passphrase = hapd->conf->ssid.wpa_passphrase; + if (hapd->conf->ssid.wpa_psk->psk) + params->psk = hapd->conf->ssid.wpa_psk->psk; + } + return 0; } diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 4b88641a2..464d8fa95 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -3203,6 +3203,8 @@ int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf) void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, int reassoc) { + int key_mgmt = wpa_auth_sta_key_mgmt(sta->wpa_sm); + if (hapd->tkip_countermeasures) { hostapd_drv_sta_deauth(hapd, sta->addr, WLAN_REASON_MICHAEL_MIC_FAILURE); @@ -3236,7 +3238,11 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, /* Start IEEE 802.1X authentication process for new stations */ ieee802_1x_new_station(hapd, sta); if (reassoc) { - if (sta->auth_alg != WLAN_AUTH_FT && + if ((hapd->iface->drv_flags2 & + WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK) && + wpa_key_mgmt_wpa_psk(key_mgmt)) + wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm); + else if (sta->auth_alg != WLAN_AUTH_FT && sta->auth_alg != WLAN_AUTH_FILS_SK && sta->auth_alg != WLAN_AUTH_FILS_SK_PFS && sta->auth_alg != WLAN_AUTH_FILS_PK && diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 6d60f2629..4b506c1db 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -696,6 +696,22 @@ int wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth, } #endif /* CONFIG_FILS */ + if (wpa_auth->conf.psk_4way_hs_offload) { + wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, + "4-way handshake offloading for WPA/WPA2-PSK"); + sm->wpa_ptk_state = WPA_PTK_PTKINITDONE; + sm->Pair = true; + wpa_auth_set_eapol(sm->wpa_auth, sm->addr, + WPA_EAPOL_authorized, 1); + wpa_auth_set_eapol(sm->wpa_auth, sm->addr, + WPA_EAPOL_portValid, 1); + wpa_auth_set_eapol(sm->wpa_auth, sm->addr, + WPA_EAPOL_keyAvailable, 0); + wpa_auth_set_eapol(sm->wpa_auth, sm->addr, + WPA_EAPOL_keyDone, 1); + return 0; + } + if (sm->started) { os_memset(&sm->key_replay, 0, sizeof(sm->key_replay)); sm->ReAuthenticationRequest = true; diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index fe47723b9..2f807893f 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -273,6 +273,8 @@ struct wpa_auth_config { * PTK derivation regardless of advertised capabilities. */ bool force_kdk_derivation; + + int psk_4way_hs_offload; }; typedef enum { diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 3e9921553..26de12b5b 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -1528,6 +1528,10 @@ int hostapd_setup_wpa(struct hostapd_data *hapd) _conf.prot_range_neg = !!(hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG); + if (!hapd->conf->p2p && + (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK)) + _conf.psk_4way_hs_offload = 1; + hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb, hapd); if (hapd->wpa_auth == NULL) { wpa_printf(MSG_ERROR, "WPA initialization failed."); -- 2.17.1