Hi, > -----Original Message----- > From: Hostap <hostap-bounces@xxxxxxxxxxxxxxxxxxx> On Behalf Of > Veerendranath Jakkam > Sent: Saturday, October 01, 2022 11:21 > To: hostap@xxxxxxxxxxxxxxxxxxx > Cc: quic_vjakkam@xxxxxxxxxxx > 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@xxxxxxxxxxx> > --- > 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. _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap