mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-01-31 09:14:03 -05:00
FT: FTE generation for SHA384-based AKM on AP
The MIC field is now a variable length field, so make FTE generation in hostapd aware of the two different field lengths. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
06f1286607
commit
a7968ea568
@ -1446,8 +1446,11 @@ prepare_auth_resp_fils(struct hostapd_data *hapd,
|
|||||||
if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta->wpa_sm))) {
|
if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta->wpa_sm))) {
|
||||||
/* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
|
/* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
|
||||||
int res;
|
int res;
|
||||||
|
int use_sha384 = wpa_key_mgmt_sha384(
|
||||||
|
wpa_auth_sta_key_mgmt(sta->wpa_sm));
|
||||||
|
|
||||||
res = wpa_auth_write_fte(hapd->wpa_auth, wpabuf_put(data, 0),
|
res = wpa_auth_write_fte(hapd->wpa_auth, use_sha384,
|
||||||
|
wpabuf_put(data, 0),
|
||||||
wpabuf_tailroom(data));
|
wpabuf_tailroom(data));
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
@ -3014,7 +3014,10 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
|
|||||||
2 + sm->assoc_resp_ftie[1]);
|
2 + sm->assoc_resp_ftie[1]);
|
||||||
res = 2 + sm->assoc_resp_ftie[1];
|
res = 2 + sm->assoc_resp_ftie[1];
|
||||||
} else {
|
} else {
|
||||||
res = wpa_write_ftie(conf, conf->r0_key_holder,
|
int use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt);
|
||||||
|
|
||||||
|
res = wpa_write_ftie(conf, use_sha384,
|
||||||
|
conf->r0_key_holder,
|
||||||
conf->r0_key_holder_len,
|
conf->r0_key_holder_len,
|
||||||
NULL, NULL, pos,
|
NULL, NULL, pos,
|
||||||
kde + kde_len - pos,
|
kde + kde_len - pos,
|
||||||
@ -4540,11 +4543,12 @@ wpa_auth_pmksa_get_fils_cache_id(struct wpa_authenticator *wpa_auth,
|
|||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211R_AP
|
#ifdef CONFIG_IEEE80211R_AP
|
||||||
int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, u8 *buf, size_t len)
|
int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, int use_sha384,
|
||||||
|
u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct wpa_auth_config *conf = &wpa_auth->conf;
|
struct wpa_auth_config *conf = &wpa_auth->conf;
|
||||||
|
|
||||||
return wpa_write_ftie(conf, 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);
|
||||||
}
|
}
|
||||||
@ -4714,7 +4718,10 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
|
|||||||
2 + sm->assoc_resp_ftie[1]);
|
2 + sm->assoc_resp_ftie[1]);
|
||||||
res = 2 + sm->assoc_resp_ftie[1];
|
res = 2 + sm->assoc_resp_ftie[1];
|
||||||
} else {
|
} else {
|
||||||
res = wpa_write_ftie(conf, conf->r0_key_holder,
|
int use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt);
|
||||||
|
|
||||||
|
res = wpa_write_ftie(conf, use_sha384,
|
||||||
|
conf->r0_key_holder,
|
||||||
conf->r0_key_holder_len,
|
conf->r0_key_holder_len,
|
||||||
NULL, NULL, pos,
|
NULL, NULL, pos,
|
||||||
kde + kde_len - pos,
|
kde + kde_len - pos,
|
||||||
|
@ -449,7 +449,8 @@ const u8 * wpa_fils_validate_fils_session(struct wpa_state_machine *sm,
|
|||||||
int wpa_fils_validate_key_confirm(struct wpa_state_machine *sm, const u8 *ies,
|
int wpa_fils_validate_key_confirm(struct wpa_state_machine *sm, const u8 *ies,
|
||||||
size_t ies_len);
|
size_t ies_len);
|
||||||
|
|
||||||
int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, u8 *buf, size_t len);
|
int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, int use_sha384,
|
||||||
|
u8 *buf, size_t len);
|
||||||
void wpa_auth_get_fils_aead_params(struct wpa_state_machine *sm,
|
void wpa_auth_get_fils_aead_params(struct wpa_state_machine *sm,
|
||||||
u8 *fils_anonce, u8 *fils_snonce,
|
u8 *fils_anonce, u8 *fils_snonce,
|
||||||
u8 *fils_kek, size_t *fils_kek_len);
|
u8 *fils_kek, size_t *fils_kek_len);
|
||||||
|
@ -746,30 +746,44 @@ int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id,
|
int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
|
||||||
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)
|
||||||
{
|
{
|
||||||
u8 *pos = buf, *ielen;
|
u8 *pos = buf, *ielen;
|
||||||
struct rsn_ftie *hdr;
|
size_t hdrlen = use_sha384 ? sizeof(struct rsn_ftie_sha384) :
|
||||||
|
sizeof(struct rsn_ftie);
|
||||||
|
|
||||||
if (len < 2 + sizeof(*hdr) + 2 + FT_R1KH_ID_LEN + 2 + r0kh_id_len +
|
if (len < 2 + hdrlen + 2 + FT_R1KH_ID_LEN + 2 + r0kh_id_len +
|
||||||
subelem_len)
|
subelem_len)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
*pos++ = WLAN_EID_FAST_BSS_TRANSITION;
|
*pos++ = WLAN_EID_FAST_BSS_TRANSITION;
|
||||||
ielen = pos++;
|
ielen = pos++;
|
||||||
|
|
||||||
hdr = (struct rsn_ftie *) pos;
|
if (use_sha384) {
|
||||||
os_memset(hdr, 0, sizeof(*hdr));
|
struct rsn_ftie_sha384 *hdr = (struct rsn_ftie_sha384 *) pos;
|
||||||
pos += sizeof(*hdr);
|
|
||||||
WPA_PUT_LE16(hdr->mic_control, 0);
|
os_memset(hdr, 0, sizeof(*hdr));
|
||||||
if (anonce)
|
pos += sizeof(*hdr);
|
||||||
os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
|
WPA_PUT_LE16(hdr->mic_control, 0);
|
||||||
if (snonce)
|
if (anonce)
|
||||||
os_memcpy(hdr->snonce, snonce, WPA_NONCE_LEN);
|
os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
|
||||||
|
if (snonce)
|
||||||
|
os_memcpy(hdr->snonce, snonce, WPA_NONCE_LEN);
|
||||||
|
} else {
|
||||||
|
struct rsn_ftie *hdr = (struct rsn_ftie *) pos;
|
||||||
|
|
||||||
|
os_memset(hdr, 0, sizeof(*hdr));
|
||||||
|
pos += sizeof(*hdr);
|
||||||
|
WPA_PUT_LE16(hdr->mic_control, 0);
|
||||||
|
if (anonce)
|
||||||
|
os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
|
||||||
|
if (snonce)
|
||||||
|
os_memcpy(hdr->snonce, snonce, WPA_NONCE_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
/* Optional Parameters */
|
/* Optional Parameters */
|
||||||
*pos++ = FTIE_SUBELEM_R1KH_ID;
|
*pos++ = FTIE_SUBELEM_R1KH_ID;
|
||||||
@ -2308,10 +2322,10 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
|
|||||||
const u8 *req_ies, size_t req_ies_len)
|
const u8 *req_ies, size_t req_ies_len)
|
||||||
{
|
{
|
||||||
u8 *end, *mdie, *ftie, *rsnie = NULL, *r0kh_id, *subelem = NULL;
|
u8 *end, *mdie, *ftie, *rsnie = NULL, *r0kh_id, *subelem = NULL;
|
||||||
|
u8 *fte_mic, *elem_count;
|
||||||
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;
|
||||||
int res;
|
int res;
|
||||||
struct wpa_auth_config *conf;
|
struct wpa_auth_config *conf;
|
||||||
struct rsn_ftie *_ftie;
|
|
||||||
struct wpa_ft_ies parse;
|
struct wpa_ft_ies parse;
|
||||||
u8 *ric_start;
|
u8 *ric_start;
|
||||||
u8 *anonce, *snonce;
|
u8 *anonce, *snonce;
|
||||||
@ -2386,8 +2400,9 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
|
|||||||
anonce = NULL;
|
anonce = NULL;
|
||||||
snonce = NULL;
|
snonce = NULL;
|
||||||
}
|
}
|
||||||
res = wpa_write_ftie(conf, r0kh_id, r0kh_id_len, anonce, snonce, pos,
|
res = wpa_write_ftie(conf, use_sha384, r0kh_id, r0kh_id_len,
|
||||||
end - pos, subelem, subelem_len);
|
anonce, snonce, pos, end - pos,
|
||||||
|
subelem, subelem_len);
|
||||||
os_free(subelem);
|
os_free(subelem);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return pos;
|
return pos;
|
||||||
@ -2395,9 +2410,20 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
|
|||||||
ftie_len = res;
|
ftie_len = res;
|
||||||
pos += res;
|
pos += res;
|
||||||
|
|
||||||
_ftie = (struct rsn_ftie *) (ftie + 2);
|
if (use_sha384) {
|
||||||
|
struct rsn_ftie_sha384 *_ftie =
|
||||||
|
(struct rsn_ftie_sha384 *) (ftie + 2);
|
||||||
|
|
||||||
|
fte_mic = _ftie->mic;
|
||||||
|
elem_count = &_ftie->mic_control[1];
|
||||||
|
} else {
|
||||||
|
struct rsn_ftie *_ftie = (struct rsn_ftie *) (ftie + 2);
|
||||||
|
|
||||||
|
fte_mic = _ftie->mic;
|
||||||
|
elem_count = &_ftie->mic_control[1];
|
||||||
|
}
|
||||||
if (auth_alg == WLAN_AUTH_FT)
|
if (auth_alg == WLAN_AUTH_FT)
|
||||||
_ftie->mic_control[1] = 3; /* Information element count */
|
*elem_count = 3; /* Information element count */
|
||||||
|
|
||||||
ric_start = pos;
|
ric_start = pos;
|
||||||
if (wpa_ft_parse_ies(req_ies, req_ies_len, &parse, use_sha384) == 0
|
if (wpa_ft_parse_ies(req_ies, req_ies_len, &parse, use_sha384) == 0
|
||||||
@ -2405,7 +2431,7 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
|
|||||||
pos = wpa_ft_process_ric(sm, pos, end, parse.ric,
|
pos = wpa_ft_process_ric(sm, pos, end, parse.ric,
|
||||||
parse.ric_len);
|
parse.ric_len);
|
||||||
if (auth_alg == WLAN_AUTH_FT)
|
if (auth_alg == WLAN_AUTH_FT)
|
||||||
_ftie->mic_control[1] +=
|
*elem_count +=
|
||||||
ieee802_11_ie_count(ric_start,
|
ieee802_11_ie_count(ric_start,
|
||||||
pos - ric_start);
|
pos - ric_start);
|
||||||
}
|
}
|
||||||
@ -2424,7 +2450,7 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
|
|||||||
mdie, mdie_len, ftie, ftie_len,
|
mdie, mdie_len, ftie, ftie_len,
|
||||||
rsnie, rsnie_len,
|
rsnie, rsnie_len,
|
||||||
ric_start, ric_start ? pos - ric_start : 0,
|
ric_start, ric_start ? pos - ric_start : 0,
|
||||||
_ftie->mic) < 0)
|
fte_mic) < 0)
|
||||||
wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
|
wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
|
||||||
|
|
||||||
os_free(sm->assoc_resp_ftie);
|
os_free(sm->assoc_resp_ftie);
|
||||||
@ -2871,7 +2897,7 @@ pmk_r1_derived:
|
|||||||
goto fail;
|
goto fail;
|
||||||
pos += ret;
|
pos += ret;
|
||||||
|
|
||||||
ret = wpa_write_ftie(conf, 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);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -277,8 +277,8 @@ int wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth,
|
|||||||
|
|
||||||
#ifdef CONFIG_IEEE80211R_AP
|
#ifdef CONFIG_IEEE80211R_AP
|
||||||
int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len);
|
int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len);
|
||||||
int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id,
|
int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
|
||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user