]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add no_encrypt flag for control port TX
authorMarkus Theil <markus.theil@tu-ilmenau.de>
Fri, 3 Jan 2020 15:17:42 +0000 (16:17 +0100)
committerJouni Malinen <j@w1.fi>
Sun, 5 Jan 2020 18:34:50 +0000 (20:34 +0200)
In order to correctly encrypt rekeying frames, wpa_supplicant now checks
if a PTK is currently installed and sets the corresponding encrypt
option for tx_control_port().

Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
src/drivers/driver.h
src/drivers/driver_nl80211.c
src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
wpa_supplicant/driver_i.h
wpa_supplicant/ibss_rsn.c
wpa_supplicant/wpas_glue.c

index 09867f2cd2dcdd3a228d82bc56c6c83710fb1db9..f455a2f90a62a03fcd3c33d41b81556f9e39f3b4 100644 (file)
@@ -2878,6 +2878,7 @@ struct wpa_driver_ops {
         * @proto: Ethertype in host byte order
         * @buf: Frame payload starting from IEEE 802.1X header
         * @len: Frame payload length
+        * @no_encrypt: Do not encrypt frame
         *
         * Returns 0 on success, else an error
         *
@@ -2894,7 +2895,8 @@ struct wpa_driver_ops {
         * API users will fall back to sending the frame via a normal socket.
         */
        int (*tx_control_port)(void *priv, const u8 *dest,
-                              u16 proto, const u8 *buf, size_t len);
+                              u16 proto, const u8 *buf, size_t len,
+                              int no_encrypt);
 
        /**
         * hapd_send_eapol - Send an EAPOL packet (AP only)
index f940ac5520b9cd3ea4c786babac11925848d1669..e9f86aabde2fa12f55d9490968f3f74aa539b8fa 100644 (file)
@@ -5093,7 +5093,8 @@ static void nl80211_teardown_ap(struct i802_bss *bss)
 
 
 static int nl80211_tx_control_port(void *priv, const u8 *dest,
-                                  u16 proto, const u8 *buf, size_t len)
+                                  u16 proto, const u8 *buf, size_t len,
+                                  int no_encrypt)
 {
        struct i802_bss *bss = priv;
        struct nl_msg *msg;
@@ -5101,14 +5102,16 @@ static int nl80211_tx_control_port(void *priv, const u8 *dest,
 
        wpa_printf(MSG_DEBUG,
                   "nl80211: Send over control port dest=" MACSTR
-                  " proto=0x%04x len=%u",
-                  MAC2STR(dest), proto, (unsigned int) len);
+                  " proto=0x%04x len=%u no_encrypt=%d",
+                  MAC2STR(dest), proto, (unsigned int) len, no_encrypt);
 
        msg = nl80211_bss_msg(bss, 0, NL80211_CMD_CONTROL_PORT_FRAME);
        if (!msg ||
            nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
            nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dest) ||
-           nla_put(msg, NL80211_ATTR_FRAME, len, buf)) {
+           nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
+           (no_encrypt &&
+            nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT))) {
                nlmsg_free(msg);
                return -ENOBUFS;
        }
index e9df04e117b2e4c81eddda63f6396d1a303d4413..85c28401b48f75b102a0c5805fef2c9a27ae5ccf 100644 (file)
@@ -3510,6 +3510,14 @@ int wpa_sm_has_ptk(struct wpa_sm *sm)
 }
 
 
+int wpa_sm_has_ptk_installed(struct wpa_sm *sm)
+{
+       if (!sm)
+               return 0;
+       return sm->ptk.installed;
+}
+
+
 void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr)
 {
        os_memcpy(sm->rx_replay_counter, replay_ctr, WPA_REPLAY_COUNTER_LEN);
index f1fbb1bb563757eca6f241f27763004fadd30ad5..31a8bd0c6e9aa9b6f7d829d08a6a062e7d6e8188 100644 (file)
@@ -172,6 +172,7 @@ int wpa_sm_pmksa_exists(struct wpa_sm *sm, const u8 *bssid,
                        const void *network_ctx);
 void wpa_sm_drop_sa(struct wpa_sm *sm);
 int wpa_sm_has_ptk(struct wpa_sm *sm);
+int wpa_sm_has_ptk_installed(struct wpa_sm *sm);
 
 void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr);
 
index d091c8761a812a01402e2a8164be31e8670f20b4..bc1373bbb1f81996e3f585ae7443656cf7faee2f 100644 (file)
@@ -344,12 +344,13 @@ static inline int wpa_drv_sta_remove(struct wpa_supplicant *wpa_s,
 
 static inline int wpa_drv_tx_control_port(struct wpa_supplicant *wpa_s,
                                          const u8 *dest, u16 proto,
-                                         const u8 *buf, size_t len)
+                                         const u8 *buf, size_t len,
+                                         int no_encrypt)
 {
        if (!wpa_s->driver->tx_control_port)
                return -1;
        return wpa_s->driver->tx_control_port(wpa_s->drv_priv, dest, proto,
-                                             buf, len);
+                                             buf, len, no_encrypt);
 }
 
 static inline int wpa_drv_hapd_send_eapol(struct wpa_supplicant *wpa_s,
index 0aba8cb04369c5a2a6a3e9290b7af3be995709e4..f1e3ecdb2394ed41d0db08b7d729dda50526946b 100644 (file)
@@ -64,13 +64,16 @@ static int supp_ether_send(void *ctx, const u8 *dest, u16 proto, const u8 *buf,
 {
        struct ibss_rsn_peer *peer = ctx;
        struct wpa_supplicant *wpa_s = peer->ibss_rsn->wpa_s;
+       int encrypt = peer->authentication_status & IBSS_RSN_REPORTED_PTK;
 
-       wpa_printf(MSG_DEBUG, "SUPP: %s(dest=" MACSTR " proto=0x%04x "
-                  "len=%lu)",
-                  __func__, MAC2STR(dest), proto, (unsigned long) len);
+       wpa_printf(MSG_DEBUG, "SUPP: %s(dest=" MACSTR
+                  " proto=0x%04x len=%lu no_encrypt=%d)",
+                  __func__, MAC2STR(dest), proto, (unsigned long) len,
+                  !encrypt);
 
        if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_CONTROL_PORT)
-               return wpa_drv_tx_control_port(wpa_s, dest, proto, buf, len);
+               return wpa_drv_tx_control_port(wpa_s, dest, proto, buf, len,
+                                              !encrypt);
 
        if (wpa_s->l2)
                return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
index b67a24e537d0963e411d3d62ad5c8d9c43fefe3d..240d6109925047beb2c7199907fab24972eb1ba0 100644 (file)
@@ -112,8 +112,13 @@ static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
        }
 #endif /* CONFIG_TESTING_OPTIONS */
 
-       if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_CONTROL_PORT)
-               return wpa_drv_tx_control_port(wpa_s, dest, proto, buf, len);
+       if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_CONTROL_PORT) {
+               int encrypt = wpa_s->wpa &&
+                       wpa_sm_has_ptk_installed(wpa_s->wpa);
+
+               return wpa_drv_tx_control_port(wpa_s, dest, proto, buf, len,
+                                              !encrypt);
+       }
 
        if (wpa_s->l2) {
                return l2_packet_send(wpa_s->l2, dest, proto, buf, len);