diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index d479006c7..664c59df7 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -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; diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index 00d3f9712..fff8bb3e5 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -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) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index e1818ece2..aa26ad4ef 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -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); diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c index fb5e92060..270691ae5 100644 --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c @@ -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; diff --git a/src/ap/ieee802_1x.h b/src/ap/ieee802_1x.h index 70dc11afe..1469351c1 100644 --- a/src/ap/ieee802_1x.h +++ b/src/ap/ieee802_1x.h @@ -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); diff --git a/src/ap/preauth_auth.c b/src/ap/preauth_auth.c index 2ff186177..3284a10a9 100644 --- a/src/ap/preauth_auth.c +++ b/src/ap/preauth_auth.c @@ -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); } diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h index af8f171b2..5c92e01da 100644 --- a/src/ap/sta_info.h +++ b/src/ap/sta_info.h @@ -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 { diff --git a/src/common/defs.h b/src/common/defs.h index f43bdb5d1..07065695d 100644 --- a/src/common/defs.h +++ b/src/common/defs.h @@ -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 */ diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 6c00fb564..5e204655c 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -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); } diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 22fb4f1e4..00f8b0cbb 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -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, diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c index 861eea2ae..f5f576045 100644 --- a/src/eapol_supp/eapol_supp_sm.c +++ b/src/eapol_supp/eapol_supp_sm.c @@ -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; diff --git a/src/eapol_supp/eapol_supp_sm.h b/src/eapol_supp/eapol_supp_sm.h index 753b947ad..ecc1ce70b 100644 --- a/src/eapol_supp/eapol_supp_sm.h +++ b/src/eapol_supp/eapol_supp_sm.h @@ -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; } diff --git a/src/rsn_supp/preauth.c b/src/rsn_supp/preauth.c index 1a38bf6bc..a96655f77 100644 --- a/src/rsn_supp/preauth.c +++ b/src/rsn_supp/preauth.c @@ -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); } diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 30061e1f0..56352af51 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -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; diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index b2335ce30..be70f4156 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -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; } diff --git a/tests/fuzzing/eapol-key-supp/eapol-key-supp.c b/tests/fuzzing/eapol-key-supp/eapol-key-supp.c index 487c889d7..0c7189571 100644 --- a/tests/fuzzing/eapol-key-supp/eapol-key-supp.c +++ b/tests/fuzzing/eapol-key-supp/eapol-key-supp.c @@ -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); } diff --git a/tests/fuzzing/eapol-supp/eapol-supp.c b/tests/fuzzing/eapol-supp/eapol-supp.c index 94e0147ad..afa30fb88 100644 --- a/tests/fuzzing/eapol-supp/eapol-supp.c +++ b/tests/fuzzing/eapol-supp/eapol-supp.c @@ -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(); } diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 7b31d8e4c..52b537e62 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -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); } diff --git a/wpa_supplicant/ap.h b/wpa_supplicant/ap.h index ccd3e7b58..865429e96 100644 --- a/wpa_supplicant/ap.h +++ b/wpa_supplicant/ap.h @@ -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, diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 4f9aa667a..ab8a624a5 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -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; diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c index f80689570..efec31c65 100644 --- a/wpa_supplicant/eapol_test.c +++ b/wpa_supplicant/eapol_test.c @@ -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); } } diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 0ce3d8fb0..ec56cfdc0 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -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 diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c index 02e63904c..874c2bf1d 100644 --- a/wpa_supplicant/ibss_rsn.c +++ b/wpa_supplicant/ibss_rsn.c @@ -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; diff --git a/wpa_supplicant/ibss_rsn.h b/wpa_supplicant/ibss_rsn.h index 626c54354..cff45a79c 100644 --- a/wpa_supplicant/ibss_rsn.h +++ b/wpa_supplicant/ibss_rsn.h @@ -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); diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c index c5d716869..ff1fb6702 100644 --- a/wpa_supplicant/wpa_priv.c +++ b/wpa_supplicant/wpa_priv.c @@ -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; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 82aaad891..e16861886 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -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); } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 504660e87..4dd9dd8b5 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -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);