FT: Set the new RSNXE Used subfield in FT reassociation

This is a workaround needed to keep FT protocol backwards compatible for
the cases where either the AP or the STA uses RSNXE, but the other one
does not. This commit adds setting of the new field to 1 in
Reassociation Request/Response frame during FT protocol when the STA/AP
uses RSNXE in other frames. This mechanism is described in 20/332r3.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2020-03-20 21:23:48 +02:00 committed by Jouni Malinen
parent c557720ef0
commit 51d1924bd8
4 changed files with 18 additions and 9 deletions

View file

@ -3422,7 +3422,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
conf->r0_key_holder_len, conf->r0_key_holder_len,
NULL, NULL, pos, NULL, NULL, pos,
kde + kde_len - pos, kde + kde_len - pos,
NULL, 0); NULL, 0, 0);
} }
if (res < 0) { if (res < 0) {
wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE " wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE "
@ -5087,7 +5087,7 @@ int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, int use_sha384,
return wpa_write_ftie(conf, use_sha384, conf->r0_key_holder, return wpa_write_ftie(conf, use_sha384, conf->r0_key_holder,
conf->r0_key_holder_len, conf->r0_key_holder_len,
NULL, NULL, buf, len, NULL, 0); NULL, NULL, buf, len, NULL, 0, 0);
} }
#endif /* CONFIG_IEEE80211R_AP */ #endif /* CONFIG_IEEE80211R_AP */
@ -5289,7 +5289,7 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
conf->r0_key_holder_len, conf->r0_key_holder_len,
NULL, NULL, pos, NULL, NULL, pos,
kde + kde_len - pos, kde + kde_len - pos,
NULL, 0); NULL, 0, 0);
} }
if (res < 0) { if (res < 0) {
wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE " wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE "

View file

@ -808,7 +808,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
const u8 *r0kh_id, size_t r0kh_id_len, const u8 *r0kh_id, size_t r0kh_id_len,
const u8 *anonce, const u8 *snonce, const u8 *anonce, const u8 *snonce,
u8 *buf, size_t len, const u8 *subelem, u8 *buf, size_t len, const u8 *subelem,
size_t subelem_len) size_t subelem_len, int rsnxe_used)
{ {
u8 *pos = buf, *ielen; u8 *pos = buf, *ielen;
size_t hdrlen = use_sha384 ? sizeof(struct rsn_ftie_sha384) : size_t hdrlen = use_sha384 ? sizeof(struct rsn_ftie_sha384) :
@ -826,7 +826,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
os_memset(hdr, 0, sizeof(*hdr)); os_memset(hdr, 0, sizeof(*hdr));
pos += sizeof(*hdr); pos += sizeof(*hdr);
WPA_PUT_LE16(hdr->mic_control, 0); WPA_PUT_LE16(hdr->mic_control, !!rsnxe_used);
if (anonce) if (anonce)
os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN); os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
if (snonce) if (snonce)
@ -836,7 +836,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
os_memset(hdr, 0, sizeof(*hdr)); os_memset(hdr, 0, sizeof(*hdr));
pos += sizeof(*hdr); pos += sizeof(*hdr);
WPA_PUT_LE16(hdr->mic_control, 0); WPA_PUT_LE16(hdr->mic_control, !!rsnxe_used);
if (anonce) if (anonce)
os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN); os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
if (snonce) if (snonce)
@ -2470,6 +2470,7 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
size_t mdie_len, ftie_len, rsnie_len = 0, r0kh_id_len, subelem_len = 0; size_t mdie_len, ftie_len, rsnie_len = 0, r0kh_id_len, subelem_len = 0;
u8 rsnxe_buf[10], *rsnxe = rsnxe_buf; u8 rsnxe_buf[10], *rsnxe = rsnxe_buf;
size_t rsnxe_len; size_t rsnxe_len;
int rsnxe_used;
int res; int res;
struct wpa_auth_config *conf; struct wpa_auth_config *conf;
struct wpa_ft_ies parse; struct wpa_ft_ies parse;
@ -2643,9 +2644,11 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
anonce = NULL; anonce = NULL;
snonce = NULL; snonce = NULL;
} }
rsnxe_used = (auth_alg == WLAN_AUTH_FT) &&
(conf->sae_pwe == 1 || conf->sae_pwe == 2);
res = wpa_write_ftie(conf, use_sha384, r0kh_id, r0kh_id_len, res = wpa_write_ftie(conf, use_sha384, r0kh_id, r0kh_id_len,
anonce, snonce, pos, end - pos, anonce, snonce, pos, end - pos,
subelem, subelem_len); subelem, subelem_len, rsnxe_used);
os_free(subelem); os_free(subelem);
if (res < 0) if (res < 0)
return NULL; return NULL;
@ -3166,7 +3169,8 @@ pmk_r1_derived:
pos += ret; pos += ret;
ret = wpa_write_ftie(conf, use_sha384, parse.r0kh_id, parse.r0kh_id_len, ret = wpa_write_ftie(conf, use_sha384, parse.r0kh_id, parse.r0kh_id_len,
sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0); sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0,
0);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
pos += ret; pos += ret;

View file

@ -294,7 +294,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
const u8 *r0kh_id, size_t r0kh_id_len, const u8 *r0kh_id, size_t r0kh_id_len,
const u8 *anonce, const u8 *snonce, const u8 *anonce, const u8 *snonce,
u8 *buf, size_t len, const u8 *subelem, u8 *buf, size_t len, const u8 *subelem,
size_t subelem_len); size_t subelem_len, int rsnxe_used);
int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, struct wpa_ptk *ptk); int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, struct wpa_ptk *ptk);
struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void); struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void);
void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache); void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache);

View file

@ -181,6 +181,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
int mdie_len; int mdie_len;
u8 rsnxe[10]; u8 rsnxe[10];
size_t rsnxe_len; size_t rsnxe_len;
int rsnxe_used;
int res; int res;
sm->ft_completed = 0; sm->ft_completed = 0;
@ -309,10 +310,13 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
ftie_pos = pos; ftie_pos = pos;
*pos++ = WLAN_EID_FAST_BSS_TRANSITION; *pos++ = WLAN_EID_FAST_BSS_TRANSITION;
ftie_len = pos++; ftie_len = pos++;
rsnxe_used = wpa_key_mgmt_sae(sm->key_mgmt) && anonce &&
(sm->sae_pwe == 1 || sm->sae_pwe == 2);
if (wpa_key_mgmt_sha384(sm->key_mgmt)) { if (wpa_key_mgmt_sha384(sm->key_mgmt)) {
struct rsn_ftie_sha384 *ftie; struct rsn_ftie_sha384 *ftie;
ftie = (struct rsn_ftie_sha384 *) pos; ftie = (struct rsn_ftie_sha384 *) pos;
ftie->mic_control[0] = !!rsnxe_used;
fte_mic = ftie->mic; fte_mic = ftie->mic;
elem_count = &ftie->mic_control[1]; elem_count = &ftie->mic_control[1];
pos += sizeof(*ftie); pos += sizeof(*ftie);
@ -323,6 +327,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
struct rsn_ftie *ftie; struct rsn_ftie *ftie;
ftie = (struct rsn_ftie *) pos; ftie = (struct rsn_ftie *) pos;
ftie->mic_control[0] = !!rsnxe_used;
fte_mic = ftie->mic; fte_mic = ftie->mic;
elem_count = &ftie->mic_control[1]; elem_count = &ftie->mic_control[1];
pos += sizeof(*ftie); pos += sizeof(*ftie);