FT: Simplify FTE parsing for FT-SAE-EXT-KEY using MIC Length subfield
Commit 25b52e5f83
("FT: Extend FTE parsing for FT-SAE-EXT-KEY") used
possible MIC length iteration to try to figure out the length of the MIC
field in FTE. That was the only option available at the time, but FTE is
now being extended in IEEE 802.11-REVme to explicitly indicate the
length of the MIC field for the new FT-SAE-EXT-KEY AKM to make this
easier.
Use the new design from the approved comment resolution (*) in
REVme/D2.0 ballot CID 3135 to simplify implementation. This gets rid of
the need to pass in key length and the somewhat strange need_{r0kh,r1kh}
parameters to wpa_ft_parse_ies().
(*)
https://mentor.ieee.org/802.11/dcn/22/11-22-1991-02-000m-proposed-resolutions-to-some-lb270-comments.docx
Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
bb171f0020
commit
40a42613e6
6 changed files with 75 additions and 81 deletions
|
@ -814,6 +814,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int key_mgmt, size_t key_len,
|
|||
{
|
||||
u8 *pos = buf, *ielen;
|
||||
size_t hdrlen;
|
||||
u16 mic_control = rsnxe_used ? FTE_MIC_CTRL_RSNXE_USED : 0;
|
||||
|
||||
if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
|
||||
key_len == SHA256_MAC_LEN)
|
||||
|
@ -842,7 +843,8 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int key_mgmt, size_t key_len,
|
|||
|
||||
os_memset(hdr, 0, sizeof(*hdr));
|
||||
pos += sizeof(*hdr);
|
||||
WPA_PUT_LE16(hdr->mic_control, !!rsnxe_used);
|
||||
mic_control |= FTE_MIC_LEN_32 << FTE_MIC_CTRL_MIC_LEN_SHIFT;
|
||||
WPA_PUT_LE16(hdr->mic_control, mic_control);
|
||||
if (anonce)
|
||||
os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
|
||||
if (snonce)
|
||||
|
@ -854,7 +856,8 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int key_mgmt, size_t key_len,
|
|||
|
||||
os_memset(hdr, 0, sizeof(*hdr));
|
||||
pos += sizeof(*hdr);
|
||||
WPA_PUT_LE16(hdr->mic_control, !!rsnxe_used);
|
||||
mic_control |= FTE_MIC_LEN_24 << FTE_MIC_CTRL_MIC_LEN_SHIFT;
|
||||
WPA_PUT_LE16(hdr->mic_control, mic_control);
|
||||
if (anonce)
|
||||
os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
|
||||
if (snonce)
|
||||
|
@ -864,7 +867,8 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int key_mgmt, size_t key_len,
|
|||
|
||||
os_memset(hdr, 0, sizeof(*hdr));
|
||||
pos += sizeof(*hdr);
|
||||
WPA_PUT_LE16(hdr->mic_control, !!rsnxe_used);
|
||||
mic_control |= FTE_MIC_LEN_16 << FTE_MIC_CTRL_MIC_LEN_SHIFT;
|
||||
WPA_PUT_LE16(hdr->mic_control, mic_control);
|
||||
if (anonce)
|
||||
os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
|
||||
if (snonce)
|
||||
|
@ -2788,8 +2792,8 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
|
|||
*elem_count = 3; /* Information element count */
|
||||
|
||||
ric_start = pos;
|
||||
if (wpa_ft_parse_ies(req_ies, req_ies_len, &parse, sm->wpa_key_mgmt,
|
||||
key_len, false, false) == 0 && parse.ric) {
|
||||
if (wpa_ft_parse_ies(req_ies, req_ies_len, &parse,
|
||||
sm->wpa_key_mgmt) == 0 && parse.ric) {
|
||||
pos = wpa_ft_process_ric(sm, pos, end, parse.ric,
|
||||
parse.ric_len);
|
||||
if (auth_alg == WLAN_AUTH_FT)
|
||||
|
@ -3165,7 +3169,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
|
|||
wpa_hexdump(MSG_DEBUG, "FT: Received authentication frame IEs",
|
||||
ies, ies_len);
|
||||
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, 0, 0, false, false)) {
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, 0)) {
|
||||
wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
|
||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
}
|
||||
|
@ -3463,8 +3467,7 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
|
|||
|
||||
wpa_hexdump(MSG_DEBUG, "FT: Reassoc Req IEs", ies, ies_len);
|
||||
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, sm->wpa_key_mgmt,
|
||||
sm->pmk_r1_len, true, true) < 0) {
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, sm->wpa_key_mgmt) < 0) {
|
||||
wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
|
||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
}
|
||||
|
|
|
@ -1090,19 +1090,46 @@ static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
|
|||
}
|
||||
|
||||
|
||||
static int wpa_ft_parse_fte(const u8 *ie, size_t len, size_t mic_len,
|
||||
static int wpa_ft_parse_fte(int key_mgmt, const u8 *ie, size_t len,
|
||||
struct wpa_ft_ies *parse)
|
||||
{
|
||||
size_t mic_len;
|
||||
u8 mic_len_info;
|
||||
const u8 *pos = ie;
|
||||
const u8 *end = pos + len;
|
||||
|
||||
wpa_hexdump(MSG_DEBUG, "FT: FTE-MIC Control", pos, 2);
|
||||
parse->fte_rsnxe_used = pos[0] & 0x01;
|
||||
parse->fte_rsnxe_used = pos[0] & FTE_MIC_CTRL_RSNXE_USED;
|
||||
mic_len_info = (pos[0] & FTE_MIC_CTRL_MIC_LEN_MASK) >>
|
||||
FTE_MIC_CTRL_MIC_LEN_SHIFT;
|
||||
parse->fte_elem_count = pos[1];
|
||||
pos += 2;
|
||||
|
||||
if (mic_len > (size_t) (end - pos))
|
||||
if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
|
||||
switch (mic_len_info) {
|
||||
case FTE_MIC_LEN_16:
|
||||
mic_len = 16;
|
||||
break;
|
||||
case FTE_MIC_LEN_24:
|
||||
mic_len = 24;
|
||||
break;
|
||||
case FTE_MIC_LEN_32:
|
||||
mic_len = 32;
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"FT: Unknown MIC Length subfield value %u",
|
||||
mic_len_info);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
mic_len = wpa_key_mgmt_sha384(key_mgmt) ? 24 : 16;
|
||||
}
|
||||
if (mic_len > (size_t) (end - pos)) {
|
||||
wpa_printf(MSG_DEBUG, "FT: No room for %zu octet MIC in FTE",
|
||||
mic_len);
|
||||
return -1;
|
||||
}
|
||||
wpa_hexdump(MSG_DEBUG, "FT: FTE-MIC", pos, mic_len);
|
||||
parse->fte_mic = pos;
|
||||
parse->fte_mic_len = mic_len;
|
||||
|
@ -1124,8 +1151,7 @@ static int wpa_ft_parse_fte(const u8 *ie, size_t len, size_t mic_len,
|
|||
|
||||
|
||||
int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
|
||||
int key_mgmt, size_t key_len, bool need_r0kh_id,
|
||||
bool need_r1kh_id)
|
||||
int key_mgmt)
|
||||
{
|
||||
const u8 *end, *pos;
|
||||
struct wpa_ie_data data;
|
||||
|
@ -1195,49 +1221,7 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
|
|||
prot_ie_count = pos[1]; /* Element Count field in
|
||||
* MIC Control */
|
||||
|
||||
if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
|
||||
(key_len == SHA512_MAC_LEN || !key_len)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"FT: Trying to parse FTE for FT-SAE-EXT-KEY - SHA512");
|
||||
if (wpa_ft_parse_fte(pos, len, 32, parse) ==
|
||||
0 &&
|
||||
(!need_r0kh_id || parse->r0kh_id) &&
|
||||
(!need_r1kh_id || parse->r1kh_id))
|
||||
break;
|
||||
}
|
||||
if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
|
||||
(key_len == SHA384_MAC_LEN || !key_len)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"FT: Trying to parse FTE for FT-SAE-EXT-KEY - SHA384");
|
||||
if (wpa_ft_parse_fte(pos, len, 24, parse) ==
|
||||
0 &&
|
||||
(!need_r0kh_id || parse->r0kh_id) &&
|
||||
(!need_r1kh_id || parse->r1kh_id))
|
||||
break;
|
||||
}
|
||||
if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
|
||||
(key_len == SHA256_MAC_LEN || !key_len)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"FT: Trying to parse FTE for FT-SAE-EXT-KEY - SHA256");
|
||||
if (wpa_ft_parse_fte(pos, len, 16, parse) ==
|
||||
0 &&
|
||||
(!need_r0kh_id || parse->r0kh_id) &&
|
||||
(!need_r1kh_id || parse->r1kh_id))
|
||||
break;
|
||||
}
|
||||
if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"FT: Failed to parse FTE for FT-SAE-EXT-KEY");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wpa_key_mgmt_sha384(key_mgmt)) {
|
||||
if (wpa_ft_parse_fte(pos, len, 24, parse) < 0)
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (wpa_ft_parse_fte(pos, len, 16, parse) < 0)
|
||||
if (wpa_ft_parse_fte(key_mgmt, pos, len, parse) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case WLAN_EID_TIMEOUT_INTERVAL:
|
||||
|
|
|
@ -186,6 +186,18 @@ WPA_CIPHER_BIP_CMAC_256)
|
|||
#define FT_R1KH_ID_LEN 6
|
||||
#define WPA_PMK_NAME_LEN 16
|
||||
|
||||
/* FTE - MIC Control - RSNXE Used */
|
||||
#define FTE_MIC_CTRL_RSNXE_USED BIT(0)
|
||||
#define FTE_MIC_CTRL_MIC_LEN_MASK (BIT(1) | BIT(2) | BIT(3))
|
||||
#define FTE_MIC_CTRL_MIC_LEN_SHIFT 1
|
||||
|
||||
/* FTE - MIC Length subfield values */
|
||||
enum ft_mic_len_subfield {
|
||||
FTE_MIC_LEN_16 = 0,
|
||||
FTE_MIC_LEN_24 = 1,
|
||||
FTE_MIC_LEN_32 = 2,
|
||||
};
|
||||
|
||||
|
||||
/* IEEE 802.11, 8.5.2 EAPOL-Key frames */
|
||||
#define WPA_KEY_INFO_TYPE_MASK ((u16) (BIT(0) | BIT(1) | BIT(2)))
|
||||
|
@ -612,8 +624,7 @@ struct wpa_pasn_params_data {
|
|||
#define WPA_PASN_PUBKEY_UNCOMPRESSED 0x04
|
||||
|
||||
int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
|
||||
int key_mgmt, size_t key_len, bool need_r0kh_id,
|
||||
bool need_r1kh_id);
|
||||
int key_mgmt);
|
||||
|
||||
struct wpa_eapol_ie_parse {
|
||||
const u8 *wpa_ie;
|
||||
|
|
|
@ -5196,8 +5196,7 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
|
|||
}
|
||||
|
||||
if (wpa_ft_parse_ies(pos, end - pos, &parse,
|
||||
sm->key_mgmt, sm->xxkey_len, true,
|
||||
true) < 0) {
|
||||
sm->key_mgmt) < 0) {
|
||||
wpa_printf(MSG_DEBUG, "FILS+FT: Failed to parse IEs");
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -127,8 +127,7 @@ int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &ft, sm->key_mgmt,
|
||||
sm->xxkey_len, false, false) < 0)
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &ft, sm->key_mgmt) < 0)
|
||||
return -1;
|
||||
|
||||
if (ft.mdie_len < MOBILITY_DOMAIN_ID_LEN + 1)
|
||||
|
@ -217,6 +216,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
|
|||
size_t rsnxe_len;
|
||||
int rsnxe_used;
|
||||
int res;
|
||||
u8 mic_control;
|
||||
|
||||
sm->ft_completed = 0;
|
||||
sm->ft_reassoc_completed = 0;
|
||||
|
@ -348,12 +348,14 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
|
|||
rsnxe_used);
|
||||
}
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
mic_control = rsnxe_used ? FTE_MIC_CTRL_RSNXE_USED : 0;
|
||||
if (sm->key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
|
||||
sm->pmk_r0_len == SHA512_MAC_LEN) {
|
||||
struct rsn_ftie_sha512 *ftie;
|
||||
|
||||
ftie = (struct rsn_ftie_sha512 *) pos;
|
||||
ftie->mic_control[0] = !!rsnxe_used;
|
||||
mic_control |= FTE_MIC_LEN_32 << FTE_MIC_CTRL_MIC_LEN_SHIFT;
|
||||
ftie->mic_control[0] = mic_control;
|
||||
fte_mic = ftie->mic;
|
||||
elem_count = &ftie->mic_control[1];
|
||||
pos += sizeof(*ftie);
|
||||
|
@ -366,7 +368,8 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
|
|||
struct rsn_ftie_sha384 *ftie;
|
||||
|
||||
ftie = (struct rsn_ftie_sha384 *) pos;
|
||||
ftie->mic_control[0] = !!rsnxe_used;
|
||||
mic_control |= FTE_MIC_LEN_24 << FTE_MIC_CTRL_MIC_LEN_SHIFT;
|
||||
ftie->mic_control[0] = mic_control;
|
||||
fte_mic = ftie->mic;
|
||||
elem_count = &ftie->mic_control[1];
|
||||
pos += sizeof(*ftie);
|
||||
|
@ -377,7 +380,8 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
|
|||
struct rsn_ftie *ftie;
|
||||
|
||||
ftie = (struct rsn_ftie *) pos;
|
||||
ftie->mic_control[0] = !!rsnxe_used;
|
||||
mic_control |= FTE_MIC_LEN_16 << FTE_MIC_CTRL_MIC_LEN_SHIFT;
|
||||
ftie->mic_control[0] = mic_control;
|
||||
fte_mic = ftie->mic;
|
||||
elem_count = &ftie->mic_control[1];
|
||||
pos += sizeof(*ftie);
|
||||
|
@ -584,7 +588,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
|
|||
int ret;
|
||||
const u8 *bssid;
|
||||
const u8 *kck;
|
||||
size_t kck_len, kdk_len, key_len;
|
||||
size_t kck_len, kdk_len;
|
||||
|
||||
wpa_hexdump(MSG_DEBUG, "FT: Response IEs", ies, ies_len);
|
||||
wpa_hexdump(MSG_DEBUG, "FT: RIC IEs", ric_ies, ric_ies_len);
|
||||
|
@ -610,11 +614,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
|
|||
return -1;
|
||||
}
|
||||
|
||||
key_len = sm->xxkey_len;
|
||||
if (!key_len)
|
||||
key_len = sm->pmk_r1_len;
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, sm->key_mgmt,
|
||||
key_len, true, false) < 0) {
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, sm->key_mgmt) < 0) {
|
||||
wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs");
|
||||
return -1;
|
||||
}
|
||||
|
@ -1032,8 +1032,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, sm->key_mgmt,
|
||||
sm->xxkey_len, true, true) < 0) {
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, sm->key_mgmt) < 0) {
|
||||
wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -250,7 +250,7 @@ static void process_ft_auth(struct wlantest *wt, struct wlantest_bss *bss,
|
|||
|
||||
if (wpa_ft_parse_ies(mgmt->u.auth.variable,
|
||||
len - IEEE80211_HDRLEN - sizeof(mgmt->u.auth),
|
||||
&parse, 0, 0, false, false)) {
|
||||
&parse, 0)) {
|
||||
add_note(wt, MSG_INFO,
|
||||
"Could not parse FT Authentication Response frame");
|
||||
return;
|
||||
|
@ -829,7 +829,7 @@ static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
|
|||
sta->state = STATE3;
|
||||
}
|
||||
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, 0, 0, false, false) == 0) {
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, 0) == 0) {
|
||||
if (parse.r0kh_id) {
|
||||
os_memcpy(bss->r0kh_id, parse.r0kh_id,
|
||||
parse.r0kh_id_len);
|
||||
|
@ -925,8 +925,7 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data,
|
|||
|
||||
use_sha384 = wpa_key_mgmt_sha384(sta->key_mgmt);
|
||||
|
||||
if (wpa_ft_parse_ies(ie, ie_len, &parse, sta->key_mgmt,
|
||||
0, false, false) < 0) {
|
||||
if (wpa_ft_parse_ies(ie, ie_len, &parse, sta->key_mgmt) < 0) {
|
||||
add_note(wt, MSG_INFO, "FT: Failed to parse FT IEs");
|
||||
return;
|
||||
}
|
||||
|
@ -1419,8 +1418,7 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
|
|||
|
||||
use_sha384 = wpa_key_mgmt_sha384(sta->key_mgmt);
|
||||
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, sta->key_mgmt,
|
||||
0, false, false) < 0) {
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, sta->key_mgmt) < 0) {
|
||||
add_note(wt, MSG_INFO, "FT: Failed to parse FT IEs");
|
||||
return;
|
||||
}
|
||||
|
@ -1730,7 +1728,7 @@ static void rx_mgmt_action_ft_request(struct wlantest *wt,
|
|||
ies_len = len - (24 + 2 + 2 * ETH_ALEN);
|
||||
wpa_hexdump(MSG_DEBUG, "FT Request frame body", ies, ies_len);
|
||||
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, 0, 0, false, false)) {
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, 0)) {
|
||||
add_note(wt, MSG_INFO, "Could not parse FT Request frame body");
|
||||
return;
|
||||
}
|
||||
|
@ -1779,7 +1777,7 @@ static void rx_mgmt_action_ft_response(struct wlantest *wt,
|
|||
ies_len = len - (24 + 2 + 2 * ETH_ALEN);
|
||||
wpa_hexdump(MSG_DEBUG, "FT Response frame body", ies, ies_len);
|
||||
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, 0, 0, false, false)) {
|
||||
if (wpa_ft_parse_ies(ies, ies_len, &parse, 0)) {
|
||||
add_note(wt, MSG_INFO,
|
||||
"Could not parse FT Response frame body");
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue