]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
OCV: Include and verify OCI in the FILS handshake
authorMathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
Mon, 6 Aug 2018 19:46:36 +0000 (15:46 -0400)
committerJouni Malinen <j@w1.fi>
Mon, 17 Dec 2018 13:50:12 +0000 (15:50 +0200)
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
src/ap/wpa_auth.c
src/rsn_supp/wpa.c

index 647b4801fe29cab029a33e32649a3a2ddd8e07fe..dc78210587dd1da0cca6dc956b5fb058ac862c4b 100644 (file)
@@ -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);
 
index c2cbbe1619603fb820d4fbe3bbf848fc09a483da..543880e14365ab9b629c3527d2bf1346d5bfe21c 100644 (file)
@@ -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;
 }
 
index c20ede9f735e526d91b3413bbdf692572a4b1558..18f8c7158b282a3ee575db33dfbb04b9d3547d40 100644 (file)
@@ -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");