xref: /freebsd/contrib/wpa/src/ap/tkip_countermeasures.c (revision 67350cb56a69468c118bd4ccf6e361b7ebfa9eb4)
1e28a4053SRui Paulo /*
2e28a4053SRui Paulo  * hostapd / TKIP countermeasures
3f05cddf9SRui Paulo  * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
4e28a4053SRui Paulo  *
5f05cddf9SRui Paulo  * This software may be distributed under the terms of the BSD license.
6f05cddf9SRui Paulo  * See README for more details.
7e28a4053SRui Paulo  */
8e28a4053SRui Paulo 
9e28a4053SRui Paulo #include "utils/includes.h"
10e28a4053SRui Paulo 
11e28a4053SRui Paulo #include "utils/common.h"
12e28a4053SRui Paulo #include "utils/eloop.h"
13e28a4053SRui Paulo #include "common/ieee802_11_defs.h"
14f05cddf9SRui Paulo #include "radius/radius.h"
15e28a4053SRui Paulo #include "hostapd.h"
16e28a4053SRui Paulo #include "sta_info.h"
17e28a4053SRui Paulo #include "ap_mlme.h"
18e28a4053SRui Paulo #include "wpa_auth.h"
19f05cddf9SRui Paulo #include "ap_drv_ops.h"
20e28a4053SRui Paulo #include "tkip_countermeasures.h"
21e28a4053SRui Paulo 
22e28a4053SRui Paulo 
ieee80211_tkip_countermeasures_stop(void * eloop_ctx,void * timeout_ctx)23e28a4053SRui Paulo static void ieee80211_tkip_countermeasures_stop(void *eloop_ctx,
24e28a4053SRui Paulo 						void *timeout_ctx)
25e28a4053SRui Paulo {
26e28a4053SRui Paulo 	struct hostapd_data *hapd = eloop_ctx;
27e28a4053SRui Paulo 	hapd->tkip_countermeasures = 0;
28f05cddf9SRui Paulo 	hostapd_drv_set_countermeasures(hapd, 0);
29e28a4053SRui Paulo 	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
30e28a4053SRui Paulo 		       HOSTAPD_LEVEL_INFO, "TKIP countermeasures ended");
31e28a4053SRui Paulo }
32e28a4053SRui Paulo 
33e28a4053SRui Paulo 
ieee80211_tkip_countermeasures_start(struct hostapd_data * hapd)34e28a4053SRui Paulo static void ieee80211_tkip_countermeasures_start(struct hostapd_data *hapd)
35e28a4053SRui Paulo {
36e28a4053SRui Paulo 	struct sta_info *sta;
37e28a4053SRui Paulo 
38e28a4053SRui Paulo 	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
39e28a4053SRui Paulo 		       HOSTAPD_LEVEL_INFO, "TKIP countermeasures initiated");
40e28a4053SRui Paulo 
41e28a4053SRui Paulo 	wpa_auth_countermeasures_start(hapd->wpa_auth);
42e28a4053SRui Paulo 	hapd->tkip_countermeasures = 1;
43f05cddf9SRui Paulo 	hostapd_drv_set_countermeasures(hapd, 1);
44e28a4053SRui Paulo 	wpa_gtk_rekey(hapd->wpa_auth);
45e28a4053SRui Paulo 	eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL);
46e28a4053SRui Paulo 	eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop,
47e28a4053SRui Paulo 			       hapd, NULL);
48f05cddf9SRui Paulo 	while ((sta = hapd->sta_list)) {
49f05cddf9SRui Paulo 		sta->acct_terminate_cause =
50f05cddf9SRui Paulo 			RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_RESET;
51f05cddf9SRui Paulo 		if (sta->flags & WLAN_STA_AUTH) {
52f05cddf9SRui Paulo 			mlme_deauthenticate_indication(
53f05cddf9SRui Paulo 				hapd, sta,
54e28a4053SRui Paulo 				WLAN_REASON_MICHAEL_MIC_FAILURE);
55f05cddf9SRui Paulo 		}
56f05cddf9SRui Paulo 		hostapd_drv_sta_deauth(hapd, sta->addr,
57f05cddf9SRui Paulo 				       WLAN_REASON_MICHAEL_MIC_FAILURE);
58f05cddf9SRui Paulo 		ap_free_sta(hapd, sta);
59e28a4053SRui Paulo 	}
60e28a4053SRui Paulo }
61e28a4053SRui Paulo 
62e28a4053SRui Paulo 
ieee80211_tkip_countermeasures_deinit(struct hostapd_data * hapd)63f05cddf9SRui Paulo void ieee80211_tkip_countermeasures_deinit(struct hostapd_data *hapd)
64e28a4053SRui Paulo {
65f05cddf9SRui Paulo 	eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL);
66f05cddf9SRui Paulo }
67f05cddf9SRui Paulo 
68f05cddf9SRui Paulo 
michael_mic_failure(struct hostapd_data * hapd,const u8 * addr,int local)69f05cddf9SRui Paulo int michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local)
70f05cddf9SRui Paulo {
715b9c547cSRui Paulo 	struct os_reltime now;
72f05cddf9SRui Paulo 	int ret = 0;
73e28a4053SRui Paulo 
74*85732ac8SCy Schubert 	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
75*85732ac8SCy Schubert 		       HOSTAPD_LEVEL_INFO,
76*85732ac8SCy Schubert 		       "Michael MIC failure detected in received frame%s",
77*85732ac8SCy Schubert 		       local ? " (local)" : "");
78*85732ac8SCy Schubert 
79e28a4053SRui Paulo 	if (addr && local) {
80e28a4053SRui Paulo 		struct sta_info *sta = ap_get_sta(hapd, addr);
81e28a4053SRui Paulo 		if (sta != NULL) {
82e28a4053SRui Paulo 			wpa_auth_sta_local_mic_failure_report(sta->wpa_sm);
83e28a4053SRui Paulo 			hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
84e28a4053SRui Paulo 				       HOSTAPD_LEVEL_INFO,
85e28a4053SRui Paulo 				       "Michael MIC failure detected in "
86e28a4053SRui Paulo 				       "received frame");
87e28a4053SRui Paulo 			mlme_michaelmicfailure_indication(hapd, addr);
88e28a4053SRui Paulo 		} else {
89e28a4053SRui Paulo 			wpa_printf(MSG_DEBUG,
90e28a4053SRui Paulo 				   "MLME-MICHAELMICFAILURE.indication "
91e28a4053SRui Paulo 				   "for not associated STA (" MACSTR
92e28a4053SRui Paulo 				   ") ignored", MAC2STR(addr));
93f05cddf9SRui Paulo 			return ret;
94e28a4053SRui Paulo 		}
95e28a4053SRui Paulo 	}
96e28a4053SRui Paulo 
975b9c547cSRui Paulo 	os_get_reltime(&now);
985b9c547cSRui Paulo 	if (os_reltime_expired(&now, &hapd->michael_mic_failure, 60)) {
99e28a4053SRui Paulo 		hapd->michael_mic_failures = 1;
100e28a4053SRui Paulo 	} else {
101e28a4053SRui Paulo 		hapd->michael_mic_failures++;
102f05cddf9SRui Paulo 		if (hapd->michael_mic_failures > 1) {
103e28a4053SRui Paulo 			ieee80211_tkip_countermeasures_start(hapd);
104f05cddf9SRui Paulo 			ret = 1;
105e28a4053SRui Paulo 		}
106f05cddf9SRui Paulo 	}
1075b9c547cSRui Paulo 	hapd->michael_mic_failure = now;
108f05cddf9SRui Paulo 
109f05cddf9SRui Paulo 	return ret;
110e28a4053SRui Paulo }
111