#define WLAN_RSNX_CAPAB_SECURE_RTT 9
#define WLAN_RSNX_CAPAB_URNM_MFPR_X20 10
#define WLAN_RSNX_CAPAB_URNM_MFPR 15
+#define WLAN_RSNX_CAPAB_SSID_PROTECTION 21
/* Multiple BSSID element subelements */
#define WLAN_MBSSID_SUBELEMENT_NONTRANSMITTED_BSSID_PROFILE 0
ie->supp_oper_classes = pos + 2;
ie->supp_oper_classes_len = pos[1];
}
+ } else if (*pos == WLAN_EID_SSID) {
+ ie->ssid = pos + 2;
+ ie->ssid_len = pos[1];
+ wpa_hexdump_ascii(MSG_DEBUG, "RSN: SSID in EAPOL-Key",
+ ie->ssid, ie->ssid_len);
} else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
ret = wpa_parse_generic(pos, ie);
if (ret == 1) {
size_t supp_channels_len;
const u8 *supp_oper_classes;
size_t supp_oper_classes_len;
+ const u8 *ssid;
+ size_t ssid_len;
u8 qosinfo;
u16 aid;
const u8 *wmm;
if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0)
goto failed;
+ if (sm->ssid_protection) {
+ if (!ie.ssid) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "RSN: No SSID included in EAPOL-Key msg 3/4");
+ goto failed;
+ }
+
+ if (ie.ssid_len != sm->ssid_len ||
+ os_memcmp(ie.ssid, sm->ssid, sm->ssid_len) != 0) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "RSN: SSID mismatch in EAPOL-Key msg 3/4");
+ wpa_hexdump_ascii(MSG_DEBUG, "RSN: Received SSID",
+ ie.ssid, ie.ssid_len);
+ wpa_hexdump_ascii(MSG_DEBUG, "RSN: Expected SSID",
+ sm->ssid, sm->ssid_len);
+ goto failed;
+ }
+
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "RSN: SSID matched expected value");
+ }
+
if (mlo && !ie.valid_mlo_gtks) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"MLO RSN: No GTK KDE included in EAPOL-Key msg 3/4");
}
+void wpa_sm_set_ssid(struct wpa_sm *sm, const u8 *ssid, size_t ssid_len)
+{
+ if (!sm)
+ return;
+
+ if (ssid) {
+ os_memcpy(sm->ssid, ssid, ssid_len);
+ sm->ssid_len = ssid_len;
+ } else {
+ sm->ssid_len = 0;
+ }
+}
+
+
int wpa_sm_set_mlo_params(struct wpa_sm *sm, const struct wpa_sm_mlo *mlo)
{
int i;
case WPA_PARAM_FT_PREPEND_PMKID:
sm->ft_prepend_pmkid = value;
break;
+ case WPA_PARAM_SSID_PROTECTION:
+ sm->ssid_protection = value;
+ break;
default:
break;
}
sm->assoc_rsnxe_len = len;
}
+ if (sm->ssid_protection &&
+ !ieee802_11_rsnx_capab(sm->assoc_rsnxe,
+ WLAN_RSNX_CAPAB_SSID_PROTECTION)) {
+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "RSN: Disabling SSID protection based on own RSNXE update");
+ sm->ssid_protection = 0;
+ }
+
return 0;
}
WPA_PARAM_ENCRYPT_EAPOL_M2,
WPA_PARAM_ENCRYPT_EAPOL_M4,
WPA_PARAM_FT_PREPEND_PMKID,
+ WPA_PARAM_SSID_PROTECTION,
};
struct rsn_supp_config {
void wpa_sm_set_fast_reauth(struct wpa_sm *sm, int fast_reauth);
void wpa_sm_set_scard_ctx(struct wpa_sm *sm, void *scard_ctx);
void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config);
+void wpa_sm_set_ssid(struct wpa_sm *sm, const u8 *ssid, size_t ssid_len);
void wpa_sm_set_own_addr(struct wpa_sm *sm, const u8 *addr);
void wpa_sm_set_ifname(struct wpa_sm *sm, const char *ifname,
const char *bridge_ifname);
unsigned int secure_ltf:1;
unsigned int secure_rtt:1;
unsigned int prot_range_neg:1;
+ unsigned int ssid_protection:1;
u8 *assoc_wpa_ie; /* Own WPA/RSN IE from (Re)AssocReq */
size_t assoc_wpa_ie_len;
int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len)
{
u8 *pos = rsnxe;
- u16 capab = 0;
+ u32 capab = 0, tmp;
size_t flen;
if (wpa_key_mgmt_sae(sm->key_mgmt) &&
capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
if (sm->prot_range_neg)
capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR);
+ if (sm->ssid_protection)
+ capab |= BIT(WLAN_RSNX_CAPAB_SSID_PROTECTION);
- flen = (capab & 0xff00) ? 2 : 1;
if (!capab)
return 0; /* no supported extended RSN capabilities */
+ tmp = capab;
+ flen = 0;
+ while (tmp) {
+ flen++;
+ tmp >>= 8;
+ }
if (rsnxe_len < 2 + flen)
return -1;
capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
*pos++ = WLAN_EID_RSNX;
*pos++ = flen;
- *pos++ = capab & 0x00ff;
- capab >>= 8;
- if (capab)
- *pos++ = capab;
+ while (capab) {
+ *pos++ = capab & 0xff;
+ capab >>= 8;
+ }
return pos - rsnxe;
}
{ INT_RANGE(disable_eht, 0, 1)},
{ INT_RANGE(enable_4addr_mode, 0, 1)},
{ INT_RANGE(max_idle, 0, 65535)},
+ { INT_RANGE(ssid_protection, 0, 1)},
};
#undef OFFSET
INT(disable_eht);
INT(enable_4addr_mode);
INT(max_idle);
+ INT(ssid_protection);
#undef STR
#undef INT
* as the maximum idle period for the STA during association.
*/
int max_idle;
+
+ /**
+ * ssid_protection - Whether to use SSID protection in 4-way handshake
+ */
+ bool ssid_protection;
};
#endif /* CONFIG_SSID_H */
old_ssid = wpa_s->current_ssid;
wpa_s->current_ssid = ssid;
wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
+ wpa_sm_set_ssid(wpa_s->wpa, bss->ssid, bss->ssid_len);
wpa_supplicant_initiate_eapol(wpa_s);
#ifdef CONFIG_FILS
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
wpa_s->mgmt_group_cipher);
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SSID_PROTECTION, 0);
pmksa_cache_clear_current(wpa_s->wpa);
os_memset(&mlo, 0, sizeof(mlo));
wmm = !!wpa_bss_get_vendor_ie(bss, WMM_IE_VENDOR_TYPE);
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_WMM_ENABLED, wmm);
+ if (ssid->ssid_protection && proto == WPA_PROTO_RSN) {
+ bool ssid_prot;
+
+ /* Enable SSID protection based on the AP advertising support
+ * for it to avoid potential interoperability issues with
+ * incorrect AP behavior if we were to send an "unexpected"
+ * RSNXE with multiple octets of payload. */
+ ssid_prot = ieee802_11_rsnx_capab(
+ bss_rsnx, WLAN_RSNX_CAPAB_SSID_PROTECTION);
+ if (!skip_default_rsne)
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SSID_PROTECTION,
+ proto == WPA_PROTO_RSN && ssid_prot);
+ } else {
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SSID_PROTECTION, false);
+ }
+
if (!skip_default_rsne) {
if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie,
wpa_ie_len)) {
}
wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
+ if (bss)
+ wpa_sm_set_ssid(wpa_s->wpa, bss->ssid, bss->ssid_len);
wpa_supplicant_initiate_eapol(wpa_s);
if (old_ssid != wpa_s->current_ssid)
wpas_notify_network_changed(wpa_s);