]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Provide information about the encryption status of received EAPOL frames
authorJouni Malinen <j@w1.fi>
Fri, 6 May 2022 21:38:35 +0000 (00:38 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 7 May 2022 18:37:03 +0000 (21:37 +0300)
This information was already available from the nl80211 control port RX
path, but it was not provided to upper layers within wpa_supplicant and
hostapd. It can be helpful, so parse the information from the driver
event.

Signed-off-by: Jouni Malinen <j@w1.fi>
27 files changed:
hostapd/ctrl_iface.c
src/ap/drv_callbacks.c
src/ap/ieee802_11.c
src/ap/ieee802_1x.c
src/ap/ieee802_1x.h
src/ap/preauth_auth.c
src/ap/sta_info.h
src/common/defs.h
src/drivers/driver.h
src/drivers/driver_nl80211_event.c
src/eapol_supp/eapol_supp_sm.c
src/eapol_supp/eapol_supp_sm.h
src/rsn_supp/preauth.c
src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
tests/fuzzing/eapol-key-supp/eapol-key-supp.c
tests/fuzzing/eapol-supp/eapol-supp.c
wpa_supplicant/ap.c
wpa_supplicant/ap.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/eapol_test.c
wpa_supplicant/events.c
wpa_supplicant/ibss_rsn.c
wpa_supplicant/ibss_rsn.h
wpa_supplicant/wpa_priv.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index d479006c7f1a48f327f33ae3944b94fe98784af8..664c59df7c8a0c8f18f9e1aee7c968d81c6c75db 100644 (file)
@@ -1682,7 +1682,7 @@ static int hostapd_ctrl_iface_eapol_rx(struct hostapd_data *hapd, char *cmd)
                return -1;
        }
 
-       ieee802_1x_receive(hapd, src, buf, len);
+       ieee802_1x_receive(hapd, src, buf, len, FRAME_ENCRYPTION_UNKNOWN);
        os_free(buf);
 
        return 0;
index 00d3f97123e9b9d61a84ebe19fee4e5fe001bcf7..fff8bb3e5f39568d7a4421b7e378d56080f112e2 100644 (file)
@@ -1543,7 +1543,8 @@ static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
 
 
 static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
-                                  const u8 *data, size_t data_len)
+                                  const u8 *data, size_t data_len,
+                                  enum frame_encryption encrypted)
 {
        struct hostapd_iface *iface = hapd->iface;
        struct sta_info *sta;
@@ -1557,7 +1558,7 @@ static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
                }
        }
 
-       ieee802_1x_receive(hapd, src, data, data_len);
+       ieee802_1x_receive(hapd, src, data, data_len, encrypted);
 }
 
 #endif /* HOSTAPD */
@@ -1949,7 +1950,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
        case EVENT_EAPOL_RX:
                hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
                                       data->eapol_rx.data,
-                                      data->eapol_rx.data_len);
+                                      data->eapol_rx.data_len,
+                                      data->eapol_rx.encrypted);
                break;
        case EVENT_ASSOC:
                if (!data)
index e1818ece2fe8649d08f23bfae08aed1e9e731058..aa26ad4effd92ab4e6baed8e01d557a126c12ed7 100644 (file)
@@ -6589,7 +6589,8 @@ static void handle_assoc_cb(struct hostapd_data *hapd,
                        ieee802_1x_receive(
                                hapd, mgmt->da,
                                wpabuf_head(sta->pending_eapol_rx->buf),
-                               wpabuf_len(sta->pending_eapol_rx->buf));
+                               wpabuf_len(sta->pending_eapol_rx->buf),
+                               sta->pending_eapol_rx->encrypted);
                }
                wpabuf_free(sta->pending_eapol_rx->buf);
                os_free(sta->pending_eapol_rx);
index fb5e92060b62be08c6c97e2872de4e753ca0ed11..270691ae5a9d3a52007c2d9b665930ad5081d9ce 100644 (file)
@@ -998,7 +998,7 @@ ieee802_1x_alloc_eapol_sm(struct hostapd_data *hapd, struct sta_info *sta)
 
 
 static void ieee802_1x_save_eapol(struct sta_info *sta, const u8 *buf,
-                                 size_t len)
+                                 size_t len, enum frame_encryption encrypted)
 {
        if (sta->pending_eapol_rx) {
                wpabuf_free(sta->pending_eapol_rx->buf);
@@ -1016,6 +1016,7 @@ static void ieee802_1x_save_eapol(struct sta_info *sta, const u8 *buf,
                return;
        }
 
+       sta->pending_eapol_rx->encrypted = encrypted;
        os_get_reltime(&sta->pending_eapol_rx->rx_time);
 }
 
@@ -1026,11 +1027,12 @@ static void ieee802_1x_save_eapol(struct sta_info *sta, const u8 *buf,
  * @sa: Source address (sender of the EAPOL frame)
  * @buf: EAPOL frame
  * @len: Length of buf in octets
+ * @encrypted: Whether the frame was encrypted
  *
  * This function is called for each incoming EAPOL frame from the interface
  */
 void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
-                       size_t len)
+                       size_t len, enum frame_encryption encrypted)
 {
        struct sta_info *sta;
        struct ieee802_1x_hdr *hdr;
@@ -1043,8 +1045,9 @@ void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
            !hapd->conf->wps_state)
                return;
 
-       wpa_printf(MSG_DEBUG, "IEEE 802.1X: %lu bytes from " MACSTR,
-                  (unsigned long) len, MAC2STR(sa));
+       wpa_printf(MSG_DEBUG, "IEEE 802.1X: %lu bytes from " MACSTR
+                  " (encrypted=%d)",
+                  (unsigned long) len, MAC2STR(sa), encrypted);
        sta = ap_get_sta(hapd, sa);
        if (!sta || (!(sta->flags & (WLAN_STA_ASSOC | WLAN_STA_PREAUTH)) &&
                     !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_WIRED))) {
@@ -1054,7 +1057,7 @@ void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
                if (sta && (sta->flags & WLAN_STA_AUTH)) {
                        wpa_printf(MSG_DEBUG, "Saving EAPOL frame from " MACSTR
                                   " for later use", MAC2STR(sta->addr));
-                       ieee802_1x_save_eapol(sta, buf, len);
+                       ieee802_1x_save_eapol(sta, buf, len, encrypted);
                }
 
                return;
index 70dc11afec74006b91863d875e0c87f925cf4670..1469351c1e5502b99b802c670c6118a527b01f4c 100644 (file)
@@ -19,7 +19,7 @@ struct radius_msg;
 
 
 void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
-                       size_t len);
+                       size_t len, enum frame_encryption encrypted);
 void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta);
 void ieee802_1x_free_station(struct hostapd_data *hapd, struct sta_info *sta);
 
index 2ff1861772f7fa7f8ae6f68bdbbc3a549d7ce46a..3284a10a9f9885985b8bbcf68611baa123311067 100644 (file)
@@ -90,7 +90,7 @@ static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
                return;
        sta->preauth_iface = piface;
        ieee802_1x_receive(hapd, ethhdr->h_source, (u8 *) (ethhdr + 1),
-                          len - sizeof(*ethhdr));
+                          len - sizeof(*ethhdr), FRAME_ENCRYPTION_UNKNOWN);
 }
 
 
index af8f171b2b09b08ff6fbd63d5ed9b7680fdfd312..5c92e01da491a87afe46908157fe8b266797e68e 100644 (file)
@@ -65,6 +65,7 @@ struct mbo_non_pref_chan_info {
 struct pending_eapol_rx {
        struct wpabuf *buf;
        struct os_reltime rx_time;
+       enum frame_encryption encrypted;
 };
 
 enum pasn_fils_state {
index f43bdb5d1b15af92d2ee2141416c1b91636f3dbc..07065695da6bc6a69717a03dd9b7ea288d748e8e 100644 (file)
@@ -475,4 +475,10 @@ enum ptk0_rekey_handling {
        PTK0_REKEY_ALLOW_NEVER
 };
 
+enum frame_encryption {
+       FRAME_ENCRYPTION_UNKNOWN = -1,
+       FRAME_NOT_ENCRYPTED = 0,
+       FRAME_ENCRYPTED = 1
+};
+
 #endif /* DEFS_H */
index 6c00fb56439fa31f647f23b5cca317de520d3bc9..5e204655c5ee1735151aeedc61dbb35fb8b7a247 100644 (file)
@@ -5847,6 +5847,7 @@ union wpa_event_data {
                const u8 *src;
                const u8 *data;
                size_t data_len;
+               enum frame_encryption encrypted;
        } eapol_rx;
 
        /**
@@ -6185,6 +6186,20 @@ static inline void drv_event_eapol_rx(void *ctx, const u8 *src, const u8 *data,
        event.eapol_rx.src = src;
        event.eapol_rx.data = data;
        event.eapol_rx.data_len = data_len;
+       event.eapol_rx.encrypted = FRAME_ENCRYPTION_UNKNOWN;
+       wpa_supplicant_event(ctx, EVENT_EAPOL_RX, &event);
+}
+
+static inline void drv_event_eapol_rx2(void *ctx, const u8 *src, const u8 *data,
+                                     size_t data_len,
+                                      enum frame_encryption encrypted)
+{
+       union wpa_event_data event;
+       os_memset(&event, 0, sizeof(event));
+       event.eapol_rx.src = src;
+       event.eapol_rx.data = data;
+       event.eapol_rx.data_len = data_len;
+       event.eapol_rx.encrypted = encrypted;
        wpa_supplicant_event(ctx, EVENT_EAPOL_RX, &event);
 }
 
index 22fb4f1e4751fb1aae90494f4709b570f8912bdb..00f8b0cbbd9b9d925cd372d0093b3d65fa5303e5 100644 (file)
@@ -2810,6 +2810,7 @@ static void nl80211_control_port_frame(struct wpa_driver_nl80211_data *drv,
 {
        u8 *src_addr;
        u16 ethertype;
+       enum frame_encryption encrypted;
 
        if (!tb[NL80211_ATTR_MAC] ||
            !tb[NL80211_ATTR_FRAME] ||
@@ -2818,6 +2819,8 @@ static void nl80211_control_port_frame(struct wpa_driver_nl80211_data *drv,
 
        src_addr = nla_data(tb[NL80211_ATTR_MAC]);
        ethertype = nla_get_u16(tb[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
+       encrypted = nla_get_flag(tb[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]) ?
+               FRAME_NOT_ENCRYPTED : FRAME_ENCRYPTED;
 
        switch (ethertype) {
        case ETH_P_RSN_PREAUTH:
@@ -2826,9 +2829,10 @@ static void nl80211_control_port_frame(struct wpa_driver_nl80211_data *drv,
                           MAC2STR(src_addr));
                break;
        case ETH_P_PAE:
-               drv_event_eapol_rx(drv->ctx, src_addr,
-                                  nla_data(tb[NL80211_ATTR_FRAME]),
-                                  nla_len(tb[NL80211_ATTR_FRAME]));
+               drv_event_eapol_rx2(drv->ctx, src_addr,
+                                   nla_data(tb[NL80211_ATTR_FRAME]),
+                                   nla_len(tb[NL80211_ATTR_FRAME]),
+                                   encrypted);
                break;
        default:
                wpa_printf(MSG_INFO,
index 861eea2ae5240c36ff0067e7786ded43fa7be7e5..f5f576045a07484ed103ddc182d85177be3270cf 100644 (file)
@@ -1281,11 +1281,12 @@ int eapol_sm_get_mib(struct eapol_sm *sm, char *buf, size_t buflen)
  * @src: Source MAC address of the EAPOL packet
  * @buf: Pointer to the beginning of the EAPOL data (EAPOL header)
  * @len: Length of the EAPOL frame
+ * @encrypted: Whether the frame was encrypted
  * Returns: 1 = EAPOL frame processed, 0 = not for EAPOL state machine,
  * -1 failure
  */
 int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf,
-                     size_t len)
+                     size_t len, enum frame_encryption encrypted)
 {
        const struct ieee802_1x_hdr *hdr;
        const struct ieee802_1x_eapol_key *key;
index 753b947adb7f146bf1428e9f064cad702c149fc4..ecc1ce70b6090082f68aad952dd07bc452aef65d 100644 (file)
@@ -323,7 +323,7 @@ int eapol_sm_get_mib(struct eapol_sm *sm, char *buf, size_t buflen);
 void eapol_sm_configure(struct eapol_sm *sm, int heldPeriod, int authPeriod,
                        int startPeriod, int maxStart);
 int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf,
-                     size_t len);
+                     size_t len, enum frame_encryption encrypted);
 void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm);
 void eapol_sm_notify_portEnabled(struct eapol_sm *sm, bool enabled);
 void eapol_sm_notify_portValid(struct eapol_sm *sm, bool valid);
@@ -389,7 +389,8 @@ static inline void eapol_sm_configure(struct eapol_sm *sm, int heldPeriod,
 {
 }
 static inline int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src,
-                                   const u8 *buf, size_t len)
+                                   const u8 *buf, size_t len,
+                                   enum frame_encryption encrypted)
 {
        return 0;
 }
index 1a38bf6bcbfac75543e3d758edd86b99d1fcd8d8..a96655f7786e98e4baf021d4cf05b80d9ea84365 100644 (file)
@@ -75,7 +75,8 @@ static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
                return;
        }
 
-       eapol_sm_rx_eapol(sm->preauth_eapol, src_addr, buf, len);
+       eapol_sm_rx_eapol(sm->preauth_eapol, src_addr, buf, len,
+                         FRAME_ENCRYPTION_UNKNOWN);
 }
 
 
index 30061e1f030297d6ffab757675615be4ec0ea357..56352af512560baf0e791aeca74fa0e754657cdf 100644 (file)
@@ -2480,6 +2480,7 @@ static int wpa_supp_aead_decrypt(struct wpa_sm *sm, u8 *buf, size_t buf_len,
  * @src_addr: Source MAC address of the EAPOL packet
  * @buf: Pointer to the beginning of the EAPOL data (EAPOL header)
  * @len: Length of the EAPOL frame
+ * @encrypted: Whether the frame was encrypted
  * Returns: 1 = WPA EAPOL-Key processed, 0 = not a WPA EAPOL-Key, -1 failure
  *
  * This function is called for each received EAPOL frame. Other than EAPOL-Key
@@ -2491,7 +2492,7 @@ static int wpa_supp_aead_decrypt(struct wpa_sm *sm, u8 *buf, size_t buf_len,
  * successful key handshake.
  */
 int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
-                   const u8 *buf, size_t len)
+                   const u8 *buf, size_t len, enum frame_encryption encrypted)
 {
        size_t plen, data_len, key_data_len;
        const struct ieee802_1x_hdr *hdr;
index b2335ce3037491cff2e452fbf7920990468b17f1..be70f4156ce9dd75de61298ff4a02e6bd54fc4e7 100644 (file)
@@ -19,6 +19,7 @@ struct eapol_sm;
 struct wpa_config_blob;
 struct hostapd_freq_params;
 struct wpa_channel_info;
+enum frame_encryption;
 
 struct wpa_sm_ctx {
        void *ctx; /* pointer to arbitrary upper level context */
@@ -184,7 +185,7 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
 void wpa_sm_aborted_cached(struct wpa_sm *sm);
 void wpa_sm_aborted_external_cached(struct wpa_sm *sm);
 int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
-                   const u8 *buf, size_t len);
+                   const u8 *buf, size_t len, enum frame_encryption encrypted);
 int wpa_sm_parse_own_wpa_ie(struct wpa_sm *sm, struct wpa_ie_data *data);
 int wpa_sm_pmksa_cache_list(struct wpa_sm *sm, char *buf, size_t len);
 struct rsn_pmksa_cache_entry * wpa_sm_pmksa_cache_head(struct wpa_sm *sm);
@@ -363,7 +364,8 @@ static inline void wpa_sm_aborted_external_cached(struct wpa_sm *sm)
 }
 
 static inline int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
-                                 const u8 *buf, size_t len)
+                                 const u8 *buf, size_t len,
+                                 enum frame_encryption encrypted)
 {
        return -1;
 }
index 487c889d7a6d4b5214dc894d94db96de8f700f4d..0c7189571b38b473250807274724eb94bee0c53c 100644 (file)
@@ -91,7 +91,7 @@ static void supp_eapol_rx(void *eloop_data, void *user_ctx)
 
        wpa_printf(MSG_DEBUG, "SUPP: RX EAPOL frame");
        wpa_sm_rx_eapol(wpa->supp, wpa->auth_addr, wpa->auth_eapol,
-                       wpa->auth_eapol_len);
+                       wpa->auth_eapol_len, FRAME_ENCRYPTION_UNKNOWN);
 }
 
 
index 94e0147adf15208146622d0bf4f2138d3c96b943..afa30fb88e22aa485402919f7fb8f51d5df6cd82 100644 (file)
@@ -44,8 +44,10 @@ static void test_send_eapol(void *eloop_data, void *user_ctx)
        wpa_ie_len = sizeof(wpa_ie);
        wpa_sm_set_assoc_wpa_ie_default(ctx->wpa, wpa_ie, &wpa_ie_len);
 
-       if (eapol_sm_rx_eapol(ctx->eapol, src, ctx->data, ctx->data_len) <= 0)
-               wpa_sm_rx_eapol(ctx->wpa, src, ctx->data, ctx->data_len);
+       if (eapol_sm_rx_eapol(ctx->eapol, src, ctx->data, ctx->data_len,
+                             FRAME_ENCRYPTION_UNKNOWN) <= 0)
+               wpa_sm_rx_eapol(ctx->wpa, src, ctx->data, ctx->data_len,
+                               FRAME_ENCRYPTION_UNKNOWN);
 
        eloop_terminate();
 }
index 7b31d8e4cfe9e6ee1772a20a8f481fbebb9bf84f..52b537e62df48aaf646192be653294c5c63b1bde 100644 (file)
@@ -1234,9 +1234,11 @@ void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok)
 
 
 void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
-                               const u8 *src_addr, const u8 *buf, size_t len)
+                               const u8 *src_addr, const u8 *buf, size_t len,
+                               enum frame_encryption encrypted)
 {
-       ieee802_1x_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
+       ieee802_1x_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len,
+                          encrypted);
 }
 
 
index ccd3e7b5853dd2cb131efe8c1acb3d09962898cc..865429e969e5f464fa0243c205ed78fd2fb20305 100644 (file)
@@ -16,7 +16,8 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
                             struct wpa_ssid *ssid);
 void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
-                               const u8 *src_addr, const u8 *buf, size_t len);
+                               const u8 *src_addr, const u8 *buf, size_t len,
+                               enum frame_encryption encrypted);
 int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
                              const u8 *p2p_dev_addr);
 int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
index 4f9aa667acb16b45e049dac375334c52f5086462..ab8a624a5d04031da0317222327b6a085a207520 100644 (file)
@@ -9521,7 +9521,7 @@ static int wpas_ctrl_iface_eapol_rx(struct wpa_supplicant *wpa_s, char *cmd)
                return -1;
        }
 
-       wpa_supplicant_rx_eapol(wpa_s, src, buf, len);
+       wpa_supplicant_rx_eapol(wpa_s, src, buf, len, FRAME_ENCRYPTION_UNKNOWN);
        os_free(buf);
 
        return 0;
index f8068957034cba9f85cdc9355143b36f8ca0cd08..efec31c655128130f6eb3d74e01dedac432ca6ab 100644 (file)
@@ -714,7 +714,7 @@ static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx)
 
        printf("Sending fake EAP-Request-Identity\n");
        eapol_sm_rx_eapol(wpa_s->eapol, wpa_s->bssid, buf,
-                         sizeof(*hdr) + 5);
+                         sizeof(*hdr) + 5, FRAME_ENCRYPTION_UNKNOWN);
 }
 
 
@@ -842,7 +842,8 @@ static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e)
                          wpabuf_len(eap));
                eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid,
                                  (u8 *) dot1x,
-                                 sizeof(*dot1x) + wpabuf_len(eap));
+                                 sizeof(*dot1x) + wpabuf_len(eap),
+                                 FRAME_ENCRYPTION_UNKNOWN);
                os_free(dot1x);
        }
 }
index 0ce3d8fb0664b6af60274c886b4cd52fd90784ec..ec56cfdc0529d4863c420e60affced24aae1f8e8 100644 (file)
@@ -3528,7 +3528,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
                        wpa_supplicant_rx_eapol(
                                wpa_s, wpa_s->pending_eapol_rx_src,
                                wpabuf_head(wpa_s->pending_eapol_rx),
-                               wpabuf_len(wpa_s->pending_eapol_rx));
+                               wpabuf_len(wpa_s->pending_eapol_rx),
+                               wpa_s->pending_eapol_encrypted);
                }
                wpabuf_free(wpa_s->pending_eapol_rx);
                wpa_s->pending_eapol_rx = NULL;
@@ -5505,7 +5506,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
        case EVENT_EAPOL_RX:
                wpa_supplicant_rx_eapol(wpa_s, data->eapol_rx.src,
                                        data->eapol_rx.data,
-                                       data->eapol_rx.data_len);
+                                       data->eapol_rx.data_len,
+                                       data->eapol_rx.encrypted);
                break;
        case EVENT_SIGNAL_CHANGE:
                wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SIGNAL_CHANGE
index 02e63904c5d73593da10f5aeec4d88586302a09c..874c2bf1d5883d42089bd361b13f07e1aecbb6c4 100644 (file)
@@ -772,7 +772,8 @@ static int ibss_rsn_eapol_dst_supp(const u8 *buf, size_t len)
 
 static int ibss_rsn_process_rx_eapol(struct ibss_rsn *ibss_rsn,
                                     struct ibss_rsn_peer *peer,
-                                    const u8 *buf, size_t len)
+                                    const u8 *buf, size_t len,
+                                    enum frame_encryption encrypted)
 {
        int supp;
        u8 *tmp;
@@ -788,7 +789,7 @@ static int ibss_rsn_process_rx_eapol(struct ibss_rsn *ibss_rsn,
                peer->authentication_status |= IBSS_RSN_AUTH_EAPOL_BY_PEER;
                wpa_printf(MSG_DEBUG, "RSN: IBSS RX EAPOL for Supplicant from "
                           MACSTR, MAC2STR(peer->addr));
-               wpa_sm_rx_eapol(peer->supp, peer->addr, tmp, len);
+               wpa_sm_rx_eapol(peer->supp, peer->addr, tmp, len, encrypted);
        } else {
                if (ibss_rsn_is_auth_started(peer) == 0) {
                        wpa_printf(MSG_DEBUG, "RSN: IBSS EAPOL for "
@@ -809,7 +810,8 @@ static int ibss_rsn_process_rx_eapol(struct ibss_rsn *ibss_rsn,
 
 
 int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
-                     const u8 *buf, size_t len)
+                     const u8 *buf, size_t len,
+                     enum frame_encryption encrypted)
 {
        struct ibss_rsn_peer *peer;
 
@@ -818,7 +820,8 @@ int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
 
        peer = ibss_rsn_get_peer(ibss_rsn, src_addr);
        if (peer)
-               return ibss_rsn_process_rx_eapol(ibss_rsn, peer, buf, len);
+               return ibss_rsn_process_rx_eapol(ibss_rsn, peer, buf, len,
+                                                encrypted);
 
        if (ibss_rsn_eapol_dst_supp(buf, len) > 0) {
                /*
@@ -836,7 +839,7 @@ int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
                                            IBSS_RSN_AUTH_EAPOL_BY_US);
 
                return ibss_rsn_process_rx_eapol(ibss_rsn, ibss_rsn->peers,
-                                                buf, len);
+                                                buf, len, encrypted);
        }
 
        return 0;
index 626c543546c8573581ef026b5db493fbd2edbfb2..cff45a79cec5e32fe70a37a825f8352110ff4ee1 100644 (file)
@@ -57,7 +57,8 @@ void ibss_rsn_deinit(struct ibss_rsn *ibss_rsn);
 int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr);
 void ibss_rsn_stop(struct ibss_rsn *ibss_rsn, const u8 *peermac);
 int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
-                     const u8 *buf, size_t len);
+                     const u8 *buf, size_t len,
+                     enum frame_encryption encrypted);
 void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk);
 void ibss_rsn_handle_auth(struct ibss_rsn *ibss_rsn, const u8 *auth_frame,
                          size_t len);
index c5d7168690f7a0aa675a805e14ed68db56f03085..ff1fb6702959106dcdcf85bca83679add97581fe 100644 (file)
@@ -1134,7 +1134,8 @@ void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
 
 
 void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
-                            const u8 *buf, size_t len)
+                            const u8 *buf, size_t len,
+                            enum frame_encryption encrypted)
 {
        struct wpa_priv_interface *iface = ctx;
        struct msghdr msg;
index 82aaad8918da561d281e9be551cd662b302117b2..e16861886ab21c1edfeccc2dd34464aa3d17aa3b 100644 (file)
@@ -4993,6 +4993,7 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
  * @src_addr: Source address of the EAPOL frame
  * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
  * @len: Length of the EAPOL data
+ * @encrypted: Whether the frame was encrypted
  *
  * This function is called for each received EAPOL frame. Most driver
  * interfaces rely on more generic OS mechanism for receiving frames through
@@ -5001,11 +5002,13 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
  * code by calling this function.
  */
 void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
-                            const u8 *buf, size_t len)
+                            const u8 *buf, size_t len,
+                            enum frame_encryption encrypted)
 {
        struct wpa_supplicant *wpa_s = ctx;
 
-       wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
+       wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " (encrypted=%d)",
+               MAC2STR(src_addr), encrypted);
        wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
 
        if (wpa_s->own_disconnect_req) {
@@ -5051,6 +5054,7 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
                        os_get_reltime(&wpa_s->pending_eapol_rx_time);
                        os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
                                  ETH_ALEN);
+                       wpa_s->pending_eapol_encrypted = encrypted;
                }
                return;
        }
@@ -5060,7 +5064,8 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
 
 #ifdef CONFIG_AP
        if (wpa_s->ap_iface) {
-               wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
+               wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len,
+                                          encrypted);
                return;
        }
 #endif /* CONFIG_AP */
@@ -5120,7 +5125,8 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
 #ifdef CONFIG_IBSS_RSN
        if (wpa_s->current_ssid &&
            wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
-               ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
+               ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len,
+                                 encrypted);
                return;
        }
 #endif /* CONFIG_IBSS_RSN */
@@ -5135,11 +5141,12 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
        if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
            wpa_s->key_mgmt != WPA_KEY_MGMT_OWE &&
            wpa_s->key_mgmt != WPA_KEY_MGMT_DPP &&
-           eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
+           eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len,
+                             encrypted) > 0)
                return;
        wpa_drv_poll(wpa_s);
        if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK))
-               wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
+               wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len, encrypted);
        else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
                /*
                 * Set portValid = true here since we are going to skip 4-way
@@ -5152,6 +5159,14 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
 }
 
 
+static void wpa_supplicant_rx_eapol_cb(void *ctx, const u8 *src_addr,
+                                      const u8 *buf, size_t len)
+{
+       wpa_supplicant_rx_eapol(ctx, src_addr, buf, len,
+                               FRAME_ENCRYPTION_UNKNOWN);
+}
+
+
 static int wpas_eapol_needs_l2_packet(struct wpa_supplicant *wpa_s)
 {
        return !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_CONTROL_PORT) ||
@@ -5169,7 +5184,7 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
                                           wpa_drv_get_mac_addr(wpa_s),
                                           ETH_P_EAPOL,
                                           wpas_eapol_needs_l2_packet(wpa_s) ?
-                                          wpa_supplicant_rx_eapol : NULL,
+                                          wpa_supplicant_rx_eapol_cb : NULL,
                                           wpa_s, 0);
                if (wpa_s->l2 == NULL)
                        return -1;
@@ -5223,7 +5238,7 @@ static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
        wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
                " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
        wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
-                               len - sizeof(*eth));
+                               len - sizeof(*eth), FRAME_ENCRYPTION_UNKNOWN);
 }
 
 
index 504660e87ab2c871feec0a73abbcf58495c094a3..4dd9dd8b5ec0c3d7270f25c92f57724edd4acc7f 100644 (file)
@@ -948,6 +948,7 @@ struct wpa_supplicant {
        struct wpabuf *pending_eapol_rx;
        struct os_reltime pending_eapol_rx_time;
        u8 pending_eapol_rx_src[ETH_ALEN];
+       enum frame_encryption pending_eapol_encrypted;
        unsigned int last_eapol_matches_bssid:1;
        unsigned int eapol_failed:1;
        unsigned int eap_expected_failure:1;
@@ -1626,7 +1627,8 @@ int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
                              struct wpa_ssid *ssid);
 void wpa_supplicant_terminate_proc(struct wpa_global *global);
 void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
-                            const u8 *buf, size_t len);
+                            const u8 *buf, size_t len,
+                            enum frame_encryption encrypted);
 void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s);
 void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid);