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 <jouni@qca.qualcomm.com>
This commit is contained in:
parent
a28675da23
commit
85fd8263a5
4 changed files with 42 additions and 79 deletions
|
@ -895,8 +895,8 @@ static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
|
||||||
const u8 *buf, size_t len,
|
const u8 *buf, size_t len,
|
||||||
unsigned int freq)
|
unsigned int freq)
|
||||||
{
|
{
|
||||||
const u8 *connector;
|
const u8 *connector, *trans_id;
|
||||||
u16 connector_len;
|
u16 connector_len, trans_id_len;
|
||||||
struct os_time now;
|
struct os_time now;
|
||||||
struct dpp_introduction intro;
|
struct dpp_introduction intro;
|
||||||
os_time_t expire;
|
os_time_t expire;
|
||||||
|
@ -931,6 +931,14 @@ static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
|
||||||
return;
|
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);
|
connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
|
||||||
if (!connector) {
|
if (!connector) {
|
||||||
wpa_printf(MSG_DEBUG,
|
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,
|
msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP,
|
||||||
2 * (4 + SHA256_MAC_LEN) +
|
5 + 4 + os_strlen(hapd->conf->dpp_connector));
|
||||||
4 + os_strlen(hapd->conf->dpp_connector));
|
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* SHA256(PK) */
|
/* Transaction ID */
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_PEER_NET_PK_HASH);
|
wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
|
||||||
wpabuf_put_le16(msg, SHA256_MAC_LEN);
|
wpabuf_put_le16(msg, 1);
|
||||||
wpabuf_put_data(msg, intro.pk_hash, SHA256_MAC_LEN);
|
wpabuf_put_u8(msg, trans_id[0]);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
/* DPP Connector */
|
/* DPP Connector */
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
|
wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
|
||||||
|
|
|
@ -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,
|
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 *net_access_key, size_t net_access_key_len,
|
||||||
const u8 *csign_key, size_t csign_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;
|
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;
|
ret = 0;
|
||||||
fail:
|
fail:
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
|
|
@ -44,12 +44,12 @@ enum dpp_attribute_id {
|
||||||
DPP_ATTR_CONNECTOR = 0x100D,
|
DPP_ATTR_CONNECTOR = 0x100D,
|
||||||
DPP_ATTR_CONFIG_ATTR_OBJ = 0x100E,
|
DPP_ATTR_CONFIG_ATTR_OBJ = 0x100E,
|
||||||
DPP_ATTR_BOOTSTRAP_KEY = 0x100F,
|
DPP_ATTR_BOOTSTRAP_KEY = 0x100F,
|
||||||
DPP_ATTR_PEER_NET_PK_HASH = 0x1010,
|
|
||||||
DPP_ATTR_OWN_NET_NK_HASH = 0x1011,
|
DPP_ATTR_OWN_NET_NK_HASH = 0x1011,
|
||||||
DPP_ATTR_FINITE_CYCLIC_GROUP = 0x1012,
|
DPP_ATTR_FINITE_CYCLIC_GROUP = 0x1012,
|
||||||
DPP_ATTR_ENCRYPTED_KEY = 0x1013,
|
DPP_ATTR_ENCRYPTED_KEY = 0x1013,
|
||||||
DPP_ATTR_ENROLLEE_NONCE = 0x1014,
|
DPP_ATTR_ENROLLEE_NONCE = 0x1014,
|
||||||
DPP_ATTR_CODE_IDENTIFIER = 0x1015,
|
DPP_ATTR_CODE_IDENTIFIER = 0x1015,
|
||||||
|
DPP_ATTR_TRANSACTION_ID = 0x1016,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum dpp_status_error {
|
enum dpp_status_error {
|
||||||
|
@ -201,8 +201,6 @@ struct dpp_introduction {
|
||||||
u8 pmkid[PMKID_LEN];
|
u8 pmkid[PMKID_LEN];
|
||||||
u8 pmk[PMK_LEN_MAX];
|
u8 pmk[PMK_LEN_MAX];
|
||||||
size_t pmk_len;
|
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);
|
void dpp_bootstrap_info_free(struct dpp_bootstrap_info *info);
|
||||||
|
|
|
@ -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 };
|
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 *
|
static struct dpp_configurator *
|
||||||
dpp_configurator_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
|
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)
|
const u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct wpa_ssid *ssid;
|
struct wpa_ssid *ssid;
|
||||||
const u8 *connector, *pk_hash, *nk_hash;
|
const u8 *connector, *trans_id;
|
||||||
u16 connector_len, pk_hash_len, nk_hash_len;
|
u16 connector_len, trans_id_len;
|
||||||
struct dpp_introduction intro;
|
struct dpp_introduction intro;
|
||||||
struct rsn_pmksa_cache_entry *entry;
|
struct rsn_pmksa_cache_entry *entry;
|
||||||
struct os_time now;
|
struct os_time now;
|
||||||
|
@ -1286,6 +1290,20 @@ static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
|
||||||
return;
|
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);
|
connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
|
||||||
if (!connector) {
|
if (!connector) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
|
@ -1304,36 +1322,6 @@ static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
|
||||||
goto fail;
|
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));
|
entry = os_zalloc(sizeof(*entry));
|
||||||
if (!entry)
|
if (!entry)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -1872,10 +1860,15 @@ int wpas_dpp_check_connect(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
|
||||||
MACSTR, MAC2STR(bss->bssid));
|
MACSTR, MAC2STR(bss->bssid));
|
||||||
|
|
||||||
msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ,
|
msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ,
|
||||||
4 + os_strlen(ssid->dpp_connector));
|
5 + 4 + os_strlen(ssid->dpp_connector));
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return -1;
|
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 */
|
/* DPP Connector */
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
|
wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
|
||||||
wpabuf_put_le16(msg, os_strlen(ssid->dpp_connector));
|
wpabuf_put_le16(msg, os_strlen(ssid->dpp_connector));
|
||||||
|
|
Loading…
Reference in a new issue