@@ -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"
@@ -2744,6 +2745,34 @@ 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)Assoc");
+ return WLAN_STATUS_UNSPECIFIED_FAILURE;
+ } else 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, 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);
@@ -2569,6 +2569,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, "Failed to get channel "
+ "info for OCI element");
+ wpabuf_free(plain);
+ return NULL;
+ }
+
+ pos = (u8*)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;
}
@@ -4047,6 +4047,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, "Failed to get channel "
+ "info for OCI element");
+ wpabuf_free(buf);
+ return NULL;
+ }
+
+ pos = (u8*)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;
@@ -4210,6 +4230,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)Assoc");
+ 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, ocv_errorstr);
+ goto fail;
+ }
+ }
+#endif /* CONFIG_OCV */
+
/* Key Delivery */
if (!elems.key_delivery) {
wpa_printf(MSG_DEBUG, "FILS: No Key Delivery element");
Include and verify the OCI element in FILS (Re)Association Request and Response frames. Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be> --- src/ap/ieee802_11.c | 29 +++++++++++++++++++++++++++++ src/ap/wpa_auth.c | 21 +++++++++++++++++++++ src/rsn_supp/wpa.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+)