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 */
} 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);
#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 */
};
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 */
#ifdef CONFIG_IEEE80211BE
+
static int hostapd_wpa_auth_get_ml_rsn_info(void *ctx,
struct wpa_auth_ml_rsn_info *info)
{
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 */
#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;