From 62a8f96e5b67e26991687731ac4dd01e63d2742a Mon Sep 17 00:00:00 2001 From: Rameshkumar Sundaram Date: Thu, 28 Mar 2024 23:46:47 +0530 Subject: [PATCH] AP MLD: Calculate ML KDE length separately for each link Calculate links specific MLO GTK/IGTK/BIGTK KDE lengths based on corresponding cipher and key instead of taking length of one link and multiplying it by no of associated links. This is needed since the group ciphers might be different between the affiliated links. Signed-off-by: Rameshkumar Sundaram Co-developed-by: Adil Saeed Musthafa Signed-off-by: Adil Saeed Musthafa Signed-off-by: Aditya Kumar Singh --- src/ap/wpa_auth.c | 53 ++++++++++++++++++++++++----------------- src/common/wpa_common.h | 2 ++ 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index ca8b16dae..69c62b498 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -4094,38 +4094,47 @@ static void wpa_auth_get_ml_key_info(struct wpa_authenticator *wpa_auth, static size_t wpa_auth_ml_group_kdes_len(struct wpa_state_machine *sm) { - struct wpa_authenticator *wpa_auth = sm->wpa_auth; - struct wpa_group *gsm = sm->group; - size_t gtk_len = gsm->GTK_len; - size_t igtk_len; - size_t kde_len; - unsigned int n_links; + struct wpa_authenticator *wpa_auth; + size_t kde_len = 0; + int link_id; if (sm->mld_assoc_link_id < 0) return 0; - n_links = sm->n_mld_affiliated_links + 1; + for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) { + if (!sm->mld_links[link_id].valid) + continue; - /* MLO GTK KDE for each link */ - kde_len = n_links * (2 + RSN_SELECTOR_LEN + 1 + 6 + gtk_len); + wpa_auth = sm->mld_links[link_id].wpa_auth; + if (!wpa_auth || !wpa_auth->group) + continue; - if (!sm->mgmt_frame_prot) - return kde_len; + /* MLO GTK KDE + * Header + Key ID + Tx + LinkID + PN + GTK */ + kde_len += KDE_HDR_LEN + 1 + RSN_PN_LEN; + kde_len += wpa_auth->group->GTK_len; - /* MLO IGTK KDE for each link */ - igtk_len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); - kde_len += n_links * (2 + RSN_SELECTOR_LEN + 2 + 6 + 1 + igtk_len); + if (!sm->mgmt_frame_prot) + continue; - if (wpa_auth->conf.tx_bss_auth) { - wpa_auth = wpa_auth->conf.tx_bss_auth; - igtk_len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); + if (wpa_auth->conf.tx_bss_auth) + wpa_auth = wpa_auth->conf.tx_bss_auth; + + /* MLO IGTK KDE + * Header + Key ID + IPN + LinkID + IGTK */ + kde_len += KDE_HDR_LEN + WPA_IGTK_KDE_PREFIX_LEN + 1; + kde_len += wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); + + if (!wpa_auth->conf.beacon_prot) + continue; + + /* MLO BIGTK KDE + * Header + Key ID + BIPN + LinkID + BIGTK */ + kde_len += KDE_HDR_LEN + WPA_BIGTK_KDE_PREFIX_LEN + 1; + kde_len += wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); } - if (!wpa_auth->conf.beacon_prot) - return kde_len; - - /* MLO BIGTK KDE for each link */ - kde_len += n_links * (2 + RSN_SELECTOR_LEN + 2 + 6 + 1 + igtk_len); + wpa_printf(MSG_DEBUG, "MLO Group KDEs len = %zu", kde_len); return kde_len; } diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index 404e571c0..8f52984a4 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -339,6 +339,8 @@ struct rsn_ie_hdr { } STRUCT_PACKED; +#define KDE_HDR_LEN (1 + 1 + RSN_SELECTOR_LEN) + struct rsn_error_kde { be16 mui; be16 error_type;