]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - hostapd/ctrl_iface.c
Add testing functionality for resetting PN/IPN for configured keys
[thirdparty/hostap.git] / hostapd / ctrl_iface.c
index 9aba5416dd899cc63dc3b959b78b4ae8f9213185..12978f79f7abe8f1573002e9733b772dc7dce4f7 100644 (file)
@@ -1949,6 +1949,90 @@ static int hostapd_ctrl_get_fail(struct hostapd_data *hapd,
 #endif /* WPA_TRACE_BFD */
 }
 
+
+static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
+{
+       struct sta_info *sta;
+       u8 addr[ETH_ALEN];
+       u8 zero[WPA_TK_MAX_LEN];
+
+       os_memset(zero, 0, sizeof(zero));
+
+       if (hwaddr_aton(cmd, addr))
+               return -1;
+
+#ifdef CONFIG_IEEE80211W
+       if (is_broadcast_ether_addr(addr) && os_strstr(cmd, "IGTK")) {
+               if (hapd->last_igtk_alg == WPA_ALG_NONE)
+                       return -1;
+
+               wpa_printf(MSG_INFO, "TESTING: Reset IPN for IGTK");
+
+               /* First, use a zero key to avoid any possible duplicate key
+                * avoidance in the driver. */
+               if (hostapd_drv_set_key(hapd->conf->iface, hapd,
+                                       hapd->last_igtk_alg,
+                                       broadcast_ether_addr,
+                                       hapd->last_igtk_key_idx, 1, NULL, 0,
+                                       zero, hapd->last_igtk_len) < 0)
+                       return -1;
+
+               /* Set the previously configured key to reset its TSC */
+               return hostapd_drv_set_key(hapd->conf->iface, hapd,
+                                          hapd->last_igtk_alg,
+                                          broadcast_ether_addr,
+                                          hapd->last_igtk_key_idx, 1, NULL, 0,
+                                          hapd->last_igtk,
+                                          hapd->last_igtk_len);
+       }
+#endif /* CONFIG_IEEE80211W */
+
+       if (is_broadcast_ether_addr(addr)) {
+               if (hapd->last_gtk_alg == WPA_ALG_NONE)
+                       return -1;
+
+               wpa_printf(MSG_INFO, "TESTING: Reset PN for GTK");
+
+               /* First, use a zero key to avoid any possible duplicate key
+                * avoidance in the driver. */
+               if (hostapd_drv_set_key(hapd->conf->iface, hapd,
+                                       hapd->last_gtk_alg,
+                                       broadcast_ether_addr,
+                                       hapd->last_gtk_key_idx, 1, NULL, 0,
+                                       zero, hapd->last_gtk_len) < 0)
+                       return -1;
+
+               /* Set the previously configured key to reset its TSC */
+               return hostapd_drv_set_key(hapd->conf->iface, hapd,
+                                          hapd->last_gtk_alg,
+                                          broadcast_ether_addr,
+                                          hapd->last_gtk_key_idx, 1, NULL, 0,
+                                          hapd->last_gtk, hapd->last_gtk_len);
+       }
+
+       sta = ap_get_sta(hapd, addr);
+       if (!sta)
+               return -1;
+
+       if (sta->last_tk_alg == WPA_ALG_NONE)
+               return -1;
+
+       wpa_printf(MSG_INFO, "TESTING: Reset PN for " MACSTR,
+                  MAC2STR(sta->addr));
+
+       /* First, use a zero key to avoid any possible duplicate key avoidance
+        * in the driver. */
+       if (hostapd_drv_set_key(hapd->conf->iface, hapd, sta->last_tk_alg,
+                               sta->addr, sta->last_tk_key_idx, 1, NULL, 0,
+                               zero, sta->last_tk_len) < 0)
+               return -1;
+
+       /* Set the previously configured key to reset its TSC/RSC */
+       return hostapd_drv_set_key(hapd->conf->iface, hapd, sta->last_tk_alg,
+                                  sta->addr, sta->last_tk_key_idx, 1, NULL, 0,
+                                  sta->last_tk, sta->last_tk_len);
+}
+
 #endif /* CONFIG_TESTING_OPTIONS */
 
 
@@ -2665,6 +2749,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
                        reply_len = -1;
        } else if (os_strcmp(buf, "GET_FAIL") == 0) {
                reply_len = hostapd_ctrl_get_fail(hapd, reply, reply_size);
+       } else if (os_strncmp(buf, "RESET_PN ", 9) == 0) {
+               if (hostapd_ctrl_reset_pn(hapd, buf + 9) < 0)
+                       reply_len = -1;
 #endif /* CONFIG_TESTING_OPTIONS */
        } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
                if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12))