]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP2: Add Enrollee netAccessKey group into Reconfig Announcement
authorJouni Malinen <jouni@codeaurora.org>
Thu, 6 Aug 2020 16:47:28 +0000 (19:47 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 7 Aug 2020 12:25:10 +0000 (15:25 +0300)
This was added to the protocol design to support cases where the
C-sign-key uses a different group than the netAccessKey. The Enrollee
now indicates its netAccessKey group in Reconfig Announcement and the
Configurator builds it own reconfig Connector using that group instead
of the group used for the C-sign-key.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/ap/dpp_hostapd.c
src/common/dpp.h
src/common/dpp_crypto.c
src/common/dpp_i.h
src/common/dpp_reconfig.c
src/common/dpp_tcp.c
wpa_supplicant/dpp_supplicant.c

index 178fd126ec043dd770f7a045ff27d97a50d85f12..ca225894a6e3d03b33bf215f9d0727b174555207 100644 (file)
@@ -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);
index cff996095cc0f491e833f4b4aba6e6610e3fb941..f6e4e25f2b42783958a2c3abfddea4417f0a1bf8 100644 (file)
@@ -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,
index e83ab9c60316b95a55b9050c7ed055b8cb837f56..6752aaa31c88587100894875773286ce0cd84667 100644 (file)
@@ -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;
        }
index e66eb6cfd6754265b8b445abe4eccc585d7c0694..cf3dedd01ea44df1c4dffb2e22cd53ad9abf69d8 100644 (file)
@@ -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);
index 0bb00cc1d10c3861f4b4d6c73cbf649411e09f25..5d7ab68026ace24c3d161446e28638578f5d49bb 100644 (file)
@@ -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)) {
index 9994c67cda2d238df2997419759081a1745f057c..a4ec81398d045e8b7d266d0acee749fb873cd804 100644 (file)
@@ -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) {
index cc35030c99156beb60c6e6ae9fd083dceacad6af..9c0056c5b4d7dd4372a2436dc5d7de112cbdd148 100644 (file)
@@ -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;