mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-29 21:42:50 +01:00
eapol: Add checking that first RSNE is as expected
This commit is contained in:
parent
7f9b8117fd
commit
9760bcb5c3
106
src/eapol.c
106
src/eapol.c
@ -564,6 +564,104 @@ static const uint8_t *eapol_find_gtk_kde(const uint8_t *data, size_t data_len,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const uint8_t *eapol_find_rsne(const uint8_t *data, size_t data_len)
|
||||||
|
{
|
||||||
|
struct ie_tlv_iter iter;
|
||||||
|
|
||||||
|
ie_tlv_iter_init(&iter, data, data_len);
|
||||||
|
|
||||||
|
while (ie_tlv_iter_next(&iter)) {
|
||||||
|
if (ie_tlv_iter_get_tag(&iter) != IE_TYPE_RSN)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return ie_tlv_iter_get_data(&iter) - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function performs a match of the RSN IE obtained from the scan
|
||||||
|
* results vs the RSN IE obtained as part of the 4-way handshake. If they
|
||||||
|
* don't match, the EAPoL packet must be silently discarded.
|
||||||
|
*/
|
||||||
|
static bool eapol_ap_rsne_matches(const uint8_t *eapol_rsne,
|
||||||
|
const uint8_t *scan_rsne)
|
||||||
|
{
|
||||||
|
struct ie_rsn_info eapol_info;
|
||||||
|
struct ie_rsn_info scan_info;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First check that the sizes match, if they do, run a bitwise
|
||||||
|
* comparison.
|
||||||
|
*/
|
||||||
|
if (eapol_rsne[1] == scan_rsne[1] &&
|
||||||
|
!memcmp(eapol_rsne + 2, scan_rsne + 2, eapol_rsne[1]))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Otherwise we have to parse the RSN IEs and compare the individual
|
||||||
|
* fields
|
||||||
|
*/
|
||||||
|
if (ie_parse_rsne_from_data(eapol_rsne, eapol_rsne[1] + 2,
|
||||||
|
&eapol_info) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (ie_parse_rsne_from_data(scan_rsne, scan_rsne[1] + 2,
|
||||||
|
&scan_info) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.group_cipher != scan_info.group_cipher)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.pairwise_ciphers != scan_info.pairwise_ciphers)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.akm_suites != scan_info.akm_suites)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.preauthentication != scan_info.preauthentication)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.no_pairwise != scan_info.no_pairwise)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.ptksa_replay_counter != scan_info.ptksa_replay_counter)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.gtksa_replay_counter != scan_info.gtksa_replay_counter)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.mfpr != scan_info.mfpr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.mfpc != scan_info.mfpc)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.peerkey_enabled != scan_info.peerkey_enabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.spp_a_msdu_capable != scan_info.spp_a_msdu_capable)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.spp_a_msdu_required != scan_info.spp_a_msdu_required)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.pbac != scan_info.pbac)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (eapol_info.extended_key_id != scan_info.extended_key_id)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* We don't check the PMKIDs since these might actually be different */
|
||||||
|
|
||||||
|
if (eapol_info.group_management_cipher !=
|
||||||
|
scan_info.group_management_cipher)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void eapol_handle_ptk_3_of_4(int ifindex, struct eapol_sm *sm,
|
static void eapol_handle_ptk_3_of_4(int ifindex, struct eapol_sm *sm,
|
||||||
const struct eapol_key *ek,
|
const struct eapol_key *ek,
|
||||||
const uint8_t *decrypted_key_data,
|
const uint8_t *decrypted_key_data,
|
||||||
@ -574,6 +672,7 @@ static void eapol_handle_ptk_3_of_4(int ifindex, struct eapol_sm *sm,
|
|||||||
uint8_t mic[16];
|
uint8_t mic[16];
|
||||||
const uint8_t *gtk;
|
const uint8_t *gtk;
|
||||||
size_t gtk_len;
|
size_t gtk_len;
|
||||||
|
const uint8_t *rsne;
|
||||||
|
|
||||||
if (!eapol_verify_ptk_3_of_4(ek))
|
if (!eapol_verify_ptk_3_of_4(ek))
|
||||||
return;
|
return;
|
||||||
@ -587,12 +686,17 @@ static void eapol_handle_ptk_3_of_4(int ifindex, struct eapol_sm *sm,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Check that first RSNE matches ap_rsne
|
|
||||||
* 11.6.6.4: "Verifies the RSNE. If it is part of a Fast BSS Transition
|
* 11.6.6.4: "Verifies the RSNE. If it is part of a Fast BSS Transition
|
||||||
* Initial Mobility Domain Association, see 12.4.2. Otherwise, if it is
|
* Initial Mobility Domain Association, see 12.4.2. Otherwise, if it is
|
||||||
* not identical to that the STA received in the Beacon or Probe
|
* not identical to that the STA received in the Beacon or Probe
|
||||||
* Response frame, the STA shall disassociate.
|
* Response frame, the STA shall disassociate.
|
||||||
*/
|
*/
|
||||||
|
rsne = eapol_find_rsne(decrypted_key_data, decrypted_key_data_size);
|
||||||
|
if (!rsne)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!eapol_ap_rsne_matches(rsne, sm->ap_rsn))
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Parse second RSNE
|
* TODO: Parse second RSNE
|
||||||
|
Loading…
Reference in New Issue
Block a user