From 12c8eacf73f67112e739a2d609221d5fc6876dd5 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 1 May 2020 21:07:42 +0300 Subject: [PATCH] DPP: Allow version number to be overridden for testing purposes "SET dpp_version_override " can now be used to request wpa_supplicant and hostapd to support a subset of DPP versions. In practice, the only valid case for now is to fall back from DPP version 2 support to version 1 in builds that include CONFIG_DPP2=y. Signed-off-by: Jouni Malinen --- hostapd/ctrl_iface.c | 7 +++++++ src/ap/dpp_hostapd.c | 10 ++++++---- src/ap/ieee802_11.c | 5 +++-- src/ap/wpa_auth.c | 7 ++++--- src/common/dpp.c | 13 +++++++++---- src/common/dpp.h | 11 +++++++++++ src/rsn_supp/wpa.c | 7 ++++--- wpa_supplicant/ctrl_iface.c | 7 +++++++ wpa_supplicant/dpp_supplicant.c | 10 ++++++---- wpa_supplicant/events.c | 5 +++-- wpa_supplicant/sme.c | 2 +- wpa_supplicant/wpa_supplicant.c | 3 ++- 12 files changed, 63 insertions(+), 24 deletions(-) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 6e8352f2f..87f2cb17e 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -1428,6 +1428,8 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd) hapd->dpp_ignore_netaccesskey_mismatch = atoi(value); } else if (os_strcasecmp(cmd, "dpp_test") == 0) { dpp_test = atoi(value); + } else if (os_strcasecmp(cmd, "dpp_version_override") == 0) { + dpp_version_override = atoi(value); #endif /* CONFIG_DPP */ #endif /* CONFIG_TESTING_OPTIONS */ #ifdef CONFIG_MBO @@ -4193,6 +4195,11 @@ static void hostapd_ctrl_iface_flush(struct hapd_interfaces *interfaces) #ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_DPP dpp_test = DPP_TEST_DISABLED; +#ifdef CONFIG_DPP2 + dpp_version_override = 2; +#else /* CONFIG_DPP2 */ + dpp_version_override = 1; +#endif /* CONFIG_DPP2 */ #endif /* CONFIG_DPP */ #endif /* CONFIG_TESTING_OPTIONS */ diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index 77518cbdf..0926a7659 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -1286,10 +1286,12 @@ skip_connector: #endif /* CONFIG_TESTING_OPTIONS */ #ifdef CONFIG_DPP2 - /* Protocol Version */ - wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION); - wpabuf_put_le16(msg, 1); - wpabuf_put_u8(msg, 2); + if (DPP_VERSION > 1) { + /* Protocol Version */ + wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION); + wpabuf_put_le16(msg, 1); + wpabuf_put_u8(msg, DPP_VERSION); + } #endif /* CONFIG_DPP2 */ wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 28ac7aa4b..15e44b912 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -3365,7 +3365,8 @@ static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, dpp_pfs_free(sta->dpp_pfs); sta->dpp_pfs = NULL; - if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) && + if (DPP_VERSION > 1 && + (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) && hapd->conf->dpp_netaccesskey && sta->wpa_sm && wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_DPP && elems.owe_dh) { @@ -3843,7 +3844,7 @@ rsnxe_done: #endif /* CONFIG_OWE */ #ifdef CONFIG_DPP2 - if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) && + if (DPP_VERSION > 1 && (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) && sta && sta->dpp_pfs && status_code == WLAN_STATUS_SUCCESS && wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_DPP) { os_memcpy(p, wpabuf_head(sta->dpp_pfs->ie), diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index cbaf9f738..019e5357e 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -14,6 +14,7 @@ #include "utils/bitfield.h" #include "common/ieee802_11_defs.h" #include "common/ocv.h" +#include "common/dpp.h" #include "crypto/aes.h" #include "crypto/aes_wrap.h" #include "crypto/aes_siv.h" @@ -3080,7 +3081,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) #endif /* CONFIG_P2P */ #ifdef CONFIG_DPP2 - if (kde.dpp_kde) { + if (DPP_VERSION > 1 && kde.dpp_kde) { wpa_printf(MSG_DEBUG, "DPP: peer Protocol Version %u Flags 0x%x", kde.dpp_kde[0], kde.dpp_kde[1]); @@ -3516,10 +3517,10 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) &conf->transition_disable, 1, NULL, 0); #ifdef CONFIG_DPP2 - if (sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP) { + if (DPP_VERSION > 1 && sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP) { u8 payload[2]; - payload[0] = 2; /* Protocol Version */ + payload[0] = DPP_VERSION; /* Protocol Version */ payload[1] = 0; /* Flags */ if (conf->dpp_pfs == 0) payload[1] |= DPP_KDE_PFS_ALLOWED; diff --git a/src/common/dpp.c b/src/common/dpp.c index 080c86aab..f8b13d6f5 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -37,6 +37,11 @@ static const char * dpp_netrole_str(enum dpp_netrole netrole); #ifdef CONFIG_TESTING_OPTIONS +#ifdef CONFIG_DPP2 +int dpp_version_override = 2; +#else +int dpp_version_override = 1; +#endif enum dpp_test_behavior dpp_test = DPP_TEST_DISABLED; u8 dpp_pkex_own_mac_override[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; u8 dpp_pkex_peer_mac_override[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; @@ -1850,7 +1855,7 @@ static struct wpabuf * dpp_auth_build_req(struct dpp_authentication *auth, /* Protocol Version */ wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION); wpabuf_put_le16(msg, 1); - wpabuf_put_u8(msg, 2); + wpabuf_put_u8(msg, DPP_VERSION); #endif /* CONFIG_DPP2 */ #ifdef CONFIG_TESTING_OPTIONS @@ -2014,7 +2019,7 @@ static struct wpabuf * dpp_auth_build_resp(struct dpp_authentication *auth, if (auth->peer_version >= 2) { wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION); wpabuf_put_le16(msg, 1); - wpabuf_put_u8(msg, 2); + wpabuf_put_u8(msg, DPP_VERSION); } #endif /* CONFIG_DPP2 */ @@ -3352,7 +3357,7 @@ dpp_auth_req_rx(struct dpp_global *dpp, void *msg_ctx, u8 dpp_allowed_roles, #ifdef CONFIG_DPP2 version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION, &version_len); - if (version) { + if (version && DPP_VERSION > 1) { if (version_len < 1 || version[0] == 0) { dpp_auth_fail(auth, "Invalid Protocol Version attribute"); @@ -3968,7 +3973,7 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr, #ifdef CONFIG_DPP2 version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION, &version_len); - if (version) { + if (version && DPP_VERSION > 1) { if (version_len < 1 || version[0] == 0) { dpp_auth_fail(auth, "Invalid Protocol Version attribute"); diff --git a/src/common/dpp.h b/src/common/dpp.h index afbedc554..e6cdf1103 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -21,6 +21,17 @@ struct crypto_ecdh; struct hostapd_ip_addr; struct dpp_global; +#ifdef CONFIG_TESTING_OPTIONS +#define DPP_VERSION (dpp_version_override) +extern int dpp_version_override; +#else /* CONFIG_TESTING_OPTIONS */ +#ifdef CONFIG_DPP2 +#define DPP_VERSION 2 +#else +#define DPP_VERSION 1 +#endif +#endif /* CONFIG_TESTING_OPTIONS */ + #define DPP_HDR_LEN (4 + 2) /* OUI, OUI Type, Crypto Suite, DPP frame type */ #define DPP_TCP_PORT 7871 diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 84ff1e1bd..a9e2e2474 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -21,6 +21,7 @@ #include "common/ieee802_11_defs.h" #include "common/ieee802_11_common.h" #include "common/ocv.h" +#include "common/dpp.h" #include "eap_common/eap_defs.h" #include "eapol_supp/eapol_supp_sm.h" #include "drivers/driver.h" @@ -784,7 +785,7 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, #endif /* CONFIG_P2P */ #ifdef CONFIG_DPP2 - if (sm->key_mgmt == WPA_KEY_MGMT_DPP) { + if (DPP_VERSION > 1 && sm->key_mgmt == WPA_KEY_MGMT_DPP) { u8 *pos; wpa_printf(MSG_DEBUG, "DPP: Add DPP KDE into EAPOL-Key 2/4"); @@ -793,7 +794,7 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, *pos++ = RSN_SELECTOR_LEN + 2; RSN_SELECTOR_PUT(pos, WFA_KEY_DATA_DPP); pos += RSN_SELECTOR_LEN; - *pos++ = 2; /* Protocol Version */ + *pos++ = DPP_VERSION; /* Protocol Version */ *pos = 0; /* Flags */ if (sm->dpp_pfs == 0) *pos |= DPP_KDE_PFS_ALLOWED; @@ -1716,7 +1717,7 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm, #endif /* CONFIG_OCV */ #ifdef CONFIG_DPP2 - if (ie.dpp_kde) { + if (DPP_VERSION > 1 && ie.dpp_kde) { wpa_printf(MSG_DEBUG, "DPP: peer Protocol Version %u Flags 0x%x", ie.dpp_kde[0], ie.dpp_kde[1]); diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 90504948a..6e673fe36 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -696,6 +696,8 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, ret = -1; else dpp_nonce_override_len = hex_len / 2; + } else if (os_strcasecmp(cmd, "dpp_version_override") == 0) { + dpp_version_override = atoi(value); #endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_DPP */ #ifdef CONFIG_TESTING_OPTIONS @@ -8160,6 +8162,11 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) dpp_pkex_ephemeral_key_override_len = 0; dpp_protocol_key_override_len = 0; dpp_nonce_override_len = 0; +#ifdef CONFIG_DPP2 + dpp_version_override = 2; +#else /* CONFIG_DPP2 */ + dpp_version_override = 1; +#endif /* CONFIG_DPP2 */ #endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_DPP */ diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index a846c7c65..eae62e289 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -2580,10 +2580,12 @@ skip_connector: #endif /* CONFIG_TESTING_OPTIONS */ #ifdef CONFIG_DPP2 - /* Protocol Version */ - wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION); - wpabuf_put_le16(msg, 1); - wpabuf_put_u8(msg, 2); + if (DPP_VERSION > 1) { + /* Protocol Version */ + wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION); + wpabuf_put_le16(msg, 1); + wpabuf_put_u8(msg, DPP_VERSION); + } #endif /* CONFIG_DPP2 */ /* TODO: Timeout on AP response */ diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 61f875742..a25b43db0 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -2703,7 +2703,8 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, #ifdef CONFIG_DPP2 wpa_sm_set_dpp_z(wpa_s->wpa, NULL); - if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP && wpa_s->dpp_pfs) { + if (DPP_VERSION > 1 && wpa_s->key_mgmt == WPA_KEY_MGMT_DPP && + wpa_s->dpp_pfs) { struct ieee802_11_elems elems; if (ieee802_11_parse_elems(data->assoc_info.resp_ies, @@ -4373,7 +4374,7 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s, * the status code defined in the DPP R2 tech spec. * WLAN_STATUS_AKMP_NOT_VALID is addressed in the same manner as an * interoperability workaround with older hostapd implementation. */ - if (wpa_s->current_ssid && + if (DPP_VERSION > 1 && wpa_s->current_ssid && wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_DPP && wpa_s->current_ssid->dpp_pfs == 0 && (data->assoc_reject.status_code == diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index c7e5fcd5a..d06f6e298 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -1793,7 +1793,7 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode, #endif /* CONFIG_OWE */ #ifdef CONFIG_DPP2 - if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP && ssid && + if (DPP_VERSION > 1 && wpa_s->key_mgmt == WPA_KEY_MGMT_DPP && ssid && ssid->dpp_netaccesskey && ssid->dpp_pfs != 2 && !ssid->dpp_pfs_fallback) { struct rsn_pmksa_cache_entry *pmksa; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 53f8c9466..af4e7eb3a 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -3087,7 +3087,8 @@ static u8 * wpas_populate_assoc_ies( #endif /* CONFIG_OWE */ #ifdef CONFIG_DPP2 - if (wpa_sm_get_key_mgmt(wpa_s->wpa) == WPA_KEY_MGMT_DPP && + if (DPP_VERSION > 1 && + wpa_sm_get_key_mgmt(wpa_s->wpa) == WPA_KEY_MGMT_DPP && ssid->dpp_netaccesskey && ssid->dpp_pfs != 2 && !ssid->dpp_pfs_fallback) { struct rsn_pmksa_cache_entry *pmksa;