mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-20 02:32:36 +01:00
eapol: Only send EAPOL-Start on step 1/4 if really needed
Currently we'd send EAPOL-Start whenever EAP was configured and we received an EAPOL-Key before EAP negotiation. Instead only do that if we know we can't respond to the 4-Way handshake because we don't have a PMK yet or the PMKID doesn't match. Require a PMKID in step 1/4 if we'd sent a list of PMKIDs in our RSNE.
This commit is contained in:
parent
f53cb22b7e
commit
48966f57e8
66
src/eapol.c
66
src/eapol.c
@ -843,10 +843,57 @@ static void eapol_handle_ptk_1_of_4(struct eapol_sm *sm,
|
||||
uint8_t *ies;
|
||||
size_t ies_len;
|
||||
const uint8_t *own_ie = sm->handshake->own_ie;
|
||||
const uint8_t *pmkid;
|
||||
struct ie_rsn_info rsn_info;
|
||||
|
||||
if (!eapol_verify_ptk_1_of_4(ek))
|
||||
goto error_unspecified;
|
||||
|
||||
pmkid = handshake_util_find_pmkid_kde(ek->key_data,
|
||||
L_BE16_TO_CPU(ek->key_data_len));
|
||||
|
||||
/*
|
||||
* Require the PMKID KDE whenever we've sent a list of PMKIDs in
|
||||
* our RSNE, otherwise treat it as optional and only validate it
|
||||
* against our PMK. Some 802.11-2012 sections show message 1/4
|
||||
* without a PMKID KDE and there are APs that send no PMKID KDE.
|
||||
*/
|
||||
if (!sm->handshake->wpa_ie &&
|
||||
ie_parse_rsne_from_data(own_ie, own_ie[1] + 2,
|
||||
&rsn_info) >= 0 &&
|
||||
rsn_info.num_pmkids) {
|
||||
bool found = false;
|
||||
int i;
|
||||
|
||||
if (!pmkid)
|
||||
goto error_unspecified;
|
||||
|
||||
for (i = 0; i < rsn_info.num_pmkids; i++)
|
||||
if (!memcmp(rsn_info.pmkids + i * 16, pmkid, 16)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
goto error_unspecified;
|
||||
} else if (pmkid) {
|
||||
uint8_t own_pmkid[16];
|
||||
|
||||
if (handshake_state_get_pmkid(sm->handshake, own_pmkid) &&
|
||||
memcmp(pmkid, own_pmkid, 16)) {
|
||||
/*
|
||||
* If the AP has a different PMKSA from ours and we
|
||||
* have means to create a new PMKSA through EAP then
|
||||
* try that, otherwise give up.
|
||||
*/
|
||||
if (sm->eap) {
|
||||
send_eapol_start(NULL, sm);
|
||||
return;
|
||||
} else
|
||||
goto error_unspecified;
|
||||
}
|
||||
}
|
||||
|
||||
handshake_state_new_snonce(sm->handshake);
|
||||
|
||||
handshake_state_set_anonce(sm->handshake, ek->key_nonce);
|
||||
@ -858,7 +905,6 @@ static void eapol_handle_ptk_1_of_4(struct eapol_sm *sm,
|
||||
(IE_RSN_AKM_SUITE_FT_OVER_8021X |
|
||||
IE_RSN_AKM_SUITE_FT_USING_PSK |
|
||||
IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256)) {
|
||||
struct ie_rsn_info rsn_info;
|
||||
const uint8_t *mde = sm->handshake->mde;
|
||||
const uint8_t *fte = sm->handshake->fte;
|
||||
|
||||
@ -868,10 +914,6 @@ static void eapol_handle_ptk_1_of_4(struct eapol_sm *sm,
|
||||
*/
|
||||
ies = alloca(512);
|
||||
|
||||
if (ie_parse_rsne_from_data(own_ie, own_ie[1] + 2,
|
||||
&rsn_info) < 0)
|
||||
goto error_unspecified;
|
||||
|
||||
rsn_info.num_pmkids = 1;
|
||||
rsn_info.pmkids = sm->handshake->pmk_r1_name;
|
||||
|
||||
@ -1533,6 +1575,12 @@ static void eapol_rx_packet(struct eapol_sm *sm,
|
||||
if (!sm->protocol_version)
|
||||
sm->protocol_version = eh->protocol_version;
|
||||
|
||||
/* Only EAPOL-EAP packets allowed in preauthentication */
|
||||
if (sm->preauth && eh->packet_type != 0) {
|
||||
handshake_failed(sm, MPDU_REASON_CODE_UNSPECIFIED);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (eh->packet_type) {
|
||||
case 0: /* EAPOL-EAP */
|
||||
l_timeout_remove(sm->eapol_start_timeout);
|
||||
@ -1556,7 +1604,10 @@ static void eapol_rx_packet(struct eapol_sm *sm,
|
||||
break;
|
||||
|
||||
case 3: /* EAPOL-Key */
|
||||
if (sm->eap) {
|
||||
if (!sm->handshake->have_pmk) {
|
||||
if (!sm->eap)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Either this is an error (EAP negotiation in
|
||||
* progress) or the server is giving us a chance to
|
||||
@ -1569,9 +1620,6 @@ static void eapol_rx_packet(struct eapol_sm *sm,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sm->handshake->have_pmk)
|
||||
return;
|
||||
|
||||
eapol_key_handle(sm, frame, len);
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user