[PATCH v2 10/17] MLD STA: Add support for processing EAPOL 3/4 frame
Peer, Ilan
ilan.peer at intel.com
Mon Oct 3 05:30:09 PDT 2022
Hi,
> -----Original Message-----
> From: Hostap <hostap-bounces at lists.infradead.org> On Behalf Of
> Veerendranath Jakkam
> Sent: Saturday, October 01, 2022 11:21
> To: hostap at lists.infradead.org
> Cc: quic_vjakkam at quicinc.com
> Subject: [PATCH v2 10/17] MLD STA: Add support for processing EAPOL 3/4
> frame
>
> Process EAPOL 3/4 frame and plumb PTK and per-link GTK/IGTK/BIGTK keys
> to driver.
>
> Signed-off-by: Veerendranath Jakkam <quic_vjakkam at quicinc.com>
> ---
> src/rsn_supp/wpa.c | 474
> ++++++++++++++++++++++++++++++++++++++++++++++++++-
> src/rsn_supp/wpa_i.h | 6 +
> 2 files changed, 478 insertions(+), 2 deletions(-)
>
> diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 5611da3..5d1ff43
> 100644
> --- a/src/rsn_supp/wpa.c
> +++ b/src/rsn_supp/wpa.c
> @@ -1220,6 +1220,64 @@ static int wpa_supplicant_install_gtk(struct
> wpa_sm *sm, }
>
>
> +static int wpa_supplicant_install_mlo_gtk(struct wpa_sm *sm, u8 link_id,
> + const struct wpa_gtk_data *gd,
> + const u8 *key_rsc, int wnm_sleep) {
> + const u8 *gtk = gd->gtk;
> + u8 gtk_buf[32];
> + char title[50];
> + int ret;
> +
> + /* Detect possible key reinstallation */
> + if ((sm->mlo.links[link_id].gtk.gtk_len == (size_t) gd->gtk_len &&
> + os_memcmp(sm->mlo.links[link_id].gtk.gtk, gd->gtk,
> + sm->mlo.links[link_id].gtk.gtk_len) == 0) ||
> + (sm->mlo.links[link_id].gtk_wnm_sleep.gtk_len ==
> + (size_t) gd->gtk_len &&
> + os_memcmp(sm->mlo.links[link_id].gtk_wnm_sleep.gtk, gd->gtk,
> + sm->mlo.links[link_id].gtk_wnm_sleep.gtk_len) == 0)) {
> + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
> + "RSN: Not reinstalling already in-use GTK to the driver
> (link_id=%d keyidx=%d tx=%d len=%d)",
> + link_id, gd->keyidx, gd->tx, gd->gtk_len);
> + return 0;
> + }
> +
> + ret = os_snprintf(title, sizeof(title), "RSN: Link %u Group Key",
> + link_id);
This is probably not needed as the link_id is also printed below. So you can just reverse the prints and directly
dump the key.
> + if (!os_snprintf_error(sizeof(title), ret))
> + wpa_hexdump_key(MSG_DEBUG, title, gd->gtk, gd-
> >gtk_len);
> + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
> + "RSN: Installing GTK to the driver (link_id=%d keyidx=%d
> tx=%d len=%d)",
> + link_id, gd->keyidx, gd->tx, gd->gtk_len);
> + ret = os_snprintf(title, sizeof(title), "RSN: Link %u RSC", link_id);
> + if (!os_snprintf_error(sizeof(title), ret))
> + wpa_hexdump(MSG_DEBUG, title, key_rsc, gd-
> >key_rsc_len);
> + if (wpa_sm_set_key(sm, link_id, gd->alg, broadcast_ether_addr,
> + gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len, gtk,
> + gd->gtk_len, KEY_FLAG_GROUP_RX) < 0) {
> + wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
> + "RSN: Failed to set GTK to the driver (link_id=%d
> alg=%d keylen=%d keyidx=%d)",
> + link_id, gd->alg, gd->gtk_len, gd->keyidx);
> + forced_memzero(gtk_buf, sizeof(gtk_buf));
This looks strange: gtk_buf was not used in this function.
> + return -1;
> + }
> + forced_memzero(gtk_buf, sizeof(gtk_buf));
> +
Same here.
> + if (wnm_sleep) {
> + sm->mlo.links[link_id].gtk_wnm_sleep.gtk_len = gd-
> >gtk_len;
> + os_memcpy(sm->mlo.links[link_id].gtk_wnm_sleep.gtk, gd-
> >gtk,
> + sm->mlo.links[link_id].gtk_wnm_sleep.gtk_len);
> + } else {
> + sm->mlo.links[link_id].gtk.gtk_len = gd->gtk_len;
> + os_memcpy(sm->mlo.links[link_id].gtk.gtk, gd->gtk,
> + sm->mlo.links[link_id].gtk.gtk_len);
> + }
> +
> + return 0;
> +}
> +
> +
Snip ...
> +static int wpa_supplicant_mlo_gtk(struct wpa_sm *sm, u8 link_id, const u8
> *gtk,
> + size_t gtk_len, int key_info)
> +{
> + struct wpa_gtk_data gd;
> + const u8 *key_rsc;
> + char title[100];
> + int ret;
> +
> + /*
> + * MLO GTK KDE format:
> + * KeyID[bits 0-1], Tx [bit 2], Reserved [bit 3], link id [4-7]
> + * PN
> + * GTK
> + */
> + os_memset(&gd, 0, sizeof(gd));
> + ret = os_snprintf(title, sizeof(title),
> + "RSN: received link %u GTK in pairwise handshake",
> + link_id);
> + if (!os_snprintf_error(sizeof(title), ret))
> + wpa_hexdump_key(MSG_DEBUG, title, gtk, gtk_len);
Consider adding wpa_hexdump_link() and wpa_hexdump_link_key() that would also directly print the link ID.
> +
> + if (gtk_len < RSN_MLO_GTK_KDE_PREFIX_LENGTH ||
> + gtk_len - RSN_MLO_GTK_KDE_PREFIX_LENGTH > sizeof(gd.gtk))
> + return -1;
> +
> + gd.keyidx = gtk[0] & 0x3;
> + gtk += 1;
> + gtk_len -= 1;
> +
> + key_rsc = gtk;
> +
> + gtk += 6;
> + gtk_len -= 6;
> +
> + os_memcpy(gd.gtk, gtk, gtk_len);
> + gd.gtk_len = gtk_len;
> +
> + ret = 0;
> + if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
> gtk_len,
> + gtk_len, &gd.key_rsc_len,
> + &gd.alg) ||
> + wpa_supplicant_install_mlo_gtk(sm, link_id, &gd, key_rsc, 0)) {
> + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
> + "RSN: Failed to install GTK for MLO Link ID %u",
> + link_id);
> + ret = -1;
> + goto out;
> + }
> +
> +out:
> + forced_memzero(&gd, sizeof(gd));
> + return ret;
> +}
> +
> +
Snip ...
> +static int _mlo_ieee80211w_set_keys(struct wpa_sm *sm, u8 link_id,
> + struct wpa_eapol_ie_parse *ie)
> +{
> + size_t len;
> +
> + if (!wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher))
> + return 0;
> +
> + if (ie->mlo_igtk[link_id]) {
> + const struct rsn_mlo_igtk_kde *igtk;
Probably not needed
> +
> + len = wpa_cipher_key_len(sm->mgmt_group_cipher);
> + if (ie->mlo_igtk_len[link_id] !=
> + (RSN_MLO_IGTK_KDE_PREFIX_LENGTH + len))
> + return -1;
> +
> + igtk = (const struct rsn_mlo_igtk_kde *) ie-
> >mlo_igtk[link_id];
> + if (wpa_supplicant_install_mlo_igtk(sm, link_id, igtk, 0) < 0)
> + return -1;
> + }
> +
> + if (ie->mlo_bigtk[link_id] && sm->beacon_prot) {
> + const struct rsn_mlo_bigtk_kde *bigtk;
Probably not needed.
> +
> + len = wpa_cipher_key_len(sm->mgmt_group_cipher);
> + if (ie->mlo_bigtk_len[link_id] !=
> + (RSN_MLO_BIGTK_KDE_PREFIX_LENGTH + len))
> + return -1;
> +
> + bigtk = (const struct rsn_mlo_bigtk_kde *) ie-
> >mlo_bigtk[link_id];
> + if (wpa_supplicant_install_mlo_bigtk(sm, link_id, bigtk, 0) <
> 0)
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +
Snip ...
> + /* Add PMKSA cache entry for Suite B AKMs here since PMKID can
> be
> + * calculated only after KCK has been derived. Though, do not replace
> an
> + * existing PMKSA entry after each 4-way handshake (i.e., new
> KCK/PMKID)
> + * to avoid unnecessary changes of PMKID while continuing to use
> the
> + * same PMK. */
> + if (sm->proto == WPA_PROTO_RSN &&
> wpa_key_mgmt_suite_b(sm->key_mgmt) &&
> + !sm->cur_pmksa) {
> + struct rsn_pmksa_cache_entry *sa;
> +
> + sa = pmksa_cache_add(sm->pmksa, sm->pmk, sm-
> >pmk_len, NULL,
> + sm->ptk.kck, sm->ptk.kck_len,
> + sm->bssid, sm->own_addr,
> + sm->network_ctx, sm->key_mgmt, NULL);
Shouldn't the PMKSA be added to all setup links?
Regards,
Ilan.
More information about the Hostap
mailing list