[18/25] OCV: Include and verify OCI in the FILS handshake

Message ID 20180806194643.1328-19-Mathy.Vanhoef@cs.kuleuven.be
State New
Headers show
Series
  • Add support for Operating Channel Validation (OCV)
Related show

Commit Message

Mathy Vanhoef Aug. 6, 2018, 7:46 p.m.
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(+)

Patch

diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index cc0e0f2e1..e7fa9c867 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"
@@ -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);
 
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 9e99020f1..51803b3a2 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -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;
 }
 
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 6eb0d3217..29717a047 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -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");