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