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