From a34ca59e4db0df63034fed4def121eaecc65bfa7 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 11 Oct 2017 23:09:16 +0300 Subject: [PATCH] SAE: Allow SAE password to be configured separately (STA) The new sae_password network profile parameter can now be used to set the SAE password instead of the previously used psk parameter. This allows shorter than 8 characters and longer than 63 characters long passwords to be used. Signed-off-by: Jouni Malinen --- wpa_supplicant/config.c | 2 ++ wpa_supplicant/config_file.c | 1 + wpa_supplicant/config_ssid.h | 10 ++++++++++ wpa_supplicant/config_winreg.c | 1 + wpa_supplicant/mesh_rsn.c | 11 ++++++++--- wpa_supplicant/sme.c | 9 ++++++--- wpa_supplicant/wpa_supplicant.c | 5 +++++ wpa_supplicant/wpa_supplicant.conf | 6 ++++++ 8 files changed, 39 insertions(+), 6 deletions(-) diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 1ff0799dc..070210d19 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2115,6 +2115,7 @@ static const struct parse_data ssid_fields[] = { { FUNC(bssid_whitelist) }, { FUNC_KEY(psk) }, { INT(mem_only_psk) }, + { STR_KEY(sae_password) }, { FUNC(proto) }, { FUNC(key_mgmt) }, { INT(bg_scan_period) }, @@ -2450,6 +2451,7 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid) os_free(ssid->ssid); str_clear_free(ssid->passphrase); os_free(ssid->ext_psk); + str_clear_free(ssid->sae_password); #ifdef IEEE8021X_EAPOL eap_peer_config_free(&ssid->eap); #endif /* IEEE8021X_EAPOL */ diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 489237cc1..2dddddb8f 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -745,6 +745,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) write_str(f, "bssid_whitelist", ssid); write_psk(f, ssid); INT(mem_only_psk); + STR(sae_password); write_proto(f, ssid); write_key_mgmt(f, ssid); INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD); diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index 2748c6a88..a3ad0cc43 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -183,6 +183,16 @@ struct wpa_ssid { */ char *passphrase; + /** + * sae_password - SAE password + * + * This parameter can be used to set a password for SAE. By default, the + * passphrase value is used if this separate parameter is not used, but + * passphrase follows the WPA-PSK constraints (8..63 characters) even + * though SAE passwords do not have such constraints. + */ + char *sae_password; + /** * ext_psk - PSK/passphrase name in external storage * diff --git a/wpa_supplicant/config_winreg.c b/wpa_supplicant/config_winreg.c index b22ed5c66..ed0b765bd 100644 --- a/wpa_supplicant/config_winreg.c +++ b/wpa_supplicant/config_winreg.c @@ -870,6 +870,7 @@ static int wpa_config_write_network(HKEY hk, struct wpa_ssid *ssid, int id) INT(scan_ssid); write_bssid(netw, ssid); write_psk(netw, ssid); + STR(sae_password); write_proto(netw, ssid); write_key_mgmt(netw, ssid); write_pairwise(netw, ssid); diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c index 90137c444..25dcde5c6 100644 --- a/wpa_supplicant/mesh_rsn.c +++ b/wpa_supplicant/mesh_rsn.c @@ -317,7 +317,12 @@ static int mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct sta_info *sta) { - if (ssid->passphrase == NULL) { + const char *password; + + password = ssid->sae_password; + if (!password) + password = ssid->passphrase; + if (!password) { wpa_msg(wpa_s, MSG_DEBUG, "SAE: No password available"); return -1; } @@ -328,8 +333,8 @@ static int mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s, } return sae_prepare_commit(wpa_s->own_addr, sta->addr, - (u8 *) ssid->passphrase, - os_strlen(ssid->passphrase), sta->sae); + (u8 *) password, os_strlen(password), + sta->sae); } diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index c14433a3f..8b35f16a5 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -87,6 +87,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, { struct wpabuf *buf; size_t len; + const char *password; #ifdef CONFIG_TESTING_OPTIONS if (wpa_s->sae_commit_override) { @@ -101,7 +102,10 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_TESTING_OPTIONS */ - if (ssid->passphrase == NULL) { + password = ssid->sae_password; + if (!password) + password = ssid->passphrase; + if (!password) { wpa_printf(MSG_DEBUG, "SAE: No password available"); return NULL; } @@ -112,8 +116,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, } if (sae_prepare_commit(wpa_s->own_addr, bssid, - (u8 *) ssid->passphrase, - os_strlen(ssid->passphrase), + (u8 *) password, os_strlen(password), &wpa_s->sme.sae) < 0) { wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE"); return NULL; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index a3face210..ff7f15ef5 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1446,6 +1446,10 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, NULL); psk_set = 1; } + + if (wpa_key_mgmt_sae(ssid->key_mgmt) && ssid->sae_password) + psk_set = 1; + #ifndef CONFIG_NO_PBKDF2 if (bss && ssid->bssid_set && ssid->ssid_len == 0 && ssid->passphrase) { @@ -6414,6 +6418,7 @@ int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set && (!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk && + !(wpa_key_mgmt_sae(ssid->key_mgmt) && ssid->sae_password) && !ssid->mem_only_psk) return 1; diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index 93b6e7042..1c2a695c3 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -934,6 +934,12 @@ fast_reauth=1 # 1 = do not store psk/passphrase to the configuration file #mem_only_psk=0 # +# sae_password: SAE password +# This parameter can be used to set a password for SAE. By default, the +# passphrase value is used if this separate parameter is not used, but +# passphrase follows the WPA-PSK constraints (8..63 characters) even +# though SAE passwords do not have such constraints. +# # eapol_flags: IEEE 802.1X/EAPOL options (bit field) # Dynamic WEP key required for non-WPA mode # bit0 (1): require dynamically generated unicast WEP key