FT: Add MDE to assoc request IEs in connect params

Add MDE (mobility domain element) to Association Request frame IEs in
the driver assoc params. wpa_supplicant will add MDE only if the network
profile allows FT, the selected AP supports FT, and the mobility domain
ID matches.

Signed-off-by: Ahmad Masri <amasri@codeaurora.org>
This commit is contained in:
Ahmad Masri 2018-04-16 13:52:27 +03:00 committed by Jouni Malinen
parent b55c623e4c
commit 3dc3afe298
4 changed files with 78 additions and 8 deletions

View file

@ -3297,6 +3297,12 @@ const u8 * wpa_sm_get_anonce(struct wpa_sm *sm)
#endif /* CONFIG_TESTING_OPTIONS */
unsigned int wpa_sm_get_key_mgmt(struct wpa_sm *sm)
{
return sm->key_mgmt;
}
#ifdef CONFIG_FILS
struct wpabuf * fils_build_auth(struct wpa_sm *sm, int dh_group, const u8 *md)

View file

@ -353,6 +353,9 @@ static inline int wpa_fils_is_completed(struct wpa_sm *sm)
int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len);
int wpa_ft_prepare_auth_request(struct wpa_sm *sm, const u8 *mdie);
int wpa_ft_add_mdie(struct wpa_sm *sm, u8 *ies, size_t ies_len,
const u8 *mdie);
const u8 * wpa_sm_get_ft_md(struct wpa_sm *sm);
int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
int ft_action, const u8 *target_ap,
const u8 *ric_ies, size_t ric_ies_len);
@ -377,6 +380,12 @@ static inline int wpa_ft_prepare_auth_request(struct wpa_sm *sm,
return 0;
}
static inline int wpa_ft_add_mdie(struct wpa_sm *sm, u8 *ies, size_t ies_len,
const u8 *mdie)
{
return 0;
}
static inline int
wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
int ft_action, const u8 *target_ap)
@ -429,6 +438,7 @@ extern unsigned int tdls_testing;
int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf);
void wpa_sm_set_test_assoc_ie(struct wpa_sm *sm, struct wpabuf *buf);
const u8 * wpa_sm_get_anonce(struct wpa_sm *sm);
unsigned int wpa_sm_get_key_mgmt(struct wpa_sm *sm);
struct wpabuf * fils_build_auth(struct wpa_sm *sm, int dh_group, const u8 *md);
int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,

View file

@ -151,6 +151,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
struct rsn_ftie *ftie;
struct rsn_ie_hdr *rsnie;
u16 capab;
int mdie_len;
sm->ft_completed = 0;
sm->ft_reassoc_completed = 0;
@ -247,14 +248,13 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
rsnie->len = (pos - (u8 *) rsnie) - 2;
/* MDIE */
*pos++ = WLAN_EID_MOBILITY_DOMAIN;
*pos++ = sizeof(*mdie);
mdie = (struct rsn_mdie *) pos;
pos += sizeof(*mdie);
os_memcpy(mdie->mobility_domain, sm->mobility_domain,
MOBILITY_DOMAIN_ID_LEN);
mdie->ft_capab = ap_mdie && ap_mdie[1] >= 3 ? ap_mdie[4] :
sm->mdie_ft_capab;
mdie_len = wpa_ft_add_mdie(sm, pos, buf_len - (pos - buf), ap_mdie);
if (mdie_len <= 0) {
os_free(buf);
return NULL;
}
mdie = (struct rsn_mdie *) (pos + 2);
pos += mdie_len;
/* FTIE[SNonce, [R1KH-ID,] R0KH-ID ] */
ftie_pos = pos;
@ -373,6 +373,37 @@ int wpa_ft_prepare_auth_request(struct wpa_sm *sm, const u8 *mdie)
}
int wpa_ft_add_mdie(struct wpa_sm *sm, u8 *buf, size_t buf_len,
const u8 *ap_mdie)
{
u8 *pos = buf;
struct rsn_mdie *mdie;
if (buf_len < 2 + sizeof(*mdie)) {
wpa_printf(MSG_INFO,
"FT: Failed to add MDIE: short buffer, length=%zu",
buf_len);
return 0;
}
*pos++ = WLAN_EID_MOBILITY_DOMAIN;
*pos++ = sizeof(*mdie);
mdie = (struct rsn_mdie *) pos;
os_memcpy(mdie->mobility_domain, sm->mobility_domain,
MOBILITY_DOMAIN_ID_LEN);
mdie->ft_capab = ap_mdie && ap_mdie[1] >= 3 ? ap_mdie[4] :
sm->mdie_ft_capab;
return 2 + sizeof(*mdie);
}
const u8 * wpa_sm_get_ft_md(struct wpa_sm *sm)
{
return sm->mobility_domain;
}
int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
int ft_action, const u8 *target_ap,
const u8 *ric_ies, size_t ric_ies_len)

View file

@ -2716,6 +2716,29 @@ static u8 * wpas_populate_assoc_ies(
}
#endif /* CONFIG_OWE */
#ifdef CONFIG_IEEE80211R
/*
* Add MDIE under these conditions: the network profile allows FT,
* the AP supports FT, and the mobility domain ID matches.
*/
if (wpa_key_mgmt_ft(wpa_sm_get_key_mgmt(wpa_s->wpa))) {
const u8 *mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
if (mdie && mdie[1] >= MOBILITY_DOMAIN_ID_LEN) {
const u8 *md = mdie + 2;
const u8 *wpa_md = wpa_sm_get_ft_md(wpa_s->wpa);
if (os_memcmp(md, wpa_md,
MOBILITY_DOMAIN_ID_LEN) == 0) {
/* Add mobility domain IE */
wpa_ie_len += wpa_ft_add_mdie(
wpa_s->wpa, wpa_ie + wpa_ie_len,
max_wpa_ie_len - wpa_ie_len, mdie);
}
}
}
#endif /* CONFIG_IEEE80211R */
params->wpa_ie = wpa_ie;
params->wpa_ie_len = wpa_ie_len;
params->auth_alg = algs;