diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 647b4801f..dc7821058 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -21,6 +21,7 @@ #include "common/ieee802_11_common.h" #include "common/wpa_ctrl.h" #include "common/sae.h" +#include "common/ocv.h" #include "radius/radius.h" #include "radius/radius_client.h" #include "p2p/p2p.h" @@ -2761,6 +2762,35 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, } #endif /* CONFIG_MBO */ +#if defined(CONFIG_FILS) && defined(CONFIG_OCV) + if (wpa_auth_uses_ocv(sta->wpa_sm) && + (sta->auth_alg == WLAN_AUTH_FILS_SK || + sta->auth_alg == WLAN_AUTH_FILS_SK_PFS || + sta->auth_alg == WLAN_AUTH_FILS_PK)) { + struct wpa_channel_info ci; + int tx_chanwidth; + int tx_seg1_idx; + + if (hostapd_drv_channel_info(hapd, &ci) != 0) { + wpa_printf(MSG_WARNING, + "Failed to get channel info to validate received OCI in FILS (Re)Association Request frame"); + return WLAN_STATUS_UNSPECIFIED_FAILURE; + } + + if (get_sta_tx_parameters(sta->wpa_sm, + channel_width_to_int(ci.chanwidth), + ci.seg1_idx, &tx_chanwidth, + &tx_seg1_idx) < 0) + return WLAN_STATUS_UNSPECIFIED_FAILURE; + + if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci, + tx_chanwidth, tx_seg1_idx) != 0) { + wpa_printf(MSG_WARNING, "FILS: %s", ocv_errorstr); + return WLAN_STATUS_UNSPECIFIED_FAILURE; + } + } +#endif /* CONFIG_FILS && CONFIG_OCV */ + ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes, elems.supp_op_classes_len); diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index c2cbbe161..543880e14 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -2572,6 +2572,27 @@ static struct wpabuf * fils_prepare_plainbuf(struct wpa_state_machine *sm, wpabuf_put(plain, tmp2 - tmp); *len = (u8 *) wpabuf_put(plain, 0) - len - 1; + +#ifdef CONFIG_OCV + if (wpa_auth_uses_ocv(sm)) { + struct wpa_channel_info ci; + u8 *pos; + + if (wpa_channel_info(sm->wpa_auth, &ci) != 0) { + wpa_printf(MSG_WARNING, + "FILS: Failed to get channel info for OCI element"); + wpabuf_free(plain); + return NULL; + } + + pos = wpabuf_put(plain, OCV_OCI_EXTENDED_LEN); + if (ocv_insert_extended_oci(&ci, pos) < 0) { + wpabuf_free(plain); + return NULL; + } + } +#endif /* CONFIG_OCV */ + return plain; } diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index c20ede9f7..18f8c7158 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -4064,6 +4064,26 @@ struct wpabuf * fils_build_assoc_req(struct wpa_sm *sm, const u8 **kek, /* TODO: FILS IP Address Assignment */ +#ifdef CONFIG_OCV + if (wpa_sm_ocv_enabled(sm)) { + struct wpa_channel_info ci; + u8 *pos; + + if (wpa_sm_channel_info(sm, &ci) != 0) { + wpa_printf(MSG_WARNING, + "FILS: Failed to get channel info for OCI element"); + wpabuf_free(buf); + return NULL; + } + + pos = wpabuf_put(buf, OCV_OCI_EXTENDED_LEN); + if (ocv_insert_extended_oci(&ci, pos) < 0) { + wpabuf_free(buf); + return NULL; + } + } +#endif /* CONFIG_OCV */ + wpa_hexdump_buf(MSG_DEBUG, "FILS: Association Request plaintext", buf); *kek = sm->ptk.kek; @@ -4227,6 +4247,25 @@ int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len) goto fail; } +#ifdef CONFIG_OCV + if (wpa_sm_ocv_enabled(sm)) { + struct wpa_channel_info ci; + + if (wpa_sm_channel_info(sm, &ci) != 0) { + wpa_printf(MSG_WARNING, + "Failed to get channel info to validate received OCI in FILS (Re)Association Response frame"); + goto fail; + } + + if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci, + channel_width_to_int(ci.chanwidth), + ci.seg1_idx) != 0) { + wpa_printf(MSG_WARNING, "FILS: %s", ocv_errorstr); + goto fail; + } + } +#endif /* CONFIG_OCV */ + /* Key Delivery */ if (!elems.key_delivery) { wpa_printf(MSG_DEBUG, "FILS: No Key Delivery element");