]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FILS: Try to use FILS authentication if PMKSA or ERP entry is available
authorJouni Malinen <jouni@qca.qualcomm.com>
Fri, 4 Sep 2015 12:32:07 +0000 (15:32 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 22 Oct 2016 20:13:17 +0000 (23:13 +0300)
If a PMKSA cache entry for the target AP is available, try to use FILS
with PMKSA caching.

If an ERP key for the target AP is available, try to use FILS with
EAP-Initiate/Re-auth added as Wrapper Data element.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
src/rsn_supp/wpa_i.h
wpa_supplicant/sme.c

index c2fc94fee34425294743a3327c4c9ee7cb0ed863..a0e37485b5ebac455cd2c8e7e77ee501e44476f0 100644 (file)
@@ -3199,3 +3199,91 @@ void wpa_sm_set_test_assoc_ie(struct wpa_sm *sm, struct wpabuf *buf)
        sm->test_assoc_ie = buf;
 }
 #endif /* CONFIG_TESTING_OPTIONS */
+
+
+#ifdef CONFIG_FILS
+
+struct wpabuf * fils_build_auth(struct wpa_sm *sm)
+{
+       struct wpabuf *buf = NULL;
+       struct wpabuf *erp_msg;
+
+       erp_msg = eapol_sm_build_erp_reauth_start(sm->eapol);
+       if (!erp_msg && !sm->cur_pmksa) {
+               wpa_printf(MSG_DEBUG,
+                          "FILS: Neither ERP EAP-Initiate/Re-auth nor PMKSA cache entry is available - skip FILS");
+               goto fail;
+       }
+
+       wpa_printf(MSG_DEBUG, "FILS: Try to use FILS (erp=%d pmksa_cache=%d)",
+                  erp_msg != NULL, sm->cur_pmksa != NULL);
+
+       if (!sm->assoc_wpa_ie) {
+               wpa_printf(MSG_INFO, "FILS: No own RSN IE set for FILS");
+               goto fail;
+       }
+
+       if (random_get_bytes(sm->fils_nonce, FILS_NONCE_LEN) < 0 ||
+           random_get_bytes(sm->fils_session, FILS_SESSION_LEN) < 0)
+               goto fail;
+
+       wpa_hexdump(MSG_DEBUG, "FILS: Generated FILS Nonce",
+                   sm->fils_nonce, FILS_NONCE_LEN);
+       wpa_hexdump(MSG_DEBUG, "FILS: Generated FILS Session",
+                   sm->fils_session, FILS_SESSION_LEN);
+
+       buf = wpabuf_alloc(1000 + sm->assoc_wpa_ie_len);
+       if (!buf)
+               goto fail;
+
+       /* Fields following the Authentication algorithm number field */
+
+       /* Authentication Transaction seq# */
+       wpabuf_put_le16(buf, 1);
+
+       /* Status Code */
+       wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
+
+       /* TODO: Finite Cyclic Group when using PK or PFS */
+       /* TODO: Element when using PK or PFS */
+
+       /* RSNE */
+       wpa_hexdump(MSG_DEBUG, "FILS: RSNE in FILS Authentication frame",
+                   sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
+       wpabuf_put_data(buf, sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
+
+       /* TODO: MDE when using FILS for FT initial association */
+       /* TODO: FTE when using FILS for FT initial association */
+
+       /* FILS Nonce */
+       wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
+       wpabuf_put_u8(buf, 1 + FILS_NONCE_LEN); /* Length */
+       /* Element ID Extension */
+       wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_NONCE);
+       wpabuf_put_data(buf, sm->fils_nonce, FILS_NONCE_LEN);
+
+       /* FILS Session */
+       wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
+       wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN); /* Length */
+       /* Element ID Extension */
+       wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
+       wpabuf_put_data(buf, sm->fils_session, FILS_SESSION_LEN);
+
+       /* FILS Wrapped Data */
+       if (erp_msg) {
+               wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
+               wpabuf_put_u8(buf, 1 + wpabuf_len(erp_msg)); /* Length */
+               /* Element ID Extension */
+               wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_WRAPPED_DATA);
+               wpabuf_put_buf(buf, erp_msg);
+       }
+
+       wpa_hexdump_buf(MSG_DEBUG, "RSN: FILS fields for Authentication frame",
+                       buf);
+
+fail:
+       wpabuf_free(erp_msg);
+       return buf;
+}
+
+#endif /* CONFIG_FILS */
index 0b7477f31bc7a724c3a012d25bcdf248227f8265..4b4b97378e52b28dcf3e19169aae488c6d595234 100644 (file)
@@ -426,4 +426,6 @@ extern unsigned int tdls_testing;
 int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf);
 void wpa_sm_set_test_assoc_ie(struct wpa_sm *sm, struct wpabuf *buf);
 
+struct wpabuf * fils_build_auth(struct wpa_sm *sm);
+
 #endif /* WPA_H */
index 6f8bc3feb92cc67d561b6b53eb9ac26f449b85ee..5a3effc0c4cef1df788122fb5e1335e9678cf73c 100644 (file)
@@ -138,6 +138,11 @@ struct wpa_sm {
 #ifdef CONFIG_TESTING_OPTIONS
        struct wpabuf *test_assoc_ie;
 #endif /* CONFIG_TESTING_OPTIONS */
+
+#ifdef CONFIG_FILS
+       u8 fils_nonce[FILS_NONCE_LEN];
+       u8 fils_session[FILS_SESSION_LEN];
+#endif /* CONFIG_FILS */
 };
 
 
index 477b4cc10422b2b9f315341b948dc1688655c7a2..bcb6a46f46835aeee050e48c369f0769f93a99ec 100644 (file)
@@ -549,6 +549,31 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
        }
 #endif /* CONFIG_SAE */
 
+       old_ssid = wpa_s->current_ssid;
+       wpa_s->current_ssid = ssid;
+       wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
+       wpa_supplicant_initiate_eapol(wpa_s);
+
+#ifdef CONFIG_FILS
+       /* TODO: FILS operations can in some cases be done between different
+        * network_ctx (i.e., same credentials can be used with multiple
+        * networks). */
+       if (params.auth_alg == WPA_AUTH_ALG_OPEN &&
+           wpa_key_mgmt_fils(ssid->key_mgmt)) {
+               if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
+                                           ssid, 0) == 0)
+                       wpa_printf(MSG_DEBUG,
+                                  "SME: Try to use FILS with PMKSA caching");
+               resp = fils_build_auth(wpa_s->wpa);
+               if (resp) {
+                       params.auth_alg = WPA_AUTH_ALG_FILS;
+                       params.auth_data = wpabuf_head(resp);
+                       params.auth_data_len = wpabuf_len(resp);
+                       wpa_s->sme.auth_alg = WPA_AUTH_ALG_FILS;
+               }
+       }
+#endif /* CONFIG_FILS */
+
        wpa_supplicant_cancel_sched_scan(wpa_s);
        wpa_supplicant_cancel_scan(wpa_s);
 
@@ -558,10 +583,6 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
 
        wpa_clear_keys(wpa_s, bss->bssid);
        wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
-       old_ssid = wpa_s->current_ssid;
-       wpa_s->current_ssid = ssid;
-       wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
-       wpa_supplicant_initiate_eapol(wpa_s);
        if (old_ssid != wpa_s->current_ssid)
                wpas_notify_network_changed(wpa_s);