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,
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);
/* 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,
}
+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)
{
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;
}
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;
}
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);
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;
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;
}
}
-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;
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);
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;
}
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)
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)) {
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,
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) {
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;
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);
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;