Passphrases/PSKs from external password databases were ignored if 4-way handshake offloading was supported by the driver. This patch splits the PSK loading functionality into a separate function and calls if to get the PSK for handshake offloading. I tested connecting to a WPA2-PSK network with both inline and external passphrases, using the iwlwifi and brcmfmac drivers. Signed-off-by: Ben Wolsieffer <benwolsieffer@xxxxxxxxx> --- wpa_supplicant/wpa_supplicant.c | 214 +++++++++++++++++--------------- 1 file changed, 113 insertions(+), 101 deletions(-) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index e085391e2..f4dfd1382 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1346,6 +1346,106 @@ void wpas_set_mgmt_group_cipher(struct wpa_supplicant *wpa_s, wpas_get_ssid_pmf(wpa_s, ssid)); } +/** + * wpa_supplicant_get_psk - Get PSK from config or external database + * @wpa_s: Pointer to wpa_supplicant data + * @bss: Scan results for the selected BSS, or %NULL if not available + * @ssid: Configuration data for the selected network + * @psk: Buffer for the PSK + * + * This function obtains the PSK for a network, either included inline in the + * config or retrieved from an external database. + */ +static int wpa_supplicant_get_psk(struct wpa_supplicant *wpa_s, + struct wpa_bss *bss, struct wpa_ssid *ssid, + u8 *psk) +{ + if (ssid->psk_set) { + wpa_hexdump_key(MSG_MSGDUMP, "PSK (set in config)", ssid->psk, + PMK_LEN); + os_memcpy(psk, ssid->psk, PMK_LEN); + return 0; + } + +#ifndef CONFIG_NO_PBKDF2 + if (bss && ssid->bssid_set && ssid->ssid_len == 0 && ssid->passphrase) { + if (pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len, + 4096, psk, PMK_LEN) != 0) { + wpa_msg(wpa_s, MSG_WARNING, "Error in pbkdf2_sha1()"); + return -1; + } + wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)", + psk, PMK_LEN); + return 0; + } +#endif /* CONFIG_NO_PBKDF2 */ + +#ifdef CONFIG_EXT_PASSWORD + if (ssid->ext_psk) { + struct wpabuf *pw = ext_password_get(wpa_s->ext_pw, + ssid->ext_psk); + char pw_str[64 + 1]; + + if (pw == NULL) { + wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK found from " + "external storage"); + return -1; + } + + if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) { + wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected PSK " + "length %d in external storage", + (int) wpabuf_len(pw)); + ext_password_free(pw); + return -1; + } + + os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw)); + pw_str[wpabuf_len(pw)] = '\0'; + +#ifndef CONFIG_NO_PBKDF2 + if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss) + { + if (pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len, + 4096, psk, PMK_LEN) != 0) { + wpa_msg(wpa_s, MSG_WARNING, + "Error in pbkdf2_sha1()"); + ext_password_free(pw); + return -1; + } + os_memset(pw_str, 0, sizeof(pw_str)); + wpa_hexdump_key(MSG_MSGDUMP, "PSK (from external " + "passphrase)", + psk, PMK_LEN); + } else +#endif /* CONFIG_NO_PBKDF2 */ + if (wpabuf_len(pw) == 2 * PMK_LEN) { + if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) { + wpa_msg(wpa_s, MSG_INFO, "EXT PW: Invalid PSK " + "hex string"); + os_memset(pw_str, 0, sizeof(pw_str)); + ext_password_free(pw); + return -1; + } + wpa_hexdump_key(MSG_MSGDUMP, "PSK (from external PSK)", + psk, PMK_LEN); + } else { + wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable PSK " + "available"); + os_memset(pw_str, 0, sizeof(pw_str)); + ext_password_free(pw); + return -1; + } + + os_memset(pw_str, 0, sizeof(pw_str)); + ext_password_free(pw); + + return 0; + } +#endif /* CONFIG_EXT_PASSWORD */ + + return -1; +} static void wpas_update_allowed_key_mgmt(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) @@ -1884,109 +1984,20 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, WPA_KEY_MGMT_FT_PSK | WPA_KEY_MGMT_PSK_SHA256)) == 0; - if (ssid->psk_set && !sae_only) { - wpa_hexdump_key(MSG_MSGDUMP, "PSK (set in config)", - ssid->psk, PMK_LEN); - wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL, - NULL); - psk_set = 1; - } - - if (wpa_key_mgmt_sae(ssid->key_mgmt) && - (ssid->sae_password || ssid->passphrase)) - psk_set = 1; - -#ifndef CONFIG_NO_PBKDF2 - if (bss && ssid->bssid_set && ssid->ssid_len == 0 && - ssid->passphrase && !sae_only) { - u8 psk[PMK_LEN]; - - if (pbkdf2_sha1(ssid->passphrase, bss->ssid, - bss->ssid_len, - 4096, psk, PMK_LEN) != 0) { - wpa_msg(wpa_s, MSG_WARNING, - "Error in pbkdf2_sha1()"); - return -1; - } - wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)", - psk, PMK_LEN); - wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL, NULL); - psk_set = 1; - os_memset(psk, 0, sizeof(psk)); - } -#endif /* CONFIG_NO_PBKDF2 */ -#ifdef CONFIG_EXT_PASSWORD - if (ssid->ext_psk && !sae_only) { - struct wpabuf *pw = ext_password_get(wpa_s->ext_pw, - ssid->ext_psk); - char pw_str[64 + 1]; + if (!sae_only) { u8 psk[PMK_LEN]; - - if (pw == NULL) { - wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK " - "found from external storage"); - return -1; - } - - if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) { - wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected " - "PSK length %d in external storage", - (int) wpabuf_len(pw)); - ext_password_free(pw); - return -1; - } - - os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw)); - pw_str[wpabuf_len(pw)] = '\0'; - -#ifndef CONFIG_NO_PBKDF2 - if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss) - { - if (pbkdf2_sha1(pw_str, bss->ssid, - bss->ssid_len, - 4096, psk, PMK_LEN) != 0) { - wpa_msg(wpa_s, MSG_WARNING, - "Error in pbkdf2_sha1()"); - ext_password_free(pw); - return -1; - } - os_memset(pw_str, 0, sizeof(pw_str)); - wpa_hexdump_key(MSG_MSGDUMP, "PSK (from " - "external passphrase)", - psk, PMK_LEN); - wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL, - NULL); - psk_set = 1; - os_memset(psk, 0, sizeof(psk)); - } else -#endif /* CONFIG_NO_PBKDF2 */ - if (wpabuf_len(pw) == 2 * PMK_LEN) { - if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) { - wpa_msg(wpa_s, MSG_INFO, "EXT PW: " - "Invalid PSK hex string"); - os_memset(pw_str, 0, sizeof(pw_str)); - ext_password_free(pw); - return -1; - } - wpa_hexdump_key(MSG_MSGDUMP, - "PSK (from external PSK)", - psk, PMK_LEN); + if (wpa_supplicant_get_psk(wpa_s, bss, ssid, + psk) >= 0) { wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL, NULL); psk_set = 1; - os_memset(psk, 0, sizeof(psk)); - } else { - wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable " - "PSK available"); - os_memset(pw_str, 0, sizeof(pw_str)); - ext_password_free(pw); - return -1; } - - os_memset(pw_str, 0, sizeof(pw_str)); - ext_password_free(pw); + os_memset(psk, 0, sizeof(psk)); } -#endif /* CONFIG_EXT_PASSWORD */ + + if (wpa_key_mgmt_sae(ssid->key_mgmt) && + (ssid->sae_password || ssid->passphrase)) + psk_set = 1; if (!psk_set) { wpa_msg(wpa_s, MSG_INFO, @@ -3754,6 +3765,7 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) int use_crypt, ret, bssid_changed; unsigned int cipher_pairwise, cipher_group, cipher_group_mgmt; struct wpa_driver_associate_params params; + u8 psk[PMK_LEN]; #if defined(CONFIG_WEP) || defined(IEEE8021X_EAPOL) int wep_keys_set = 0; #endif /* CONFIG_WEP || IEEE8021X_EAPOL */ @@ -4046,8 +4058,8 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) (params.allowed_key_mgmts & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK)))) { params.passphrase = ssid->passphrase; - if (ssid->psk_set) - params.psk = ssid->psk; + if (wpa_supplicant_get_psk(wpa_s, bss, ssid, psk) >= 0) + params.psk = psk; } if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X) && @@ -4070,8 +4082,8 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) if ((wpa_key_mgmt_wpa_psk_no_sae(params.key_mgmt_suite) || wpa_key_mgmt_wpa_psk_no_sae(params.allowed_key_mgmts)) && - ssid->psk_set) - params.psk = ssid->psk; + wpa_supplicant_get_psk(wpa_s, bss, ssid, psk) >= 0) + params.psk = psk; } params.drop_unencrypted = use_crypt; -- 2.37.2 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap