From 137b85509248f9ebdc95790229aae24afd9e30a6 Mon Sep 17 00:00:00 2001 From: Andrei Otcheretianski Date: Mon, 22 May 2023 22:34:02 +0300 Subject: [PATCH] MLO: Mechanism for fetching group key information for the links Allow RSN authenticator to fetch the current group key information with the keys and the last used PN/IPN/BIPN for MLO specific KDEs. Signed-off-by: Ilan Peer Signed-off-by: Andrei Otcheretianski --- src/ap/wpa_auth.c | 45 ++++++++++++++++++++++++++++++++++++++++ src/ap/wpa_auth.h | 28 +++++++++++++++++++++++++ src/ap/wpa_auth_glue.c | 47 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 71b331a73..aeaffd07d 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -3700,6 +3700,51 @@ static void wpa_auth_get_ml_rsn_info(struct wpa_authenticator *wpa_auth, wpa_auth->cb->get_ml_rsn_info(wpa_auth->cb_ctx, info); } + +void wpa_auth_ml_get_key_info(struct wpa_authenticator *a, + struct wpa_auth_ml_link_key_info *info, + bool mgmt_frame_prot, bool beacon_prot) +{ + struct wpa_group *gsm = a->group; + u8 rsc[WPA_KEY_RSC_LEN]; + + wpa_printf(MSG_DEBUG, + "MLD: Get group key info: link_id=%u, IGTK=%u, BIGTK=%u", + info->link_id, mgmt_frame_prot, beacon_prot); + + info->gtkidx = gsm->GN & 0x03; + info->gtk = gsm->GTK[gsm->GN - 1]; + info->gtk_len = gsm->GTK_len; + + if (wpa_auth_get_seqnum(a, NULL, gsm->GN, rsc) < 0) + os_memset(info->pn, 0, sizeof(info->pn)); + else + os_memcpy(info->pn, rsc, sizeof(info->pn)); + + if (!mgmt_frame_prot) + return; + + info->igtkidx = gsm->GN_igtk; + info->igtk = gsm->IGTK[gsm->GN_igtk - 4]; + info->igtk_len = wpa_cipher_key_len(a->conf.group_mgmt_cipher); + + if (wpa_auth_get_seqnum(a, NULL, gsm->GN_igtk, rsc) < 0) + os_memset(info->ipn, 0, sizeof(info->ipn)); + else + os_memcpy(info->ipn, rsc, sizeof(info->ipn)); + + if (!beacon_prot) + return; + + info->bigtkidx = gsm->GN_bigtk; + info->bigtk = gsm->BIGTK[gsm->GN_bigtk - 6]; + + if (wpa_auth_get_seqnum(a, NULL, gsm->GN_bigtk, rsc) < 0) + os_memset(info->bipn, 0, sizeof(info->bipn)); + else + os_memcpy(info->bipn, rsc, sizeof(info->bipn)); +} + #endif /* CONFIG_IEEE80211BE */ diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 311d91f7f..c076d71a6 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -299,6 +299,30 @@ struct wpa_auth_ml_rsn_info { } links[MAX_NUM_MLD_LINKS]; }; +struct wpa_auth_ml_key_info { + unsigned int n_mld_links; + bool mgmt_frame_prot; + bool beacon_prot; + + struct wpa_auth_ml_link_key_info { + u8 link_id; + + u8 gtkidx; + u8 gtk_len; + u8 pn[6]; + const u8 *gtk; + + u8 igtkidx; + u8 igtk_len; + const u8 *igtk; + u8 ipn[6]; + + u8 bigtkidx; + const u8 *bigtk; + u8 bipn[6]; + } links[MAX_NUM_MLD_LINKS]; +}; + struct wpa_auth_callbacks { void (*logger)(void *ctx, const u8 *addr, logger_level level, const char *txt); @@ -368,6 +392,7 @@ struct wpa_auth_callbacks { #endif /* CONFIG_PASN */ #ifdef CONFIG_IEEE80211BE int (*get_ml_rsn_info)(void *ctx, struct wpa_auth_ml_rsn_info *info); + int (*get_ml_key_info)(void *ctx, struct wpa_auth_ml_key_info *info); #endif /* CONFIG_IEEE80211BE */ }; @@ -611,5 +636,8 @@ 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); +void wpa_auth_ml_get_key_info(struct wpa_authenticator *a, + struct wpa_auth_ml_link_key_info *info, + bool mgmt_frame_prot, bool beacon_prot); #endif /* WPA_AUTH_H */ diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 41c029973..eeeecaf4c 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -1497,6 +1497,7 @@ static int hostapd_set_ltf_keyseed(void *ctx, const u8 *peer_addr, #ifdef CONFIG_IEEE80211BE + static int hostapd_wpa_auth_get_ml_rsn_info(void *ctx, struct wpa_auth_ml_rsn_info *info) { @@ -1537,6 +1538,51 @@ static int hostapd_wpa_auth_get_ml_rsn_info(void *ctx, return 0; } + + +static int hostapd_wpa_auth_get_ml_key_info(void *ctx, + struct wpa_auth_ml_key_info *info) +{ + struct hostapd_data *hapd = ctx; + unsigned int i, j; + + wpa_printf(MSG_DEBUG, "WPA_AUTH: MLD: Get key 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++) { + u8 link_id = info->links[i].link_id; + + wpa_printf(MSG_DEBUG, + "WPA_AUTH: MLD: Get link info 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_key_info(iface->bss[0]->wpa_auth, + &info->links[i], + info->mgmt_frame_prot, + info->beacon_prot); + 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 */ @@ -1591,6 +1637,7 @@ int hostapd_setup_wpa(struct hostapd_data *hapd) #endif /* CONFIG_PASN */ #ifdef CONFIG_IEEE80211BE .get_ml_rsn_info = hostapd_wpa_auth_get_ml_rsn_info, + .get_ml_key_info = hostapd_wpa_auth_get_ml_key_info, #endif /* CONFIG_IEEE80211BE */ }; const u8 *wpa_ie;