mesh: Check PMKID in AMPE Action frames
From IEEE Std 802.11-2012 13.3.5: If the incoming Mesh Peering Management frame is for AMPE and the Chosen PMK from the received frame contains a PMKID that does not identify a valid mesh PMKSA, the frame shall be silently discarded. We were not checking the PMKID previously, and we also weren't parsing it correctly, so fix both. Signed-off-by: Bob Copeland <me@bobcopeland.com>
This commit is contained in:
parent
6c33eed3ee
commit
b2817cd5c2
3 changed files with 10 additions and 1 deletions
|
@ -74,8 +74,8 @@ static int mesh_mpm_parse_peer_mgmt(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
/* remove optional PMK at end */
|
/* remove optional PMK at end */
|
||||||
if (len >= 16) {
|
if (len >= 16) {
|
||||||
len -= 16;
|
|
||||||
mpm_ie->pmk = ie + len - 16;
|
mpm_ie->pmk = ie + len - 16;
|
||||||
|
len -= 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((action_field == PLINK_OPEN && len != 4) ||
|
if ((action_field == PLINK_OPEN && len != 4) ||
|
||||||
|
@ -1014,6 +1014,7 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
|
||||||
if ((mconf->security & MESH_CONF_SEC_AMPE) &&
|
if ((mconf->security & MESH_CONF_SEC_AMPE) &&
|
||||||
mesh_rsn_process_ampe(wpa_s, sta, &elems,
|
mesh_rsn_process_ampe(wpa_s, sta, &elems,
|
||||||
&mgmt->u.action.category,
|
&mgmt->u.action.category,
|
||||||
|
peer_mgmt_ie.pmk,
|
||||||
ies, ie_len)) {
|
ies, ie_len)) {
|
||||||
wpa_printf(MSG_DEBUG, "MPM: RSN process rejected frame");
|
wpa_printf(MSG_DEBUG, "MPM: RSN process rejected frame");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -500,6 +500,7 @@ free:
|
||||||
|
|
||||||
int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
|
int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
|
||||||
struct ieee802_11_elems *elems, const u8 *cat,
|
struct ieee802_11_elems *elems, const u8 *cat,
|
||||||
|
const u8 *chosen_pmk,
|
||||||
const u8 *start, size_t elems_len)
|
const u8 *start, size_t elems_len)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -513,6 +514,12 @@ int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
|
||||||
const size_t aad_len[] = { ETH_ALEN, ETH_ALEN,
|
const size_t aad_len[] = { ETH_ALEN, ETH_ALEN,
|
||||||
(elems->mic - 2) - cat };
|
(elems->mic - 2) - cat };
|
||||||
|
|
||||||
|
if (chosen_pmk && os_memcmp(chosen_pmk, sta->sae->pmkid, PMKID_LEN)) {
|
||||||
|
wpa_msg(wpa_s, MSG_DEBUG,
|
||||||
|
"Mesh RSN: Invalid PMKID (Chosen PMK did not match calculated PMKID)");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!elems->mic || elems->mic_len < AES_BLOCK_SIZE) {
|
if (!elems->mic || elems->mic_len < AES_BLOCK_SIZE) {
|
||||||
wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: missing mic ie");
|
wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: missing mic ie");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -30,6 +30,7 @@ int mesh_rsn_protect_frame(struct mesh_rsn *rsn, struct sta_info *sta,
|
||||||
const u8 *cat, struct wpabuf *buf);
|
const u8 *cat, struct wpabuf *buf);
|
||||||
int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
|
int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
|
||||||
struct ieee802_11_elems *elems, const u8 *cat,
|
struct ieee802_11_elems *elems, const u8 *cat,
|
||||||
|
const u8 *chosen_pmk,
|
||||||
const u8 *start, size_t elems_len);
|
const u8 *start, size_t elems_len);
|
||||||
void mesh_auth_timer(void *eloop_ctx, void *user_data);
|
void mesh_auth_timer(void *eloop_ctx, void *user_data);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue