Update to new version 0.8.16 from BRCM
Sync with main tree commit b8349523e460493fa0b4de36c689595109e45e91
Author: Neeraj Kumar Garg <neerajkg@broadcom.com>
Date: Tue Dec 27 23:21:45 2011 +0200
P2P: Reject p2p_group_add if forced frequency is not acceptable
Change-Id: Icb4541a371b05c270e80440d7a7fdea7f33ff61e
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 0836887..adc69e2 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -1,6 +1,6 @@
/*
- * hostapd - IEEE 802.11i-2004 / WPA Authenticator
- * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
+ * IEEE 802.11 RSN / WPA Authenticator
+ * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -52,6 +52,7 @@
static const u32 dot11RSNAConfigPairwiseUpdateCount = 4;
static const u32 eapol_key_timeout_first = 100; /* ms */
static const u32 eapol_key_timeout_subseq = 1000; /* ms */
+static const u32 eapol_key_timeout_first_group = 500; /* ms */
/* TODO: make these configurable */
static const int dot11RSNAConfigPMKLifetime = 43200;
@@ -194,6 +195,7 @@
{
if (wpa_auth->cb.disconnect == NULL)
return;
+ wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR, MAC2STR(addr));
wpa_auth->cb.disconnect(wpa_auth->cb.ctx, addr,
WLAN_REASON_PREV_AUTH_NOT_VALID);
}
@@ -332,7 +334,7 @@
static struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth,
- int vlan_id)
+ int vlan_id, int delay_init)
{
struct wpa_group *group;
@@ -349,10 +351,6 @@
wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool "
"for secure operations - update keys later when "
"the first station connects");
-#ifdef ANDROID_BRCM_P2P_PATCH
- os_free(group);
- return NULL;
-#endif
}
/*
@@ -369,9 +367,15 @@
}
group->GInit = TRUE;
- wpa_group_sm_step(wpa_auth, group);
- group->GInit = FALSE;
- wpa_group_sm_step(wpa_auth, group);
+ if (delay_init) {
+ wpa_printf(MSG_DEBUG, "WPA: Delay group state machine start "
+ "until Beacon frames have been configured");
+ /* Initialization is completed in wpa_init_keys(). */
+ } else {
+ wpa_group_sm_step(wpa_auth, group);
+ group->GInit = FALSE;
+ wpa_group_sm_step(wpa_auth, group);
+ }
return group;
}
@@ -403,7 +407,7 @@
return NULL;
}
- wpa_auth->group = wpa_group_init(wpa_auth, 0);
+ wpa_auth->group = wpa_group_init(wpa_auth, 0, 1);
if (wpa_auth->group == NULL) {
os_free(wpa_auth->wpa_ie);
os_free(wpa_auth);
@@ -444,6 +448,19 @@
}
+int wpa_init_keys(struct wpa_authenticator *wpa_auth)
+{
+ struct wpa_group *group = wpa_auth->group;
+
+ wpa_printf(MSG_DEBUG, "WPA: Start group state machine to set initial "
+ "keys");
+ wpa_group_sm_step(wpa_auth, group);
+ group->GInit = FALSE;
+ wpa_group_sm_step(wpa_auth, group);
+ return 0;
+}
+
+
/**
* wpa_deinit - Deinitialize WPA authenticator
* @wpa_auth: Pointer to WPA authenticator data from wpa_init()
@@ -695,6 +712,37 @@
#endif /* CONFIG_IEEE80211R */
+static void 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,
+ "received EAPOL-Key Error Request "
+ "(STA detected Michael MIC failure (group=%d))",
+ group);
+
+ if (group && wpa_auth->conf.wpa_group != WPA_CIPHER_TKIP) {
+ wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
+ "ignore Michael MIC failure report since "
+ "group cipher is not TKIP");
+ } else if (!group && sm->pairwise != WPA_CIPHER_TKIP) {
+ wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
+ "ignore Michael MIC failure report since "
+ "pairwise cipher is not TKIP");
+ } else {
+ wpa_auth_mic_failure_report(wpa_auth, sm->addr);
+ sm->dot11RSNAStatsTKIPRemoteMICFailures++;
+ wpa_auth->dot11RSNAStatsTKIPRemoteMICFailures++;
+ }
+
+ /*
+ * Error report is not a request for a new key handshake, but since
+ * Authenticator may do it, let's change the keys now anyway.
+ */
+ wpa_request_new_ptk(sm);
+}
+
+
void wpa_receive(struct wpa_authenticator *wpa_auth,
struct wpa_state_machine *sm,
u8 *data, size_t data_len)
@@ -720,6 +768,9 @@
key = (struct wpa_eapol_key *) (hdr + 1);
key_info = WPA_GET_BE16(key->key_info);
key_data_length = WPA_GET_BE16(key->key_data_length);
+ wpa_printf(MSG_DEBUG, "WPA: Received EAPOL-Key from " MACSTR
+ " key_info=0x%x type=%u key_data_length=%u",
+ MAC2STR(sm->addr), key_info, key->type, key_data_length);
if (key_data_length > data_len - sizeof(*hdr) - sizeof(*key)) {
wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - "
"key_data overflow (%d > %lu)",
@@ -819,7 +870,7 @@
if (!(key_info & WPA_KEY_INFO_REQUEST) &&
!wpa_replay_counter_valid(sm, key->replay_counter)) {
int i;
- wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
+ wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
"received EAPOL-Key %s with unexpected "
"replay counter", msgtxt);
for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) {
@@ -1000,17 +1051,9 @@
#endif /* CONFIG_PEERKEY */
return;
} else if (key_info & WPA_KEY_INFO_ERROR) {
- /* Supplicant reported a Michael MIC error */
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key Error Request "
- "(STA detected Michael MIC failure)");
- wpa_auth_mic_failure_report(wpa_auth, sm->addr);
- sm->dot11RSNAStatsTKIPRemoteMICFailures++;
- wpa_auth->dot11RSNAStatsTKIPRemoteMICFailures++;
- /* Error report is not a request for a new key
- * handshake, but since Authenticator may do it, let's
- * change the keys now anyway. */
- wpa_request_new_ptk(sm);
+ wpa_receive_error_report(
+ wpa_auth, sm,
+ !(key_info & WPA_KEY_INFO_KEY_TYPE));
} else if (key_info & WPA_KEY_INFO_KEY_TYPE) {
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
"received EAPOL-Key Request for new "
@@ -1028,9 +1071,6 @@
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
"received EAPOL-Key Request for GTK "
"rekeying");
- /* FIX: why was this triggering PTK rekeying for the
- * STA that requested Group Key rekeying?? */
- /* wpa_request_new_ptk(sta->wpa_sm); */
eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL);
wpa_rekey_gtk(wpa_auth, NULL);
}
@@ -1057,6 +1097,7 @@
os_memcpy(sm->last_rx_eapol_key, data, data_len);
sm->last_rx_eapol_key_len = data_len;
+ sm->rx_eapol_key_secure = !!(key_info & WPA_KEY_INFO_SECURE);
sm->EAPOLKeyReceived = TRUE;
sm->EAPOLKeyPairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE);
sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST);
@@ -1293,7 +1334,8 @@
ctr = pairwise ? sm->TimeoutCtr : sm->GTimeoutCtr;
if (ctr == 1 && wpa_auth->conf.tx_status)
- timeout_ms = eapol_key_timeout_first;
+ timeout_ms = pairwise ? eapol_key_timeout_first :
+ eapol_key_timeout_first_group;
else
timeout_ms = eapol_key_timeout_subseq;
if (pairwise && ctr == 1 && !(key_info & WPA_KEY_INFO_MIC))
@@ -1844,6 +1886,20 @@
gtk_len = 0;
keyidx = 0;
_rsc = NULL;
+ if (sm->rx_eapol_key_secure) {
+ /*
+ * It looks like Windows 7 supplicant tries to use
+ * Secure bit in msg 2/4 after having reported Michael
+ * MIC failure and it then rejects the 4-way handshake
+ * if msg 3/4 does not set Secure bit. Work around this
+ * by setting the Secure bit here even in the case of
+ * WPA if the supplicant used it first.
+ */
+ wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
+ "STA used Secure bit in WPA msg 2/4 - "
+ "set Secure for 3/4 as workaround");
+ secure = 1;
+ }
}
kde_len = wpa_ie_len + ieee80211w_kde_len(sm);
@@ -2469,6 +2525,7 @@
group->GN_igtk = tmp;
#endif /* CONFIG_IEEE80211W */
wpa_gtk_update(wpa_auth, group);
+ wpa_group_config_group_keys(wpa_auth, group);
}
}
@@ -2771,7 +2828,7 @@
wpa_printf(MSG_DEBUG, "WPA: Add group state machine for VLAN-ID %d",
vlan_id);
- group = wpa_group_init(wpa_auth, vlan_id);
+ group = wpa_group_init(wpa_auth, vlan_id, 0);
if (group == NULL)
return NULL;