Skip to content

esp-radio: WPA3-Personal (SAE) for the station - #6321

Draft
scv9 wants to merge 1 commit into
esp-rs:mainfrom
scv9:wpa3-sae-station
Draft

scv9 wants to merge 1 commit into
esp-rs:mainfrom
scv9:wpa3-sae-station

Conversation

@scv9

@scv9 scv9 commented Sep 12, 2026

Copy link
Copy Markdown

Thank you for your contribution!

Submission Checklist 📝

  • I have updated existing examples or added new ones (if applicable). — not applicable, the examples keep using WPA2.
  • I have used cargo xtask fmt command to ensure that all changed code is formatted correctly.
  • I have added changelog entries and/or migration guide notes in the sections below, or I will ask a maintainer to add the skip-changelog or manual-changelog label as appropriate.
  • My changes are in accordance to the esp-rs developer guidelines

Extra:

Pull Request Details 📖

Description

WPA3-Personal (SAE) for the station, closing #1600.

The missing piece was never in esp-radio: the libwpa_supplicant.a in esp-wifi-sys is built with CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=n / CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=n, so the open-source supplicant has no SAE client, and the closed blobs (which reach SAE only through the wpa_funcs table the supplicant registers) report a WPA3-only AP as WIFI_AUTH_OPENNoAccessPointFound. Two companion PRs rebuild the esp32 supplicant with SAE on mbedTLS crypto and ship the libmbedcrypto.a it needs:

This PR is the esp-radio side, kept to what is needed:

  • AuthenticationMethodConfig gets Wpa3Personal(Password) and Wpa2Wpa3Personal(Password) back (removed in Introduce AuthenticationMethodConfig #6146 as unsupported), mapped to the existing AuthenticationMethod::{Wpa3Personal, Wpa2Wpa3Personal}. The station config already sets PMF capable and sae_pwe_h2e = 3 (hunt-and-peck + hash-to-element) — that is exactly the configuration the hardware test used, so nothing else in apply_sta_config changes.
  • AccessPointConfig::validate refuses both with WifiError::Unsupported + a warning: the supplicant is also built with CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT (IDF default once SAE is on), but I have not verified a WPA3 soft-AP and would rather not expose a silently failing option — the very complaint in Support connecting to a WPA3 AP from ESP32 support #1600. Easy to lift once someone tests it.
  • Module docs / the from_raw comment no longer say WPA3 is unsupported.

No compat shim is needed: the mbedTLS build in the companion PRs uses libc calloc/free, no threading, no PSA key storage, so libmbedcrypto.a references nothing esp-radio does not already provide (cargo xtask build embassy_dhcp esp32 links against the new archives with no other change).

Depends on esp-rs/esp-wifi-sys#511: esp-radio/Cargo.toml must bump the esp-wifi-sys rev to a commit containing it (not done here — the rev does not exist upstream yet). Only esp32 archives are rebuilt in the companion PRs; on other chips these two variants will behave as before (driver reports the AP as open) until their libraries are rebuilt — see the "all chips?" question in the 3rdparty PR. Draft for that reason.

Testing

  • Hardware (ESP32-D0WD-V3, 240 MHz): the same supplicant/mbedcrypto recipe applied to ESP-IDF v5.5.3 (the IDF behind crates.io esp-wifi-sys-esp32 0.2.0; its supplicant is byte-identical to 3rdparty bf1e59a2) with esp-radio 1.0.0-beta.0, against a WPA3-only AP (SSID/BSSID withheld). Before: scan classifies the AP as None, every threshold incl. BSSID/channel pinning ends in NoAccessPointFound, a WPA2 AP on the same radio joins. After: scan reports Wpa3Personal; connect_async() with the weakest threshold succeeds — SAE commit/confirm + 4-way in 0.95 / 1.35 / 2.9 s over three boots (software P-256 on the LX6); heap peak +7 KiB during SAE (89.4 KiB used vs 82.4 KiB after); image +63.9 KiB flash; IRAM (.rwtext.wifi 51 800 B) unchanged; DHCP and TCP normal afterwards.
  • This branch (esp-hal main + the v6.1 archives from esp-wifi-sys#511 via [patch]): cargo xtask build embassy_dhcp esp32 links, cargo xtask lint esp-radio esp32 clean, cargo +nightly fmt clean. The ELF contains sae_prepare_commit, sae_process_commit, esp_wifi_register_wpa3_cb, mbedtls_ecp_mul, psa_import_key. Versus main with the current archives: .text +69 767 B, .rodata +10 896 B, .bss +420 B, IRAM unchanged (≈ +81 KiB flash; IDF 6.1's mbedTLS 4 / TF-PSA-Crypto costs more than 5.5's). Not run on hardware with the v6.1 archives — my board is on esp-hal 1.1 / IDF 5.5 libraries.

Changelog

esp-radio

  • Added: AuthenticationMethodConfig::Wpa3Personal and AuthenticationMethodConfig::Wpa2Wpa3Personal — WPA3-Personal (SAE) for the station, with the SAE-enabled supplicant from esp-wifi-sys.
  • Changed: AccessPointConfig rejects WPA3 authentication methods with WifiError::Unsupported until a WPA3 soft-AP is verified.

Re-adds `Wpa3Personal` and `Wpa2Wpa3Personal` to
`AuthenticationMethodConfig` (dropped in esp-rs#6146 as unsupported) now that
the esp32 supplicant in esp-wifi-sys is built with SAE on mbedTLS crypto
(esp-rs/esp-wireless-drivers-3rdparty#11, esp-rs/esp-wifi-sys#511).

Station only: `AccessPointConfig::validate` refuses the two methods with
`WifiError::Unsupported` until a WPA3 soft-AP has been verified. The
station config already sets PMF capable and `sae_pwe_h2e = 3`
(hunt-and-peck and hash-to-element), which is what the hardware test
used. Module docs updated.

Closes esp-rs#1600.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant