[RFC 14/30] WPA: Handle SMD configuration in WPA SM
Ilan Peer
ilan.peer at intel.com
Wed Oct 21 06:43:32 PDT 2026
- Indicate support for SMD in RSNXE when supported.
- Configure SMD_KDK derivation in PMK to PTK derivation,
when SMD is supported and the PTK mode is per-AP MLD.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
src/rsn_supp/wpa.c | 51 ++++++++++++++++++++++++++++++++++++++++---
src/rsn_supp/wpa_ie.c | 3 +++
2 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index ab0a87fcfc15..980d659c3a4e 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -749,12 +749,31 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
}
+static bool wpa_sm_is_smd_per_ap_mld_ptk(struct wpa_sm *sm)
+{
+ const struct ieee80211_smd_info *smd;
+
+ if (!sm->smd || !sm->ap_smd_info)
+ return false;
+
+ if (!ieee802_11_sec_prof_rsnx_capab(sm->ap_security_profile,
+ WLAN_RSNX_CAPAB_SMD))
+ return false;
+
+ smd = (const struct ieee80211_smd_info *)sm->ap_smd_info;
+ return !!(smd->smd_capabilities & SMD_CAPA_PER_AP_MLD_PTK_MODE);
+}
+
+
static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
const struct wpa_eapol_key *key, struct wpa_ptk *ptk)
{
int ret;
const u8 *z = NULL, *ap_rsnxe;
- size_t z_len = 0, kdk_len, ap_rsnxe_len;
+ const u8 *xxkey = sm->pmk;
+ size_t xxkey_len = sm->pmk_len;
+ u8 z_buf[WPA_MAX_Z_LEN];
+ size_t z_len = 0, kdk_len, ap_rsnxe_len, smd_kdk_len;
int akmp;
ap_rsnxe = wpa_sm_get_ap_rsnxe(sm, &ap_rsnxe_len);
@@ -771,6 +790,17 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
}
#endif /* CONFIG_DPP2 */
+ if (sm->smd && sm->ap_smd_info) {
+ const struct ieee80211_smd_info *smd;
+
+ smd = (const struct ieee80211_smd_info *) sm->ap_smd_info;
+ if (z && z_len)
+ os_memcpy(z_buf, z, z_len);
+ os_memcpy(z_buf + z_len, smd->smd_id, ETH_ALEN);
+ z_len += ETH_ALEN;
+ z = z_buf;
+ }
+
akmp = sm->key_mgmt;
#ifdef CONFIG_OWE
if (sm->owe_ptk_workaround && akmp == WPA_KEY_MGMT_OWE &&
@@ -788,11 +818,26 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
else
kdk_len = 0;
- ret = wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
+ if (wpa_sm_is_smd_per_ap_mld_ptk(sm))
+ smd_kdk_len = sm->pmk_len;
+ else
+ smd_kdk_len = 0;
+
+ /*
+ * The SMD_KDK is not rederived on PTK rekeying, but it is used instead
+ * of the PMK. See section 37.16.4.2 in Draft IEEE P802.11bn/D2.0.
+ */
+ if (smd_kdk_len && sm->ptk.smd_kdk_len) {
+ xxkey = sm->ptk.smd_kdk;
+ xxkey_len = sm->ptk.smd_kdk_len;
+ smd_kdk_len = 0;
+ }
+
+ ret = wpa_pmk_to_ptk(xxkey, xxkey_len, "Pairwise key expansion",
sm->own_addr, wpa_sm_get_auth_addr(sm), sm->snonce,
key->key_nonce, ptk, akmp,
sm->pairwise_cipher, z, z_len,
- kdk_len, sm->pasn_group, 0);
+ kdk_len, sm->pasn_group, smd_kdk_len);
if (ret) {
wpa_printf(MSG_ERROR, "WPA: PTK derivation failed");
return ret;
diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c
index faca57216a22..9225aa6864e6 100644
--- a/src/rsn_supp/wpa_ie.c
+++ b/src/rsn_supp/wpa_ie.c
@@ -694,6 +694,9 @@ u64 wpa_sm_get_rsnxe_capab(struct wpa_sm *sm)
capab |= BIT(WLAN_RSNX_CAPAB_802_1X_IN_AUTH_FRAMES);
#endif /* CONFIG_IEEE8021X_AUTH */
+ if (sm->smd)
+ capab |= BIT_ULL(WLAN_RSNX_CAPAB_SMD);
+
return capab;
}
--
2.55.0
More information about the Hostap
mailing list