diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index 178fd126e..ca225894a 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -1235,11 +1235,12 @@ hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src, const u8 *hdr, const u8 *buf, size_t len, unsigned int freq) { - const u8 *csign_hash; - u16 csign_hash_len; + const u8 *csign_hash, *fcgroup; + u16 csign_hash_len, fcgroup_len; struct dpp_configurator *conf; struct dpp_authentication *auth; unsigned int wait_time, max_wait_time; + u16 group; if (hapd->dpp_auth) { wpa_printf(MSG_DEBUG, @@ -1271,8 +1272,18 @@ hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src, return; } + fcgroup = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP, + &fcgroup_len); + if (!fcgroup || fcgroup_len != 2) { + wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL + "Missing or invalid required Finite Cyclic Group attribute"); + return; + } + group = WPA_GET_LE16(fcgroup); + wpa_printf(MSG_DEBUG, "DPP: Enrollee finite cyclic group: %u", group); + auth = dpp_reconfig_init(hapd->iface->interfaces->dpp, hapd->msg_ctx, - conf, freq); + conf, freq, group); if (!auth) return; hostapd_dpp_set_testing_options(hapd, auth); diff --git a/src/common/dpp.h b/src/common/dpp.h index cff996095..f6e4e25f2 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -683,10 +683,12 @@ 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); + size_t csign_key_len, + const u8 *net_access_key, + size_t net_access_key_len); struct dpp_authentication * dpp_reconfig_init(struct dpp_global *dpp, void *msg_ctx, - struct dpp_configurator *conf, unsigned int freq); + struct dpp_configurator *conf, unsigned int freq, u16 group); struct dpp_authentication * dpp_reconfig_auth_req_rx(struct dpp_global *dpp, void *msg_ctx, const char *own_connector, diff --git a/src/common/dpp_crypto.c b/src/common/dpp_crypto.c index e83ab9c60..6752aaa31 100644 --- a/src/common/dpp_crypto.c +++ b/src/common/dpp_crypto.c @@ -130,6 +130,18 @@ const struct dpp_curve_params * dpp_get_curve_nid(int nid) } +const struct dpp_curve_params * dpp_get_curve_ike_group(u16 group) +{ + int i; + + for (i = 0; dpp_curves[i].name; i++) { + if (dpp_curves[i].ike_group == group) + return &dpp_curves[i]; + } + return NULL; +} + + void dpp_debug_print_point(const char *title, const EC_GROUP *group, const EC_POINT *point) { @@ -2272,7 +2284,7 @@ int dpp_reconfig_derive_ke_responder(struct dpp_authentication *auth, if (auth->curve != curve) { wpa_printf(MSG_DEBUG, - "DPP: Mismatching netAccessKey curves (%s != %s)", + "DPP: Mismatching netAccessKey curves (own=%s != peer=%s)", auth->curve->name, curve->name); goto fail; } @@ -2381,7 +2393,7 @@ int dpp_reconfig_derive_ke_initiator(struct dpp_authentication *auth, dpp_debug_print_key("DPP: Received netAccessKey", peer_key); if (auth->curve != curve) { wpa_printf(MSG_DEBUG, - "DPP: Mismatching netAccessKey curves (%s != %s)", + "DPP: Mismatching netAccessKey curves (own=%s != peer=%s)", auth->curve->name, curve->name); goto fail; } diff --git a/src/common/dpp_i.h b/src/common/dpp_i.h index e66eb6cfd..cf3dedd01 100644 --- a/src/common/dpp_i.h +++ b/src/common/dpp_i.h @@ -73,6 +73,7 @@ dpp_check_signed_connector(struct dpp_signed_connector_info *info, const struct dpp_curve_params * dpp_get_curve_name(const char *name); const struct dpp_curve_params * dpp_get_curve_jwk_crv(const char *name); const struct dpp_curve_params * dpp_get_curve_nid(int nid); +const struct dpp_curve_params * dpp_get_curve_ike_group(u16 group); int dpp_bi_pubkey_hash(struct dpp_bootstrap_info *bi, const u8 *data, size_t data_len); struct wpabuf * dpp_get_pubkey_point(EVP_PKEY *pkey, int prefix); diff --git a/src/common/dpp_reconfig.c b/src/common/dpp_reconfig.c index 0bb00cc1d..5d7ab6802 100644 --- a/src/common/dpp_reconfig.c +++ b/src/common/dpp_reconfig.c @@ -34,9 +34,11 @@ static void dpp_build_attr_csign_key_hash(struct wpabuf *msg, const u8 *hash) struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key, - size_t csign_key_len) + size_t csign_key_len, + const u8 *net_access_key, + size_t net_access_key_len) { - struct wpabuf *msg; + struct wpabuf *msg = NULL; EVP_PKEY *csign = NULL; const unsigned char *p; struct wpabuf *uncomp; @@ -44,39 +46,61 @@ struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key, const u8 *addr[1]; size_t len[1]; int res; + size_t attr_len; + const struct dpp_curve_params *own_curve; + EVP_PKEY *own_key; wpa_printf(MSG_DEBUG, "DPP: Build Reconfig Announcement frame"); + own_key = dpp_set_keypair(&own_curve, net_access_key, + net_access_key_len); + if (!own_key) { + wpa_printf(MSG_ERROR, "DPP: Failed to parse own netAccessKey"); + goto fail; + } + 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; + goto fail; } uncomp = dpp_get_pubkey_point(csign, 1); EVP_PKEY_free(csign); if (!uncomp) - return NULL; + goto fail; 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; + goto fail; 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); + attr_len = 4 + SHA256_MAC_LEN; + attr_len += 4 + 2; + msg = dpp_alloc_msg(DPP_PA_RECONFIG_ANNOUNCEMENT, attr_len); if (!msg) - return NULL; + goto fail; /* Configurator C-sign key Hash */ dpp_build_attr_csign_key_hash(msg, hash); + + /* Finite Cyclic Group attribute */ + wpa_printf(MSG_DEBUG, "DPP: Finite Cyclic Group: %u", + own_curve->ike_group); + wpabuf_put_le16(msg, DPP_ATTR_FINITE_CYCLIC_GROUP); + wpabuf_put_le16(msg, 2); + wpabuf_put_le16(msg, own_curve->ike_group); + wpa_hexdump_buf(MSG_DEBUG, "DPP: Reconfig Announcement frame attributes", msg); +fail: + EVP_PKEY_free(own_key); return msg; } @@ -121,7 +145,9 @@ static struct wpabuf * dpp_reconfig_build_req(struct dpp_authentication *auth) } -static int dpp_configurator_build_own_connector(struct dpp_configurator *conf) +static int +dpp_configurator_build_own_connector(struct dpp_configurator *conf, + const struct dpp_curve_params *curve) { struct wpabuf *dppcon = NULL; int ret = -1; @@ -132,12 +158,12 @@ static int dpp_configurator_build_own_connector(struct dpp_configurator *conf) wpa_printf(MSG_DEBUG, "DPP: Sign own Configurator Connector for reconfiguration with curve %s", conf->curve->name); - conf->connector_key = dpp_gen_keypair(conf->curve); + conf->connector_key = dpp_gen_keypair(curve); if (!conf->connector_key) goto fail; /* Connector (JSON dppCon object) */ - dppcon = wpabuf_alloc(1000 + 2 * conf->curve->prime_len * 4 / 3); + dppcon = wpabuf_alloc(1000 + 2 * curve->prime_len * 4 / 3); if (!dppcon) goto fail; json_start_object(dppcon, NULL); @@ -150,7 +176,7 @@ static int dpp_configurator_build_own_connector(struct dpp_configurator *conf) json_end_array(dppcon); json_value_sep(dppcon); if (dpp_build_jwk(dppcon, "netAccessKey", conf->connector_key, NULL, - conf->curve) < 0) { + curve) < 0) { wpa_printf(MSG_DEBUG, "DPP: Failed to build netAccessKey JWK"); goto fail; } @@ -172,9 +198,18 @@ fail: struct dpp_authentication * dpp_reconfig_init(struct dpp_global *dpp, void *msg_ctx, - struct dpp_configurator *conf, unsigned int freq) + struct dpp_configurator *conf, unsigned int freq, u16 group) { struct dpp_authentication *auth; + const struct dpp_curve_params *curve; + + curve = dpp_get_curve_ike_group(group); + if (!curve) { + wpa_printf(MSG_DEBUG, + "DPP: Unsupported group %u - cannot reconfigure", + group); + return NULL; + } auth = dpp_alloc_auth(dpp, msg_ctx); if (!auth) @@ -186,12 +221,12 @@ dpp_reconfig_init(struct dpp_global *dpp, void *msg_ctx, auth->waiting_auth_resp = 1; auth->allowed_roles = DPP_CAPAB_CONFIGURATOR; auth->configurator = 1; - auth->curve = conf->curve; + auth->curve = curve; auth->transaction_id = 1; if (freq && dpp_prepare_channel_list(auth, freq, NULL, 0) < 0) goto fail; - if (dpp_configurator_build_own_connector(conf) < 0) + if (dpp_configurator_build_own_connector(conf, curve) < 0) goto fail; if (random_get_bytes(auth->i_nonce, auth->curve->nonce_len)) { diff --git a/src/common/dpp_tcp.c b/src/common/dpp_tcp.c index 9994c67cd..a4ec81398 100644 --- a/src/common/dpp_tcp.c +++ b/src/common/dpp_tcp.c @@ -844,11 +844,12 @@ static int dpp_controller_rx_reconfig_announcement(struct dpp_connection *conn, const u8 *hdr, const u8 *buf, size_t len) { - const u8 *csign_hash; - u16 csign_hash_len; + const u8 *csign_hash, *fcgroup; + u16 csign_hash_len, fcgroup_len; struct dpp_configurator *conf; struct dpp_global *dpp = conn->ctrl->global; struct dpp_authentication *auth; + u16 group; if (conn->auth) { wpa_printf(MSG_DEBUG, @@ -874,7 +875,17 @@ static int dpp_controller_rx_reconfig_announcement(struct dpp_connection *conn, return -1; } - auth = dpp_reconfig_init(dpp, dpp->msg_ctx, conf, 0); + fcgroup = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP, + &fcgroup_len); + if (!fcgroup || fcgroup_len != 2) { + wpa_msg(dpp->msg_ctx, MSG_INFO, DPP_EVENT_FAIL + "Missing or invalid required Finite Cyclic Group attribute"); + return -1; + } + group = WPA_GET_LE16(fcgroup); + wpa_printf(MSG_DEBUG, "DPP: Enrollee finite cyclic group: %u", group); + + auth = dpp_reconfig_init(dpp, dpp->msg_ctx, conf, 0, group); if (!auth) return -1; if (dpp_set_configurator(auth, conn->ctrl->configurator_params) < 0) { diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index cc35030c9..9c0056c5b 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -2022,11 +2022,12 @@ wpas_dpp_rx_reconfig_announcement(struct wpa_supplicant *wpa_s, const u8 *src, const u8 *hdr, const u8 *buf, size_t len, unsigned int freq) { - const u8 *csign_hash; - u16 csign_hash_len; + const u8 *csign_hash, *fcgroup; + u16 csign_hash_len, fcgroup_len; struct dpp_configurator *conf; struct dpp_authentication *auth; unsigned int wait_time, max_wait_time; + u16 group; if (!wpa_s->dpp) return; @@ -2056,7 +2057,17 @@ wpas_dpp_rx_reconfig_announcement(struct wpa_supplicant *wpa_s, const u8 *src, return; } - auth = dpp_reconfig_init(wpa_s->dpp, wpa_s, conf, freq); + fcgroup = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP, + &fcgroup_len); + if (!fcgroup || fcgroup_len != 2) { + wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL + "Missing or invalid required Finite Cyclic Group attribute"); + return; + } + group = WPA_GET_LE16(fcgroup); + wpa_printf(MSG_DEBUG, "DPP: Enrollee finite cyclic group: %u", group); + + auth = dpp_reconfig_init(wpa_s->dpp, wpa_s, conf, freq, group); if (!auth) return; wpas_dpp_set_testing_options(wpa_s, auth); @@ -3636,7 +3647,9 @@ int wpas_dpp_reconfig(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) wpa_s->dpp_qr_mutual = 0; wpa_s->dpp_reconfig_announcement = dpp_build_reconfig_announcement(ssid->dpp_csign, - ssid->dpp_csign_len); + ssid->dpp_csign_len, + ssid->dpp_netaccesskey, + ssid->dpp_netaccesskey_len); if (!wpa_s->dpp_reconfig_announcement) return -1; wpa_s->dpp_reconfig_ssid = ssid;