Accumulative patch from commit f5f37d3a4fc2df2a24676b4f95afca15ed793cba

Author: Jouni Malinen <j@w1.fi>
Date:   Sun Nov 25 22:05:32 2012 +0200

   Fix REAUTHENTICATE command after PMKSA caching

   The current PMKSA cache entry needs to be clear to allow EAPOL
   reauthentication to be started in case this association used PMKSA
   caching.

 - Remove old WPS_OOB NCF
 - WPS: Add preliminary NFC connection handover support for Enrollee
 - WPS: Reenable the networks disabled during wpa_wpas_reassoc
 - P2P: Avoid multi-channel scans when they are not needed
 - P2P: Allow discoverable interval for p2p_find to be configured
 - P2P: Allow all channels with multi-channel concurrency
 - Bonjour changes
 - Remove disassociate
 - HS 2.0 changes
 - Add preliminary support for using SQLite for eap_user database
 - Add SAE support
 - Add disallow_aps parameter to disallow BSSIDs/SSIDs

Change-Id: I85358a05b39d46b8db49acdad667e771c580b05c
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 49d8175..0816b25 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -54,11 +54,12 @@
 static const int dot11RSNAConfigSATimeout = 60;
 
 
-static inline void wpa_auth_mic_failure_report(
+static inline int wpa_auth_mic_failure_report(
 	struct wpa_authenticator *wpa_auth, const u8 *addr)
 {
 	if (wpa_auth->cb.mic_failure_report)
-		wpa_auth->cb.mic_failure_report(wpa_auth->cb.ctx, addr);
+		return wpa_auth->cb.mic_failure_report(wpa_auth->cb.ctx, addr);
+	return 0;
 }
 
 
@@ -700,8 +701,8 @@
 #endif /* CONFIG_IEEE80211R */
 
 
-static void wpa_receive_error_report(struct wpa_authenticator *wpa_auth,
-				     struct wpa_state_machine *sm, int group)
+static int wpa_receive_error_report(struct wpa_authenticator *wpa_auth,
+				    struct wpa_state_machine *sm, int group)
 {
 	/* Supplicant reported a Michael MIC error */
 	wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
@@ -718,7 +719,8 @@
 				"ignore Michael MIC failure report since "
 				"pairwise cipher is not TKIP");
 	} else {
-		wpa_auth_mic_failure_report(wpa_auth, sm->addr);
+		if (wpa_auth_mic_failure_report(wpa_auth, sm->addr) > 0)
+			return 1; /* STA entry was removed */
 		sm->dot11RSNAStatsTKIPRemoteMICFailures++;
 		wpa_auth->dot11RSNAStatsTKIPRemoteMICFailures++;
 	}
@@ -728,6 +730,7 @@
 	 * Authenticator may do it, let's change the keys now anyway.
 	 */
 	wpa_request_new_ptk(sm);
+	return 0;
 }
 
 
@@ -1081,9 +1084,10 @@
 #endif /* CONFIG_PEERKEY */
 			return;
 		} else if (key_info & WPA_KEY_INFO_ERROR) {
-			wpa_receive_error_report(
-				wpa_auth, sm,
-				!(key_info & WPA_KEY_INFO_KEY_TYPE));
+			if (wpa_receive_error_report(
+				    wpa_auth, sm,
+				    !(key_info & WPA_KEY_INFO_KEY_TYPE)) > 0)
+				return; /* STA entry was removed */
 		} else if (key_info & WPA_KEY_INFO_KEY_TYPE) {
 			wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
 					"received EAPOL-Key Request for new "
@@ -3056,3 +3060,11 @@
 				       wpa_send_eapol_timeout, wpa_auth, sm);
 	}
 }
+
+
+int wpa_auth_uses_sae(struct wpa_state_machine *sm)
+{
+	if (sm == NULL)
+		return 0;
+	return wpa_key_mgmt_sae(sm->wpa_key_mgmt);
+}