git: 9ad44da950f3 - stable/12 - wpa: Import wpa_supplicant/hostapd commit b26f5c0fe
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 08 Feb 2022 01:11:59 UTC
The branch stable/12 has been updated by cy: URL: https://cgit.FreeBSD.org/src/commit/?id=9ad44da950f3600725c6165e81f3e70bcc886995 commit 9ad44da950f3600725c6165e81f3e70bcc886995 Author: Cy Schubert <cy@FreeBSD.org> AuthorDate: 2022-01-06 18:28:57 +0000 Commit: Cy Schubert <cy@FreeBSD.org> CommitDate: 2022-02-07 14:05:37 +0000 wpa: Import wpa_supplicant/hostapd commit b26f5c0fe This is the December/January update to vendor/wpa committed upstream 2021-12-13. (cherry picked from commit 32a95656b51ebefcdf3e0b02c110825f59abd26f) --- contrib/wpa/hostapd/Android.mk | 3 + contrib/wpa/hostapd/Makefile | 3 + contrib/wpa/hostapd/config_file.c | 10 + contrib/wpa/hostapd/ctrl_iface.c | 10 +- contrib/wpa/hostapd/defconfig | 8 + contrib/wpa/hostapd/hostapd.conf | 4 + contrib/wpa/src/ap/acs.c | 9 + contrib/wpa/src/ap/ap_config.h | 3 + contrib/wpa/src/ap/ap_drv_ops.c | 3 +- contrib/wpa/src/ap/beacon.c | 8 +- contrib/wpa/src/ap/dfs.c | 3 + contrib/wpa/src/ap/dpp_hostapd.c | 69 ++++- contrib/wpa/src/ap/drv_callbacks.c | 6 + contrib/wpa/src/ap/hostapd.c | 15 ++ contrib/wpa/src/common/dpp.c | 41 ++- contrib/wpa/src/common/dpp.h | 19 +- contrib/wpa/src/common/dpp_crypto.c | 55 ++-- contrib/wpa/src/common/dpp_i.h | 1 + contrib/wpa/src/common/dpp_pkex.c | 237 ++++++++++++----- contrib/wpa/src/common/hw_features_common.c | 141 +++++----- contrib/wpa/src/common/hw_features_common.h | 1 - contrib/wpa/src/common/qca-vendor.h | 41 ++- contrib/wpa/src/drivers/driver.h | 2 + contrib/wpa/src/drivers/driver_nl80211.c | 3 + contrib/wpa/tests/hwsim/test_dpp3.py | 49 ++++ contrib/wpa/wpa_supplicant/Android.mk | 3 + contrib/wpa/wpa_supplicant/Makefile | 3 + contrib/wpa/wpa_supplicant/README-HS20 | 6 + contrib/wpa/wpa_supplicant/config.c | 37 +++ contrib/wpa/wpa_supplicant/config.h | 34 +++ contrib/wpa/wpa_supplicant/config_file.c | 15 ++ contrib/wpa/wpa_supplicant/config_ssid.h | 5 + contrib/wpa/wpa_supplicant/ctrl_iface.c | 63 +---- contrib/wpa/wpa_supplicant/dbus/dbus_new.c | 133 ++++++++++ contrib/wpa/wpa_supplicant/dbus/dbus_new.h | 27 ++ .../wpa/wpa_supplicant/dbus/dbus_new_handlers.c | 287 +++++++++++++++++++++ .../wpa/wpa_supplicant/dbus/dbus_new_handlers.h | 13 + .../wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 5 +- contrib/wpa/wpa_supplicant/defconfig | 7 +- contrib/wpa/wpa_supplicant/dpp_supplicant.c | 62 ++++- contrib/wpa/wpa_supplicant/events.c | 2 +- contrib/wpa/wpa_supplicant/interworking.c | 41 ++- contrib/wpa/wpa_supplicant/mesh.c | 6 + contrib/wpa/wpa_supplicant/mesh_mpm.c | 5 +- contrib/wpa/wpa_supplicant/notify.c | 30 +++ contrib/wpa/wpa_supplicant/notify.h | 7 + contrib/wpa/wpa_supplicant/sme.c | 54 ++-- contrib/wpa/wpa_supplicant/sme.h | 6 +- contrib/wpa/wpa_supplicant/wpa_cli.c | 1 + contrib/wpa/wpa_supplicant/wpa_supplicant.c | 76 ++++++ contrib/wpa/wpa_supplicant/wpa_supplicant.conf | 3 + contrib/wpa/wpa_supplicant/wpa_supplicant_i.h | 3 + 52 files changed, 1380 insertions(+), 298 deletions(-) diff --git a/contrib/wpa/hostapd/Android.mk b/contrib/wpa/hostapd/Android.mk index dd8aa2450d7e..bf26e41c6b23 100644 --- a/contrib/wpa/hostapd/Android.mk +++ b/contrib/wpa/hostapd/Android.mk @@ -567,6 +567,9 @@ NEED_ASN1=y ifdef CONFIG_DPP2 L_CFLAGS += -DCONFIG_DPP2 endif +ifdef CONFIG_DPP3 +L_CFLAGS += -DCONFIG_DPP3 +endif endif ifdef CONFIG_PASN diff --git a/contrib/wpa/hostapd/Makefile b/contrib/wpa/hostapd/Makefile index ac085fd10520..e37c13b27a6e 100644 --- a/contrib/wpa/hostapd/Makefile +++ b/contrib/wpa/hostapd/Makefile @@ -593,6 +593,9 @@ NEED_ASN1=y ifdef CONFIG_DPP2 CFLAGS += -DCONFIG_DPP2 endif +ifdef CONFIG_DPP3 +CFLAGS += -DCONFIG_DPP3 +endif endif ifdef CONFIG_PASN diff --git a/contrib/wpa/hostapd/config_file.c b/contrib/wpa/hostapd/config_file.c index daf3f37ad99e..b14728d1b507 100644 --- a/contrib/wpa/hostapd/config_file.c +++ b/contrib/wpa/hostapd/config_file.c @@ -3193,6 +3193,16 @@ static int hostapd_config_fill(struct hostapd_config *conf, conf->acs_freq_list_present = 1; } else if (os_strcmp(buf, "acs_exclude_6ghz_non_psc") == 0) { conf->acs_exclude_6ghz_non_psc = atoi(pos); + } else if (os_strcmp(buf, "min_tx_power") == 0) { + int val = atoi(pos); + + if (val < 0 || val > 255) { + wpa_printf(MSG_ERROR, + "Line %d: invalid min_tx_power %d (expected 0..255)", + line, val); + return 1; + } + conf->min_tx_power = val; } else if (os_strcmp(buf, "beacon_int") == 0) { int val = atoi(pos); /* MIB defines range as 1..65535, but very small values diff --git a/contrib/wpa/hostapd/ctrl_iface.c b/contrib/wpa/hostapd/ctrl_iface.c index 6c99a3105f49..86adf18e5fe3 100644 --- a/contrib/wpa/hostapd/ctrl_iface.c +++ b/contrib/wpa/hostapd/ctrl_iface.c @@ -1504,7 +1504,7 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd) return -1; val = atoi(value); - if (val < 0 || val > 1) + if (val < 0 || val > MBO_ASSOC_DISALLOW_REASON_LOW_RSSI) return -1; hapd->mbo_assoc_disallow = val; @@ -3463,7 +3463,9 @@ static int hostapd_ctrl_iface_get_capability(struct hostapd_data *hapd, if (os_strcmp(field, "dpp") == 0) { int res; -#ifdef CONFIG_DPP2 +#ifdef CONFIG_DPP3 + res = os_snprintf(buf, buflen, "DPP=3"); +#elif defined(CONFIG_DPP2) res = os_snprintf(buf, buflen, "DPP=2"); #else /* CONFIG_DPP2 */ res = os_snprintf(buf, buflen, "DPP=1"); @@ -4492,7 +4494,9 @@ 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 +#ifdef CONFIG_DPP3 + dpp_version_override = 3; +#elif defined(CONFIG_DPP2) dpp_version_override = 2; #else /* CONFIG_DPP2 */ dpp_version_override = 1; diff --git a/contrib/wpa/hostapd/defconfig b/contrib/wpa/hostapd/defconfig index 666447e4ab40..6b50b6c59b46 100644 --- a/contrib/wpa/hostapd/defconfig +++ b/contrib/wpa/hostapd/defconfig @@ -402,3 +402,11 @@ CONFIG_IPV6=y # production use. # This requires CONFIG_IEEE80211W=y to be enabled, too. #CONFIG_PASN=y + +# Device Provisioning Protocol (DPP) (also known as Wi-Fi Easy Connect) +CONFIG_DPP=y +# DPP version 2 support +CONFIG_DPP2=y +# DPP version 3 support (experimental and still changing; do not enable for +# production use) +#CONFIG_DPP3=y diff --git a/contrib/wpa/hostapd/hostapd.conf b/contrib/wpa/hostapd/hostapd.conf index 67d4cefb920b..3c2019f73048 100644 --- a/contrib/wpa/hostapd/hostapd.conf +++ b/contrib/wpa/hostapd/hostapd.conf @@ -225,6 +225,10 @@ channel=1 # Default behavior is to include all PSC and non-PSC channels. #acs_exclude_6ghz_non_psc=1 +# Set minimum permitted max TX power (in dBm) for ACS and DFS channel selection. +# (default 0, i.e., not constraint) +#min_tx_power=20 + # Beacon interval in kus (1.024 ms) (default: 100; range 15..65535) beacon_int=100 diff --git a/contrib/wpa/src/ap/acs.c b/contrib/wpa/src/ap/acs.c index 46429f265433..0030edc2a90f 100644 --- a/contrib/wpa/src/ap/acs.c +++ b/contrib/wpa/src/ap/acs.c @@ -546,6 +546,9 @@ static void acs_survey_mode_interference_factor( if (!is_in_freqlist(iface, chan)) continue; + if (chan->max_tx_power < iface->conf->min_tx_power) + continue; + wpa_printf(MSG_DEBUG, "ACS: Survey analysis for channel %d (%d MHz)", chan->chan, chan->freq); @@ -673,6 +676,9 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface, if (!is_in_freqlist(iface, chan)) continue; + if (chan->max_tx_power < iface->conf->min_tx_power) + continue; + if (!chan_bw_allowed(chan, bw, 1, 1)) { wpa_printf(MSG_DEBUG, "ACS: Channel %d: BW %u is not supported", @@ -1047,6 +1053,9 @@ static int * acs_request_scan_add_freqs(struct hostapd_iface *iface, if (!is_in_freqlist(iface, chan)) continue; + if (chan->max_tx_power < iface->conf->min_tx_power) + continue; + *freq++ = chan->freq; } diff --git a/contrib/wpa/src/ap/ap_config.h b/contrib/wpa/src/ap/ap_config.h index b8f791e56307..49cd3168a2fa 100644 --- a/contrib/wpa/src/ap/ap_config.h +++ b/contrib/wpa/src/ap/ap_config.h @@ -51,6 +51,7 @@ struct mesh_conf { int dot11MeshRetryTimeout; /* msec */ int dot11MeshConfirmTimeout; /* msec */ int dot11MeshHoldingTimeout; /* msec */ + int mesh_fwding; }; #define MAX_STA_COUNT 2007 @@ -696,6 +697,7 @@ struct hostapd_bss_config { #define MESH_ENABLED BIT(0) int mesh; + int mesh_fwding; u8 radio_measurements[RRM_CAPABILITIES_IE_LEN]; @@ -953,6 +955,7 @@ struct hostapd_config { struct wpa_freq_range_list acs_freq_list; u8 acs_freq_list_present; int acs_exclude_dfs; + u8 min_tx_power; enum hostapd_hw_mode hw_mode; /* HOSTAPD_MODE_IEEE80211A, .. */ int acs_exclude_6ghz_non_psc; enum { diff --git a/contrib/wpa/src/ap/ap_drv_ops.c b/contrib/wpa/src/ap/ap_drv_ops.c index d1642d7dff15..e917736664bd 100644 --- a/contrib/wpa/src/ap/ap_drv_ops.c +++ b/contrib/wpa/src/ap/ap_drv_ops.c @@ -888,7 +888,8 @@ static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd, continue; if (!(chan->flag & HOSTAPD_CHAN_DISABLED) && !(hapd->iface->conf->acs_exclude_dfs && - (chan->flag & HOSTAPD_CHAN_RADAR))) + (chan->flag & HOSTAPD_CHAN_RADAR)) && + !(chan->max_tx_power < hapd->iface->conf->min_tx_power)) int_array_add_unique(freq_list, chan->freq); } } diff --git a/contrib/wpa/src/ap/beacon.c b/contrib/wpa/src/ap/beacon.c index 22782f54e480..8cd1c417043e 100644 --- a/contrib/wpa/src/ap/beacon.c +++ b/contrib/wpa/src/ap/beacon.c @@ -570,9 +570,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, pos = hostapd_eid_txpower_envelope(hapd, pos); #endif /* CONFIG_IEEE80211AX */ - if ((hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) || - (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax)) - pos = hostapd_eid_wb_chsw_wrapper(hapd, pos); + pos = hostapd_eid_wb_chsw_wrapper(hapd, pos); pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_PROBE_RESP); pos = hostapd_eid_fils_indic(hapd, pos, 0); @@ -1594,9 +1592,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, tailpos = hostapd_eid_txpower_envelope(hapd, tailpos); #endif /* CONFIG_IEEE80211AX */ - if ((hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) || - (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax)) - tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos); + tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos); tailpos = hostapd_eid_rnr(hapd, tailpos, WLAN_FC_STYPE_BEACON); tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0); diff --git a/contrib/wpa/src/ap/dfs.c b/contrib/wpa/src/ap/dfs.c index 03c99b175215..5c99ecfd017e 100644 --- a/contrib/wpa/src/ap/dfs.c +++ b/contrib/wpa/src/ap/dfs.c @@ -246,6 +246,9 @@ static int dfs_find_channel(struct hostapd_iface *iface, continue; } + if (chan->max_tx_power < iface->conf->min_tx_power) + continue; + if (ret_chan && idx == channel_idx) { wpa_printf(MSG_DEBUG, "Selected channel %d (%d)", chan->freq, chan->chan); diff --git a/contrib/wpa/src/ap/dpp_hostapd.c b/contrib/wpa/src/ap/dpp_hostapd.c index 41769f475544..13e1fc5bdd96 100644 --- a/contrib/wpa/src/ap/dpp_hostapd.c +++ b/contrib/wpa/src/ap/dpp_hostapd.c @@ -1554,17 +1554,38 @@ skip_status: #ifdef CONFIG_TESTING_OPTIONS skip_connector: + if (dpp_test == DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_RESP) { + wpa_printf(MSG_INFO, "DPP: TESTING - no Protocol Version"); + goto skip_proto_ver; + } #endif /* CONFIG_TESTING_OPTIONS */ #ifdef CONFIG_DPP2 if (DPP_VERSION > 1) { + u8 ver = DPP_VERSION; +#ifdef CONFIG_DPP3 + int conn_ver; + + conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector); + if (conn_ver > 0 && ver != conn_ver) { + wpa_printf(MSG_DEBUG, + "DPP: Use Connector version %d instead of current protocol version %d", + conn_ver, ver); + ver = conn_ver; + } +#endif /* CONFIG_DPP3 */ + /* Protocol Version */ wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION); wpabuf_put_le16(msg, 1); - wpabuf_put_u8(msg, DPP_VERSION); + wpabuf_put_u8(msg, ver); } #endif /* CONFIG_DPP2 */ +#ifdef CONFIG_TESTING_OPTIONS +skip_proto_ver: +#endif /* CONFIG_TESTING_OPTIONS */ + wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR " status=%d", MAC2STR(src), status); wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR @@ -1648,6 +1669,28 @@ static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd, return; } +#ifdef CONFIG_DPP3 + if (intro.peer_version && intro.peer_version >= 2) { + const u8 *version; + u16 version_len; + u8 attr_version = 1; + + version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION, + &version_len); + if (version && version_len >= 1) + attr_version = version[0]; + if (attr_version != intro.peer_version) { + wpa_printf(MSG_INFO, + "DPP: Protocol version mismatch (Connector: %d Attribute: %d", + intro.peer_version, attr_version); + hostapd_dpp_send_peer_disc_resp(hapd, src, freq, + trans_id[0], + DPP_STATUS_NO_MATCH); + return; + } + } +#endif /* CONFIG_DPP3 */ + if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire) expire = hapd->conf->dpp_netaccesskey_expiry; if (expire) @@ -1670,7 +1713,7 @@ static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd, static void hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src, const u8 *buf, size_t len, - unsigned int freq) + unsigned int freq, bool v2) { struct wpabuf *msg; @@ -1698,7 +1741,7 @@ hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src, hapd->own_addr, src, hapd->dpp_pkex_identifier, hapd->dpp_pkex_code, - buf, len); + buf, len, v2); if (!hapd->dpp_pkex) { wpa_printf(MSG_DEBUG, "DPP: Failed to process the request - ignore it"); @@ -1910,8 +1953,18 @@ void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src, case DPP_PA_PEER_DISCOVERY_REQ: hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq); break; +#ifdef CONFIG_DPP3 case DPP_PA_PKEX_EXCHANGE_REQ: - hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq); + /* This is for PKEXv2, but for now, process only with + * CONFIG_DPP3 to avoid issues with a capability that has not + * been tested with other implementations. */ + hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq, + true); + break; +#endif /* CONFIG_DPP3 */ + case DPP_PA_PKEX_V1_EXCHANGE_REQ: + hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq, + false); break; case DPP_PA_PKEX_EXCHANGE_RESP: hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq); @@ -2118,15 +2171,16 @@ int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd) if (!hapd->dpp_pkex_code) return -1; - if (os_strstr(cmd, " init=1")) { + if (os_strstr(cmd, " init=1") || os_strstr(cmd, " init=2")) { struct wpabuf *msg; + bool v2 = os_strstr(cmd, " init=2") != NULL; wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX"); dpp_pkex_free(hapd->dpp_pkex); hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, own_bi, hapd->own_addr, hapd->dpp_pkex_identifier, - hapd->dpp_pkex_code); + hapd->dpp_pkex_code, v2); if (!hapd->dpp_pkex) return -1; @@ -2134,7 +2188,8 @@ int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd) /* TODO: Which channel to use? */ wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d", MAC2STR(broadcast), 2437, - DPP_PA_PKEX_EXCHANGE_REQ); + v2 ? DPP_PA_PKEX_EXCHANGE_REQ : + DPP_PA_PKEX_V1_EXCHANGE_REQ); hostapd_drv_send_action(hapd, 2437, 0, broadcast, wpabuf_head(msg), wpabuf_len(msg)); } diff --git a/contrib/wpa/src/ap/drv_callbacks.c b/contrib/wpa/src/ap/drv_callbacks.c index ec5abf166b23..a50e6f2afa77 100644 --- a/contrib/wpa/src/ap/drv_callbacks.c +++ b/contrib/wpa/src/ap/drv_callbacks.c @@ -957,6 +957,12 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, hapd->iconf->ch_switch_vht_config = 0; hapd->iconf->ch_switch_he_config = 0; + if (width == CHAN_WIDTH_40 || width == CHAN_WIDTH_80 || + width == CHAN_WIDTH_80P80 || width == CHAN_WIDTH_160) + hapd->iconf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; + else if (width == CHAN_WIDTH_20 || width == CHAN_WIDTH_20_NOHT) + hapd->iconf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; + hapd->iconf->secondary_channel = offset; hostapd_set_oper_chwidth(hapd->iconf, chwidth); hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, seg0_idx); diff --git a/contrib/wpa/src/ap/hostapd.c b/contrib/wpa/src/ap/hostapd.c index 913a8e29e16d..4b88641a2dde 100644 --- a/contrib/wpa/src/ap/hostapd.c +++ b/contrib/wpa/src/ap/hostapd.c @@ -3461,6 +3461,20 @@ static int hostapd_change_config_freq(struct hostapd_data *hapd, NULL)) return -1; + switch (params->bandwidth) { + case 0: + case 20: + conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; + break; + case 40: + case 80: + case 160: + conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; + break; + default: + return -1; + } + switch (params->bandwidth) { case 0: case 20: @@ -3482,6 +3496,7 @@ static int hostapd_change_config_freq(struct hostapd_data *hapd, conf->channel = channel; conf->ieee80211n = params->ht_enabled; + conf->ieee80211ac = params->vht_enabled; conf->secondary_channel = params->sec_channel_offset; ieee80211_freq_to_chan(params->center_freq1, &seg0); diff --git a/contrib/wpa/src/common/dpp.c b/contrib/wpa/src/common/dpp.c index 1fd074f05627..ac6eae4c893e 100644 --- a/contrib/wpa/src/common/dpp.c +++ b/contrib/wpa/src/common/dpp.c @@ -28,7 +28,9 @@ static const char * dpp_netrole_str(enum dpp_netrole netrole); #ifdef CONFIG_TESTING_OPTIONS -#ifdef CONFIG_DPP2 +#ifdef CONFIG_DPP3 +int dpp_version_override = 3; +#elif defined(CONFIG_DPP2) int dpp_version_override = 2; #else int dpp_version_override = 1; @@ -306,6 +308,8 @@ int dpp_parse_uri_version(struct dpp_bootstrap_info *bi, const char *version) bi->version = 1; else if (*version == '2') bi->version = 2; + else if (*version == '3') + bi->version = 3; else wpa_printf(MSG_DEBUG, "DPP: Unknown URI version"); @@ -628,7 +632,8 @@ int dpp_gen_uri(struct dpp_bootstrap_info *bi) macstr, bi->info ? "I:" : "", bi->info ? bi->info : "", bi->info ? ";" : "", - DPP_VERSION == 2 ? "V:2;" : "", + DPP_VERSION == 3 ? "V:3;" : + (DPP_VERSION == 2 ? "V:2;" : ""), bi->pk); return 0; } @@ -1499,6 +1504,10 @@ skip_groups: json_value_sep(dppcon); json_add_string(dppcon, "expiry", expiry); } +#ifdef CONFIG_DPP3 + json_value_sep(dppcon); + json_add_int(dppcon, "version", auth->peer_version); +#endif /* CONFIG_DPP3 */ json_end_object(dppcon); wpa_printf(MSG_DEBUG, "DPP: dppCon: %s", (const char *) wpabuf_head(dppcon)); @@ -3694,6 +3703,14 @@ dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector, } } +#ifdef CONFIG_DPP3 + token = json_get_member(root, "version"); + if (token && token->type == JSON_NUMBER) { + wpa_printf(MSG_DEBUG, "DPP: version = %d", token->number); + intro->peer_version = token->number; + } +#endif /* CONFIG_DPP3 */ + netkey = json_get_member(root, "netAccessKey"); if (!netkey || netkey->type != JSON_OBJECT) { wpa_printf(MSG_DEBUG, "DPP: No netAccessKey object found"); @@ -3751,6 +3768,26 @@ fail: } +#ifdef CONFIG_DPP3 +int dpp_get_connector_version(const char *connector) +{ + struct json_token *root, *token; + int ver = -1; + + root = dpp_parse_own_connector(connector); + if (!root) + return -1; + + token = json_get_member(root, "version"); + if (token && token->type == JSON_NUMBER) + ver = token->number; + + json_free(root); + return ver; +} +#endif /* CONFIG_DPP3 */ + + unsigned int dpp_next_id(struct dpp_global *dpp) { struct dpp_bootstrap_info *bi; diff --git a/contrib/wpa/src/common/dpp.h b/contrib/wpa/src/common/dpp.h index a47c685f64b9..8d62a0e2ac3b 100644 --- a/contrib/wpa/src/common/dpp.h +++ b/contrib/wpa/src/common/dpp.h @@ -25,7 +25,9 @@ struct dpp_reconfig_id; #define DPP_VERSION (dpp_version_override) extern int dpp_version_override; #else /* CONFIG_TESTING_OPTIONS */ -#ifdef CONFIG_DPP2 +#ifdef CONFIG_DPP3 +#define DPP_VERSION 3 +#elif defined(CONFIG_DPP2) #define DPP_VERSION 2 #else #define DPP_VERSION 1 @@ -41,7 +43,7 @@ enum dpp_public_action_frame_type { DPP_PA_AUTHENTICATION_CONF = 2, DPP_PA_PEER_DISCOVERY_REQ = 5, DPP_PA_PEER_DISCOVERY_RESP = 6, - DPP_PA_PKEX_EXCHANGE_REQ = 7, + DPP_PA_PKEX_V1_EXCHANGE_REQ = 7, DPP_PA_PKEX_EXCHANGE_RESP = 8, DPP_PA_PKEX_COMMIT_REVEAL_REQ = 9, DPP_PA_PKEX_COMMIT_REVEAL_RESP = 10, @@ -52,6 +54,7 @@ enum dpp_public_action_frame_type { DPP_PA_RECONFIG_AUTH_REQ = 15, DPP_PA_RECONFIG_AUTH_RESP = 16, DPP_PA_RECONFIG_AUTH_CONF = 17, + DPP_PA_PKEX_EXCHANGE_REQ = 18, }; enum dpp_attribute_id { @@ -173,6 +176,7 @@ struct dpp_pkex { unsigned int initiator:1; unsigned int exchange_done:1; unsigned int failed:1; + unsigned int v2:1; struct dpp_bootstrap_info *own_bi; u8 own_mac[ETH_ALEN]; u8 peer_mac[ETH_ALEN]; @@ -190,6 +194,7 @@ struct dpp_pkex { unsigned int exch_req_wait_time; unsigned int exch_req_tries; unsigned int freq; + u8 peer_version; }; enum dpp_akm { @@ -372,6 +377,7 @@ struct dpp_introduction { u8 pmkid[PMKID_LEN]; u8 pmk[PMK_LEN_MAX]; size_t pmk_len; + int peer_version; }; struct dpp_relay_config { @@ -491,6 +497,8 @@ enum dpp_test_behavior { DPP_TEST_STOP_AT_AUTH_CONF = 89, DPP_TEST_STOP_AT_CONF_REQ = 90, DPP_TEST_REJECT_CONFIG = 91, + DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_REQ = 92, + DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_RESP = 93, }; extern enum dpp_test_behavior dpp_test; @@ -593,17 +601,18 @@ dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector, const u8 *csign_key, size_t csign_key_len, const u8 *peer_connector, size_t peer_connector_len, os_time_t *expiry); +int dpp_get_connector_version(const char *connector); struct dpp_pkex * dpp_pkex_init(void *msg_ctx, struct dpp_bootstrap_info *bi, const u8 *own_mac, - const char *identifier, - const char *code); + const char *identifier, const char *code, + bool v2); struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx, struct dpp_bootstrap_info *bi, const u8 *own_mac, const u8 *peer_mac, const char *identifier, const char *code, - const u8 *buf, size_t len); + const u8 *buf, size_t len, bool v2); struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex, const u8 *peer_mac, const u8 *buf, size_t len); diff --git a/contrib/wpa/src/common/dpp_crypto.c b/contrib/wpa/src/common/dpp_crypto.c index da59730eb7b7..300416fb12ec 100644 --- a/contrib/wpa/src/common/dpp_crypto.c +++ b/contrib/wpa/src/common/dpp_crypto.c @@ -1447,12 +1447,15 @@ dpp_pkex_derive_Qi(const struct dpp_curve_params *curve, const u8 *mac_init, struct crypto_bignum *hash_bn = NULL; struct crypto_ec *ec = NULL; - /* Qi = H(MAC-Initiator | [identifier |] code) * Pi */ + /* Qi = H([MAC-Initiator |] [identifier |] code) * Pi */ - wpa_printf(MSG_DEBUG, "DPP: MAC-Initiator: " MACSTR, MAC2STR(mac_init)); - addr[num_elem] = mac_init; - len[num_elem] = ETH_ALEN; - num_elem++; + if (mac_init) { + wpa_printf(MSG_DEBUG, "DPP: MAC-Initiator: " MACSTR, + MAC2STR(mac_init)); + addr[num_elem] = mac_init; + len[num_elem] = ETH_ALEN; + num_elem++; + } if (identifier) { wpa_printf(MSG_DEBUG, "DPP: code identifier: %s", identifier); @@ -1467,7 +1470,7 @@ dpp_pkex_derive_Qi(const struct dpp_curve_params *curve, const u8 *mac_init, if (dpp_hash_vector(curve, num_elem, addr, len, hash) < 0) goto fail; wpa_hexdump_key(MSG_DEBUG, - "DPP: H(MAC-Initiator | [identifier |] code)", + "DPP: H([MAC-Initiator |] [identifier |] code)", hash, curve->hash_len); Pi_key = dpp_pkex_get_role_elem(curve, 1); if (!Pi_key) @@ -1519,12 +1522,15 @@ dpp_pkex_derive_Qr(const struct dpp_curve_params *curve, const u8 *mac_resp, struct crypto_bignum *hash_bn = NULL; struct crypto_ec *ec = NULL; - /* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */ + /* Qr = H([MAC-Responder |] [identifier |] code) * Pr */ - wpa_printf(MSG_DEBUG, "DPP: MAC-Responder: " MACSTR, MAC2STR(mac_resp)); - addr[num_elem] = mac_resp; - len[num_elem] = ETH_ALEN; - num_elem++; + if (mac_resp) { + wpa_printf(MSG_DEBUG, "DPP: MAC-Responder: " MACSTR, + MAC2STR(mac_resp)); + addr[num_elem] = mac_resp; + len[num_elem] = ETH_ALEN; + num_elem++; + } if (identifier) { wpa_printf(MSG_DEBUG, "DPP: code identifier: %s", identifier); @@ -1539,7 +1545,7 @@ dpp_pkex_derive_Qr(const struct dpp_curve_params *curve, const u8 *mac_resp, if (dpp_hash_vector(curve, num_elem, addr, len, hash) < 0) goto fail; wpa_hexdump_key(MSG_DEBUG, - "DPP: H(MAC-Responder | [identifier |] code)", + "DPP: H([MAC-Responder |] [identifier |] code)", hash, curve->hash_len); Pr_key = dpp_pkex_get_role_elem(curve, 0); if (!Pr_key) @@ -1578,6 +1584,7 @@ fail: int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp, + u8 ver_init, u8 ver_resp, const u8 *Mx, size_t Mx_len, const u8 *Nx, size_t Nx_len, const char *code, @@ -1589,7 +1596,10 @@ int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp, u8 *info, *pos; size_t info_len; - /* z = HKDF(<>, MAC-Initiator | MAC-Responder | M.x | N.x | code, K.x) + /* + * v1: info = MAC-Initiator | MAC-Responder + * v2: info = Protocol Version-Initiator | Protocol Version-Responder + * z = HKDF(<>, info | M.x | N.x | code, K.x) */ /* HKDF-Extract(<>, IKM=K.x) */ @@ -1598,15 +1608,24 @@ int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp, return -1; wpa_hexdump_key(MSG_DEBUG, "DPP: PRK = HKDF-Extract(<>, IKM)", prk, hash_len); - info_len = 2 * ETH_ALEN + Mx_len + Nx_len + os_strlen(code); + if (mac_init && mac_resp) + info_len = 2 * ETH_ALEN; + else + info_len = 2; + info_len += Mx_len + Nx_len + os_strlen(code); info = os_malloc(info_len); if (!info) return -1; pos = info; - os_memcpy(pos, mac_init, ETH_ALEN); - pos += ETH_ALEN; - os_memcpy(pos, mac_resp, ETH_ALEN); - pos += ETH_ALEN; + if (mac_init && mac_resp) { + os_memcpy(pos, mac_init, ETH_ALEN); + pos += ETH_ALEN; + os_memcpy(pos, mac_resp, ETH_ALEN); + pos += ETH_ALEN; + } else { + *pos++ = ver_init; + *pos++ = ver_resp; + } os_memcpy(pos, Mx, Mx_len); pos += Mx_len; os_memcpy(pos, Nx, Nx_len); diff --git a/contrib/wpa/src/common/dpp_i.h b/contrib/wpa/src/common/dpp_i.h index 087878a508cb..c00b1ee41240 100644 --- a/contrib/wpa/src/common/dpp_i.h +++ b/contrib/wpa/src/common/dpp_i.h @@ -118,6 +118,7 @@ dpp_pkex_derive_Qr(const struct dpp_curve_params *curve, const u8 *mac_resp, const char *code, const char *identifier, struct crypto_ec **ret_ec); int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp, + u8 ver_init, u8 ver_resp, const u8 *Mx, size_t Mx_len, const u8 *Nx, size_t Nx_len, const char *code, diff --git a/contrib/wpa/src/common/dpp_pkex.c b/contrib/wpa/src/common/dpp_pkex.c index 06532b5457bd..38349fa3f540 100644 --- a/contrib/wpa/src/common/dpp_pkex.c +++ b/contrib/wpa/src/common/dpp_pkex.c @@ -26,7 +26,8 @@ size_t dpp_pkex_ephemeral_key_override_len = 0; #endif /* CONFIG_TESTING_OPTIONS */ -static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex) +static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex, + bool v2) { struct crypto_ec *ec = NULL; const struct crypto_ec_point *X; @@ -36,10 +37,11 @@ static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex) size_t attr_len; const struct dpp_curve_params *curve = pkex->own_bi->curve; - wpa_printf(MSG_DEBUG, "DPP: Build PKEX Exchange Request"); + wpa_printf(MSG_DEBUG, "DPP: Build PKEX %sExchange Request", + v2 ? "" : "Version 1 "); - /* Qi = H(MAC-Initiator | [identifier |] code) * Pi */ - Qi = dpp_pkex_derive_Qi(curve, pkex->own_mac, pkex->code, + /* Qi = H([MAC-Initiator |] [identifier |] code) * Pi */ + Qi = dpp_pkex_derive_Qi(curve, v2 ? NULL : pkex->own_mac, pkex->code, pkex->identifier, &ec); if (!Qi) goto fail; @@ -76,13 +78,27 @@ static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex) /* Initiator -> Responder: group, [identifier,] M */ attr_len = 4 + 2; +#ifdef CONFIG_DPP2 + if (v2) + attr_len += 4 + 1; +#endif /* CONFIG_DPP2 */ if (pkex->identifier) attr_len += 4 + os_strlen(pkex->identifier); attr_len += 4 + 2 * curve->prime_len; - msg = dpp_alloc_msg(DPP_PA_PKEX_EXCHANGE_REQ, attr_len); + msg = dpp_alloc_msg(v2 ? DPP_PA_PKEX_EXCHANGE_REQ : + DPP_PA_PKEX_V1_EXCHANGE_REQ, attr_len); if (!msg) goto fail; +#ifdef CONFIG_DPP2 + if (v2) { + /* Protocol Version */ + wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION); + wpabuf_put_le16(msg, 1); + wpabuf_put_u8(msg, DPP_VERSION); + } +#endif /* CONFIG_DPP2 */ + #ifdef CONFIG_TESTING_OPTIONS if (dpp_test == DPP_TEST_NO_FINITE_CYCLIC_GROUP_PKEX_EXCHANGE_REQ) { wpa_printf(MSG_INFO, "DPP: TESTING - no Finite Cyclic Group"); @@ -154,8 +170,8 @@ static void dpp_pkex_fail(struct dpp_pkex *pkex, const char *txt) struct dpp_pkex * dpp_pkex_init(void *msg_ctx, struct dpp_bootstrap_info *bi, const u8 *own_mac, - const char *identifier, - const char *code) + const char *identifier, const char *code, + bool v2) { struct dpp_pkex *pkex; @@ -172,6 +188,7 @@ struct dpp_pkex * dpp_pkex_init(void *msg_ctx, struct dpp_bootstrap_info *bi, return NULL; pkex->msg_ctx = msg_ctx; pkex->initiator = 1; + pkex->v2 = v2; pkex->own_bi = bi; os_memcpy(pkex->own_mac, own_mac, ETH_ALEN); if (identifier) { @@ -182,7 +199,7 @@ struct dpp_pkex * dpp_pkex_init(void *msg_ctx, struct dpp_bootstrap_info *bi, pkex->code = os_strdup(code); if (!pkex->code) goto fail; - pkex->exchange_req = dpp_pkex_build_exchange_req(pkex); + pkex->exchange_req = dpp_pkex_build_exchange_req(pkex, v2); if (!pkex->exchange_req) goto fail; return pkex; @@ -201,8 +218,13 @@ dpp_pkex_build_exchange_resp(struct dpp_pkex *pkex, size_t attr_len; const struct dpp_curve_params *curve = pkex->own_bi->curve; - /* Initiator -> Responder: DPP Status, [identifier,] N */ + /* Initiator -> Responder: DPP Status, [Protocol Version,] [identifier,] + * N */ attr_len = 4 + 1; +#ifdef CONFIG_DPP2 + if (pkex->v2) + attr_len += 4 + 1; +#endif /* CONFIG_DPP2 */ if (pkex->identifier) attr_len += 4 + os_strlen(pkex->identifier); attr_len += 4 + 2 * curve->prime_len; @@ -229,6 +251,15 @@ dpp_pkex_build_exchange_resp(struct dpp_pkex *pkex, skip_status: #endif /* CONFIG_TESTING_OPTIONS */ +#ifdef CONFIG_DPP2 + if (pkex->v2) { + /* Protocol Version */ + wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION); + wpabuf_put_le16(msg, 1); + wpabuf_put_u8(msg, DPP_VERSION); + } +#endif /* CONFIG_DPP2 */ + /* Code Identifier attribute */ if (pkex->identifier) { wpabuf_put_le16(msg, DPP_ATTR_CODE_IDENTIFIER); @@ -310,7 +341,7 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx, const u8 *peer_mac, const char *identifier, const char *code, - const u8 *buf, size_t len) + const u8 *buf, size_t len, bool v2) { const u8 *attr_group, *attr_id, *attr_key; u16 attr_group_len, attr_id_len, attr_key_len; @@ -325,6 +356,7 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx, u8 Kx[DPP_MAX_SHARED_SECRET_LEN]; size_t Kx_len; int res; + u8 peer_version = 0; if (bi->pkex_t >= PKEX_COUNTER_T_LIMIT) { wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL @@ -332,6 +364,24 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx, return NULL; } +#ifdef CONFIG_DPP2 + if (v2) { + const u8 *version; + u16 version_len; + + version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION, + &version_len); + if (!version || version_len < 1 || version[0] == 0) { + wpa_msg(msg_ctx, MSG_INFO, + "Missing or invalid Protocol Version attribute"); + return NULL; + } + peer_version = version[0]; + wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u", + peer_version); + } +#endif /* CONFIG_DPP2 */ + #ifdef CONFIG_TESTING_OPTIONS if (!is_zero_ether_addr(dpp_pkex_peer_mac_override)) { wpa_printf(MSG_INFO, "DPP: TESTING - peer_mac override " MACSTR, @@ -366,6 +416,8 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx, pkex = os_zalloc(sizeof(*pkex)); if (!pkex) goto fail; + pkex->v2 = v2; + pkex->peer_version = peer_version; pkex->own_bi = bi; pkex->failed = 1; pkex->exchange_resp = dpp_pkex_build_exchange_resp( @@ -385,8 +437,9 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx, return NULL; } - /* Qi = H(MAC-Initiator | [identifier |] code) * Pi */ - Qi = dpp_pkex_derive_Qi(curve, peer_mac, code, identifier, &ec); + /* Qi = H([MAC-Initiator |] [identifier |] code) * Pi */ + Qi = dpp_pkex_derive_Qi(curve, v2 ? NULL : peer_mac, code, identifier, + &ec); if (!Qi) goto fail; @@ -411,6 +464,8 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx, pkex = os_zalloc(sizeof(*pkex)); if (!pkex) goto fail; + pkex->v2 = v2; + pkex->peer_version = peer_version; pkex->t = bi->pkex_t; pkex->msg_ctx = msg_ctx; pkex->own_bi = bi; @@ -438,8 +493,9 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx, if (!pkex->x) goto fail; - /* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */ - Qr = dpp_pkex_derive_Qr(curve, own_mac, code, identifier, NULL); *** 2189 LINES SKIPPED ***