aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@codeaurora.org>2020-05-01 21:02:15 (GMT)
committerJouni Malinen <j@w1.fi>2020-05-11 13:41:33 (GMT)
commit0c043d9de71f1ea8b9ddcc4acb02b223711d4ead (patch)
treeef0acb5604c92878dcc8b95320516fe32d8d6fb3
parent92492dd3ac1a036324f1d40b518c8349cc342f42 (diff)
downloadhostap-0c043d9de71f1ea8b9ddcc4acb02b223711d4ead.zip
hostap-0c043d9de71f1ea8b9ddcc4acb02b223711d4ead.tar.gz
hostap-0c043d9de71f1ea8b9ddcc4acb02b223711d4ead.tar.bz2
DPP2: Reconfig Announcement transmission
Extend DPP chirping mechanism to allow Reconfig Announcement frames to be transmitted instead of the Presence Announcement frames. Add a new wpa_supplicant control interface command "DPP_RECONFIG <network id>" to initiate reconfiguration for a specific network profile. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
-rw-r--r--hostapd/Android.mk1
-rw-r--r--hostapd/Makefile1
-rw-r--r--src/common/dpp.h5
-rw-r--r--src/common/dpp_reconfig.c76
-rw-r--r--tests/fuzzing/dpp-uri/Makefile1
-rw-r--r--wpa_supplicant/Android.mk1
-rw-r--r--wpa_supplicant/Makefile1
-rw-r--r--wpa_supplicant/ctrl_iface.c6
-rw-r--r--wpa_supplicant/dpp_supplicant.c56
-rw-r--r--wpa_supplicant/dpp_supplicant.h1
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h3
11 files changed, 144 insertions, 8 deletions
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index c581f5d..f331630 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -539,6 +539,7 @@ L_CFLAGS += -DCONFIG_DPP
OBJS += src/common/dpp.c
OBJS += src/common/dpp_crypto.c
OBJS += src/common/dpp_pkex.c
+OBJS += src/common/dpp_reconfig.c
OBJS += src/ap/dpp_hostapd.c
OBJS += src/ap/gas_query_ap.c
NEED_AES_SIV=y
diff --git a/hostapd/Makefile b/hostapd/Makefile
index c20a1a8..ded784f 100644
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -570,6 +570,7 @@ CFLAGS += -DCONFIG_DPP
OBJS += ../src/common/dpp.o
OBJS += ../src/common/dpp_crypto.o
OBJS += ../src/common/dpp_pkex.o
+OBJS += ../src/common/dpp_reconfig.o
OBJS += ../src/ap/dpp_hostapd.o
OBJS += ../src/ap/gas_query_ap.o
NEED_AES_SIV=y
diff --git a/src/common/dpp.h b/src/common/dpp.h
index e81526f..988c6fc 100644
--- a/src/common/dpp.h
+++ b/src/common/dpp.h
@@ -626,5 +626,10 @@ struct dpp_global * dpp_global_init(struct dpp_global_config *config);
void dpp_global_clear(struct dpp_global *dpp);
void dpp_global_deinit(struct dpp_global *dpp);
+/* dpp_reconfig.c */
+
+struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key,
+ size_t csign_key_len);
+
#endif /* CONFIG_DPP */
#endif /* DPP_H */
diff --git a/src/common/dpp_reconfig.c b/src/common/dpp_reconfig.c
new file mode 100644
index 0000000..597963f
--- /dev/null
+++ b/src/common/dpp_reconfig.c
@@ -0,0 +1,76 @@
+/*
+ * DPP reconfiguration
+ * Copyright (c) 2020, The Linux Foundation
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "utils/includes.h"
+
+#include "utils/common.h"
+#include "crypto/crypto.h"
+#include "dpp.h"
+#include "dpp_i.h"
+
+
+#ifdef CONFIG_DPP2
+
+static void dpp_build_attr_csign_key_hash(struct wpabuf *msg, const u8 *hash)
+{
+ if (hash) {
+ wpa_printf(MSG_DEBUG, "DPP: Configurator C-sign key Hash");
+ wpabuf_put_le16(msg, DPP_ATTR_C_SIGN_KEY_HASH);
+ wpabuf_put_le16(msg, SHA256_MAC_LEN);
+ wpabuf_put_data(msg, hash, SHA256_MAC_LEN);
+ }
+}
+
+
+struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key,
+ size_t csign_key_len)
+{
+ struct wpabuf *msg;
+ EVP_PKEY *csign = NULL;
+ const unsigned char *p;
+ struct wpabuf *uncomp;
+ u8 hash[SHA256_MAC_LEN];
+ const u8 *addr[1];
+ size_t len[1];
+ int res;
+
+ wpa_printf(MSG_DEBUG, "DPP: Build Reconfig Announcement frame");
+
+ p = csign_key;
+ csign = d2i_PUBKEY(NULL, &p, csign_key_len);
+ if (!csign) {
+ wpa_printf(MSG_ERROR,
+ "DPP: Failed to parse local C-sign-key information");
+ return NULL;
+ }
+
+ uncomp = dpp_get_pubkey_point(csign, 1);
+ EVP_PKEY_free(csign);
+ if (!uncomp)
+ return NULL;
+ addr[0] = wpabuf_head(uncomp);
+ len[0] = wpabuf_len(uncomp);
+ wpa_hexdump(MSG_DEBUG, "DPP: Uncompressed C-sign key", addr[0], len[0]);
+ res = sha256_vector(1, addr, len, hash);
+ wpabuf_free(uncomp);
+ if (res < 0)
+ return NULL;
+ wpa_hexdump(MSG_DEBUG, "DPP: kid = SHA256(uncompressed C-sign key)",
+ hash, SHA256_MAC_LEN);
+
+ msg = dpp_alloc_msg(DPP_PA_RECONFIG_ANNOUNCEMENT, 4 + SHA256_MAC_LEN);
+ if (!msg)
+ return NULL;
+
+ /* Configurator C-sign key Hash */
+ dpp_build_attr_csign_key_hash(msg, hash);
+ wpa_hexdump_buf(MSG_DEBUG,
+ "DPP: Reconfig Announcement frame attributes", msg);
+ return msg;
+}
+#endif /* CONFIG_DPP2 */
diff --git a/tests/fuzzing/dpp-uri/Makefile b/tests/fuzzing/dpp-uri/Makefile
index e5788a8..6125e4b 100644
--- a/tests/fuzzing/dpp-uri/Makefile
+++ b/tests/fuzzing/dpp-uri/Makefile
@@ -23,6 +23,7 @@ OBJS += $(SRC)/tls/asn1.o
OBJS += $(SRC)/common/dpp.o
OBJS += $(SRC)/common/dpp_crypto.o
OBJS += $(SRC)/common/dpp_pkex.o
+OBJS += $(SRC)/common/dpp_reconfig.o
dpp-uri: dpp-uri.o $(OBJS) $(LIBS)
$(LDO) $(LDFLAGS) -o $@ $^ -lcrypto
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index a589b27..0b091d7 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -249,6 +249,7 @@ L_CFLAGS += -DCONFIG_DPP
OBJS += src/common/dpp.c
OBJS += src/common/dpp_crypto.c
OBJS += src/common/dpp_pkex.c
+OBJS += src/common/dpp_reconfig.c
OBJS += dpp_supplicant.c
NEED_AES_SIV=y
NEED_HMAC_SHA256_KDF=y
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 441a7db..d2bdbc4 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -281,6 +281,7 @@ CFLAGS += -DCONFIG_DPP
OBJS += ../src/common/dpp.o
OBJS += ../src/common/dpp_crypto.o
OBJS += ../src/common/dpp_pkex.o
+OBJS += ../src/common/dpp_reconfig.o
OBJS += dpp_supplicant.o
NEED_AES_SIV=y
NEED_HMAC_SHA256_KDF=y
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 6e673fe..5c99735 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -11013,6 +11013,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
reply_len = -1;
} else if (os_strcmp(buf, "DPP_STOP_CHIRP") == 0) {
wpas_dpp_chirp_stop(wpa_s);
+ } else if (os_strncmp(buf, "DPP_RECONFIG ", 13) == 0) {
+ struct wpa_ssid *ssid;
+
+ ssid = wpa_config_get_network(wpa_s->conf, atoi(buf + 13));
+ if (!ssid || wpas_dpp_reconfig(wpa_s, ssid) < 0)
+ reply_len = -1;
#endif /* CONFIG_DPP2 */
#endif /* CONFIG_DPP */
} else {
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index 837ddbe..f74f1d6 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -2878,15 +2878,24 @@ static void wpas_dpp_chirp_tx_status(struct wpa_supplicant *wpa_s,
static void wpas_dpp_chirp_start(struct wpa_supplicant *wpa_s)
{
+ struct wpabuf *msg;
+ int type;
+
+ msg = wpa_s->dpp_presence_announcement;
+ type = DPP_PA_PRESENCE_ANNOUNCEMENT;
+ if (!msg) {
+ msg = wpa_s->dpp_reconfig_announcement;
+ if (!msg)
+ return;
+ type = DPP_PA_RECONFIG_ANNOUNCEMENT;
+ }
wpa_printf(MSG_DEBUG, "DPP: Chirp on %d MHz", wpa_s->dpp_chirp_freq);
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(broadcast), wpa_s->dpp_chirp_freq,
- DPP_PA_PRESENCE_ANNOUNCEMENT);
+ MAC2STR(broadcast), wpa_s->dpp_chirp_freq, type);
if (offchannel_send_action(
wpa_s, wpa_s->dpp_chirp_freq, broadcast,
wpa_s->own_addr, broadcast,
- wpabuf_head(wpa_s->dpp_presence_announcement),
- wpabuf_len(wpa_s->dpp_presence_announcement),
+ wpabuf_head(msg), wpabuf_len(msg),
2000, wpas_dpp_chirp_tx_status, 0) < 0)
wpas_dpp_chirp_stop(wpa_s);
}
@@ -2901,7 +2910,7 @@ static void wpas_dpp_chirp_scan_res_handler(struct wpa_supplicant *wpa_s,
int c;
struct wpa_bss *bss;
- if (!bi)
+ if (!bi && !wpa_s->dpp_reconfig_announcement)
return;
wpa_s->dpp_chirp_scan_done = 1;
@@ -2910,8 +2919,11 @@ static void wpas_dpp_chirp_scan_res_handler(struct wpa_supplicant *wpa_s,
wpa_s->dpp_chirp_freqs = NULL;
/* Channels from own bootstrapping info */
- for (i = 0; i < bi->num_freq; i++)
- int_array_add_unique(&wpa_s->dpp_chirp_freqs, bi->freq[i]);
+ if (bi) {
+ for (i = 0; i < bi->num_freq; i++)
+ int_array_add_unique(&wpa_s->dpp_chirp_freqs,
+ bi->freq[i]);
+ }
/* Preferred chirping channels */
int_array_add_unique(&wpa_s->dpp_chirp_freqs, 2437);
@@ -3085,13 +3097,16 @@ int wpas_dpp_chirp(struct wpa_supplicant *wpa_s, const char *cmd)
void wpas_dpp_chirp_stop(struct wpa_supplicant *wpa_s)
{
- if (wpa_s->dpp_presence_announcement) {
+ if (wpa_s->dpp_presence_announcement ||
+ wpa_s->dpp_reconfig_announcement) {
offchannel_send_action_done(wpa_s);
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CHIRP_STOPPED);
}
wpa_s->dpp_chirp_bi = NULL;
wpabuf_free(wpa_s->dpp_presence_announcement);
wpa_s->dpp_presence_announcement = NULL;
+ wpabuf_free(wpa_s->dpp_reconfig_announcement);
+ wpa_s->dpp_reconfig_announcement = NULL;
if (wpa_s->dpp_chirp_listen)
wpas_dpp_listen_stop(wpa_s);
wpa_s->dpp_chirp_listen = 0;
@@ -3106,4 +3121,29 @@ void wpas_dpp_chirp_stop(struct wpa_supplicant *wpa_s)
}
}
+
+int wpas_dpp_reconfig(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+ if (!ssid->dpp_connector || !ssid->dpp_netaccesskey ||
+ !ssid->dpp_csign)
+ return -1;
+
+ wpas_dpp_chirp_stop(wpa_s);
+ wpa_s->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
+ wpa_s->dpp_qr_mutual = 0;
+ wpa_s->dpp_reconfig_announcement =
+ dpp_build_reconfig_announcement(ssid->dpp_csign,
+ ssid->dpp_csign_len);
+ if (!wpa_s->dpp_reconfig_announcement)
+ return -1;
+ wpa_s->dpp_reconfig_ssid = ssid;
+ wpa_s->dpp_reconfig_ssid_id = ssid->id;
+ wpa_s->dpp_chirp_iter = 1;
+ wpa_s->dpp_chirp_round = 0;
+ wpa_s->dpp_chirp_scan_done = 0;
+ wpa_s->dpp_chirp_listen = 0;
+
+ return eloop_register_timeout(0, 0, wpas_dpp_chirp_next, wpa_s, NULL);
+}
+
#endif /* CONFIG_DPP2 */
diff --git a/wpa_supplicant/dpp_supplicant.h b/wpa_supplicant/dpp_supplicant.h
index 6d70874..2dc86e0 100644
--- a/wpa_supplicant/dpp_supplicant.h
+++ b/wpa_supplicant/dpp_supplicant.h
@@ -39,5 +39,6 @@ void wpas_dpp_send_conn_status_result(struct wpa_supplicant *wpa_s,
enum dpp_status_error result);
int wpas_dpp_chirp(struct wpa_supplicant *wpa_s, const char *cmd);
void wpas_dpp_chirp_stop(struct wpa_supplicant *wpa_s);
+int wpas_dpp_reconfig(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
#endif /* DPP_SUPPLICANT_H */
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 2ed8e2f..734ba07 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1277,6 +1277,7 @@ struct wpa_supplicant {
#ifdef CONFIG_DPP2
struct dpp_pfs *dpp_pfs;
int dpp_pfs_fallback;
+ struct wpabuf *dpp_reconfig_announcement;
struct wpabuf *dpp_presence_announcement;
struct dpp_bootstrap_info *dpp_chirp_bi;
int dpp_chirp_freq;
@@ -1285,6 +1286,8 @@ struct wpa_supplicant {
int dpp_chirp_round;
int dpp_chirp_scan_done;
int dpp_chirp_listen;
+ struct wpa_ssid *dpp_reconfig_ssid;
+ int dpp_reconfig_ssid_id;
#endif /* CONFIG_DPP2 */
#ifdef CONFIG_TESTING_OPTIONS
char *dpp_config_obj_override;