]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SAE: Centralize function for sending initial COMMIT
authorBob Copeland <me@bobcopeland.com>
Wed, 7 Jan 2015 06:10:56 +0000 (01:10 -0500)
committerJouni Malinen <j@w1.fi>
Sat, 10 Jan 2015 09:43:29 +0000 (11:43 +0200)
When performing SAE authentication in mesh, one station may
initiate authentication by sending a COMMIT as soon as a peer
candidate is discovered. Previously we did this in mesh_rsn.c,
but this left some of the state initialization in a different
part of the code from the rest of the state machine, and we may
need to add other initializations here in the future, so move
that to a more central function.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
src/ap/ieee802_11.c
src/ap/ieee802_11.h
wpa_supplicant/mesh_rsn.c

index 97f98f28e0b86aa7655a926b6b646a5ef3f6e6d6..0459a17876b2c986c61232b9bfaa6483f669adf1 100644 (file)
@@ -755,6 +755,37 @@ reply:
        }
        wpabuf_free(data);
 }
+
+
+/**
+ * auth_sae_init_committed - Send COMMIT and start SAE in committed state
+ * @hapd: BSS data for the device initiating the authentication
+ * @sta: the peer to which commit authentication frame is sent
+ *
+ * This function implements Init event handling (IEEE Std 802.11-2012,
+ * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
+ * sta->sae structure should be initialized appropriately via a call to
+ * sae_prepare_commit().
+ */
+int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta)
+{
+       int ret;
+
+       if (!sta->sae || !sta->sae->tmp)
+               return -1;
+
+       if (sta->sae->state != SAE_NOTHING)
+               return -1;
+
+       ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0);
+       if (ret)
+               return -1;
+
+       sta->sae->state = SAE_COMMITTED;
+
+       return 0;
+}
+
 #endif /* CONFIG_SAE */
 
 
index cf0d3f2bf8e73d0016ae875e87b6200da4102296..8229c5e508d5a13784a32e0337be3fc048730f12 100644 (file)
@@ -89,4 +89,6 @@ int hostapd_update_time_adv(struct hostapd_data *hapd);
 void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr);
 u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid);
 
+int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta);
+
 #endif /* IEEE802_11_H */
index e6ae7c38b45ec2223b598a20eaaf714316e5e20b..aee325a3e33c8b2c64283e9ba6e1f5bc386ffc6b 100644 (file)
@@ -18,6 +18,7 @@
 #include "ap/hostapd.h"
 #include "ap/wpa_auth.h"
 #include "ap/sta_info.h"
+#include "ap/ieee802_11.h"
 #include "wpa_supplicant_i.h"
 #include "driver_i.h"
 #include "wpas_glue.h"
@@ -245,80 +246,23 @@ static int mesh_rsn_sae_group(struct wpa_supplicant *wpa_s,
 }
 
 
-struct wpabuf *
-mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s,
-                         struct wpa_ssid *ssid, struct sta_info *sta)
+static int mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s,
+                                    struct wpa_ssid *ssid,
+                                    struct sta_info *sta)
 {
-       struct wpabuf *buf;
-       int len;
-
        if (ssid->passphrase == NULL) {
                wpa_msg(wpa_s, MSG_DEBUG, "SAE: No password available");
-               return NULL;
+               return -1;
        }
 
        if (mesh_rsn_sae_group(wpa_s, sta->sae) < 0) {
                wpa_msg(wpa_s, MSG_DEBUG, "SAE: Failed to select group");
-               return NULL;
-       }
-
-       if (sae_prepare_commit(wpa_s->own_addr, sta->addr,
-                              (u8 *) ssid->passphrase,
-                              os_strlen(ssid->passphrase), sta->sae) < 0) {
-               wpa_msg(wpa_s, MSG_DEBUG, "SAE: Could not pick PWE");
-               return NULL;
+               return -1;
        }
 
-       len = wpa_s->mesh_rsn->sae_token ?
-               wpabuf_len(wpa_s->mesh_rsn->sae_token) : 0;
-       buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + len);
-       if (buf == NULL)
-               return NULL;
-
-       sae_write_commit(sta->sae, buf, wpa_s->mesh_rsn->sae_token);
-
-       return buf;
-}
-
-
-static void mesh_rsn_send_auth(struct wpa_supplicant *wpa_s,
-                              const u8 *dst, const u8 *src,
-                              u16 auth_transaction, u16 resp,
-                              struct wpabuf *data)
-{
-       struct ieee80211_mgmt *auth;
-       u8 *buf;
-       size_t len, ielen = 0;
-
-       if (data)
-               ielen = wpabuf_len(data);
-       len = IEEE80211_HDRLEN + sizeof(auth->u.auth) + ielen;
-       buf = os_zalloc(len);
-       if (buf == NULL)
-               return;
-
-       auth = (struct ieee80211_mgmt *) buf;
-       auth->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
-                                          WLAN_FC_STYPE_AUTH);
-       os_memcpy(auth->da, dst, ETH_ALEN);
-       os_memcpy(auth->sa, src, ETH_ALEN);
-       os_memcpy(auth->bssid, src, ETH_ALEN);
-
-       auth->u.auth.auth_alg = host_to_le16(WLAN_AUTH_SAE);
-       auth->u.auth.auth_transaction = host_to_le16(auth_transaction);
-       auth->u.auth.status_code = host_to_le16(resp);
-
-       if (data)
-               os_memcpy(auth->u.auth.variable, wpabuf_head(data), ielen);
-
-       wpa_msg(wpa_s, MSG_DEBUG, "authentication frame: STA=" MACSTR
-               " auth_transaction=%d resp=%d (IE len=%lu)",
-               MAC2STR(dst), auth_transaction, resp, (unsigned long) ielen);
-       if (wpa_drv_send_mlme(wpa_s, buf, len, 0) < 0)
-               wpa_printf(MSG_INFO, "send_auth_reply: send_mlme failed: %s",
-                          strerror(errno));
-
-       os_free(buf);
+       return sae_prepare_commit(wpa_s->own_addr, sta->addr,
+                                 (u8 *) ssid->passphrase,
+                                 os_strlen(ssid->passphrase), sta->sae);
 }
 
 
@@ -326,9 +270,10 @@ static void mesh_rsn_send_auth(struct wpa_supplicant *wpa_s,
 int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s,
                          struct sta_info *sta)
 {
+       struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
        struct wpa_ssid *ssid = wpa_s->current_ssid;
-       struct wpabuf *buf;
        unsigned int rnd;
+       int ret;
 
        if (!ssid) {
                wpa_msg(wpa_s, MSG_DEBUG,
@@ -342,25 +287,21 @@ int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s,
                        return -1;
        }
 
-       buf = mesh_rsn_build_sae_commit(wpa_s, ssid, sta);
-       if (!buf)
+       if (mesh_rsn_build_sae_commit(wpa_s, ssid, sta))
                return -1;
 
        wpa_msg(wpa_s, MSG_DEBUG,
                "AUTH: started authentication with SAE peer: " MACSTR,
                MAC2STR(sta->addr));
 
-       sta->sae->state = SAE_COMMITTED;
        wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
-
-       mesh_rsn_send_auth(wpa_s, sta->addr, wpa_s->own_addr,
-                          1, WLAN_STATUS_SUCCESS, buf);
+       ret = auth_sae_init_committed(hapd, sta);
+       if (ret)
+               return ret;
 
        rnd = rand() % MESH_AUTH_TIMEOUT;
        eloop_register_timeout(MESH_AUTH_TIMEOUT + rnd, 0, mesh_auth_timer,
                               wpa_s, sta);
-       wpabuf_free(buf);
-
        return 0;
 }