RSNO: Verify all RSNE/RSNXE variants in multi-link cases

Use the RSN Override Link KDE to include the override variants of the
RSNE/RSNXE for each link so that all variants are verifies when
processing the protected EAPOL-Key message 3/4.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
Jouni Malinen 2024-07-30 19:56:00 +03:00 committed by Jouni Malinen
parent 4d110b4f87
commit be6e4279fa
6 changed files with 289 additions and 108 deletions

View file

@ -4479,34 +4479,47 @@ static size_t wpa_auth_ml_kdes_len(struct wpa_state_machine *sm)
/* For the MAC Address KDE */
kde_len = 2 + RSN_SELECTOR_LEN + ETH_ALEN;
/* MLO Link KDE for each link */
/* MLO Link KDE and RSN Override Link KDE for each link */
for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
struct wpa_authenticator *wpa_auth;
const u8 *ie, *ieo;
const u8 *ie;
wpa_auth = wpa_get_link_auth(sm->wpa_auth, link_id);
if (!wpa_auth)
continue;
/* MLO Link KDE */
kde_len += 2 + RSN_SELECTOR_LEN + 1 + ETH_ALEN;
ie = get_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
WLAN_EID_RSN);
ieo = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
sm->rsn_override_2 ?
RSNE_OVERRIDE_2_IE_VENDOR_TYPE :
RSNE_OVERRIDE_IE_VENDOR_TYPE);
if ((sm->rsn_override || sm->rsn_override_2) && ieo)
kde_len += 2 + ieo[1 - 4];
else
if (ie)
kde_len += 2 + ie[1];
ie = get_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
WLAN_EID_RSNX);
ieo = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
if (ie)
kde_len += 2 + ie[1];
if (!rsn_is_snonce_cookie(sm->SNonce))
continue;
/* RSN Override Link KDE */
kde_len += 2 + RSN_SELECTOR_LEN + 1;
ie = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
RSNE_OVERRIDE_IE_VENDOR_TYPE);
if (ie)
kde_len += 2 + ie[1];
ie = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
if (ie)
kde_len += 2 + ie[1];
ie = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
RSNXE_OVERRIDE_IE_VENDOR_TYPE);
if ((sm->rsn_override || sm->rsn_override_2) && ieo)
kde_len += 2 + ieo[1] - 4;
else if (ie)
if (ie)
kde_len += 2 + ie[1];
}
@ -4532,8 +4545,8 @@ static u8 * wpa_auth_ml_kdes(struct wpa_state_machine *sm, u8 *pos)
for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
struct wpa_authenticator *wpa_auth;
const u8 *rsne, *rsnxe, *rsneo, *rsnxeo;
size_t rsne_len, rsnxe_len;
const u8 *rsne, *rsnxe, *rsnoe, *rsno2e, *rsnxoe;
size_t rsne_len, rsnxe_len, rsnoe_len, rsno2e_len, rsnxoe_len;
wpa_auth = wpa_get_link_auth(sm->wpa_auth, link_id);
if (!wpa_auth)
@ -4542,30 +4555,17 @@ static u8 * wpa_auth_ml_kdes(struct wpa_state_machine *sm, u8 *pos)
rsne = get_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
WLAN_EID_RSN);
rsne_len = rsne ? 2 + rsne[1] : 0;
rsneo = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
sm->rsn_override_2 ?
RSNE_OVERRIDE_2_IE_VENDOR_TYPE :
RSNE_OVERRIDE_IE_VENDOR_TYPE);
if ((sm->rsn_override || sm->rsn_override_2) && rsneo)
rsne_len = 2 + rsneo[1] - 4;
else
rsneo = NULL;
rsnxe = get_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
WLAN_EID_RSNX);
rsnxe_len = rsnxe ? 2 + rsnxe[1] : 0;
rsnxeo = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
RSNXE_OVERRIDE_IE_VENDOR_TYPE);
if ((sm->rsn_override || sm->rsn_override_2) && rsnxeo)
rsnxe_len = 2 + rsnxeo[1] - 4;
else
rsnxeo = NULL;
wpa_printf(MSG_DEBUG,
"RSN: MLO Link: link=%u, len=%zu", link_id,
RSN_SELECTOR_LEN + 1 + ETH_ALEN +
rsne_len + rsnxe_len);
/* MLO Link KDE */
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
*pos++ = RSN_SELECTOR_LEN + 1 + ETH_ALEN +
rsne_len + rsnxe_len;
@ -4585,31 +4585,64 @@ static u8 * wpa_auth_ml_kdes(struct wpa_state_machine *sm, u8 *pos)
pos += ETH_ALEN;
if (rsne_len) {
if (rsneo) {
*pos++ = WLAN_EID_RSN;
*pos++ = rsneo[1] - 4;
os_memcpy(pos, &rsneo[2 + 4], rsneo[1] - 4);
pos += rsneo[1] - 4;
} else {
os_memcpy(pos, rsne, rsne_len);
pos += rsne_len;
}
}
if (rsnxe_len) {
if (rsnxeo) {
*pos++ = WLAN_EID_RSNX;
*pos++ = rsnxeo[1] - 4;
os_memcpy(pos, &rsnxeo[2 + 4], rsnxeo[1] - 4);
pos += rsnxeo[1] - 4;
} else {
os_memcpy(pos, rsnxe, rsnxe_len);
pos += rsnxe_len;
}
if (!rsn_is_snonce_cookie(sm->SNonce))
continue;
rsnoe = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
RSNE_OVERRIDE_IE_VENDOR_TYPE);
rsnoe_len = rsnoe ? 2 + rsnoe[1] : 0;
rsno2e = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
rsno2e_len = rsno2e ? 2 + rsno2e[1] : 0;
rsnxoe = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
RSNXE_OVERRIDE_IE_VENDOR_TYPE);
rsnxoe_len = rsnxoe ? 2 + rsnxoe[1] : 0;
wpa_printf(MSG_DEBUG,
"RSN: RSN Override Link KDE: link=%u, len=%zu",
link_id, RSN_SELECTOR_LEN + rsnoe_len + rsno2e_len +
rsnxoe_len);
/* RSN Override Link KDE */
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
*pos++ = RSN_SELECTOR_LEN + 1 + rsnoe_len + rsno2e_len +
rsnxoe_len;
RSN_SELECTOR_PUT(pos, WFA_KEY_DATA_RSN_OVERRIDE_LINK);
pos += RSN_SELECTOR_LEN;
*pos++ = link_id;
if (rsnoe_len) {
os_memcpy(pos, rsnoe, rsnoe_len);
pos += rsnoe_len;
}
if (rsno2e_len) {
os_memcpy(pos, rsno2e, rsno2e_len);
pos += rsno2e_len;
}
if (rsnxoe_len) {
os_memcpy(pos, rsnxoe, rsnxoe_len);
pos += rsnxoe_len;
}
}
wpa_printf(MSG_DEBUG, "RSN: MLO Link KDE len = %ld", pos - start);
wpa_printf(MSG_DEBUG,
"RSN: MLO Link KDEs and RSN Override Link KDEs len = %ld",
pos - start);
pos = wpa_auth_ml_group_kdes(sm, pos);
#endif /* CONFIG_IEEE80211BE */

View file

@ -3448,7 +3448,7 @@ static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
const u8 *p;
size_t left;
u8 link_id;
char title[50];
char title[100];
int ret;
if (len == 0)
@ -3629,6 +3629,21 @@ static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
return 0;
}
if (left >= 1 && selector == WFA_KEY_DATA_RSN_OVERRIDE_LINK) {
link_id = p[0];
if (link_id >= MAX_NUM_MLD_LINKS)
return 2;
ie->rsn_override_link[link_id] = p;
ie->rsn_override_link_len[link_id] = left;
ret = os_snprintf(title, sizeof(title),
"RSN: Link ID %u - RSN Override Link KDE in EAPOL-Key",
link_id);
if (!os_snprintf_error(sizeof(title), ret))
wpa_hexdump(MSG_DEBUG, title, pos, dlen);
return 0;
}
if (selector == RSNE_OVERRIDE_IE_VENDOR_TYPE) {
ie->rsne_override = pos;
ie->rsne_override_len = dlen;

View file

@ -144,6 +144,7 @@ WPA_CIPHER_BIP_CMAC_256)
#define WFA_KEY_DATA_IP_ADDR_ALLOC RSN_SELECTOR(0x50, 0x6f, 0x9a, 5)
#define WFA_KEY_DATA_TRANSITION_DISABLE RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x20)
#define WFA_KEY_DATA_DPP RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x21)
#define WFA_KEY_DATA_RSN_OVERRIDE_LINK RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x2d)
#define WPA_OUI_TYPE RSN_SELECTOR(0x00, 0x50, 0xf2, 1)
@ -732,6 +733,8 @@ struct wpa_eapol_ie_parse {
u16 valid_mlo_links; /* bitmap of valid MLO link KDEs */
const u8 *mlo_link[MAX_NUM_MLD_LINKS];
size_t mlo_link_len[MAX_NUM_MLD_LINKS];
const u8 *rsn_override_link[MAX_NUM_MLD_LINKS];
size_t rsn_override_link_len[MAX_NUM_MLD_LINKS];
};
int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie);

View file

@ -2437,10 +2437,14 @@ int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
static int wpa_supplicant_validate_link_kde(struct wpa_sm *sm, u8 link_id,
const u8 *link_kde,
size_t link_kde_len)
size_t link_kde_len,
const u8 *rsn_override_link_kde,
size_t rsn_override_link_kde_len)
{
size_t rsne_len = 0, rsnxe_len = 0;
const u8 *rsne = NULL, *rsnxe = NULL;
size_t rsne_len = 0, rsnxe_len = 0, rsnoe_len = 0, rsno2e_len = 0,
rsnxoe_len = 0;
const u8 *rsne = NULL, *rsnxe = NULL, *rsnoe = NULL, *rsno2e = NULL,
*rsnxoe = NULL;
if (!link_kde ||
link_kde_len < RSN_MLO_LINK_KDE_LINK_MAC_INDEX + ETH_ALEN) {
@ -2496,19 +2500,39 @@ static int wpa_supplicant_validate_link_kde(struct wpa_sm *sm, u8 link_id,
rsnxe_len = rsnxe[1] + 2;
}
if (rsn_override_link_kde) {
rsnoe = get_vendor_ie(rsn_override_link_kde + 1,
rsn_override_link_kde_len - 1,
RSNE_OVERRIDE_IE_VENDOR_TYPE);
if (rsnoe)
rsnoe_len = 2 + rsnoe[1];
rsno2e = get_vendor_ie(rsn_override_link_kde + 1,
rsn_override_link_kde_len - 1,
RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
if (rsno2e)
rsno2e_len = 2 + rsno2e[1];
rsnxoe = get_vendor_ie(rsn_override_link_kde + 1,
rsn_override_link_kde_len - 1,
RSNXE_OVERRIDE_IE_VENDOR_TYPE);
if (rsnxoe)
rsnxoe_len = 2 + rsnxoe[1];
}
if (wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
sm->mlo.links[link_id].ap_rsne,
sm->mlo.links[link_id].ap_rsne_len,
rsne, rsne_len)) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN MLO: IE in 3/4 msg does not match with IE in Beacon/ProbeResp for link ID %u",
"RSN MLO: RSNE in 3/4 msg does not match with IE in Beacon/ProbeResp for link ID %u",
link_id);
wpa_hexdump(MSG_INFO, "RSNE in Beacon/ProbeResp",
sm->mlo.links[link_id].ap_rsne,
sm->mlo.links[link_id].ap_rsne_len);
wpa_hexdump(MSG_INFO, "RSNE in EAPOL-Key msg 3/4",
rsne, rsne_len);
return -1;
goto fail;
}
if ((sm->mlo.links[link_id].ap_rsnxe && !rsnxe) ||
@ -2525,11 +2549,66 @@ static int wpa_supplicant_validate_link_kde(struct wpa_sm *sm, u8 link_id,
sm->mlo.links[link_id].ap_rsnxe_len);
wpa_hexdump(MSG_INFO, "RSNXE in EAPOL-Key msg 3/4",
rsnxe, rsnxe_len);
wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);
return -1;
goto fail;
}
if ((sm->mlo.links[link_id].ap_rsnoe && !rsnoe) ||
(!sm->mlo.links[link_id].ap_rsnoe && rsnoe) ||
(sm->mlo.links[link_id].ap_rsnoe && rsnoe &&
wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
sm->mlo.links[link_id].ap_rsnoe,
sm->mlo.links[link_id].ap_rsnoe_len,
rsnoe, rsnoe_len))) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN MLO: RSNOE in 3/4 msg does not match with IE in Beacon/ProbeResp for link ID %u",
link_id);
wpa_hexdump(MSG_INFO, "RSNOE in Beacon/ProbeResp",
sm->mlo.links[link_id].ap_rsnoe,
sm->mlo.links[link_id].ap_rsnoe_len);
wpa_hexdump(MSG_INFO, "RSNOE in EAPOL-Key msg 3/4",
rsnoe, rsnoe_len);
goto fail;
}
if ((sm->mlo.links[link_id].ap_rsno2e && !rsno2e) ||
(!sm->mlo.links[link_id].ap_rsno2e && rsno2e) ||
(sm->mlo.links[link_id].ap_rsno2e && rsno2e &&
wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
sm->mlo.links[link_id].ap_rsno2e,
sm->mlo.links[link_id].ap_rsno2e_len,
rsno2e, rsno2e_len))) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN MLO: RSNO2E in 3/4 msg does not match with IE in Beacon/ProbeResp for link ID %u",
link_id);
wpa_hexdump(MSG_INFO, "RSNO2E in Beacon/ProbeResp",
sm->mlo.links[link_id].ap_rsno2e,
sm->mlo.links[link_id].ap_rsno2e_len);
wpa_hexdump(MSG_INFO, "RSNOE in EAPOL-Key msg 3/4",
rsno2e, rsno2e_len);
goto fail;
}
if ((sm->mlo.links[link_id].ap_rsnxoe && !rsnxoe) ||
(!sm->mlo.links[link_id].ap_rsnxoe && rsnxoe) ||
(sm->mlo.links[link_id].ap_rsnxoe && rsnxoe &&
(sm->mlo.links[link_id].ap_rsnxoe_len != rsnxoe_len ||
os_memcmp(sm->mlo.links[link_id].ap_rsnxoe, rsnxoe,
sm->mlo.links[link_id].ap_rsnxoe_len) != 0))) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN MLO: RSNXOE mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4 for link ID %u",
link_id);
wpa_hexdump(MSG_INFO, "RSNXOE in Beacon/ProbeResp",
sm->mlo.links[link_id].ap_rsnxoe,
sm->mlo.links[link_id].ap_rsnxoe_len);
wpa_hexdump(MSG_INFO, "RSNXOE in EAPOL-Key msg 3/4",
rsnxoe, rsnxoe_len);
goto fail;
}
return 0;
fail:
wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);
return -1;
}
@ -2697,8 +2776,10 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
if (!(sm->mlo.req_links & BIT(i)))
continue;
if (wpa_supplicant_validate_link_kde(sm, i, ie.mlo_link[i],
ie.mlo_link_len[i]) < 0)
if (wpa_supplicant_validate_link_kde(
sm, i, ie.mlo_link[i], ie.mlo_link_len[i],
ie.rsn_override_link[i],
ie.rsn_override_link_len[i]) < 0)
goto failed;
if (!(sm->mlo.valid_links & BIT(i)))
@ -4277,6 +4358,9 @@ void wpa_sm_deinit(struct wpa_sm *sm)
for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
os_free(sm->mlo.links[i].ap_rsne);
os_free(sm->mlo.links[i].ap_rsnxe);
os_free(sm->mlo.links[i].ap_rsnoe);
os_free(sm->mlo.links[i].ap_rsno2e);
os_free(sm->mlo.links[i].ap_rsnxoe);
}
wpa_sm_drop_sa(sm);
os_free(sm->ctx);
@ -4651,20 +4735,6 @@ int wpa_sm_set_mlo_params(struct wpa_sm *sm, const struct wpa_sm_mlo *mlo)
} else {
wpa_hexdump_link(MSG_DEBUG, i, "RSN: Set AP RSNE",
ie, len);
if (ie[0] == WLAN_EID_VENDOR_SPECIFIC && len > 2 + 4) {
sm->mlo.links[i].ap_rsne = os_malloc(len - 4);
if (!sm->mlo.links[i].ap_rsne)
return -1;
sm->mlo.links[i].ap_rsne[0] = WLAN_EID_RSN;
sm->mlo.links[i].ap_rsne[1] = len - 2 - 4;
os_memcpy(&sm->mlo.links[i].ap_rsne[2],
ie + 2 + 4, len - 2 - 4);
sm->mlo.links[i].ap_rsne_len = len - 4;
wpa_hexdump(MSG_DEBUG,
"RSN: Converted RSNE override to RSNE",
sm->mlo.links[i].ap_rsne,
sm->mlo.links[i].ap_rsne_len);
} else {
sm->mlo.links[i].ap_rsne = os_memdup(ie, len);
if (!sm->mlo.links[i].ap_rsne) {
sm->mlo.links[i].ap_rsne_len = 0;
@ -4672,7 +4742,6 @@ int wpa_sm_set_mlo_params(struct wpa_sm *sm, const struct wpa_sm_mlo *mlo)
}
sm->mlo.links[i].ap_rsne_len = len;
}
}
ie = mlo->links[i].ap_rsnxe;
len = mlo->links[i].ap_rsnxe_len;
@ -4687,20 +4756,6 @@ int wpa_sm_set_mlo_params(struct wpa_sm *sm, const struct wpa_sm_mlo *mlo)
} else {
wpa_hexdump_link(MSG_DEBUG, i, "RSN: Set AP RSNXE", ie,
len);
if (ie[0] == WLAN_EID_VENDOR_SPECIFIC && len > 2 + 4) {
sm->mlo.links[i].ap_rsnxe = os_malloc(len - 4);
if (!sm->mlo.links[i].ap_rsnxe)
return -1;
sm->mlo.links[i].ap_rsnxe[0] = WLAN_EID_RSNX;
sm->mlo.links[i].ap_rsnxe[1] = len - 2 - 4;
os_memcpy(&sm->mlo.links[i].ap_rsnxe[2],
ie + 2 + 4, len - 2 - 4);
sm->mlo.links[i].ap_rsnxe_len = len - 4;
wpa_hexdump(MSG_DEBUG,
"RSN: Converted RSNXE override to RSNXE",
sm->mlo.links[i].ap_rsnxe,
sm->mlo.links[i].ap_rsnxe_len);
} else {
sm->mlo.links[i].ap_rsnxe = os_memdup(ie, len);
if (!sm->mlo.links[i].ap_rsnxe) {
sm->mlo.links[i].ap_rsnxe_len = 0;
@ -4708,6 +4763,68 @@ int wpa_sm_set_mlo_params(struct wpa_sm *sm, const struct wpa_sm_mlo *mlo)
}
sm->mlo.links[i].ap_rsnxe_len = len;
}
ie = mlo->links[i].ap_rsnoe;
len = mlo->links[i].ap_rsnoe_len;
os_free(sm->mlo.links[i].ap_rsnoe);
if (!ie || len == 0) {
if (sm->mlo.links[i].ap_rsnoe)
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Clearing MLO link[%u] AP RSNOE",
i);
sm->mlo.links[i].ap_rsnoe = NULL;
sm->mlo.links[i].ap_rsnoe_len = 0;
} else {
wpa_hexdump_link(MSG_DEBUG, i, "RSN: Set AP RSNOE",
ie, len);
sm->mlo.links[i].ap_rsnoe = os_memdup(ie, len);
if (!sm->mlo.links[i].ap_rsnoe) {
sm->mlo.links[i].ap_rsnoe_len = 0;
return -1;
}
sm->mlo.links[i].ap_rsnoe_len = len;
}
ie = mlo->links[i].ap_rsno2e;
len = mlo->links[i].ap_rsno2e_len;
os_free(sm->mlo.links[i].ap_rsno2e);
if (!ie || len == 0) {
if (sm->mlo.links[i].ap_rsno2e)
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Clearing MLO link[%u] AP RSNO2E",
i);
sm->mlo.links[i].ap_rsno2e = NULL;
sm->mlo.links[i].ap_rsno2e_len = 0;
} else {
wpa_hexdump_link(MSG_DEBUG, i, "RSN: Set AP RSNO2E",
ie, len);
sm->mlo.links[i].ap_rsno2e = os_memdup(ie, len);
if (!sm->mlo.links[i].ap_rsno2e) {
sm->mlo.links[i].ap_rsno2e_len = 0;
return -1;
}
sm->mlo.links[i].ap_rsno2e_len = len;
}
ie = mlo->links[i].ap_rsnxoe;
len = mlo->links[i].ap_rsnxoe_len;
os_free(sm->mlo.links[i].ap_rsnxoe);
if (!ie || len == 0) {
if (sm->mlo.links[i].ap_rsnxoe)
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Clearing MLO link[%u] AP RSNXOE",
i);
sm->mlo.links[i].ap_rsnxoe = NULL;
sm->mlo.links[i].ap_rsnxoe_len = 0;
} else {
wpa_hexdump_link(MSG_DEBUG, i, "RSN: Set AP RSNXOE",
ie, len);
sm->mlo.links[i].ap_rsnxoe = os_memdup(ie, len);
if (!sm->mlo.links[i].ap_rsnxoe) {
sm->mlo.links[i].ap_rsnxoe_len = 0;
return -1;
}
sm->mlo.links[i].ap_rsnxoe_len = len;
}
}

View file

@ -168,8 +168,9 @@ struct rsn_supp_config {
struct wpa_sm_link {
u8 addr[ETH_ALEN];
u8 bssid[ETH_ALEN];
u8 *ap_rsne, *ap_rsnxe;
size_t ap_rsne_len, ap_rsnxe_len;
u8 *ap_rsne, *ap_rsnxe, *ap_rsnoe, *ap_rsno2e, *ap_rsnxoe;
size_t ap_rsne_len, ap_rsnxe_len, ap_rsnoe_len, ap_rsno2e_len,
ap_rsnxoe_len;;
struct wpa_gtk gtk;
struct wpa_gtk gtk_wnm_sleep;
struct wpa_igtk igtk;

View file

@ -4129,7 +4129,6 @@ static int wpa_sm_set_ml_info(struct wpa_supplicant *wpa_s)
{
struct driver_sta_mlo_info drv_mlo;
struct wpa_sm_mlo wpa_mlo;
const u8 *bss_rsn = NULL, *bss_rsnx = NULL;
int i;
os_memset(&drv_mlo, 0, sizeof(drv_mlo));
@ -4149,6 +4148,7 @@ static int wpa_sm_set_ml_info(struct wpa_supplicant *wpa_s)
for_each_link(drv_mlo.req_links, i) {
struct wpa_bss *bss;
const u8 *rsne, *rsnxe, *rsnoe, *rsno2e, *rsnxoe;
bss = wpa_supplicant_get_new_bss(wpa_s, drv_mlo.links[i].bssid);
if (!bss) {
@ -4157,13 +4157,25 @@ static int wpa_sm_set_ml_info(struct wpa_supplicant *wpa_s)
return -1;
}
bss_rsn = wpa_bss_get_rsne(wpa_s, bss, NULL, true);
bss_rsnx = wpa_bss_get_rsnxe(wpa_s, bss, NULL, true);
rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
rsnoe = wpa_bss_get_vendor_ie(bss,
RSNE_OVERRIDE_IE_VENDOR_TYPE);
rsno2e = wpa_bss_get_vendor_ie(bss,
RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
rsnxoe = wpa_bss_get_vendor_ie(bss,
RSNXE_OVERRIDE_IE_VENDOR_TYPE);
wpa_mlo.links[i].ap_rsne = bss_rsn ? (u8 *) bss_rsn : NULL;
wpa_mlo.links[i].ap_rsne_len = bss_rsn ? 2 + bss_rsn[1] : 0;
wpa_mlo.links[i].ap_rsnxe = bss_rsnx ? (u8 *) bss_rsnx : NULL;
wpa_mlo.links[i].ap_rsnxe_len = bss_rsnx ? 2 + bss_rsnx[1] : 0;
wpa_mlo.links[i].ap_rsne = rsne ? (u8 *) rsne : NULL;
wpa_mlo.links[i].ap_rsne_len = rsne ? 2 + rsne[1] : 0;
wpa_mlo.links[i].ap_rsnxe = rsnxe ? (u8 *) rsnxe : NULL;
wpa_mlo.links[i].ap_rsnxe_len = rsnxe ? 2 + rsnxe[1] : 0;
wpa_mlo.links[i].ap_rsnoe = rsnoe ? (u8 *) rsnoe : NULL;
wpa_mlo.links[i].ap_rsnoe_len = rsnoe ? 2 + rsnoe[1] : 0;
wpa_mlo.links[i].ap_rsno2e = rsno2e ? (u8 *) rsno2e : NULL;
wpa_mlo.links[i].ap_rsno2e_len = rsno2e ? 2 + rsno2e[1] : 0;
wpa_mlo.links[i].ap_rsnxoe = rsnxoe ? (u8 *) rsnxoe : NULL;
wpa_mlo.links[i].ap_rsnxoe_len = rsnxoe ? 2 + rsnxoe[1] : 0;
os_memcpy(wpa_mlo.links[i].bssid, drv_mlo.links[i].bssid,
ETH_ALEN);