diff mbox

[34/44] FT: do not change ANonce during re-sent auth request

Message ID 1456314830-12935-35-git-send-email-michael-dev@fami-braun.de
State Changes Requested
Headers show

Commit Message

michael-dev Feb. 24, 2016, 11:53 a.m. UTC
From: Michael Braun <michael-dev@fami-braun.de>

Otherwise the station might end up using old ANonce.

Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
---
 src/ap/wpa_auth_ft.c | 15 ++++++++++++---
 src/ap/wpa_auth_i.h  |  1 +
 2 files changed, 13 insertions(+), 3 deletions(-)

Comments

Jouni Malinen Feb. 28, 2016, 5:19 p.m. UTC | #1
On Wed, Feb 24, 2016 at 12:53:40PM +0100, michael-dev@fami-braun.de wrote:
> Otherwise the station might end up using old ANonce.

Could you please clarify what type of Authentication frame
retransmission case are you addressing here? It sounds like the station
is broken if it sends another FT Authentication frame and does not use
the ANonce it receives from the response to that frame. Is this because
of mac80211 Authentication frame retries? If so, the correct fix would
be in mac80211, not in hostapd.
Johannes Berg Feb. 29, 2016, 10:17 p.m. UTC | #2
On Sun, 2016-02-28 at 19:19 +0200, Jouni Malinen wrote:
> On Wed, Feb 24, 2016 at 12:53:40PM +0100, michael-dev@fami-braun.de
> wrote:
> > Otherwise the station might end up using old ANonce.
> 
> Could you please clarify what type of Authentication frame
> retransmission case are you addressing here? It sounds like the
> station
> is broken if it sends another FT Authentication frame and does not
> use
> the ANonce it receives from the response to that frame. Is this
> because
> of mac80211 Authentication frame retries? If so, the correct fix
> would be in mac80211, not in hostapd.

I tend to agree, though I'll note that it might not be so simple.
mac80211 itself has no knowledge of the nonce usage, and will stop
listening and ask wpa_s to process on the first successful auth frame
received, regardless of which frame it was a response to. If, by way of
timing, it receives the response for the first after sending the
second, this could cause issues?

johannes
michael-dev March 2, 2016, 5:45 p.m. UTC | #3
Am 28.02.2016 um 18:19 schrieb Jouni Malinen:
> On Wed, Feb 24, 2016 at 12:53:40PM +0100, michael-dev@fami-braun.de wrote:
>> Otherwise the station might end up using old ANonce.
> 
> Could you please clarify what type of Authentication frame
> retransmission case are you addressing here? It sounds like the station
> is broken if it sends another FT Authentication frame and does not use
> the ANonce it receives from the response to that frame. Is this because
> of mac80211 Authentication frame retries? If so, the correct fix would
> be in mac80211, not in hostapd.
> 

I tried using wpa_supplicant as client. This was with hostapd being very
slow due to being run on real hardware with debugging and address
sanitizer enabled.

I think this was due to the following sequence:

[Over-the-air FT Protocol in an RSN]
1. client sends auth req frame and ap receives it
2. client resends auth req frame due to timeout (no reply from AP) and
   ap receives it
3. hostapd processes auth request, generates a nonce and sends reply
4. hostapd processes second auth request, generates a-nonce,
   overwrites and the old A-Nonce and sends reply
5. client receives first reply and uses that a-nonce
6. client ignores second reply
7. now hostapd and wpa_supplicant have different A-Nonce stored and
   reassociation fails (A-Nonce mismatch) [and so would key derivation
   result in different keys]

It works similarly with FT-over-DS, where additionally the FT Request /
Reply might be lost while being forwarded between the APs.

I'm not sure how mac80211 should resolve this.

Regards,
 M. Braun
diff mbox

Patch

diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index 6158212..7dff527 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -1297,16 +1297,22 @@  static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
 	sm->pmk_r1_name_valid = 1;
 	os_memcpy(sm->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN);
 
-	if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
+	if (!sm->ANoncePresent &&
+	    random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
 		wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
 			   "ANonce");
 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
 	}
+	if (!sm->ANoncePresent)
+		wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce",
+			    sm->ANonce, WPA_NONCE_LEN);
+	else
+		wpa_hexdump(MSG_DEBUG, "FT: Reuse ANonce",
+			    sm->ANonce, WPA_NONCE_LEN);
+	sm->ANoncePresent = 1;
 
 	wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
 		    sm->SNonce, WPA_NONCE_LEN);
-	wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce",
-		    sm->ANonce, WPA_NONCE_LEN);
 
 	if (wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr,
 			      sm->wpa_auth->addr, pmk_r1_name,
@@ -1420,6 +1426,9 @@  u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
 	if (sm == NULL)
 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
 
+	/* station entered ASSOC state, so next AUTH will get new ANonce */
+	sm->ANoncePresent = 0;
+
 	wpa_hexdump(MSG_DEBUG, "FT: Reassoc Req IEs", ies, ies_len);
 
 	if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h
index c634c32..ec4e40c 100644
--- a/src/ap/wpa_auth_i.h
+++ b/src/ap/wpa_auth_i.h
@@ -57,6 +57,7 @@  struct wpa_state_machine {
 	Boolean MICVerified;
 	Boolean GUpdateStationKeys;
 	u8 ANonce[WPA_NONCE_LEN];
+	Boolean ANoncePresent;
 	u8 SNonce[WPA_NONCE_LEN];
 	u8 alt_SNonce[WPA_NONCE_LEN];
 	u8 alt_replay_counter[WPA_REPLAY_COUNTER_LEN];