From 85fd8263a51081350de9c7529aa6a58948dcb70c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 23 Aug 2017 12:49:22 +0300 Subject: [PATCH] DPP: Use Transaction ID in Peer Discovery Request/Response frames DPP tech spec changed the contents of these frames by replacing the public key hash attributes with a Transaction ID attribute that gets copied from the request to the response to identify the transaction in a simpler manner. Signed-off-by: Jouni Malinen --- src/ap/dpp_hostapd.c | 28 ++++++++-------- src/common/dpp.c | 30 ----------------- src/common/dpp.h | 4 +-- wpa_supplicant/dpp_supplicant.c | 59 +++++++++++++++------------------ 4 files changed, 42 insertions(+), 79 deletions(-) diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index 8a8b4be64..27caa6407 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -895,8 +895,8 @@ static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd, const u8 *buf, size_t len, unsigned int freq) { - const u8 *connector; - u16 connector_len; + const u8 *connector, *trans_id; + u16 connector_len, trans_id_len; struct os_time now; struct dpp_introduction intro; os_time_t expire; @@ -931,6 +931,14 @@ static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd, return; } + trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID, + &trans_id_len); + if (!trans_id || trans_id_len != 1) { + wpa_printf(MSG_DEBUG, + "DPP: Peer did not include Transaction ID"); + return; + } + connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len); if (!connector) { wpa_printf(MSG_DEBUG, @@ -966,20 +974,14 @@ static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd, } msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP, - 2 * (4 + SHA256_MAC_LEN) + - 4 + os_strlen(hapd->conf->dpp_connector)); + 5 + 4 + os_strlen(hapd->conf->dpp_connector)); if (!msg) return; - /* SHA256(PK) */ - wpabuf_put_le16(msg, DPP_ATTR_PEER_NET_PK_HASH); - wpabuf_put_le16(msg, SHA256_MAC_LEN); - wpabuf_put_data(msg, intro.pk_hash, SHA256_MAC_LEN); - - /* SHA256(NK) */ - wpabuf_put_le16(msg, DPP_ATTR_OWN_NET_NK_HASH); - wpabuf_put_le16(msg, SHA256_MAC_LEN); - wpabuf_put_data(msg, intro.nk_hash, SHA256_MAC_LEN); + /* Transaction ID */ + wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID); + wpabuf_put_le16(msg, 1); + wpabuf_put_u8(msg, trans_id[0]); /* DPP Connector */ wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR); diff --git a/src/common/dpp.c b/src/common/dpp.c index 1edfc9be0..5ef700b18 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -4577,30 +4577,6 @@ fail: } -static int dpp_netkey_hash(EVP_PKEY *key, u8 *hash) -{ - EC_KEY *eckey; - unsigned char *der = NULL; - int ret, der_len; - const u8 *addr[1]; - size_t len[1]; - - eckey = EVP_PKEY_get1_EC_KEY(key); - if (!eckey) - return -1; - EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED); - der_len = i2d_EC_PUBKEY(eckey, &der); - EC_KEY_free(eckey); - if (der_len <= 0) - return -1; - addr[0] = der; - len[0] = der_len; - ret = sha256_vector(1, addr, len, hash); - OPENSSL_free(der); - return ret; -} - - int dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector, const u8 *net_access_key, size_t net_access_key_len, const u8 *csign_key, size_t csign_key_len, @@ -4753,12 +4729,6 @@ int dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector, goto fail; } - if (dpp_netkey_hash(own_key, intro->nk_hash) < 0 || - dpp_netkey_hash(peer_key, intro->pk_hash) < 0) { - wpa_printf(MSG_ERROR, "DPP: Failed to derive NK/PK hash"); - goto fail; - } - ret = 0; fail: if (ret < 0) diff --git a/src/common/dpp.h b/src/common/dpp.h index 277b03ae2..550157e18 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -44,12 +44,12 @@ enum dpp_attribute_id { DPP_ATTR_CONNECTOR = 0x100D, DPP_ATTR_CONFIG_ATTR_OBJ = 0x100E, DPP_ATTR_BOOTSTRAP_KEY = 0x100F, - DPP_ATTR_PEER_NET_PK_HASH = 0x1010, DPP_ATTR_OWN_NET_NK_HASH = 0x1011, DPP_ATTR_FINITE_CYCLIC_GROUP = 0x1012, DPP_ATTR_ENCRYPTED_KEY = 0x1013, DPP_ATTR_ENROLLEE_NONCE = 0x1014, DPP_ATTR_CODE_IDENTIFIER = 0x1015, + DPP_ATTR_TRANSACTION_ID = 0x1016, }; enum dpp_status_error { @@ -201,8 +201,6 @@ struct dpp_introduction { u8 pmkid[PMKID_LEN]; u8 pmk[PMK_LEN_MAX]; size_t pmk_len; - u8 pk_hash[SHA256_MAC_LEN]; - u8 nk_hash[SHA256_MAC_LEN]; }; void dpp_bootstrap_info_free(struct dpp_bootstrap_info *info); diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index 4d632b389..f5d1409c3 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -38,6 +38,10 @@ static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s, static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +/* Use a hardcoded Transaction ID 1 in Peer Discovery frames since there is only + * a single transaction in progress at any point in time. */ +static const u8 TRANSACTION_ID = 1; + static struct dpp_configurator * dpp_configurator_get_id(struct wpa_supplicant *wpa_s, unsigned int id) @@ -1256,8 +1260,8 @@ static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s, const u8 *buf, size_t len) { struct wpa_ssid *ssid; - const u8 *connector, *pk_hash, *nk_hash; - u16 connector_len, pk_hash_len, nk_hash_len; + const u8 *connector, *trans_id; + u16 connector_len, trans_id_len; struct dpp_introduction intro; struct rsn_pmksa_cache_entry *entry; struct os_time now; @@ -1286,6 +1290,20 @@ static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s, return; } + trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID, + &trans_id_len); + if (!trans_id || trans_id_len != 1) { + wpa_printf(MSG_DEBUG, + "DPP: Peer did not include Transaction ID"); + goto fail; + } + if (trans_id[0] != TRANSACTION_ID) { + wpa_printf(MSG_DEBUG, + "DPP: Ignore frame with unexpected Transaction ID %u", + trans_id[0]); + goto fail; + } + connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len); if (!connector) { wpa_printf(MSG_DEBUG, @@ -1304,36 +1322,6 @@ static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s, goto fail; } - pk_hash = dpp_get_attr(buf, len, DPP_ATTR_PEER_NET_PK_HASH, - &pk_hash_len); - if (!pk_hash || pk_hash_len != SHA256_MAC_LEN) { - wpa_printf(MSG_DEBUG, "DPP: Peer did not include SHA256(PK)"); - goto fail; - } - if (os_memcmp(pk_hash, intro.nk_hash, SHA256_MAC_LEN) != 0) { - wpa_printf(MSG_DEBUG, "DPP: SHA256(PK) mismatch"); - wpa_hexdump(MSG_DEBUG, "DPP: Received SHA256(PK)", - pk_hash, pk_hash_len); - wpa_hexdump(MSG_DEBUG, "DPP: Calculated SHA256(PK)", - intro.nk_hash, SHA256_MAC_LEN); - goto fail; - } - - nk_hash = dpp_get_attr(buf, len, DPP_ATTR_OWN_NET_NK_HASH, - &nk_hash_len); - if (!nk_hash || nk_hash_len != SHA256_MAC_LEN) { - wpa_printf(MSG_DEBUG, "DPP: Peer did not include SHA256(NK)"); - goto fail; - } - if (os_memcmp(nk_hash, intro.pk_hash, SHA256_MAC_LEN) != 0) { - wpa_printf(MSG_DEBUG, "DPP: SHA256(NK) mismatch"); - wpa_hexdump(MSG_DEBUG, "DPP: Received SHA256(NK)", - nk_hash, nk_hash_len); - wpa_hexdump(MSG_DEBUG, "DPP: Calculated SHA256(NK)", - intro.pk_hash, SHA256_MAC_LEN); - goto fail; - } - entry = os_zalloc(sizeof(*entry)); if (!entry) goto fail; @@ -1872,10 +1860,15 @@ int wpas_dpp_check_connect(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, MACSTR, MAC2STR(bss->bssid)); msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ, - 4 + os_strlen(ssid->dpp_connector)); + 5 + 4 + os_strlen(ssid->dpp_connector)); if (!msg) return -1; + /* Transaction ID */ + wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID); + wpabuf_put_le16(msg, 1); + wpabuf_put_u8(msg, TRANSACTION_ID); + /* DPP Connector */ wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR); wpabuf_put_le16(msg, os_strlen(ssid->dpp_connector));