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>
master
Jouni Malinen 6 years ago
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))) {
/* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
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));
if (res < 0) {
*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;

@ -3014,7 +3014,10 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
2 + sm->assoc_resp_ftie[1]);
res = 2 + sm->assoc_resp_ftie[1];
} 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,
NULL, NULL, 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
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;
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,
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]);
res = 2 + sm->assoc_resp_ftie[1];
} 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,
NULL, NULL, 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,
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,
u8 *fils_anonce, u8 *fils_snonce,
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,
size_t r0kh_id_len,
int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
const u8 *r0kh_id, size_t r0kh_id_len,
const u8 *anonce, const u8 *snonce,
u8 *buf, size_t len, const u8 *subelem,
size_t subelem_len)
{
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)
return -1;
*pos++ = WLAN_EID_FAST_BSS_TRANSITION;
ielen = pos++;
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);
if (use_sha384) {
struct rsn_ftie_sha384 *hdr = (struct rsn_ftie_sha384 *) 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);
} 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 */
*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)
{
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;
int res;
struct wpa_auth_config *conf;
struct rsn_ftie *_ftie;
struct wpa_ft_ies parse;
u8 *ric_start;
u8 *anonce, *snonce;
@ -2386,8 +2400,9 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
anonce = NULL;
snonce = NULL;
}
res = wpa_write_ftie(conf, r0kh_id, r0kh_id_len, anonce, snonce, pos,
end - pos, subelem, subelem_len);
res = wpa_write_ftie(conf, use_sha384, r0kh_id, r0kh_id_len,
anonce, snonce, pos, end - pos,
subelem, subelem_len);
os_free(subelem);
if (res < 0)
return pos;
@ -2395,9 +2410,20 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
ftie_len = 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)
_ftie->mic_control[1] = 3; /* Information element count */
*elem_count = 3; /* Information element count */
ric_start = pos;
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,
parse.ric_len);
if (auth_alg == WLAN_AUTH_FT)
_ftie->mic_control[1] +=
*elem_count +=
ieee802_11_ie_count(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,
rsnie, rsnie_len,
ric_start, ric_start ? pos - ric_start : 0,
_ftie->mic) < 0)
fte_mic) < 0)
wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
os_free(sm->assoc_resp_ftie);
@ -2871,7 +2897,7 @@ pmk_r1_derived:
goto fail;
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);
if (ret < 0)
goto fail;

@ -277,8 +277,8 @@ int wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth,
#ifdef CONFIG_IEEE80211R_AP
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,
size_t r0kh_id_len,
int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
const u8 *r0kh_id, size_t r0kh_id_len,
const u8 *anonce, const u8 *snonce,
u8 *buf, size_t len, const u8 *subelem,
size_t subelem_len);

Loading…
Cancel
Save