18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / TKIP countermeasures
31f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Copyright (c) 2002-2011, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h"
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hostapd.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sta_info.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_mlme.h"
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth.h"
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_drv_ops.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tkip_countermeasures.h"
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee80211_tkip_countermeasures_stop(void *eloop_ctx,
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						void *timeout_ctx)
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd = eloop_ctx;
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd->tkip_countermeasures = 0;
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_drv_set_countermeasures(hapd, 0);
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       HOSTAPD_LEVEL_INFO, "TKIP countermeasures ended");
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee80211_tkip_countermeasures_start(struct hostapd_data *hapd)
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct sta_info *sta;
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       HOSTAPD_LEVEL_INFO, "TKIP countermeasures initiated");
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_auth_countermeasures_start(hapd->wpa_auth);
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd->tkip_countermeasures = 1;
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_drv_set_countermeasures(hapd, 1);
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_gtk_rekey(hapd->wpa_auth);
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL);
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop,
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       hapd, NULL);
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (sta = hapd->sta_list; sta != NULL; sta = sta->next) {
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hostapd_drv_sta_deauth(hapd, sta->addr,
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       WLAN_REASON_MICHAEL_MIC_FAILURE);
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ap_sta_set_authorized(hapd, sta, 0);
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hostapd_drv_sta_remove(hapd, sta->addr);
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid ieee80211_tkip_countermeasures_deinit(struct hostapd_data *hapd)
581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL);
601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local)
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct os_time now;
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (addr && local) {
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct sta_info *sta = ap_get_sta(hapd, addr);
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (sta != NULL) {
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_auth_sta_local_mic_failure_report(sta->wpa_sm);
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       HOSTAPD_LEVEL_INFO,
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       "Michael MIC failure detected in "
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       "received frame");
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			mlme_michaelmicfailure_indication(hapd, addr);
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG,
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "MLME-MICHAELMICFAILURE.indication "
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "for not associated STA (" MACSTR
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   ") ignored", MAC2STR(addr));
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_get_time(&now);
861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (now.sec > hapd->michael_mic_failure + 60) {
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd->michael_mic_failures = 1;
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd->michael_mic_failures++;
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hapd->michael_mic_failures > 1)
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ieee80211_tkip_countermeasures_start(hapd);
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	hapd->michael_mic_failure = now.sec;
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
95