DPP2: Try to negotiate PFS only if AP supports version 2 or newer

Check AP's DPP Protocol Version during network introduction and mark the
PMKSA cache as suitable for PFS use with version 2 or newer. This avoids
unnecessary attempt of negotiating PFS with version 1 APs.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2020-05-01 17:30:03 +03:00 committed by Jouni Malinen
parent f6c22dcdea
commit 1f5f000086
4 changed files with 26 additions and 1 deletions

View file

@ -28,6 +28,7 @@ struct rsn_pmksa_cache_entry {
*/ */
u8 fils_cache_id[2]; u8 fils_cache_id[2];
unsigned int fils_cache_id_set:1; unsigned int fils_cache_id_set:1;
unsigned int dpp_pfs:1;
os_time_t reauth_time; os_time_t reauth_time;

View file

@ -1771,6 +1771,11 @@ static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid; struct wpa_ssid *ssid;
const u8 *connector, *trans_id, *status; const u8 *connector, *trans_id, *status;
u16 connector_len, trans_id_len, status_len; u16 connector_len, trans_id_len, status_len;
#ifdef CONFIG_DPP2
const u8 *version;
u16 version_len;
#endif /* CONFIG_DPP2 */
u8 peer_version = 1;
struct dpp_introduction intro; struct dpp_introduction intro;
struct rsn_pmksa_cache_entry *entry; struct rsn_pmksa_cache_entry *entry;
struct os_time now; struct os_time now;
@ -1871,6 +1876,13 @@ static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
os_memcpy(entry->pmk, intro.pmk, intro.pmk_len); os_memcpy(entry->pmk, intro.pmk, intro.pmk_len);
entry->pmk_len = intro.pmk_len; entry->pmk_len = intro.pmk_len;
entry->akmp = WPA_KEY_MGMT_DPP; entry->akmp = WPA_KEY_MGMT_DPP;
#ifdef CONFIG_DPP2
version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
&version_len);
if (version && version_len >= 1)
peer_version = version[0];
entry->dpp_pfs = peer_version >= 2;
#endif /* CONFIG_DPP2 */
if (expiry) { if (expiry) {
os_get_time(&now); os_get_time(&now);
seconds = expiry - now.sec; seconds = expiry - now.sec;
@ -1884,7 +1896,7 @@ static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, entry); wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, entry);
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
" status=%u", MAC2STR(src), status[0]); " status=%u version=%u", MAC2STR(src), status[0], peer_version);
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Try connection again after successful network introduction"); "DPP: Try connection again after successful network introduction");

View file

@ -1796,6 +1796,12 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP && ssid && if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP && ssid &&
ssid->dpp_netaccesskey && ssid->dpp_pfs != 2 && ssid->dpp_netaccesskey && ssid->dpp_pfs != 2 &&
!ssid->dpp_pfs_fallback) { !ssid->dpp_pfs_fallback) {
struct rsn_pmksa_cache_entry *pmksa;
pmksa = pmksa_cache_get_current(wpa_s->wpa);
if (!pmksa || !pmksa->dpp_pfs)
goto pfs_fail;
dpp_pfs_free(wpa_s->dpp_pfs); dpp_pfs_free(wpa_s->dpp_pfs);
wpa_s->dpp_pfs = dpp_pfs_init(ssid->dpp_netaccesskey, wpa_s->dpp_pfs = dpp_pfs_init(ssid->dpp_netaccesskey,
ssid->dpp_netaccesskey_len); ssid->dpp_netaccesskey_len);

View file

@ -3087,6 +3087,12 @@ static u8 * wpas_populate_assoc_ies(
if (wpa_sm_get_key_mgmt(wpa_s->wpa) == WPA_KEY_MGMT_DPP && if (wpa_sm_get_key_mgmt(wpa_s->wpa) == WPA_KEY_MGMT_DPP &&
ssid->dpp_netaccesskey && ssid->dpp_netaccesskey &&
ssid->dpp_pfs != 2 && !ssid->dpp_pfs_fallback) { ssid->dpp_pfs != 2 && !ssid->dpp_pfs_fallback) {
struct rsn_pmksa_cache_entry *pmksa;
pmksa = pmksa_cache_get_current(wpa_s->wpa);
if (!pmksa || !pmksa->dpp_pfs)
goto pfs_fail;
dpp_pfs_free(wpa_s->dpp_pfs); dpp_pfs_free(wpa_s->dpp_pfs);
wpa_s->dpp_pfs = dpp_pfs_init(ssid->dpp_netaccesskey, wpa_s->dpp_pfs = dpp_pfs_init(ssid->dpp_netaccesskey,
ssid->dpp_netaccesskey_len); ssid->dpp_netaccesskey_len);