Re: brcmfmac SAE/WPA3 negotiation

Arend van Spriel
2024-12-12T20:17:39Z

On 12/12/2024 3:24 PM, KeithG wrote:
> Based on a hunch that brcmfmac dbug might reveal something, I turned
> it on to see what turned up. I attempted the same as before: using iwd
> to connect to the WPA3 AP.
>
> [iwd]# station wlan0 connect deskSAE
> Type the network passphrase for deskSAE psk.
> Passphrase: *********
> [iwd]# station wlan0 show
> Station: wlan0
> --------------------------------------------------------------------------------
> Settable Property Value
> --------------------------------------------------------------------------------
> Scanning no
> State connecting
> Connected network deskSAE
> IPv4 address 169.254.203.147
>
> the attached log shows brcmfmac debug
>
> it always shows 'State connecting' never connected.
>
> Is one of these what is causing it to error out:
> Dec 09 18:11:06 jackrune kernel: brcmfmac: brcmf_fil_cmd_data Firmware
> error: BCME_UNSUPPORTED (-23)
> Dec 09 18:11:06 jackrune kernel: brcmfmac: brcmf_fil_iovar_data_get
> ifidx=0, name=tdls_sta_info, len=296, err=-52
> ...
> Dec 09 18:11:06 jackrune kernel: brcmfmac: brcmf_fil_cmd_data Firmware
> error: BCME_BADADDR (-21)
> Dec 09 18:11:06 jackrune kernel: brcmfmac: brcmf_fil_iovar_data_get
> ifidx=0, name=sta_info, len=296, err=-52
> ...
> Dec 09 18:33:32 jackrune kernel: ieee80211 phy0:
> brcmf_cfg80211_get_station: GET STA INFO failed, -52
>
> I do not know what BCME is.

BCME are the error codes produced by the firmware. Without debug prints
you will only see a generic error code, ie. -52 (-EBADE). So you always
see the "Firmware error" message following by the "generic" error
message. It is not truly generic as it mentions the command name. So the
above says the command "tdls_sta_info" is unsupported and the mac
address provided in the "sta_info" command is not found in firmware.

Looking at the log I see periodically:

Dec 09 18:32:55 jackrune kernel: brcmfmac: brcmf_fil_cmd_data Firmware
error: BCME_NOTASSOCIATED (-17)
Dec 09 18:32:55 jackrune kernel: brcmfmac: brcmf_fil_cmd_data_get
ifidx=0, cmd=23, len=6, err=-52

According fwil.h the driver sends BRCMF_C_GET_BSSID command. When
associated is returns the BSSID of your AP. As you are not yet
associated it fails. Not really related to the external auth procedure I
think.

The following is more interesting:

Dec 09 18:32:55 jackrune kernel: brcmfmac: brcmf_cfg80211_external_auth
Enter
Dec 09 18:32:55 jackrune kernel: brcmfmac: brcmf_fil_iovar_data_set
ifidx=0, name=auth_status, len=44
Dec 09 18:32:55 jackrune kernel: brcmutil: data
Dec 09 18:32:55 jackrune kernel: 00000000: 04 00 d8 3a dd 60 a3 0c 07 00
00 00 64 65 73 6b ...:.`......desk
Dec 09 18:32:55 jackrune kernel: 00000010: 53 41 45 00 00 00 00 00 00 00
00 00 00 00 00 00 SAE.............
Dec 09 18:32:55 jackrune kernel: 00000020: 00 00 00 00 00 00 00 00 00 00
00 00 ............
Dec 09 18:32:55 jackrune kernel: brcmfmac: brcmf_sdio_bus_txctl Enter
Dec 09 18:32:55 jackrune kernel: brcmfmac: brcmf_sdio_bus_rxctl Enter
Dec 09 18:32:55 jackrune kernel: brcmfmac: brcmf_sdio_isr Enter
Dec 09 18:32:55 jackrune kernel: brcmfmac: brcmf_sdio_bus_rxctl resumed
on rxctl frame, got 72 expected 72
Dec 09 18:32:55 jackrune kernel: brcmfmac: brcmf_fil_cmd_data Firmware
error: BCME_BADLEN (-24)
Dec 09 18:32:55 jackrune kernel: ieee80211 phy0:
brcmf_cfg80211_external_auth: auth_status iovar failed: ret=-52

So the "auth_status" command fails and the firmware error code indicates
the length is invalid. The length of the "auth_status" command as sent
by the driver to the device is 44 and apparently the firmware expects
some other length. Here is what I did in my patch:

+static int
+brcmf_cyw_external_auth(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_external_auth_params *params)
+{
+ struct brcmf_if *ifp;
+ struct brcmf_pub *drvr;
+ struct brcmf_auth_req_status_le auth_status;
+ int ret = 0;
+
+ brcmf_dbg(TRACE, "Enter\n");
+
+ ifp = netdev_priv(dev);
+ drvr = ifp->drvr;
+ if (params->status == WLAN_STATUS_SUCCESS) {
+ auth_status.flags = cpu_to_le16(BRCMF_EXTAUTH_SUCCESS);
+ } else {
+ bphy_err(drvr, "External authentication failed: status=%d\n",
+ params->status);
+ auth_status.flags = cpu_to_le16(BRCMF_EXTAUTH_FAIL);
+ }
+
+ memcpy(auth_status.peer_mac, params->bssid, ETH_ALEN);
+ auth_status.ssid_len = cpu_to_le32(min_t(u8, params->ssid.ssid_len,
+ IEEE80211_MAX_SSID_LEN));
+ memcpy(auth_status.ssid, params->ssid.ssid, auth_status.ssid_len);
+
+ ret = brcmf_fil_iovar_data_set(ifp, "auth_status", &auth_status,
+ sizeof(auth_status));
+ if (ret < 0)
+ bphy_err(drvr, "auth_status iovar failed: ret=%d\n", ret);
+
+ return ret;
+}

So the type struct brcmf_auth_req_status_le is used for external auth
request and for auth_status. Maybe for the "auth_status" it only needs a
subset of fields. Here is the struct declaration:

+/**
+ * struct brcmf_auth_req_status_le - external auth request and status
update
+ *
+ * @flags: flags for external auth status
+ * @peer_mac: peer MAC address
+ * @ssid_len: length of ssid
+ * @ssid: ssid characters
+ */
+struct brcmf_auth_req_status_le {
+ __le16 flags;
+ u8 peer_mac[ETH_ALEN];
+ __le32 ssid_len;
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+};

Maybe flags and peer_mac is sufficient? That would be 8 bytes so can you
try and change brcmf_cyw_external_auth() such that it does:

+ ret = brcmf_fil_iovar_data_set(ifp, "auth_status", &auth_status, 8);

Without firmware source code we can only guess.

Regards,
Arend

> On Mon, Dec 9, 2024 at 8:30 AM KeithG <ys3al35l@gmail.com> wrote:
>>
>> I poked at this a while back and decided to try it again over the weekend.
>>
>> Infineon has released a new firmware:
>> Firmware: BCM4345/6 wl0: Oct 28 2024 23:27:00 version 7.45.286
>> (be70ab3 CY) FWID 01-95efe7fa
>> it is not in the RPiOS release, yet, but I installed it on a Pi3B+ and
>> decided to give it a try. I have an AP running WPA3 personal on a
>> desktop in the home and can connect to it with my phone as proof that
>> it 'works'.
>>
>> I tried to connect to it once again from the Pi while running this new
>> firmware. It gets closer than last time I checked, but it does not
>> actually negotiate a functional connection.
>> I tried with connman/iwd, NetworkManager/iwd and it gets close, but
>> still errors out. I get a number of these in the iwmon log:
>>
>>> Response: Get Station (0x11) len 4 38.439787
>> Status: Invalid exchange (52)
>>
>> Can I probe this further to assist in diagnosing the cause and
>> potentially help with a solution?
>> The log is attached.
>>
>> Regards,
>>
>> Keith