SAE implementation doesn't follow the spec

James Prestwood prestwoj at gmail.com
Fri Sep 3 11:59:05 PDT 2021


Hi,

I have noticed a two problems with hostapd and wpa_supplicant with
respect to SAE. There are several places where the spec is not followed
and this actually leads to connection failures when using a supplicant
that does follow the spec (IWD) under certain conditions explained
later. Funny enough these two implementation bugs actually allow
wpa_supplicant and hostapd to work fine with each other.

#1. wpa_supplicant/hostapd are not properly sending a commit + confirm
in the case of a received commit while in a confirmed state. This is
stated in 802.11-2020 section 12.4.8.6.5:

"Upon receipt of a Com event ... protocol instance shall increment
Sync, increment Sc, and transmit its SAE Commit message and its SAE
Confirm message with the new Sc value"

Intead wpa_supplicant drops the frame completely and does not send out
either commit or confirm as seen in sme.c:sme_sae_auth():

if (wpa_s->sme.sae.state != SAE_COMMITTED) {
	wpa_printf(MSG_DEBUG, "SAE: Ignore commit message while
waiting for confirm");
	return 0;
}

and hostapd appears to only send a commit in this case, not commit +
confirm.

#2. Hostapd has a separate problem when it receives a commit while in
an accepted state. This is described in 802.11-2020 12.4.8.6.1:

"Upon receipt of an SAE Commit message, the parent process checks
whether a protocol instance for the peer MAC address exists in the
database. ... If one does and it is in Accepted state, the scalar in
the received frame is checked against the peer-scalar used in
authentication of the existing protocol instance (in Acceptedstate). If
it is identical, the frame shall be dropped."

But in this case hostapd terminates the protocol as seen in
sae_parse_commit_scalar() (there is even a comment from an earlier
802.11 version which states to drop the message but instead it returns
a fatal error).

Further, the return of sae_parse_commit() is checked for
SAE_SILENTLY_DISCARD but instead of discarding the station is removed
which terminates the protocol.

Where this poses at least one problem is if the supplicant's commit ack
is lost:

1. Client sends commit, not acked (committed state)
2. AP receives commit, sends commit reply (committed state)
3. Client retransmits original commit
4. Client receives AP's commit, sends confirm (confirmed state)
5. AP receives clients retransmitted commit, sends only commit (#1)
6. AP receives clients confirm and accepts (accepted state)
7. Client receives AP's commit and sends both commit + confirm.
8. AP receives clients commit while in accepted state, and deauths (#2)

There could be more obscure code paths taken when an ack/frame is lost
but so far this is the only problem I have been able to recreate. We
have had a few users describe similar problems with consumer APs.

Unfortunately since these issues are out in real products its looking
like our only choice (from IWD's perspective) is to copy how
wpa_supplicant incorrectly does not send out the commit + confirm
described in #1.

I still wanted to bring this to attention though I'm not sure how this
can be fixed without interoperability problems.

Thanks,
James




More information about the Hostap mailing list