tkip_countermeasures.c revision 04949598a23f501be6eec21697465fd46a28840a
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/* 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * hostapd / TKIP countermeasures 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi> 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * This software may be distributed under the terms of the BSD license. 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * See README for more details. 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) */ 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "utils/includes.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "utils/common.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "utils/eloop.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "common/ieee802_11_defs.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "radius/radius.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "hostapd.h" 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "sta_info.h" 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ap_mlme.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "wpa_auth.h" 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ap_drv_ops.h" 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "tkip_countermeasures.h" 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static void ieee80211_tkip_countermeasures_stop(void *eloop_ctx, 247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void *timeout_ctx) 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) struct hostapd_data *hapd = eloop_ctx; 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) hapd->tkip_countermeasures = 0; 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) hostapd_drv_set_countermeasures(hapd, 0); 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HOSTAPD_LEVEL_INFO, "TKIP countermeasures ended"); 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static void ieee80211_tkip_countermeasures_start(struct hostapd_data *hapd) 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) struct sta_info *sta; 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HOSTAPD_LEVEL_INFO, "TKIP countermeasures initiated"); 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) wpa_auth_countermeasures_start(hapd->wpa_auth); 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) hapd->tkip_countermeasures = 1; 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) hostapd_drv_set_countermeasures(hapd, 1); 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) wpa_gtk_rekey(hapd->wpa_auth); 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL); 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop, 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) hapd, NULL); 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) while ((sta = hapd->sta_list)) { 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sta->acct_terminate_cause = 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_RESET; 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (sta->flags & WLAN_STA_AUTH) { 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) mlme_deauthenticate_indication( 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hapd, sta, 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) WLAN_REASON_MICHAEL_MIC_FAILURE); 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) hostapd_drv_sta_deauth(hapd, sta->addr, 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) WLAN_REASON_MICHAEL_MIC_FAILURE); 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ap_free_sta(hapd, sta); 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ieee80211_tkip_countermeasures_deinit(struct hostapd_data *hapd) 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){ 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL); 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local) 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){ 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) struct os_time now; 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (addr && local) { 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) struct sta_info *sta = ap_get_sta(hapd, addr); 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (sta != NULL) { 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) wpa_auth_sta_local_mic_failure_report(sta->wpa_sm); 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HOSTAPD_LEVEL_INFO, 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "Michael MIC failure detected in " 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "received frame"); 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mlme_michaelmicfailure_indication(hapd, addr); 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) wpa_printf(MSG_DEBUG, 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "MLME-MICHAELMICFAILURE.indication " 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "for not associated STA (" MACSTR 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ") ignored", MAC2STR(addr)); 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) os_get_time(&now); 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (now.sec > hapd->michael_mic_failure + 60) { 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) hapd->michael_mic_failures = 1; 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch hapd->michael_mic_failures++; 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (hapd->michael_mic_failures > 1) 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ieee80211_tkip_countermeasures_start(hapd); 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) hapd->michael_mic_failure = now.sec; 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)