]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FILS: Move Session element validation to a helper function
authorJeffin Mammen <jmammen@qti.qualcomm.com>
Fri, 21 Apr 2017 15:42:00 +0000 (18:42 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 23 Apr 2017 14:47:15 +0000 (17:47 +0300)
This can be reused from driver-based AP SME callback.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/ap/wpa_auth.c
src/ap/wpa_auth.h

index 3149da4eafe9200c7eda20c00ebc93d07bfe085e..6f67dadf17e51f65a829f1c8ebd492f771011619 100644 (file)
@@ -2161,6 +2161,60 @@ static int wpa_aead_decrypt(struct wpa_state_machine *sm, struct wpa_ptk *ptk,
 }
 
 
+const u8 * wpa_fils_validate_fils_session(struct wpa_state_machine *sm,
+                                         const u8 *ies, size_t ies_len,
+                                         const u8 *fils_session)
+{
+       const u8 *ie, *end;
+       const u8 *session = NULL;
+
+       if (!wpa_key_mgmt_fils(sm->wpa_key_mgmt)) {
+               wpa_printf(MSG_DEBUG,
+                          "FILS: Not a FILS AKM - reject association");
+               return NULL;
+       }
+
+       /* Verify Session element */
+       ie = ies;
+       end = ((const u8 *) ie) + ies_len;
+       while (ie + 1 < end) {
+               if (ie + 2 + ie[1] > end)
+                       break;
+               if (ie[0] == WLAN_EID_EXTENSION &&
+                   ie[1] >= 1 + FILS_SESSION_LEN &&
+                   ie[2] == WLAN_EID_EXT_FILS_SESSION) {
+                       session = ie;
+                       break;
+               }
+               ie += 2 + ie[1];
+       }
+
+       if (!session) {
+               wpa_printf(MSG_DEBUG,
+                          "FILS: %s: Could not find FILS Session element in Assoc Req - reject",
+                          __func__);
+               return NULL;
+       }
+
+       if (!fils_session) {
+               wpa_printf(MSG_DEBUG,
+                          "FILS: %s: Could not find FILS Session element in STA entry - reject",
+                          __func__);
+               return NULL;
+       }
+
+       if (os_memcmp(fils_session, session + 3, FILS_SESSION_LEN) != 0) {
+               wpa_printf(MSG_DEBUG, "FILS: Session mismatch");
+               wpa_hexdump(MSG_DEBUG, "FILS: Expected FILS Session",
+                           fils_session, FILS_SESSION_LEN);
+               wpa_hexdump(MSG_DEBUG, "FILS: Received FILS Session",
+                           session + 3, FILS_SESSION_LEN);
+               return NULL;
+       }
+       return session;
+}
+
+
 int fils_decrypt_assoc(struct wpa_state_machine *sm, const u8 *fils_session,
                       const struct ieee80211_mgmt *mgmt, size_t frame_len,
                       u8 *pos, size_t left)
@@ -2196,32 +2250,13 @@ int fils_decrypt_assoc(struct wpa_state_machine *sm, const u8 *fils_session,
         * Find FILS Session element which is the last unencrypted element in
         * the frame.
         */
-       session = NULL;
-       while (ie + 1 < end) {
-               if (ie + 2 + ie[1] > end)
-                       break;
-               if (ie[0] == WLAN_EID_EXTENSION &&
-                   ie[1] >= 1 + FILS_SESSION_LEN &&
-                   ie[2] == WLAN_EID_EXT_FILS_SESSION) {
-                       session = ie;
-                       break;
-               }
-               ie += 2 + ie[1];
-       }
-
+       session = wpa_fils_validate_fils_session(sm, ie, end - ie,
+                                                fils_session);
        if (!session) {
-               wpa_printf(MSG_DEBUG,
-                          "FILS: Could not find FILS Session element in Association Request frame - reject");
-               return -1;
-       }
-       if (os_memcmp(fils_session, session + 3, FILS_SESSION_LEN) != 0) {
-               wpa_printf(MSG_DEBUG, "FILS: Session mismatch");
-               wpa_hexdump(MSG_DEBUG, "FILS: Expected FILS Session",
-                           fils_session, FILS_SESSION_LEN);
-               wpa_hexdump(MSG_DEBUG, "FILS: Received FILS Session",
-                           session + 3, FILS_SESSION_LEN);
+               wpa_printf(MSG_DEBUG, "FILS: Session validation failed");
                return -1;
        }
+
        crypt = session + 2 + session[1];
 
        if (end - crypt < AES_BLOCK_SIZE) {
index a16a560365054662f2265c91cd0a1a6f609de929..3d5182b78d6db6f5d2429dd4769fecd1bb976837 100644 (file)
@@ -374,6 +374,9 @@ int fils_encrypt_assoc(struct wpa_state_machine *sm, u8 *buf,
                       size_t current_len, size_t max_len,
                       const struct wpabuf *hlp);
 int fils_set_tk(struct wpa_state_machine *sm);
+const u8 *  wpa_fils_validate_fils_session(struct wpa_state_machine *sm,
+                                          const u8 *ies, size_t ies_len,
+                                          const u8 *fils_session);
 
 int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, u8 *buf, size_t len);
 void wpa_auth_get_fils_aead_params(struct wpa_state_machine *sm,