MLO: Store MLO link information in RSN Authentication

Make the MLO related information available for the RSN Authenticator
state machine to be able to perform steps needed on an AP MLD. The
actual use of this information will be in the following commits.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
This commit is contained in:
Andrei Otcheretianski 2023-05-22 22:33:59 +03:00 committed by Jouni Malinen
parent cb130bbcb9
commit 3102d7676b
5 changed files with 215 additions and 5 deletions

View file

@ -3970,15 +3970,34 @@ static int __check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
wpa_ie -= 2;
wpa_ie_len += 2;
if (sta->wpa_sm == NULL)
if (!sta->wpa_sm) {
#ifdef CONFIG_IEEE80211BE
struct mld_info *info = &sta->mld_info;
#endif /* CONFIG_IEEE80211BE */
sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
sta->addr,
p2p_dev_addr);
if (sta->wpa_sm == NULL) {
wpa_printf(MSG_WARNING, "Failed to initialize WPA "
"state machine");
return WLAN_STATUS_UNSPECIFIED_FAILURE;
if (!sta->wpa_sm) {
wpa_printf(MSG_WARNING,
"Failed to initialize RSN state machine");
return WLAN_STATUS_UNSPECIFIED_FAILURE;
}
#ifdef CONFIG_IEEE80211BE
if (info->mld_sta) {
wpa_printf(MSG_DEBUG,
"MLD: Set ML info in RSN Authenticator");
wpa_auth_set_ml_info(sta->wpa_sm,
hapd->mld_addr,
sta->mld_assoc_link_id,
info);
}
#endif /* CONFIG_IEEE80211BE */
}
wpa_auth_set_auth_alg(sta->wpa_sm, sta->auth_alg);
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
hapd->iface->freq,

View file

@ -29,6 +29,7 @@
#include "drivers/driver.h"
#include "ap_config.h"
#include "ieee802_11.h"
#include "sta_info.h"
#include "wpa_auth.h"
#include "pmksa_cache_auth.h"
#include "wpa_auth_i.h"
@ -695,6 +696,9 @@ wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr,
sm->wpa_auth = wpa_auth;
sm->group = wpa_auth->group;
wpa_group_get(sm->wpa_auth, sm->group);
#ifdef CONFIG_IEEE80211BE
sm->mld_assoc_link_id = -1;
#endif /* CONFIG_IEEE80211BE */
return sm;
}
@ -3590,6 +3594,31 @@ static u8 * replace_ie(const char *name, const u8 *old_buf, size_t *len, u8 eid,
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_IEEE80211BE
void wpa_auth_ml_get_rsn_info(struct wpa_authenticator *a,
struct wpa_auth_ml_link_rsn_info *info)
{
info->rsn_ies = a->wpa_ie;
info->rsn_ies_len = a->wpa_ie_len;
wpa_printf(MSG_DEBUG, "RSN: MLD: link_id=%u, rsn_ies_len=%zu",
info->link_id, info->rsn_ies_len);
}
static void wpa_auth_get_ml_rsn_info(struct wpa_authenticator *wpa_auth,
struct wpa_auth_ml_rsn_info *info)
{
if (!wpa_auth->cb->get_ml_rsn_info)
return;
wpa_auth->cb->get_ml_rsn_info(wpa_auth->cb_ctx, info);
}
#endif /* CONFIG_IEEE80211BE */
SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
{
u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde = NULL, *pos, stub_gtk[32];
@ -6026,3 +6055,81 @@ void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success)
eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL);
}
void wpa_auth_set_ml_info(struct wpa_state_machine *sm, const u8 *mld_addr,
u8 mld_assoc_link_id, struct mld_info *info)
{
#ifdef CONFIG_IEEE80211BE
struct wpa_auth_ml_rsn_info ml_rsn_info;
unsigned int link_id, i;
if (!info)
return;
os_memset(sm->mld_links, 0, sizeof(sm->mld_links));
wpa_auth_logger(sm->wpa_auth, wpa_auth_get_spa(sm), LOGGER_DEBUG,
"MLD: Initialization");
os_memcpy(sm->own_mld_addr, mld_addr, ETH_ALEN);
os_memcpy(sm->peer_mld_addr, info->common_info.mld_addr, ETH_ALEN);
sm->mld_assoc_link_id = mld_assoc_link_id;
os_memset(&ml_rsn_info, 0, sizeof(ml_rsn_info));
for (i = 0, link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
struct mld_link_info *link = &info->links[link_id];
struct mld_link *sm_link = &sm->mld_links[link_id];
sm_link->valid = link->valid;
if (!link->valid)
continue;
os_memcpy(sm_link->peer_addr, link->peer_addr, ETH_ALEN);
os_memcpy(sm_link->own_addr, link->local_addr, ETH_ALEN);
wpa_printf(MSG_DEBUG,
"WPA_AUTH: MLD: id=%u, addr=" MACSTR " peer=" MACSTR,
link_id,
MAC2STR(sm_link->own_addr),
MAC2STR(sm_link->peer_addr));
if (link_id != mld_assoc_link_id)
sm->n_mld_affiliated_links++;
ml_rsn_info.links[i++].link_id = link_id;
}
ml_rsn_info.n_mld_links = i;
wpa_auth_get_ml_rsn_info(sm->wpa_auth, &ml_rsn_info);
for (i = 0; i < ml_rsn_info.n_mld_links; i++) {
struct mld_link *sm_link;
const u8 *rsn_ies;
u8 rsn_ies_len;
sm_link = &sm->mld_links[ml_rsn_info.links[i].link_id];
rsn_ies = ml_rsn_info.links[i].rsn_ies;
rsn_ies_len = ml_rsn_info.links[i].rsn_ies_len;
/* This should not really happen */
if (!rsn_ies || rsn_ies_len < 2 || rsn_ies[0] != WLAN_EID_RSN ||
rsn_ies[1] + 2 > rsn_ies_len) {
wpa_printf(MSG_INFO, "WPA_AUTH: MLD: Invalid RSNE");
continue;
}
sm_link->rsne = rsn_ies;
sm_link->rsne_len = rsn_ies[1] + 2;
if (rsn_ies[1] + 2UL + 2UL < rsn_ies_len &&
rsn_ies[rsn_ies[1] + 2] == WLAN_EID_RSNX) {
sm_link->rsnxe = rsn_ies + 2 + rsn_ies[1];
sm_link->rsnxe_len = sm_link->rsnxe[1] + 2;
}
}
#endif /* CONFIG_IEEE80211BE */
}

View file

@ -15,6 +15,7 @@
#include "common/ieee802_11_defs.h"
struct vlan_description;
struct mld_info;
#define MAX_OWN_IE_OVERRIDE 256
@ -288,6 +289,16 @@ typedef enum {
WPA_EAPOL_keyDone, WPA_EAPOL_inc_EapolFramesTx
} wpa_eapol_variable;
struct wpa_auth_ml_rsn_info {
unsigned int n_mld_links;
struct wpa_auth_ml_link_rsn_info {
unsigned int link_id;
const u8 *rsn_ies;
size_t rsn_ies_len;
} links[MAX_NUM_MLD_LINKS];
};
struct wpa_auth_callbacks {
void (*logger)(void *ctx, const u8 *addr, logger_level level,
const char *txt);
@ -355,6 +366,9 @@ struct wpa_auth_callbacks {
int (*set_ltf_keyseed)(void *ctx, const u8 *addr, const u8 *ltf_keyseed,
size_t ltf_keyseed_len);
#endif /* CONFIG_PASN */
#ifdef CONFIG_IEEE80211BE
int (*get_ml_rsn_info)(void *ctx, struct wpa_auth_ml_rsn_info *info);
#endif /* CONFIG_IEEE80211BE */
};
struct wpa_authenticator * wpa_init(const u8 *addr,
@ -593,4 +607,9 @@ void wpa_auth_set_ocv_override_freq(struct wpa_authenticator *wpa_auth,
void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success);
void wpa_auth_set_ml_info(struct wpa_state_machine *sm, const u8 *mld_addr,
u8 mld_assoc_link_id, struct mld_info *info);
void wpa_auth_ml_get_rsn_info(struct wpa_authenticator *a,
struct wpa_auth_ml_link_rsn_info *info);
#endif /* WPA_AUTH_H */

View file

@ -1496,6 +1496,50 @@ static int hostapd_set_ltf_keyseed(void *ctx, const u8 *peer_addr,
#endif /* CONFIG_PASN */
#ifdef CONFIG_IEEE80211BE
static int hostapd_wpa_auth_get_ml_rsn_info(void *ctx,
struct wpa_auth_ml_rsn_info *info)
{
struct hostapd_data *hapd = ctx;
unsigned int i, j;
wpa_printf(MSG_DEBUG, "WPA_AUTH: MLD: Get RSN info CB: n_mld_links=%u",
info->n_mld_links);
if (!hapd->conf->mld_ap || !hapd->iface || !hapd->iface->interfaces)
return -1;
for (i = 0; i < info->n_mld_links; i++) {
unsigned int link_id = info->links[i].link_id;
wpa_printf(MSG_DEBUG,
"WPA_AUTH: MLD: Get link RSN CB: link_id=%u",
link_id);
for (j = 0; j < hapd->iface->interfaces->count; j++) {
struct hostapd_iface *iface =
hapd->iface->interfaces->iface[j];
if (!iface->bss[0]->conf->mld_ap ||
hapd->conf->mld_id != iface->bss[0]->conf->mld_id ||
link_id != iface->bss[0]->mld_link_id)
continue;
wpa_auth_ml_get_rsn_info(iface->bss[0]->wpa_auth,
&info->links[i]);
break;
}
if (j == hapd->iface->interfaces->count)
wpa_printf(MSG_DEBUG,
"WPA_AUTH: MLD: link=%u not found", link_id);
}
return 0;
}
#endif /* CONFIG_IEEE80211BE */
int hostapd_setup_wpa(struct hostapd_data *hapd)
{
struct wpa_auth_config _conf;
@ -1545,6 +1589,9 @@ int hostapd_setup_wpa(struct hostapd_data *hapd)
#ifdef CONFIG_PASN
.set_ltf_keyseed = hostapd_set_ltf_keyseed,
#endif /* CONFIG_PASN */
#ifdef CONFIG_IEEE80211BE
.get_ml_rsn_info = hostapd_wpa_auth_get_ml_rsn_info,
#endif /* CONFIG_IEEE80211BE */
};
const u8 *wpa_ie;
size_t wpa_ie_len;

View file

@ -172,6 +172,24 @@ struct wpa_state_machine {
void *eapol_status_cb_ctx1;
void *eapol_status_cb_ctx2;
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_IEEE80211BE
u8 own_mld_addr[ETH_ALEN];
u8 peer_mld_addr[ETH_ALEN];
s8 mld_assoc_link_id;
u8 n_mld_affiliated_links;
struct mld_link {
bool valid;
u8 peer_addr[ETH_ALEN];
u8 own_addr[ETH_ALEN];
const u8 *rsne;
size_t rsne_len;
const u8 *rsnxe;
size_t rsnxe_len;
} mld_links[MAX_NUM_MLD_LINKS];
#endif /* CONFIG_IEEE80211BE */
};