aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rsn_supp/wpa.c88
-rw-r--r--src/rsn_supp/wpa.h2
-rw-r--r--src/rsn_supp/wpa_i.h5
3 files changed, 95 insertions, 0 deletions
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index c2fc94f..a0e3748 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -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 */
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index 0b7477f..4b4b973 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -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 */
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index 6f8bc3f..5a3effc 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -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 */
};