drivers: Add separate driver flags for 802.1X and PSK 4-way HS offloads

Allow drivers to indicate support for offloading 4-way handshake for
either IEEE 802.1X (WPA2-Enterprise; EAP) and/or WPA/WPA2-PSK
(WPA2-Personal) by splitting the WPA_DRIVER_FLAGS_4WAY_HANDSHAKE flag
into two separate flags.

Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
This commit is contained in:
Arend van Spriel 2019-01-07 12:14:40 +01:00 committed by Jouni Malinen
parent 78a9ba72d0
commit 436ee2fd93
9 changed files with 29 additions and 23 deletions

View file

@ -931,10 +931,10 @@ struct wpa_driver_associate_params {
* passphrase - RSN passphrase for PSK * passphrase - RSN passphrase for PSK
* *
* This value is made available only for WPA/WPA2-Personal (PSK) and * This value is made available only for WPA/WPA2-Personal (PSK) and
* only for drivers that set WPA_DRIVER_FLAGS_4WAY_HANDSHAKE. This is * only for drivers that set WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK. This
* the 8..63 character ASCII passphrase, if available. Please note that * is the 8..63 character ASCII passphrase, if available. Please note
* this can be %NULL if passphrase was not used to generate the PSK. In * that this can be %NULL if passphrase was not used to generate the
* that case, the psk field must be used to fetch the PSK. * PSK. In that case, the psk field must be used to fetch the PSK.
*/ */
const char *passphrase; const char *passphrase;
@ -942,9 +942,9 @@ struct wpa_driver_associate_params {
* psk - RSN PSK (alternative for passphrase for PSK) * psk - RSN PSK (alternative for passphrase for PSK)
* *
* This value is made available only for WPA/WPA2-Personal (PSK) and * This value is made available only for WPA/WPA2-Personal (PSK) and
* only for drivers that set WPA_DRIVER_FLAGS_4WAY_HANDSHAKE. This is * only for drivers that set WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK. This
* the 32-octet (256-bit) PSK, if available. The driver wrapper should * is the 32-octet (256-bit) PSK, if available. The driver wrapper
* be prepared to handle %NULL value as an error. * should be prepared to handle %NULL value as an error.
*/ */
const u8 *psk; const u8 *psk;
@ -1492,7 +1492,7 @@ struct wpa_driver_capa {
#define WPA_DRIVER_FLAGS_DFS_OFFLOAD 0x00000004 #define WPA_DRIVER_FLAGS_DFS_OFFLOAD 0x00000004
/** Driver takes care of RSN 4-way handshake internally; PMK is configured with /** Driver takes care of RSN 4-way handshake internally; PMK is configured with
* struct wpa_driver_ops::set_key using alg = WPA_ALG_PMK */ * struct wpa_driver_ops::set_key using alg = WPA_ALG_PMK */
#define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE 0x00000008 #define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X 0x00000008
/** Driver is for a wired Ethernet interface */ /** Driver is for a wired Ethernet interface */
#define WPA_DRIVER_FLAGS_WIRED 0x00000010 #define WPA_DRIVER_FLAGS_WIRED 0x00000010
/** Driver provides separate commands for authentication and association (SME in /** Driver provides separate commands for authentication and association (SME in
@ -1616,6 +1616,8 @@ struct wpa_driver_capa {
#define WPA_DRIVER_FLAGS_SELF_MANAGED_REGULATORY 0x0080000000000000ULL #define WPA_DRIVER_FLAGS_SELF_MANAGED_REGULATORY 0x0080000000000000ULL
/** Driver supports FTM responder functionality */ /** Driver supports FTM responder functionality */
#define WPA_DRIVER_FLAGS_FTM_RESPONDER 0x0100000000000000ULL #define WPA_DRIVER_FLAGS_FTM_RESPONDER 0x0100000000000000ULL
/** Driver support 4-way handshake offload for WPA-Personal */
#define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK 0x0200000000000000ULL
u64 flags; u64 flags;
#define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \ #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \

View file

@ -253,7 +253,8 @@ const char * driver_flag_to_string(u64 flag)
DF2S(DRIVER_IE); DF2S(DRIVER_IE);
DF2S(SET_KEYS_AFTER_ASSOC); DF2S(SET_KEYS_AFTER_ASSOC);
DF2S(DFS_OFFLOAD); DF2S(DFS_OFFLOAD);
DF2S(4WAY_HANDSHAKE); DF2S(4WAY_HANDSHAKE_PSK);
DF2S(4WAY_HANDSHAKE_8021X);
DF2S(WIRED); DF2S(WIRED);
DF2S(SME); DF2S(SME);
DF2S(AP); DF2S(AP);

View file

@ -3031,7 +3031,7 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
#endif /* CONFIG_DRIVER_NL80211_QCA */ #endif /* CONFIG_DRIVER_NL80211_QCA */
if (alg == WPA_ALG_PMK && if (alg == WPA_ALG_PMK &&
(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X))
return nl80211_set_pmk(drv, key, key_len, addr); return nl80211_set_pmk(drv, key, key_len, addr);
if (alg == WPA_ALG_NONE) { if (alg == WPA_ALG_NONE) {
@ -5570,7 +5570,7 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
/* Add PSK in case of 4-way handshake offload */ /* Add PSK in case of 4-way handshake offload */
if (params->psk && if (params->psk &&
(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) { (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK)) {
wpa_hexdump_key(MSG_DEBUG, " * PSK", params->psk, 32); wpa_hexdump_key(MSG_DEBUG, " * PSK", params->psk, 32);
if (nla_put(msg, NL80211_ATTR_PMK, 32, params->psk)) if (nla_put(msg, NL80211_ATTR_PMK, 32, params->psk))
return -1; return -1;

View file

@ -403,10 +403,11 @@ static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info,
capa->flags |= WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD; capa->flags |= WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD;
if (ext_feature_isset(ext_features, len, if (ext_feature_isset(ext_features, len,
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK) && NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK))
ext_feature_isset(ext_features, len, capa->flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK;
if (ext_feature_isset(ext_features, len,
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X)) NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
capa->flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE; capa->flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X;
if (ext_feature_isset(ext_features, len, if (ext_feature_isset(ext_features, len,
NL80211_EXT_FEATURE_MFP_OPTIONAL)) NL80211_EXT_FEATURE_MFP_OPTIONAL))

View file

@ -62,7 +62,8 @@ static int
wpa_driver_openbsd_get_capa(void *priv, struct wpa_driver_capa *capa) wpa_driver_openbsd_get_capa(void *priv, struct wpa_driver_capa *capa)
{ {
os_memset(capa, 0, sizeof(*capa)); os_memset(capa, 0, sizeof(*capa));
capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE; capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK |
WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X;
return 0; return 0;
} }

View file

@ -1647,7 +1647,8 @@ static int wpa_driver_wext_get_range(void *priv)
if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP) if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP)
drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP; drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE) if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)
drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE; drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK |
WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X;
drv->capa.auth = WPA_DRIVER_AUTH_OPEN | drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
WPA_DRIVER_AUTH_SHARED | WPA_DRIVER_AUTH_SHARED |
WPA_DRIVER_AUTH_LEAP; WPA_DRIVER_AUTH_LEAP;
@ -1678,7 +1679,7 @@ static int wpa_driver_wext_set_psk(struct wpa_driver_wext_data *drv,
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
if (!(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) if (!(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X))
return 0; return 0;
if (!psk) if (!psk)

View file

@ -2805,7 +2805,7 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
} }
wpa_supplicant_cancel_scan(wpa_s); wpa_supplicant_cancel_scan(wpa_s);
if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) && if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
/* /*
* We are done; the driver will take care of RSN 4-way * We are done; the driver will take care of RSN 4-way
@ -2815,7 +2815,7 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
eapol_sm_notify_portValid(wpa_s->eapol, TRUE); eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
eapol_sm_notify_eap_success(wpa_s->eapol, TRUE); eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
} else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) && } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X) &&
wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) { wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
/* /*
* The driver will take care of RSN 4-way handshake, so we need * The driver will take care of RSN 4-way handshake, so we need

View file

@ -3106,7 +3106,7 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
} }
params.wep_tx_keyidx = ssid->wep_tx_keyidx; params.wep_tx_keyidx = ssid->wep_tx_keyidx;
if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) && if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
(params.key_mgmt_suite == WPA_KEY_MGMT_PSK || (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) { params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
params.passphrase = ssid->passphrase; params.passphrase = ssid->passphrase;
@ -4113,7 +4113,7 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
} }
if (wpa_s->eapol_received == 0 && if (wpa_s->eapol_received == 0 &&
(!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) || (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) ||
!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
wpa_s->wpa_state != WPA_COMPLETED) && wpa_s->wpa_state != WPA_COMPLETED) &&
(wpa_s->current_ssid == NULL || (wpa_s->current_ssid == NULL ||
@ -4179,7 +4179,7 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0) eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
return; return;
wpa_drv_poll(wpa_s); wpa_drv_poll(wpa_s);
if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK))
wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len); wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) { else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
/* /*

View file

@ -296,7 +296,7 @@ static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol,
} }
if (result != EAPOL_SUPP_RESULT_SUCCESS || if (result != EAPOL_SUPP_RESULT_SUCCESS ||
!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X))
return; return;
if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt))