mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-23 06:02:37 +01:00
ft: rework ft_parse_ies
This adds the RSNE verification to ft_parse_ies which will be common between over-Air and over-DS. The MDE check was also factored out into its own minimal function as to retain the spec comment but allow reuse elsewhere.
This commit is contained in:
parent
2697af428e
commit
2c0234e161
155
src/ft.c
155
src/ft.c
@ -329,57 +329,6 @@ error:
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ft_parse_ies(const uint8_t *ies, size_t ies_len,
|
|
||||||
const uint8_t **rsne_out, const uint8_t **mde_out,
|
|
||||||
const uint8_t **fte_out)
|
|
||||||
{
|
|
||||||
struct ie_tlv_iter iter;
|
|
||||||
const uint8_t *rsne = NULL;
|
|
||||||
const uint8_t *mde = NULL;
|
|
||||||
const uint8_t *fte = NULL;
|
|
||||||
|
|
||||||
ie_tlv_iter_init(&iter, ies, ies_len);
|
|
||||||
|
|
||||||
while (ie_tlv_iter_next(&iter)) {
|
|
||||||
switch (ie_tlv_iter_get_tag(&iter)) {
|
|
||||||
case IE_TYPE_RSN:
|
|
||||||
if (rsne)
|
|
||||||
goto ft_error;
|
|
||||||
|
|
||||||
rsne = ie_tlv_iter_get_data(&iter) - 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IE_TYPE_MOBILITY_DOMAIN:
|
|
||||||
if (mde)
|
|
||||||
goto ft_error;
|
|
||||||
|
|
||||||
mde = ie_tlv_iter_get_data(&iter) - 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IE_TYPE_FAST_BSS_TRANSITION:
|
|
||||||
if (fte)
|
|
||||||
goto ft_error;
|
|
||||||
|
|
||||||
fte = ie_tlv_iter_get_data(&iter) - 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rsne_out)
|
|
||||||
*rsne_out = rsne;
|
|
||||||
|
|
||||||
if (mde_out)
|
|
||||||
*mde_out = mde;
|
|
||||||
|
|
||||||
if (fte_out)
|
|
||||||
*fte_out = fte;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ft_error:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ft_verify_rsne(const uint8_t *rsne, const uint8_t *pmk_r0_name,
|
static bool ft_verify_rsne(const uint8_t *rsne, const uint8_t *pmk_r0_name,
|
||||||
const uint8_t *authenticator_ie)
|
const uint8_t *authenticator_ie)
|
||||||
{
|
{
|
||||||
@ -416,6 +365,65 @@ static bool ft_verify_rsne(const uint8_t *rsne, const uint8_t *pmk_r0_name,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ft_parse_ies(struct handshake_state *hs,
|
||||||
|
const uint8_t *ies, size_t ies_len,
|
||||||
|
const uint8_t **mde_out,
|
||||||
|
const uint8_t **fte_out)
|
||||||
|
{
|
||||||
|
struct ie_tlv_iter iter;
|
||||||
|
const uint8_t *rsne = NULL;
|
||||||
|
const uint8_t *mde = NULL;
|
||||||
|
const uint8_t *fte = NULL;
|
||||||
|
bool is_rsn;
|
||||||
|
|
||||||
|
ie_tlv_iter_init(&iter, ies, ies_len);
|
||||||
|
|
||||||
|
while (ie_tlv_iter_next(&iter)) {
|
||||||
|
switch (ie_tlv_iter_get_tag(&iter)) {
|
||||||
|
case IE_TYPE_RSN:
|
||||||
|
if (rsne)
|
||||||
|
goto ft_error;
|
||||||
|
|
||||||
|
rsne = ie_tlv_iter_get_data(&iter) - 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IE_TYPE_MOBILITY_DOMAIN:
|
||||||
|
if (mde)
|
||||||
|
goto ft_error;
|
||||||
|
|
||||||
|
mde = ie_tlv_iter_get_data(&iter) - 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IE_TYPE_FAST_BSS_TRANSITION:
|
||||||
|
if (fte)
|
||||||
|
goto ft_error;
|
||||||
|
|
||||||
|
fte = ie_tlv_iter_get_data(&iter) - 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is_rsn = hs->supplicant_ie != NULL;
|
||||||
|
|
||||||
|
if (is_rsn) {
|
||||||
|
if (!ft_verify_rsne(rsne, hs->pmk_r0_name,
|
||||||
|
hs->authenticator_ie))
|
||||||
|
goto ft_error;
|
||||||
|
} else if (rsne)
|
||||||
|
goto ft_error;
|
||||||
|
|
||||||
|
if (mde_out)
|
||||||
|
*mde_out = mde;
|
||||||
|
|
||||||
|
if (fte_out)
|
||||||
|
*fte_out = fte;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ft_error:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
static bool ft_parse_fte(struct handshake_state *hs,
|
static bool ft_parse_fte(struct handshake_state *hs,
|
||||||
const uint8_t *snonce,
|
const uint8_t *snonce,
|
||||||
const uint8_t *fte,
|
const uint8_t *fte,
|
||||||
@ -465,29 +473,10 @@ static bool ft_parse_fte(struct handshake_state *hs,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ft_process_ies(struct handshake_state *hs, const uint8_t *ies,
|
static bool mde_equal(const uint8_t *mde1, const uint8_t *mde2)
|
||||||
size_t ies_len)
|
|
||||||
{
|
{
|
||||||
const uint8_t *rsne = NULL;
|
if (!mde1 || !mde2)
|
||||||
const uint8_t *mde = NULL;
|
return false;
|
||||||
const uint8_t *fte = NULL;
|
|
||||||
bool is_rsn;
|
|
||||||
|
|
||||||
/* Check 802.11r IEs */
|
|
||||||
if (!ies)
|
|
||||||
goto ft_error;
|
|
||||||
|
|
||||||
if (ft_parse_ies(ies, ies_len, &rsne, &mde, &fte) < 0)
|
|
||||||
goto ft_error;
|
|
||||||
|
|
||||||
is_rsn = hs->supplicant_ie != NULL;
|
|
||||||
|
|
||||||
if (is_rsn) {
|
|
||||||
if (!ft_verify_rsne(rsne, hs->pmk_r0_name,
|
|
||||||
hs->authenticator_ie))
|
|
||||||
goto ft_error;
|
|
||||||
} else if (rsne)
|
|
||||||
goto ft_error;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for an MD IE identical to the one we sent in message 1
|
* Check for an MD IE identical to the one we sent in message 1
|
||||||
@ -496,7 +485,25 @@ static int ft_process_ies(struct handshake_state *hs, const uint8_t *ies,
|
|||||||
* Policy fields. This element shall be the same as the MDE
|
* Policy fields. This element shall be the same as the MDE
|
||||||
* advertised by the target AP in Beacon and Probe Response frames."
|
* advertised by the target AP in Beacon and Probe Response frames."
|
||||||
*/
|
*/
|
||||||
if (!mde || memcmp(hs->mde, mde, hs->mde[1] + 2))
|
return memcmp(mde1, mde1, mde1[1] + 2) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ft_process_ies(struct handshake_state *hs, const uint8_t *ies,
|
||||||
|
size_t ies_len)
|
||||||
|
{
|
||||||
|
const uint8_t *mde = NULL;
|
||||||
|
const uint8_t *fte = NULL;
|
||||||
|
bool is_rsn = hs->supplicant_ie != NULL;
|
||||||
|
|
||||||
|
/* Check 802.11r IEs */
|
||||||
|
if (!ies)
|
||||||
|
goto ft_error;
|
||||||
|
|
||||||
|
if (ft_parse_ies(hs, ies, ies_len, &mde, &fte) < 0)
|
||||||
|
goto ft_error;
|
||||||
|
|
||||||
|
|
||||||
|
if (!mde_equal(hs->mde, mde))
|
||||||
goto ft_error;
|
goto ft_error;
|
||||||
|
|
||||||
if (is_rsn) {
|
if (is_rsn) {
|
||||||
|
Loading…
Reference in New Issue
Block a user