From 199b53d1ad52acc221f537709821a7a9b7cb5505 Mon Sep 17 00:00:00 2001 From: dkwo Date: Sun, 24 Sep 2023 18:36:24 -0400 Subject: [PATCH] wpa_supplicant: add upstream patches --- .../wpa_supplicant/patches/4way-hand.patch | 247 ++++++++++++++++++ .../patches/SAE_external_database.patch | 182 +++++++++++++ srcpkgs/wpa_supplicant/template | 2 +- 3 files changed, 430 insertions(+), 1 deletion(-) create mode 100644 srcpkgs/wpa_supplicant/patches/4way-hand.patch create mode 100644 srcpkgs/wpa_supplicant/patches/SAE_external_database.patch diff --git a/srcpkgs/wpa_supplicant/patches/4way-hand.patch b/srcpkgs/wpa_supplicant/patches/4way-hand.patch new file mode 100644 index 0000000000000..d2baa8a839aac --- /dev/null +++ b/srcpkgs/wpa_supplicant/patches/4way-hand.patch @@ -0,0 +1,247 @@ +From 023c17659786fe381312f154cf06663f1cb3607c Mon Sep 17 00:00:00 2001 +From: Ben Wolsieffer +Date: Tue, 23 Aug 2022 21:34:55 -0400 +Subject: [PATCH] Fix external passwords with 4-way handshake offloading + +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 +--- + wpa_supplicant/wpa_supplicant.c | 184 +++++++++++++++++--------------- + 1 file changed, 95 insertions(+), 89 deletions(-) + +diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c +index d37a994f9..bb063380f 100644 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -1337,6 +1337,88 @@ void wpas_set_mgmt_group_cipher(struct wpa_supplicant *wpa_s, + wpas_get_ssid_pmf(wpa_s, ssid)); + } + ++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) { ++ pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len, 4096, ++ psk, PMK_LEN); ++ 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) ++ { ++ pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len, 4096, psk, ++ PMK_LEN); ++ 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; ++} + + /** + * wpa_supplicant_set_suites - Set authentication and encryption parameters +@@ -1756,97 +1838,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) { ++ if (!sae_only) { + u8 psk[PMK_LEN]; +- pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len, +- 4096, psk, PMK_LEN); +- 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]; +- 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) +- { +- pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len, +- 4096, psk, PMK_LEN); +- 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, +@@ -3606,6 +3611,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 */ +@@ -3890,8 +3896,8 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) + (params.key_mgmt_suite == WPA_KEY_MGMT_PSK || + params.key_mgmt_suite == 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) && +@@ -3915,8 +3921,8 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) + if ((params.key_mgmt_suite == WPA_KEY_MGMT_PSK || + params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 || + params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK) && +- 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; diff --git a/srcpkgs/wpa_supplicant/patches/SAE_external_database.patch b/srcpkgs/wpa_supplicant/patches/SAE_external_database.patch new file mode 100644 index 0000000000000..b3ed31f58eb1a --- /dev/null +++ b/srcpkgs/wpa_supplicant/patches/SAE_external_database.patch @@ -0,0 +1,182 @@ +From bdc35acd5abae45bd53e3117bfc673fc0e1ab0b9 Mon Sep 17 00:00:00 2001 +From: Ben Wolsieffer +Date: Sat, 17 Sep 2022 00:21:02 -0400 +Subject: SAE: Allow loading of the password from an external database + +There was no support for loading SAE passwords from an external password +database. + +Signed-off-by: Ben Wolsieffer +--- + wpa_supplicant/sme.c | 65 ++++++++++++++++++++++++++++++++--------- + wpa_supplicant/wpa_supplicant.c | 2 +- + 2 files changed, 53 insertions(+), 14 deletions(-) + +diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c +index 52861c805..28ac03f23 100644 +--- a/wpa_supplicant/sme.c ++++ b/wpa_supplicant/sme.c +@@ -10,6 +10,7 @@ + + #include "common.h" + #include "utils/eloop.h" ++#include "utils/ext_password.h" + #include "common/ieee802_11_defs.h" + #include "common/ieee802_11_common.h" + #include "common/ocv.h" +@@ -90,7 +91,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, + { + struct wpabuf *buf; + size_t len; +- const char *password; ++ char *password = NULL; + struct wpa_bss *bss; + int use_pt = 0; + bool use_pk = false; +@@ -106,7 +107,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, + wpa_printf(MSG_DEBUG, "SAE: TESTING - commit override"); + buf = wpabuf_alloc(4 + wpabuf_len(wpa_s->sae_commit_override)); + if (!buf) +- return NULL; ++ goto fail; + if (!external) { + wpabuf_put_le16(buf, 1); /* Transaction seq# */ + wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS); +@@ -116,12 +117,45 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, + } + #endif /* CONFIG_TESTING_OPTIONS */ + +- password = ssid->sae_password; +- if (!password) +- password = ssid->passphrase; ++ if (ssid->sae_password) { ++ password = os_strdup(ssid->sae_password); ++ if (!password) { ++ wpa_dbg(wpa_s, MSG_INFO, ++ "SAE: Failed to allocate password"); ++ goto fail; ++ } ++ } ++ if (!password && ssid->passphrase) { ++ password = os_strdup(ssid->passphrase); ++ if (!password) { ++ wpa_dbg(wpa_s, MSG_INFO, ++ "SAE: Failed to allocate password"); ++ goto fail; ++ } ++ } ++ if (!password && ssid->ext_psk) { ++ struct wpabuf *pw = ext_password_get(wpa_s->ext_pw, ++ ssid->ext_psk); ++ ++ if (!pw) { ++ wpa_msg(wpa_s, MSG_INFO, ++ "SAE: No password found from external storage"); ++ goto fail; ++ } ++ ++ password = os_malloc(wpabuf_len(pw) + 1); ++ if (!password) { ++ wpa_dbg(wpa_s, MSG_INFO, ++ "SAE: Failed to allocate password"); ++ goto fail; ++ } ++ os_memcpy(password, wpabuf_head(pw), wpabuf_len(pw)); ++ password[wpabuf_len(pw)] = '\0'; ++ ext_password_free(pw); ++ } + if (!password) { + wpa_printf(MSG_DEBUG, "SAE: No password available"); +- return NULL; ++ goto fail; + } + + if (reuse && wpa_s->sme.sae.tmp && +@@ -134,7 +168,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, + } + if (sme_set_sae_group(wpa_s) < 0) { + wpa_printf(MSG_DEBUG, "SAE: Failed to select group"); +- return NULL; ++ goto fail; + } + + bss = wpa_bss_get_bssid_latest(wpa_s, bssid); +@@ -171,7 +205,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, + if (ssid->sae_pk == SAE_PK_MODE_ONLY && !use_pk) { + wpa_printf(MSG_DEBUG, + "SAE: Cannot use PK with the selected AP"); +- return NULL; ++ goto fail; + } + #endif /* CONFIG_SAE_PK */ + +@@ -184,7 +218,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, + !use_pt) { + wpa_printf(MSG_DEBUG, + "SAE: Cannot use H2E with the selected AP"); +- return NULL; ++ goto fail; + } + } + +@@ -192,13 +226,13 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, + sae_prepare_commit_pt(&wpa_s->sme.sae, ssid->pt, + wpa_s->own_addr, bssid, + wpa_s->sme.sae_rejected_groups, NULL) < 0) +- return NULL; ++ goto fail; + if (!use_pt && + sae_prepare_commit(wpa_s->own_addr, bssid, + (u8 *) password, os_strlen(password), + &wpa_s->sme.sae) < 0) { + wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE"); +- return NULL; ++ goto fail; + } + if (wpa_s->sme.sae.tmp) { + os_memcpy(wpa_s->sme.sae.tmp->bssid, bssid, ETH_ALEN); +@@ -218,7 +252,7 @@ reuse_data: + len += 4 + os_strlen(ssid->sae_password_id); + buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + len); + if (buf == NULL) +- return NULL; ++ goto fail; + if (!external) { + wpabuf_put_le16(buf, 1); /* Transaction seq# */ + if (use_pk) +@@ -231,14 +265,19 @@ reuse_data: + if (sae_write_commit(&wpa_s->sme.sae, buf, wpa_s->sme.sae_token, + ssid->sae_password_id) < 0) { + wpabuf_free(buf); +- return NULL; ++ goto fail; + } + if (ret_use_pt) + *ret_use_pt = use_pt; + if (ret_use_pk) + *ret_use_pk = use_pk; + ++ str_clear_free(password); + return buf; ++ ++fail: ++ str_clear_free(password); ++ return NULL; + } + + +diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c +index 54c3c859e..ef5d0cd71 100644 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -1998,7 +1998,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, + } + + if (wpa_key_mgmt_sae(ssid->key_mgmt) && +- (ssid->sae_password || ssid->passphrase)) ++ (ssid->sae_password || ssid->passphrase || ssid->ext_psk)) + psk_set = 1; + + if (!psk_set) { +-- +cgit v1.2.3-18-g5258 diff --git a/srcpkgs/wpa_supplicant/template b/srcpkgs/wpa_supplicant/template index 87203097b009e..1706dbcfa7b71 100644 --- a/srcpkgs/wpa_supplicant/template +++ b/srcpkgs/wpa_supplicant/template @@ -1,7 +1,7 @@ # Template file for 'wpa_supplicant' pkgname=wpa_supplicant version=2.10 -revision=3 +revision=4 build_wrksrc="$pkgname" short_desc="WPA/WPA2/IEEE 802.1X Supplicant" maintainer="Enno Boland "