]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FILS: Add elements to FILS Association Request frame
authorJouni Malinen <jouni@qca.qualcomm.com>
Tue, 8 Sep 2015 17:58:53 +0000 (20:58 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 25 Oct 2016 17:01:06 +0000 (20:01 +0300)
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant_i.h

index 9201a1035f5876a60a9c72146299ba3b2a5373e9..136fd091e7b90256ba2db5928ab0e980711fc3b8 100644 (file)
@@ -3422,4 +3422,53 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *data, size_t len)
        return res;
 }
 
+
+struct wpabuf * fils_build_assoc_req(struct wpa_sm *sm, const u8 **kek,
+                                    size_t *kek_len, const u8 **snonce,
+                                    const u8 **anonce)
+{
+       struct wpabuf *buf;
+
+       buf = wpabuf_alloc(1000);
+       if (!buf)
+               return NULL;
+
+       /* 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);
+
+       /* Everything after FILS Session element gets encrypted in the driver
+        * with KEK. The buffer returned from here is the plaintext version. */
+
+       /* TODO: FILS Public Key */
+
+       /* FILS Key Confirm */
+       wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
+       wpabuf_put_u8(buf, 1 + sm->fils_key_auth_len); /* Length */
+       /* Element ID Extension */
+       wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_KEY_CONFIRM);
+       wpabuf_put_data(buf, sm->fils_key_auth_sta, sm->fils_key_auth_len);
+
+       /* TODO: FILS HLP Container */
+
+       /* TODO: FILS IP Address Assignment */
+
+       wpa_hexdump_buf(MSG_DEBUG, "FILS: Association Request plaintext", buf);
+
+       *kek = sm->ptk.kek;
+       *kek_len = sm->ptk.kek_len;
+       wpa_hexdump_key(MSG_DEBUG, "FILS: KEK for AEAD", *kek, *kek_len);
+       *snonce = sm->fils_nonce;
+       wpa_hexdump(MSG_DEBUG, "FILS: SNonce for AEAD AAD",
+                   *snonce, FILS_NONCE_LEN);
+       *anonce = sm->fils_anonce;
+       wpa_hexdump(MSG_DEBUG, "FILS: ANonce for AEAD AAD",
+                   *anonce, FILS_NONCE_LEN);
+
+       return buf;
+}
+
 #endif /* CONFIG_FILS */
index 2f99b6ee152298417123fea22d0027b7386605bb..3b2dbcf43746f480ba91229c80789e7102a547f2 100644 (file)
@@ -428,5 +428,8 @@ void wpa_sm_set_test_assoc_ie(struct wpa_sm *sm, struct wpabuf *buf);
 
 struct wpabuf * fils_build_auth(struct wpa_sm *sm);
 int fils_process_auth(struct wpa_sm *sm, const u8 *data, size_t len);
+struct wpabuf * fils_build_assoc_req(struct wpa_sm *sm, const u8 **kek,
+                                    size_t *kek_len, const u8 **snonce,
+                                    const u8 **anonce);
 
 #endif /* WPA_H */
index 4e004e979e25c073a099e19ee7a71bf77d10a565..ab71f6d92ff3692333b76e16467c799d22f919c4 100644 (file)
@@ -986,6 +986,9 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
 {
        struct wpa_driver_associate_params params;
        struct ieee802_11_elems elems;
+#ifdef CONFIG_FILS
+       u8 nonces[2 * FILS_NONCE_LEN];
+#endif /* CONFIG_FILS */
 #ifdef CONFIG_HT_OVERRIDES
        struct ieee80211_ht_capabilities htcaps;
        struct ieee80211_ht_capabilities htcaps_mask;
@@ -996,6 +999,37 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
 #endif /* CONFIG_VHT_OVERRIDES */
 
        os_memset(&params, 0, sizeof(params));
+
+#ifdef CONFIG_FILS
+       if (auth_type == WLAN_AUTH_FILS_SK) {
+               struct wpabuf *buf;
+               const u8 *snonce, *anonce;
+
+               buf = fils_build_assoc_req(wpa_s->wpa, &params.fils_kek,
+                                          &params.fils_kek_len, &snonce,
+                                          &anonce);
+               if (!buf)
+                       return;
+               /* TODO: Make wpa_s->sme.assoc_req_ie use dynamic allocation */
+               if (wpa_s->sme.assoc_req_ie_len + wpabuf_len(buf) >
+                   sizeof(wpa_s->sme.assoc_req_ie)) {
+                       wpa_printf(MSG_ERROR,
+                                  "FILS: Not enough buffer room for own AssocReq elements");
+                       wpabuf_free(buf);
+                       return;
+               }
+               os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
+                         wpabuf_head(buf), wpabuf_len(buf));
+               wpa_s->sme.assoc_req_ie_len += wpabuf_len(buf);
+               wpabuf_free(buf);
+
+               os_memcpy(nonces, snonce, FILS_NONCE_LEN);
+               os_memcpy(nonces + FILS_NONCE_LEN, anonce, FILS_NONCE_LEN);
+               params.fils_nonces = nonces;
+               params.fils_nonces_len = sizeof(nonces);
+       }
+#endif /* CONFIG_FILS */
+
        params.bssid = bssid;
        params.ssid = wpa_s->sme.ssid;
        params.ssid_len = wpa_s->sme.ssid_len;
index ef9273d09a3258b1d8193b4c77032b0c14e544f2..d6ff6dee2fca0f0eed75ee7c1ac987e3dd40db03 100644 (file)
@@ -721,7 +721,7 @@ struct wpa_supplicant {
                u8 ssid[SSID_MAX_LEN];
                size_t ssid_len;
                int freq;
-               u8 assoc_req_ie[200];
+               u8 assoc_req_ie[300];
                size_t assoc_req_ie_len;
                int mfp;
                int ft_used;