3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-07 12:39:23 +01:00
Commit Graph

4085 Commits

Author SHA1 Message Date
James Prestwood
3c02f387cb dpp: scan to pick up extra frequencies when enrolling
The DPP-PKEX spec provides a very limited list of frequencies used
to discover configurators, only 3 on 2.4 and 5GHz bands. Since
configurators (at least in IWD's implementation) are only allowed
on the current operating frequency its very unlikely an enrollee
will find a configurator on these frequencies out of the entire
spectrum.

The spec does mention that the 3 default frequencies should be used
"In lieu of specific channel information obtained in a manner outside
the scope of this specification, ...". This allows the implementation
some flexibility in using a broader range of frequencies.

To increase the chances of finding a configurator shared code
enrollees will first issue a scan to determine what access points are
around, then iterate these frequencies. This is especially helpful
when the configurators are IWD-based since we know that they'll be
on the same channels as the APs in the area.
2023-11-16 09:14:32 -06:00
James Prestwood
c8a86edffe dpp: fix fragile scan/connecting logic
The post-DPP connection was never done quite right due to station's
state being unknown. The state is now tracked in DPP by a previous
patch but the scan path in DPP is still wrong.

It relies on station autoconnect logic which has the potential to
connect to a different network than what was configured with DPP.
Its unlikely but still could happen in theory. In addition the scan
was not selectively filtering results by the SSID that DPP
configured.

This fixes the above problems by first filtering the scan by the
SSID. Then setting the scan results into station without triggering
autoconnect. And finally using network_autoconnect() directly
instead of relying on station to choose the SSID.
2023-11-16 09:10:39 -06:00
James Prestwood
e2f28312e2 dpp: add station watch to DPP
DPP (both DPP and PKEX) run the risk of odd behavior if station
decides to change state. DPP is completely unaware of this and
best case would just result in a protocol failure, worst case
duplicate calls to __station_connect_network.

Add a station watch and stop DPP if station changes state during
the protocol.
2023-11-16 09:07:22 -06:00
James Prestwood
485f9f56bf dpp: remove duplicate connected network check 2023-11-16 09:07:10 -06:00
Denis Kenzior
30c6a10f28 netdev: Separate connect_failed and disconnected paths
Commit c59669a366 ("netdev: disambiguate between disconnection types")
introduced different paths for different types of disconnection
notifications from netdev.  Formalize this further by having
netdev_connect_failed only invoke connect_cb.

Disconnections that could be triggered outside of connection
related events are now handled on a different code path.  For this
purpose, netdev_disconnected() is introduced.
2023-11-14 17:40:56 -06:00
Denis Kenzior
a14d78596d netdev: Simplify netdev_auth_cb error logic 2023-11-14 17:29:59 -06:00
Denis Kenzior
972d277363 netdev: Remove improper use of netdev_connect_failed
When a roam event is received, iwd generates a firmware scan request and
notifies its event filter of the ROAMING condition.  In cases where the
firmware scan could not be started successfully, netdev_connect_failed
is invoked.  This is not a correct use of netev_connect_failed since it
doesn't actually disconnect the underlying netdev and the reflected
state becomes de-synchronized from the underlying kernel device.

The firmware scan request could currently fail for two reasons:
  1. nl80211 genl socket is in a bad state, or
  2. the scan context does not exist

Since both reasons are highly unlikely, simply use L_WARN instead.

The other two cases where netdev_connect_failed is used could only occur
if the kernel message is invalid.  The message is ignored in that case
and a warning is printed.

The situation described above also exists in netdev_get_fw_scan_cb. If
the scan could not be completed successfully, there's not much iwd can
do to recover.  Have iwd remain in roaming state and print an error.
2023-11-14 17:27:34 -06:00
Denis Kenzior
c59669a366 netdev: disambiguate between disconnection types
There are generally three scenarios where iwd generates a disconnection
command to the kernel:
  1. Error conditions stemming from a connection related event.  For
     example if SAE/FT/FILS authentication fails during Authenticate or
     Associate steps and the kernel doesn't disconnect properly.
  2. Deauthentication after the connection has been established and not
     related to a connection attempt in progress.  For example, SA Query
     processing that triggers an disconnect.
  3. Disconnects that are triggered due to a handshake failure or if
     setting keys resulting from the handshake fails.  These disconnects
     can be triggered as a result of a pending connection or when a
     connection has been established (e.g. due to rekeying).

Distinguish between 1 and 2/3 by having the disconnect procedure take
different paths.  For now there are no functional changes since all
paths end up in netdev_connect_failed(), but this will change in the
future.
2023-11-14 14:55:06 -06:00
Denis Kenzior
28798990d2 netdev: Move CMD_REKEY_OFFLOAD builder to nl80211util 2023-11-14 10:09:07 -06:00
Denis Kenzior
05c1d34c6e netdev: Move CMD_NEW_KEY RX-only builder to nl80211util 2023-11-14 10:03:58 -06:00
Denis Kenzior
708a8feaba netdev: Move pairwise NEW_KEY builder to nl80211util 2023-11-14 09:57:36 -06:00
Denis Kenzior
1aa83722a0 netdev: Move CMD_DEL_STATION builder to nl80211util
While here, also get rid of netdev_del_station.  The only user of this
function was in ap.c and it could easily be replaced by invoking the new
nl80211_build_del_station function.  The callback used by
netdev_build_del_station only printed an error and didn't do anything
useful.  Get rid of it for now.
2023-11-14 09:49:39 -06:00
Denis Kenzior
904373eee7 netdev: Move CMD_DEAUTHENTICATE builder to nl80211util 2023-11-14 09:26:49 -06:00
Denis Kenzior
7498eaae62 netdev: Move CMD_DISCONNECT builder to nl80211util 2023-11-14 09:21:58 -06:00
Denis Kenzior
d12d8bec85 netdev: Don't unnecessarily call netdev_connect_failed
netdev_begin_connection() already invokes netdev_connect_failed on
error.  Remove any calls to netdev_connect_failed in callers of
netdev_begin_connection().

Fixes: 4165d9414f ("netdev: use wiphy radio work queue for connections")
2023-11-13 23:11:12 -06:00
Denis Kenzior
afc8f53fd3 netdev: Use CMD_DISCONNECT if OCI fails
If netdev_get_oci fails, a goto deauth is invoked in order to terminate
the current connection and return an error to the caller.  Unfortunately
the deauth label builds CMD_DEAUTHENTICATE in order to terminate the
connection.  This was fine because it used to handle authentication
protocols that ran over CMD_AUTHENTICATE and CMD_ASSOCIATE.  However,
OCI can also be used on FullMAC hardware that does not support them.
Use CMD_DISCONNECT instead which works everywhere.

Fixes: 06482b8116 ("netdev: Obtain operating channel info")
2023-11-13 21:29:08 -06:00
Denis Kenzior
e1c2706674 netdev: sa_query: Fix reason code handling
The reason code field was being obtained as a uint8_t value, while it is
actually a uint16_t in little-endian byte order.

Fixes: f3cc96499c ("netdev: added support for SA Query")
2023-11-13 17:14:34 -06:00
Denis Kenzior
bef70275f7 netdev: Fix obtaining reason code from deauth frames
The reason code from deauthentication frame was being obtained as a
uint8_t instead of a uint16_t.  The value was only ever used in an
informational statement.  Since the value was in little endian, only the
first 8 bits of the reason code were obtained.  Fix that.

Fixes: 2bebb4bdc7 ("netdev: Handle deauth frames prior to association")
2023-11-13 16:43:39 -06:00
James Prestwood
2f4c09def0 dpp: fix removed dpp_reset in Stop()
It seems in my patch reordering both stop methods lost the actual
call to dpp_reset().
2023-11-09 20:15:56 -06:00
James Prestwood
2ca9a55fd5 dpp: Add StartConfigurator, PKEX agent support
Adds a configurator variant to be used along side an agent. When
called the configurator will start and wait for an initial PKEX
exchange message from an enrollee at which point it will request
the code from an agent. This provides more flexibility for
configurators that are capable of configuring multiple enrollees
with different identifiers/codes.

Note that the timing requirements per the DPP spec still apply
so this is not meant to be used with a human configurator but
within an automated agent which does a quick lookup of potential
identifiers/codes and can reply within the 200ms window.
2023-11-09 10:34:46 -06:00
James Prestwood
cf378e562e dpp: initial version of PKEX configurator support
The PKEX configurator role is currently limited to being a responder.
When started the configurator will listen on its current operating
channel for a PKEX exchange request. Once received it and the
encrypted key is properly decrypted it treats this peer as the
enrollee and won't allow configurations from other peers unless
PKEX is restarted. The configurator will encrypt and send its
encrypted ephemeral key in the PKEX exchange response. The enrollee
then sends its encrypted bootstrapping key (as commit-reveal request)
then the same for the configurator (as commit-reveal response).

After this, PKEX authentication begins. The enrollee is expected to
send the authenticate request, since its the initiator.
2023-11-09 10:26:59 -06:00
James Prestwood
a7d35a27a3 dpp: initial version of PKEX enrollee support
This is the initial support for PKEX enrollees acting as the
initiator. A PKEX initiator starts the protocol by broadcasting
the PKEX exchange request. This request contains a key encrypted
with the pre-shared PKEX code. If accepted the peer sends back
the exchange response with its own encrypted key. The enrollee
decrypts this and performs some crypto/hashing in order to establish
an ephemeral key used to encrypt its own boostrapping key. The
boostrapping key is encrypted and sent to the peer in the PKEX
commit-reveal request. The peer then does the same thing, encrypting
its own bootstrapping key and sending to the initiator as the
PKEX commit-reveal response.

After this, both peers have exchanged their boostrapping keys
securely and can begin DPP authentication, then configuration.

For now the enrollee will only iterate the default channel list
from the Easy Connect spec. Future upates will need to include some
way of discovering non-default channel configurators, but the
protocol needs to be ironed out first.
2023-11-09 10:23:01 -06:00
James Prestwood
f9833665b7 dpp: introduce dpp_interface type, prep for PKEX
PKEX and DPP will share the same state machine since the DPP protocol
follows PKEX. This does pose an issue with the DBus interfaces
because we don't want DPP initiated by the SharedCode interface to
start setting properties on the DeviceProvisioning interface.

To handle this a dpp_interface enum is being introduced which binds
the dpp_sm object to a particular interface, for the life of the
protocol run. Once the protocol finishes the dpp_sm can be unbound
allowing either interface to use it again later.
2023-11-09 10:05:13 -06:00
James Prestwood
c0a356711d dpp-util: fix typo, 'REQUST' 2023-11-09 10:05:07 -06:00
Denis Kenzior
653122498a treewide: Fix compilation due to missing rtnetlink.h 2023-11-09 09:27:00 -06:00
Ronan Pigott
c574c80e27 tree-wide: correct the spelling Ghz -> GHz
This mispelling was present in the configuration, so I retained parsing
of the legacy BandModifier*Ghz options for compatibility. Without this
change anyone spelling GHz correctly in their configs would be very
confused.
2023-11-07 21:11:50 -06:00
James Prestwood
8864329928 netdev: handle/send beacon loss event 2023-11-07 12:15:05 -06:00
James Prestwood
e57cc5d4c6 station: start roam on beacon loss event
Beacon loss handling was removed in the past because it was
determined that this even always resulted in a disconnect. This
was short sighted and not always true. The default kernel behavior
waits for 7 lost beacons before emitting this event, then sends
either a few nullfuncs or probe requests to the BSS to determine
if its really gone. If these come back successfully the connection
will remain alive. This can give IWD some time to roam in some
cases so we should be handling this event.

Since beacon loss indicates a very poor connection the roam scan
is delayed by a few seconds in order to give the kernel a chance
to send the nullfuncs/probes or receive more beacons. This may
result in a disconnect, but it would have happened anyways.
Attempting a roam mainly handles the case when the connection can
be maintained after beacon loss, but is still poor.
2023-11-07 12:15:05 -06:00
James Prestwood
9107378efe station: provide new state in __station_connect_network
This is being done to allow the DPP module to work correctly. DPP
currently uses __station_connect_network incorrectly since it
does not (and cannot) change the state after calling. The only
way to connect with a state change is via station_connect_network
which requires a DBus method that triggered the connection; DPP
does not have this due to its potentially long run time.

To support DPP there are a few options:
 1. Pass a state into __station_connect_network (this patch)
 2. Support a NULL DBus message in station_connect_network. This
    would require several NULL checks and adding all that to only
    support DPP just didn't feel right.
 3. A 3rd connect API in station which wraps
    __station_connect_network and changes the state. And again, an
    entirely new API for only DPP felt wrong (I guess we did this
    for network_autoconnect though...)

Its about 50/50 between call sites that changed state after calling
and those that do not. Changing the state inside
__station_connect_network felt useful enough to cover the cases that
could benefit and the remaining cases could handle it easily enough:
 - network_autoconnect(), and the state is changed by station after
   calling so it more or less follows the same pattern just routes
   through network. This will now pass the CONNECTING_AUTO state
   from within network vs station.
 - The disconnect/reconnect path. Here the state is changed to
   ROAMING prior in order to avoid multiple state changes. Knowing
   this the same ROAMING state can be passed which won't trigger a
   state change.
 - Retrying after a failed BSS. The state changes on the first call
   then remains the same for each connection attempt. To support this
   the current station->state is passed to avoid a state change.
2023-11-02 20:40:07 -05:00
James Prestwood
5a78ebe895 dbus: add net.connman.iwd.SharedCodeAgent DBus interface 2023-11-02 20:31:05 -05:00
James Prestwood
c398672200 dpp: allow enrollee to be authentication initiator
Until now IWD only supported enrollees as responders (configurators
could do both). For PKEX it makes sense for the enrollee to be the
initiator because configurators in the area are already on their
operating channel and going off is inefficient. For PKEX, whoever
initiates also initiates authentication so for this reason the
authentication path is being opened up to allow enrollees to
initiate.
2023-11-02 20:30:18 -05:00
James Prestwood
b8bfbc141d dpp: fix config request header check
The check for the header was incorrect according to the spec.
Table 58 indicates that the "Query Response Info" should be set
to 0x00 for the configuration request. The frame handler was
expecting 0x7f which is the value for the config response frame.

Unfortunately wpa_supplicant also gets this wrong and uses 0x7f
in all cases which is likely why this value was set incorrectly
in IWD. The issue is that IWD's config request is correct which
means IWD<->IWD configuration is broken. (and wpa_supplicant as
a configurator likely doesn't validate the config request).

Fix this by checking both 0x7f and 0x00 to handle both
supplicants.
2023-11-02 20:28:06 -05:00
James Prestwood
a943a81f87 dpp: remove scan_periodic_stop calls
Stopping periodic scans and not restarting them prevents autoconnect
from working again if DPP (or the post-DPP connect) fails. Since
the DPP offchannel work is at a higher priority than scanning (and
since new offchannels are queue'd before canceling) there is no risk
of a scan happening during DPP so its safe to leave periodic scans
running.
2023-11-02 20:27:59 -05:00
James Prestwood
320041eaf2 station: rate limit packet loss roam scans
The packet loss handler puts a higher priority on roaming compared
to the low signal roam path. This is generally beneficial since this
event usually indicates some problem with the BSS and generally is
an indicator that a disconnect will follow sometime soon.

But by immediately issuing a scan we run the risk of causing many
successive scans if more packet loss events arrive following
the roam scans (and if no candidates are found). Logs provided
further.

To help with this handle the first event with priority and
immediately issue a roam scan. If another event comes in within a
certain timeframe (2 seconds) don't immediately scan, but instead
rearm the roam timer instead of issuing a scan. This also handles
the case of a low signal roam scan followed by a packet loss
event. Delaying the roam will at least provide some time for packets
to get out in between roam scans.

Logs were snipped to be less verbose, but this cycled happened
5 times prior. In total 7 scans were issued in 5 seconds which may
very well have been the reason for the local disconnect:

Oct 27 16:23:46 src/station.c:station_roam_failed() 9
Oct 27 16:23:46 src/wiphy.c:wiphy_radio_work_done() Work item 29 done
Oct 27 16:23:47 src/netdev.c:netdev_mlme_notify() MLME notification Notify CQM(64)
Oct 27 16:23:47 src/station.c:station_packets_lost() Packets lost event: 10
Oct 27 16:23:47 src/station.c:station_roam_scan() ifindex: 9
Oct 27 16:23:47 src/wiphy.c:wiphy_radio_work_insert() Inserting work item 30
Oct 27 16:23:47 src/wiphy.c:wiphy_radio_work_next() Starting work item 30
Oct 27 16:23:47 src/station.c:station_start_roam() Using cached neighbor report for roam
Oct 27 16:23:47 src/scan.c:scan_notify() Scan notification Trigger Scan(33)
Oct 27 16:23:47 src/scan.c:scan_request_triggered() Active scan triggered for wdev a
Oct 27 16:23:47 src/scan.c:scan_notify() Scan notification New Scan Results(34)
Oct 27 16:23:47 src/netdev.c:netdev_link_notify() event 16 on ifindex 9
... scan results ...
Oct 27 16:23:47 src/station.c:station_roam_failed() 9
Oct 27 16:23:47 src/wiphy.c:wiphy_radio_work_done() Work item 30 done
Oct 27 16:23:47 src/netdev.c:netdev_mlme_notify() MLME notification Notify CQM(64)
Oct 27 16:23:47 src/station.c:station_packets_lost() Packets lost event: 10
Oct 27 16:23:47 src/station.c:station_roam_scan() ifindex: 9
Oct 27 16:23:47 src/wiphy.c:wiphy_radio_work_insert() Inserting work item 31
Oct 27 16:23:47 src/wiphy.c:wiphy_radio_work_next() Starting work item 31
Oct 27 16:23:47 src/station.c:station_start_roam() Using cached neighbor report for roam
Oct 27 16:23:47 src/scan.c:scan_notify() Scan notification Trigger Scan(33)
Oct 27 16:23:47 src/scan.c:scan_request_triggered() Active scan triggered for wdev a
Oct 27 16:23:48 src/scan.c:scan_notify() Scan notification New Scan Results(34)
Oct 27 16:23:48 src/netdev.c:netdev_link_notify() event 16 on ifindex 9
... scan results ...
Oct 27 16:23:48 src/station.c:station_roam_failed() 9
Oct 27 16:23:48 src/wiphy.c:wiphy_radio_work_done() Work item 31 done
Oct 27 16:23:48 src/netdev.c:netdev_mlme_notify() MLME notification Notify CQM(64)
Oct 27 16:23:48 src/station.c:station_packets_lost() Packets lost event: 10
Oct 27 16:23:48 src/station.c:station_roam_scan() ifindex: 9
Oct 27 16:23:48 src/wiphy.c:wiphy_radio_work_insert() Inserting work item 32
Oct 27 16:23:48 src/wiphy.c:wiphy_radio_work_next() Starting work item 32
Oct 27 16:23:48 src/station.c:station_start_roam() Using cached neighbor report for roam
Oct 27 16:23:48 src/scan.c:scan_notify() Scan notification Trigger Scan(33)
Oct 27 16:23:48 src/scan.c:scan_request_triggered() Active scan triggered for wdev a
Oct 27 16:23:49 src/netdev.c:netdev_link_notify() event 16 on ifindex 9
Oct 27 16:23:49 src/netdev.c:netdev_mlme_notify() MLME notification Del Station(20)
Oct 27 16:23:49 src/netdev.c:netdev_mlme_notify() MLME notification Deauthenticate(39)
Oct 27 16:23:49 src/netdev.c:netdev_deauthenticate_event()
Oct 27 16:23:49 src/netdev.c:netdev_mlme_notify() MLME notification Disconnect(48)
Oct 27 16:23:49 src/netdev.c:netdev_disconnect_event()
Oct 27 16:23:49 Received Deauthentication event, reason: 4, from_ap: false
2023-10-30 09:43:12 -05:00
James Prestwood
3ac5da2535 dbus: add SharedCodeDeviceProvisioning interface definition 2023-10-29 17:28:03 -05:00
James Prestwood
acb1abceae dpp: support mutual authentication
This will be needed for PKEX support. It requires an additional
value, L, be derived and used in some of the hashing functions.
2023-10-29 17:17:21 -05:00
James Prestwood
2f2798afb8 dpp-util: add crypto for PKEX 2023-10-29 17:08:08 -05:00
James Prestwood
0859ed8448 dpp: make the protocol timeout more flexible
Include a specific timeout value so different protocols can specify
different timeouts. For example once the authentication timeout
should not take very long (even 10 seconds seems excessive) but
adding PKEX may warrant longer timeouts.

For example discovering a configurator IWD may want to wait several
minutes before ending the discovery. Similarly running PKEX as a
configurator we should put a hard limit on the time, but again
minutes rather than 10 seconds.
2023-10-29 17:05:35 -05:00
James Prestwood
efdc2a63eb dpp: check configurator role in config request frame
We shouldn't ever get this frame as an enrollee, so disregard
2023-10-29 17:05:10 -05:00
James Prestwood
49b9eae18c offchannel: handle out of order ACKs/events
Its been seen (so far only in mac80211_hwsim + UML) where an
offchannel requests ACK comes after the ROC started event. This
causes the ROC started event to never call back to notify since
info->roc_cookie is unset and it appears to be coming from an
external process.

We can detect this situation in the ROC notify event by checking
if there is a pending ROC command and if info->roc_cookie does
not match. This can also be true for an external event so we just
set a new "early_cookie" member and return.

Then, when the ACK comes in for the ROC request, we can validate
if the prior event was associated with IWD or some external
process. If it was from IWD call the started callback, otherwise
the ROC notify event should come later and handled under the
normal logic where the cookies match.
2023-10-26 09:30:03 -05:00
James Prestwood
0a502562c3 offchannel: Use roc id in offchannel_cancel lookup
Instead of looking up by wdev, lookup by the ID itself. We
shouldn't ever have more than one info per wdev in the queue but
looking up the _exact_ info structure doesn't hurt in case things
change in the future.
2023-10-24 21:21:36 -05:00
James Prestwood
ef27f87dbe station: reload settings in 'netconfig_after_roam' case
If netconfig is canceled before completion (when roaming) the
settings are freed and never loaded again once netconfig is started
post-roam. Now after a roam make sure to re-load the settings and
start netconfig.
2023-10-20 10:25:44 -05:00
James Prestwood
ccb29663cc station: fix unintended netconfig_reset pre-roaming
Commit 23f0f5717c did not correctly handle the reassociation
case where the state is set from within station_try_next_transition.
If IWD reassociates netconfig will get reset and DHCP will need to
be done over again after the roam. Instead get the state ahead of
station_try_next_transition.

Fixes: 23f0f5717c ("station: allow roaming before netconfig finishes")
2023-10-20 10:23:17 -05:00
James Prestwood
c0b92d9498 dpp-util: allow mutual auth in dpp_derive_ke
The Ke derivation requires an additional "L.x" value when
mutual authentication is used.
2023-10-19 09:33:24 -05:00
James Prestwood
808f8eea34 dpp-util: allow for mutual authentication in i/r_auth
When using mutual authentication an additional value needs to
be hashed when deriving i/r_auth values. A NULL value indicates
no mutual authentication (zero length iovec is passed to hash).
2023-10-19 09:25:35 -05:00
James Prestwood
0c9df85f5e dpp: fix retransmits if on operating channel
DPP configurators are running the majority of the protocol on the
current operating channel, meaning no ROC work. The retry logic
was bailing out if !dpp->roc_started with the assumption that DPP
was in between requesting offchannel work and it actually starting.
For configurators, this may not be the case. The offchannel ID also
needs to be checked, and if no work is scheduled we can send the
frame.
2023-10-17 10:35:13 -05:00
James Prestwood
30effaf164 dpp: move/store max_roc setting into dpp_create
This value won't change since its per-phy so initialize it
when creating the DPP state machine rather than every time
DPP is started.
2023-10-17 10:31:32 -05:00
James Prestwood
33ba7f7dcd dpp: rename dpp_presence_timeout to be generic
PKEX will utilize the same offchannel timeout, so rename to
dpp_offchannel_timeout to be more generic.
2023-10-17 10:30:47 -05:00
James Prestwood
d0c1025179 dpp: rename auth_addr to peer_addr
This is more generic and with adding PKEX it makes sense to
refer to it as peer_addr.
2023-10-17 10:20:50 -05:00
James Prestwood
fe9751d4d8 dpp-util: fix typo "COMMIT_REVEAP_RESPONSE" 2023-10-17 10:18:49 -05:00
James Prestwood
6320d6db0f crypto: remove label from prf_plus, instead use va_args
The prf_plus API was a bit restrictive because it only took a
string label which isn't compatible with some specs (e.g. DPP
inputs to HKDF-Expand). In addition it took additional label
aruments which were appended to the HMAC call (and the
non-intuitive '\0' if there were extra arguments).

Instead the label argument has been removed and callers can pass
it in through va_args. This also lets the caller decided the length
and can include the '\0' or not, dependent on the spec the caller
is following.
2023-10-17 10:13:42 -05:00
James Prestwood
dfb76edda8 sae: fix usage of compressed points (after ELL is fixed)
SAE was also relying on the ELL bug which was incorrectly performing
a subtraction on the Y coordinate based on the compressed point type.
Correct this and make the point type more clear (rather than
something like "is_odd + 2").
2023-10-11 10:19:42 -05:00
James Prestwood
06ad1ace00 eap-pwd: fix usage of compressed points (after ELL is fixed)
EAP-PWD was incorrectly computing the PWE but due to the also
incorrect logic in ELL the point converted correctly. This is
being fixed, so both places need the reverse logic.

Also added a big comment explaining why this is, and how
l_ecc_point_from_data behaves since its somewhat confusing since
EAP-PWD expects the pwd-seed to be compared to the actual Y
coordinate (which is handled automatically by ELL).
2023-10-11 10:19:34 -05:00
James Prestwood
2ba88f05e9 dpp-util: fix incorrect ASN1 compressed public key encoding
The prefix to the X coordinate was incorrect when using compressed
points. This has been modified to match the ANSI X9.62 spec.
2023-10-11 10:19:24 -05:00
Denis Kenzior
600bea73ec crypto: use SWAP from useful.h 2023-10-11 09:58:31 -05:00
Denis Kenzior
f86e7283e7 eap: Silence warning
The previous attempt at working around this warning seems to no longer
work with gcc 13

In function ‘eap_handle_response’,
    inlined from ‘eap_rx_packet’ at src/eap.c:570:3:
src/eap.c:421:49: error: ‘vendor_id’ may be used uninitialized [-Werror=maybe-uninitialized]
  421 |         (type == EAP_TYPE_EXPANDED && vendor_id == (id) && vendor_type == (t))
      |                                       ~~~~~~~~~~^~~~~~~
src/eap.c:533:20: note: in expansion of macro ‘IS_EXPANDED_RESPONSE’
  533 |         } else if (IS_EXPANDED_RESPONSE(our_vendor_id, our_vendor_type))
      |                    ^~~~~~~~~~~~~~~~~~~~
src/eap.c: In function ‘eap_rx_packet’:
src/eap.c:431:18: note: ‘vendor_id’ was declared here
  431 |         uint32_t vendor_id;
      |                  ^~~~~~~~~
2023-10-06 23:24:25 -05:00
Denis Kenzior
073292315f band: Silence warning
width must be initialized since it depends on best not being NULL.  If
best passes the non-NULL check above, then width must be initialized
since both width and best are set at the same time.
2023-10-06 23:21:48 -05:00
James Prestwood
0cb3e4af30 station: check disabled band configuration in station_init
For IWD to work correctly either 2.4GHz or 5GHz bands must be enabled
(even for 6GHz to work). Check this and don't allow IWD to initialize
if both 2.4 and 5GHz is disabled.
2023-10-03 11:32:44 -05:00
Denis Kenzior
66f47343d9 wiphy: Remove unused wiphy_supports_adhoc_rsn() 2023-09-30 17:21:30 -05:00
Denis Kenzior
6e5df64f6d wiphy: Remove unused wiphy_can_offchannel_tx() 2023-09-30 17:20:29 -05:00
Denis Kenzior
71c125193f wiphy: Remove unused wiphy_get_permanent_address() 2023-09-30 17:19:22 -05:00
James Prestwood
c972684e1a wiphy: remove wiphy_get_allowed_freqs
This was recently added but with the modifications to
wiphy_band_is_disabled() its no longer needed.
2023-09-29 21:57:08 -05:00
James Prestwood
06ed56e78f scan: remove use of wiphy_get_allowed_freqs to optimize 6ghz path
wiphy_get_allowed_freqs was only being used to see if 6GHz was disabled
or not. This is expensive and requires several allocations when there
already exists wiphy_is_band_disabled(). The prior patch modified
wiphy_is_band_disabled() to return -ENOTSUP which allows scan.c to
completely remove the need for wiphy_get_allowed_freqs.

scan_wiphy_watch was also slightly re-ordered to avoid allocating
freqs_6ghz if the scan request was being completed.
2023-09-29 21:39:58 -05:00
James Prestwood
970d23a858 wiphy: make wiphy_band_is_disabled return more descriptive
The function wiphy_band_is_disabled() return was a bit misleading
because if the band was not supported it would return true which
could be misunderstood as the band is supported, but disabled.
There was only one call site and because of this behavior
wiphy_band_is_disabled needed to be paired with checking if the
band was supported.

To be more descriptive to the caller, wiphy_band_is_disabled() now
returns an int and if the band isn't supported -ENOTSUP will be
returned, otherwise 1 is returned if the band is disabled and 0
otherwise.
2023-09-29 21:32:45 -05:00
James Prestwood
0bb99bcc33 doc: document disabling bands with a 0.0 modifier 2023-09-29 10:19:03 -05:00
James Prestwood
52c098ea74 station: support user-disabled bands
This adds support to allow users to disable entire bands, preventing
scanning and connecting on those frequencies. If the
[Rank].BandModifier* options are set to 0.0 it will imply those
bands should not be used for scanning, connecting or roaming. This
now applies to autoconnect, quick, hidden, roam, and dbus scans.

This is a station only feature meaning other modules like RRM, DPP,
WSC or P2P may still utilize those bands. Trying to limit bands in
those modules may sometimes conflict with the spec which is why it
was not added there. In addition modules like DPP/WSC are only used
in limited capacity for connecting so there is little benefit gained
to disallowing those bands.
2023-09-29 10:11:40 -05:00
James Prestwood
e83070e074 scan: filter user-disabled bands for periodic scans.
To support user-disabled bands periodic scans need to specify a
frequency list filtered by any bands that are disabled. This was
needed in scan.c since periodic scans don't provide a frequency
list in the scan request.

If no bands are disabled the allowed freqs API should still
result in the same scan behavior as if a frequency list is left
out i.e. IWD just filters the frequencies as opposed to the kernel.
2023-09-29 10:10:33 -05:00
James Prestwood
6463fa2561 scan: allow splitting of scans with defined frequencies
Currently the only way a scan can be split is if the request does
not specify any frequencies, implying the request should scan the
entire spectrum. This allows the scan logic to issue an extra
request if 6GHz becomes available during the 2.4 or 5GHz scans.
This restriction was somewhat arbitrary and done to let periodic
scans pick up 6GHz APs through a single scan request.

But now with the addition of allowing user-disabled bands
periodic scans will need to specify a frequency list in case a
given band has been disabled. This will break the scan splitting
code which is why this prep work is being done.

The main difference now is the original scan frequencies are
tracked with the scan request. The reason for this is so if a
request comes in with a limited set of 6GHz frequences IWD won't
end up scanning the full 6GHz spectrum later on.
2023-09-29 10:08:03 -05:00
James Prestwood
112b1de2ee wiphy: add wiphy_get_allowed_freqs
This is more or less copied from scan_get_allowed_freqs but is
going to be needed by station (basically just saves the need for
station to do the same clone/constrain sequence itself).

One slight alteration is now a band mask can be passed in which
provides more flexibility for additional filtering.
2023-09-27 14:22:13 -05:00
James Prestwood
e4fb9786c5 scan: add scan_get_band_rank_modifier
This exposes the [Rank].BandModifier* settings so other modules
can use then. Doing this will allow user-disabling of certain
bands by setting these modifier values to 0.0.
2023-09-27 14:21:28 -05:00
James Prestwood
043a050e57 doc: document [Rank].BandModifier2_4Ghz 2023-09-27 14:21:19 -05:00
James Prestwood
f5ae310eae scan: add [Rank].BandModifier2_4Ghz
Similar to the 5/6Ghz options, allow modifying the rank for 2.4Ghz
scan results.
2023-09-27 14:20:53 -05:00
James Prestwood
59033bc705 wiphy: fix wiphy_contrain_freq_set skipping last channel
The loop iterating the frequency attributes list was not including
the entire channel set since it was stopping at i < band->freqs_len.
The freq_attrs array is allocated to include the last channel:

band->freq_attrs = l_new(struct band_freq_attrs, num_channels + 1);
band->freqs_len = num_channels;

So instead the for loop should use i <= band->freqs_len. (I also
changed this to start the loop at 1 since channel zero is invalid).
2023-09-25 09:30:26 -05:00
James Prestwood
e74dd446fb station: fall back to reassociation under certain FT failures
The auth/action status is now tracked in ft.c. If an AP rejects the
FT attempt with "Invalid PMKID" we can now assume this AP is either
mis-configured for FT or is lagging behind getting the proper keys
from neighboring APs (e.g. was just rebooted).

If we see this condition IWD can now fall back to reassociation in
an attempt to still roam to the best candidate. The fallback decision
is still rank based: if a BSS fails FT it is marked as such, its
ranking is reset removing the FT factor and it is inserted back
into the queue.

The motivation behind this isn't necessarily to always force a roam,
but instead to handle two cases where IWD can either make a bad roam
decision or get 'stuck' and never roam:

  1. If there is one good roam candidate and other bad ones. For
     example say BSS A is experiencing this FT key pull issue:
         Current BSS: -85dbm
         BSS A:       -55dbm
         BSS B:       -80dbm
     The current logic would fail A, and roam to B. In this case
     reassociation would have likely succeeded so it makes more sense
     to reassociate to A as a fallback.

  2. If there is only one candidate, but its failing FT. IWD will
     never try anything other than FT and repeatedly fail.

Both of the above have been seen on real network deployments and
result in either poor performance (1) or eventually lead to a full
disconnect due to never roaming (2).
2023-09-01 22:56:25 -05:00
James Prestwood
0007699677 ft: track FT auth/action response status
Certain return codes, though failures, can indicate that the AP is
just confused or booting up and treating it as a full failure may
not be the best route.

For example in some production deployments if an AP is rebooted it
may take some time for neighboring APs to exchange keys for
current associations. If a client roams during that time it will
reject saying the PMKID is invalid.

Use the ft_associate call return to communicate the status (if any)
that was in the auth/action response. If there was a parsing error
or no response -ENOENT is still returned.
2023-09-01 22:49:21 -05:00
Salahaldeen Altous
4a0a973790 doc: APRanges is deprecated (use APAddressPool instead) 2023-08-08 00:00:05 -05:00
James Prestwood
822ad91faa scan: remove unneeded debug prints
Removed several debug prints which are very verbose and provide
little to no important information.

The get_scan_{done,callback} prints are pointless since all the
parsed scan results are printed by station anyways.

Printing the BSS load is also not that useful since it doesn't
include the BSSID. If anything the BSS load should be included
when station prints out each individual BSS (along with frequency,
rank, etc).

The advertisement protocol print was just just left in there by
accident when debugging, and also provides basically no useful
information.
2023-08-07 23:59:17 -05:00
James Prestwood
b736f07e2e netdev: relax requirement for OWE AKM in assoc reply
Some APs don't include the RSNE in the associate reply during
the OWE exchange. This causes IWD to be incompatible since it has
a hard requirement on the AKM being included.

This relaxes the requirement for the AKM and instead warns if it
is not included.

Below is an example of an association reply without the RSN element

IEEE 802.11 Association Response, Flags: ........
     Type/Subtype: Association Response (0x0001)
     Frame Control Field: 0x1000
     .000 0000 0011 1100 = Duration: 60 microseconds
     Receiver address: 64:c4:03:88:ff:26
     Destination address: 64:c4:03:88:ff:26
     Transmitter address: fc:34:97:2b:1b:48
     Source address: fc:34:97:2b:1b:48
     BSS Id: fc:34:97:2b:1b:48
     .... .... .... 0000 = Fragment number: 0
     0001 1100 1000 .... = Sequence number: 456
IEEE 802.11 wireless LAN
     Fixed parameters (6 bytes)
     Tagged parameters (196 bytes)
         Tag: Supported Rates 6(B), 9, 12(B), 18, 24(B), 36, 48, 54, [Mbit/sec]
         Tag: RM Enabled Capabilities (5 octets)
         Tag: Extended Capabilities (11 octets)
         Ext Tag: HE Capabilities (IEEE Std 802.11ax/D3.0)
         Ext Tag: HE Operation (IEEE Std 802.11ax/D3.0)
         Ext Tag: MU EDCA Parameter Set
         Ext Tag: HE 6GHz Band Capabilities
         Ext Tag: OWE Diffie-Hellman Parameter
             Tag Number: Element ID Extension (255)
             Ext Tag length: 51
             Ext Tag Number: OWE Diffie-Hellman Parameter (32)
             Group: 384-bit random ECP group (20)
             Public Key: 14ba9d8abeb2ecd5d95e6c12491b16489d1bcc303e7a7fbd…
         Tag: Vendor Specific: Broadcom
         Tag: Vendor Specific: Microsoft Corp.: WMM/WME: Parameter Element

Reported-By: Wen Gong <quic_wgong@quicinc.com>
Tested-By: Wen Gong <quic_wgong@quicinc.com>
2023-07-14 09:09:51 -05:00
James Prestwood
9479c31a72 handshake: add FT_OVER_8021X AKM for SHA256 PMKID derivation
Hostapd commit b6d3fd05e3 changed the PMKID derivation in accordance
with 802.11-2020 which then breaks PMKID validation in IWD. This
breaks the FT-8021x AKM in IWD if the AP uses this hostapd version
since the PMKID doesn't validate during EAPoL.

This updates the PMKID derivation to use the correct SHA hash for
this AKM and adds SHA1 based PMKID checking for interoperability
with older hostapd versions.
2023-07-05 18:16:01 +02:00
James Prestwood
8c4633ef72 handshake: split handshake_state_get_pmkid into separate APIs
The PMKID derivation has gotten messy due to the spec
updating/clarifying the hash size for the FT-8021X AKM. This
has led to hostapd updating the derivation which leaves older
hostapd versions using SHA1 and newer versions using SHA256.

To support this the checksum type is being fed to
handshake_state_get_pmkid so the caller can decide what sha to
use. In addition handshake_state_pmkid_matches is being added
which uses get_pmkid() but handles sorting out the hash type
automatically.

This lets preauthentication use handshake_state_get_pmkid where
there is the potential that a new PMKID is derived and eapol
can use handshake_state_pmkid_matches which only derives the
PMKID to compare against the peers.
2023-06-26 21:55:24 -05:00
James Prestwood
ae76fa876f crypto: modify crypto_derive_pmkid to take the length/checksum type
The existing API was limited to SHA1 or SHA256 and assumed a key
length of 32 bytes. Since other AKMs plan to be added update
this to take the checksum/length directly for better flexibility.
2023-06-26 21:32:11 -05:00
James Prestwood
d09b106998 ft: add debug prints for FT-over-DS
This is consistent with the over-Air path, and makes it clear when
reading the logs if over-DS was used, if there was a response frame,
and if the frame failed to parse in some way.
2023-06-26 21:31:20 -05:00
James Prestwood
2e2f6f991d wiphy: remove l_info's for control port/power save
These should not have been put into a getter for wiphy and now
the driver quirks are printed out in wiphy_print_basic_info.
2023-06-19 20:23:37 -05:00
James Prestwood
29edb1626d netdev: disable power save if required
Disable power save if the wiphy indicates its needed. Do this
before issuing GET_LINK so the netdev doesn't signal its up until
power save is disabled.
2023-06-19 20:23:28 -05:00
James Prestwood
b7872de90a netdev: move GETLINK into its own function, track command ID
Move this logic into its own function and track the command ID
so it can be canceled in case of netdev going down.
2023-06-19 20:23:14 -05:00
James Prestwood
8eab0229f1 doc: Document [DriverQuirks].PowerSaveDisable 2023-06-18 14:06:24 -05:00
James Prestwood
855318374e wiphy: print driver flags on startup
Similar to other basic information, print the driver flags so the
user is informed what is set.
2023-06-18 14:06:24 -05:00
James Prestwood
a50605a456 wiphy: add [DriverQuirks].PowerSaveDisable flag
Certain drivers do not handle power save very well resulting in
missed frames, firmware crashes, or other bad behavior. Its easy
enough to disable power save via iw, iwconfig, etc but since IWD
removes and creates the interface on startup it blows away any
previous power save setting. The setting must be done *after* IWD
creates the interface which can be done, but needs to be via some
external daemon monitoring IWD's state. For minimal systems,
e.g. without NetworkManager, it becomes difficult and annoying to
persistently disable power save.

For this reason a new driver flag POWER_SAVE_DISABLE is being
added. This can then be referenced when creating the interfaces
and if set, disable power save.
2023-06-18 14:06:21 -05:00
James Prestwood
0b4dc9d8a5 doc: document [DriverQuirks] group settings 2023-06-18 13:35:33 -05:00
James Prestwood
b1b45f5509 wiphy: allow for user-defined driver flags
The driver_infos list in wiphy.c is hard coded and, naturally,
not configurable from a user perspective. As drivers are updated
or added users may be left with their system being broken until the
driver is added, IWD released, and packaged.

This adds the ability to define driver flags inside main.conf under
the "DriverQuirks" group. Keys in this group correspond to values in
enum driver_flag and values are a list of glob matches for specific
drivers:

[DriverQuirks]
DefaultInterface=rtl81*,rtl87*,rtl88*,rtw_*,brcmfmac,bcmsdh_sdmmc
ForcePae=buggy_pae_*
2023-06-18 13:32:58 -05:00
James Prestwood
6065d86fa7 wiphy: store driver flags directly in wiphy object
Rather than keep a pointer to the driver_info entry copy the flags
into the wiphy object. This preps for supporting driver flags via
a configuration file, specifically allowing for entries that are a
subset of others. For example:

{ "rtl88*",          DEFAULT_IF },
{ "rtl88x2bu",       FORCE_PAE },

Before it was not possible to add entires like this since only the
last entry match would get set. Now DEFAULT_IF would get set to all
matches, and FORCE_PAE to only rtl88x2bu. This isn't especially
important for the static list since it could be modified to work
correctly, but will be needed when parsing flags from a
configuration file that may contain duplicates or subsets of the
static list.
2023-06-18 13:16:03 -05:00
James Prestwood
568048b0ee ft: add debugging in __ft_rx_authenticate
If there was some problem during the FT authenticate stage
its nice to know more of what happened: whether the AP didn't
respond, rejected the attempt, or sent an invalid frame/IEs.
2023-06-06 10:35:48 -05:00
James Prestwood
189c23a5d9 station: use wiphy_radio_work_reschedule in FT path
If FT fails the work item needs to be rescheduled rather than
inserted.
2023-05-22 09:37:25 -05:00
James Prestwood
109cb70f22 wiphy: make wiphy work queue reentrant
In some situations its convenient for the same work item to be
inserted (rescheduled) while its in progress. FT for example does
this now if a roam fails. The same ft_work item gets re-inserted
which, currently, is not safe to do since the item is modified
and removed once completed.

Fix this by introducing wiphy_radio_work_reschedule which is an
explicit API for re-inserting work items from within the do_work
callback.

The wiphy work logic was changed around slightly to remove the item
at the head of the queue prior to starting and note the ID going
into do_work. If do_work signaled done and ID changed we know it
was re-inserted and can skip the destroy logic and move onto the
next item. If the item is not done continue as normal but set the
priority to INT_MIN, as usual, to prevent other items from getting
to the head of the queue.
2023-05-22 09:35:20 -05:00
James Prestwood
23f0f5717c station: allow roaming before netconfig finishes
If IWD connects under bad RF conditions and netconfig takes
a while to complete (e.g. slow DHCP), the roam timeout
could fire before DHCP is done. Then, after the roam,
IWD would transition automatically to connected before
DHCP was finished. In theory DHCP could still complete after
this point but any process depending on IWD's connected
state would be uninformed and assume IP networking is up.

Fix this by stopping netconfig prior to a roam if IWD is not
in a connected state. Then, once the roam either failed or
succeeded, start netconfig again.
2023-05-07 18:04:08 -05:00
James Prestwood
b080854d3e dpp: fix incorrect offchannel usage as configurator
When acting as a configurator the enrollee can start on a different
channel than IWD is connected to. IWD will begin the auth process
on this channel but tell the enrollee to transition to the current
channel after the auth request. Since a configurator must be
connected (a requirement IWD enforces) we can assume a channel
transition will always be to the currently connected channel. This
allows us to simply cancel the offchannel request and wait for a
response (rather than start another offchannel).

Doing this improves the DPP performance and reduces the potential
for a lost frame during the channel transition.

This patch also addresses the comment that we should wait for the
auth request ACK before canceling the offchannel. Now a flag is
set and IWD will cancel the offchannel once the ACK is received.
2023-04-30 13:03:48 -05:00
James Prestwood
6c97ebb813 ft: fix double free when disconnecting mid-FT
If IWD gets a disconnect during FT the roaming state will be
cleared, as well as any ft_info's during ft_clear_authentications.
This includes canceling the offchannel operation which also
destroys any pending ft_info's if !info->parsed. This causes a
double free afterwards. In addition the l_queue_remove inside the
foreach callback is not a safe operation either.

To fix this don't remove the ft_info inside the offchannel
destroy callback. The info will get freed by ft_associate regardless
of the outcome (parsed or !parsed). This is also consistent with
how the onchannel logic works.

Log and crash backtrace below:

iwd[488]: src/station.c:station_try_next_transition() 5, target aa:46:8d:37:7c:87
iwd[488]: src/wiphy.c:wiphy_radio_work_insert() Inserting work item 16668
iwd[488]: src/wiphy.c:wiphy_radio_work_insert() Inserting work item 16669
iwd[488]: src/wiphy.c:wiphy_radio_work_done() Work item 16667 done
iwd[488]: src/wiphy.c:wiphy_radio_work_next() Starting work item 16668
iwd[488]: src/netdev.c:netdev_mlme_notify() MLME notification Remain on Channel(55)
iwd[488]: src/netdev.c:netdev_mlme_notify() MLME notification Del Station(20)
iwd[488]: src/netdev.c:netdev_link_notify() event 16 on ifindex 5
iwd[488]: src/netdev.c:netdev_mlme_notify() MLME notification Deauthenticate(39)
iwd[488]: src/netdev.c:netdev_deauthenticate_event()
iwd[488]: src/netdev.c:netdev_mlme_notify() MLME notification Disconnect(48)
iwd[488]: src/netdev.c:netdev_disconnect_event()
iwd[488]: Received Deauthentication event, reason: 6, from_ap: true
iwd[488]: src/station.c:station_disconnect_event() 5
iwd[488]: src/station.c:station_disassociated() 5
iwd[488]: src/station.c:station_reset_connection_state() 5
iwd[488]: src/station.c:station_roam_state_clear() 5
iwd[488]: double free or corruption (fasttop)

5  0x0000555b3dbf44a4 in ft_info_destroy ()
6  0x0000555b3dbf45b3 in remove_ifindex ()
7  0x0000555b3dc4653c in l_queue_foreach_remove ()
8  0x0000555b3dbd0dd1 in station_reset_connection_state ()
9  0x0000555b3dbd37e5 in station_disassociated ()
10 0x0000555b3dbc8bb8 in netdev_mlme_notify ()
11 0x0000555b3dc4e80b in received_data ()
12 0x0000555b3dc4b430 in io_callback ()
13 0x0000555b3dc4a5ed in l_main_iterate ()
14 0x0000555b3dc4a6bc in l_main_run ()
15 0x0000555b3dc4a8e0 in l_main_run_with_signal ()
16 0x0000555b3dbbe888 in main ()
2023-04-30 13:00:03 -05:00
James Prestwood
e13e2a5636 common: add FT-8021X-SHA384 to AKM_IS_8021X
Without this the AKM shows up as WEP.
2023-04-16 13:01:01 -05:00
James Prestwood
ad769b718b handshake: remove hardcoded kek_len for FTE decode
The KEK length should be obtained with the getter to ensure the
AKM is taken into account
2023-04-16 13:00:41 -05:00
James Prestwood
590e8f4f13 eapol: add support for FT-8021X-SHA384
The SHA384 variant was not being checked for in any of the
MIC calculations/verifications or for EAPoL decryption.
2023-04-16 12:59:54 -05:00