Skip to content

wolfSupplicant: clean-room WPA/WPA2/WPA3 supplicant (PSK 4-way, EAP-TLS, PEAP/MSCHAPv2, SAE with H2E)#123

Draft
dgarske wants to merge 3 commits into
wolfSSL:masterfrom
dgarske:supplicant
Draft

wolfSupplicant: clean-room WPA/WPA2/WPA3 supplicant (PSK 4-way, EAP-TLS, PEAP/MSCHAPv2, SAE with H2E)#123
dgarske wants to merge 3 commits into
wolfSSL:masterfrom
dgarske:supplicant

Conversation

@dgarske

@dgarske dgarske commented May 20, 2026

Copy link
Copy Markdown
Member

wolfIP: in-tree Wi-Fi supplicant + hardware ports

Adds a clean-room, embeddable Wi-Fi supplicant (src/supplicant/) to wolfIP, plus two hardware ports that exercise it. wolfCrypt-only (no OpenSSL compat), caller-allocated (no malloc on the core path), and driver-agnostic via a small ops interface (send_eapol / install_key / get_pmk).

Supplicant features

  • WPA2-Personal (PSK) - full 4-way handshake with PTK/GTK derivation and key install.
  • WPA2-Enterprise (EAP) - EAP-TLS, with optional PEAPv0/MSCHAPv2.
  • WPA3-Personal (SAE) - dragonfly key exchange with both hunt-and-peck and RFC 9380 Hash-to-Element (H2E) PWE, ECC groups 19/20/21 (P-256/P-384/P-521).
  • RSN IE build and parse, including MFP / 802.11w (management frame protection) capability bits.
  • PMKSA caching - skips PBKDF2 / SAE on reconnect to a known BSSID.
  • Per-feature build gates so unused methods compile out for small targets.

Backed by broad automated test coverage: unit tests for the 4-way, SAE, EAP-TLS, MSCHAPv2 and RSN-IE primitives, plus a live interop harness against hostapd and mac80211_hwsim across the PSK, SAE and EAP paths.

Tested platforms

  • Host (POSIX) - unit + hostapd/hwsim interop, all green.
  • STM32H563 (Cortex-M33) - wired IEEE 802.1X EAP-TLS against hostapd; hardware-validated (AUTHENTICATED end to end).
  • Pi Pico 2 W (RP2350 + CYW43439) - bare-metal port (clean-room CYW43439 firmware loader / PIO gSPI / SDPCM-CDC-BDC); WPA2-PSK join + DHCP + ICMP hardware-validated. Vendor firmware blob is git-ignored.

Planned: TP-Link real-radio testing

Next up is validating the SAE and EAP paths over a real over-the-air radio using a TP-Link USB Wi-Fi card on Linux - a host STA that runs wolfIP + the supplicant and drives the card via nl80211 (reusing the existing nl80211 glue). This closes the last coverage gap: the FullMAC CYW43439 offloads the PSK 4-way in radio firmware, and mac80211_hwsim is SoftMAC, so neither exercises the host supplicant's SAE or EAP handshakes over real RF. The matrix: WPA3-SAE (H2E + HnP, groups 19/20/21) and WPA2-Enterprise EAP-TLS/PEAP against a real AP, with WPA2-PSK as the baseline.

@dgarske dgarske self-assigned this May 20, 2026
Copilot AI review requested due to automatic review settings June 10, 2026 00:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a clean-room WPA/WPA2/WPA3 supplicant (“wolfSupplicant”) to wolfIP and introduces Linux hostapd-based interop harnesses (wired + mac80211_hwsim) to validate EAP-TLS/PEAP, WPA2-PSK 4-way, and WPA3-SAE flows against a real authenticator.

Changes:

  • Introduces an optional Wi‑Fi control vtable (wolfIP_wifi_ops) and an EAPOL (0x888E) RX demux hook for supplicant integration.
  • Adds the supplicant implementation (src/supplicant/*) including EAP-TLS, PEAP/MSCHAPv2, RSN parsing, WPA(2) 4-way, and SAE (incl. H2E) plus test binaries.
  • Adds hostapd/mac80211_hwsim scripts + templates and an nl80211_connect helper, and wires new build/test targets into the Makefile.

Reviewed changes

Copilot reviewed 50 out of 50 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
wolfip.h Adds Wi‑Fi ops vtable + public EAPOL handler registration API.
src/wolfip.c Implements EAPOL handler registration and EAPOL ethertype demux in RX path.
src/test/unit/unit_tests_dns_dhcp.c Adds unit coverage for EAPOL handler register/unregister behavior.
src/test/unit/unit.c Registers the new unit test in the suite.
Makefile Adds supplicant build outputs and hostapd/hwsim interop targets (+ nl80211 helper build).
src/supplicant/supplicant.c Core supplicant state machine (PSK/EAP/SAE integration).
src/supplicant/supplicant.h Supplicant public interface/types.
src/supplicant/eapol.c 802.1X/EAPOL framing helpers.
src/supplicant/eapol.h EAPOL constants and APIs.
src/supplicant/eap.c EAP packet parsing/building.
src/supplicant/eap.h EAP structs/APIs and documentation for EAP parsing/building.
src/supplicant/eap_tls.c EAP-TLS outer method implementation.
src/supplicant/eap_tls.h EAP-TLS API/types.
src/supplicant/eap_tls_engine.c TLS engine glue (wolfSSL IO/exporter integration) for EAP-TLS/PEAP.
src/supplicant/eap_tls_engine.h TLS engine API/types.
src/supplicant/eap_peap.c PEAP outer method implementation (when enabled).
src/supplicant/eap_peap.h PEAP API/types.
src/supplicant/mschapv2.c MSCHAPv2 inner method implementation (when enabled).
src/supplicant/mschapv2.h MSCHAPv2 API/types.
src/supplicant/rsn_ie.c RSN IE parse/build utilities (AKM/ciphers).
src/supplicant/rsn_ie.h RSN IE API/types.
src/supplicant/wpa_crypto.c WPA(2) key derivation/PRFs and related crypto helpers.
src/supplicant/wpa_crypto.h WPA crypto API/types.
src/supplicant/sae_crypto.c SAE (dragonfly) + H2E crypto/state helpers.
src/supplicant/sae_crypto.h SAE crypto API/types.
src/supplicant/test_eap_certs.h Test certificate material helpers for EAP-TLS/PEAP tests.
src/supplicant/test_eap_framing.c Unit tests for EAP framing/parsing.
src/supplicant/test_eap_tls_engine.c Unit tests for EAP-TLS engine behavior.
src/supplicant/test_mschapv2.c Unit tests for MSCHAPv2 vectors.
src/supplicant/test_wpa_crypto.c Unit tests for WPA crypto routines.
src/supplicant/test_supplicant_4way.c In-process tests for 4-way handshake state machine.
src/supplicant/test_supplicant_eap_tls.c In-process tests for EAP-TLS supplicant flow.
src/supplicant/test_sae_crypto.c Unit tests/vectors for SAE crypto (incl. H2E).
src/supplicant/test_supplicant_sae.c In-process tests for SAE handshake state machine.
src/supplicant/test_supplicant_hostapd.c Wired hostapd interop test binary for EAP-TLS.
src/supplicant/test_supplicant_hostapd_psk.c hostapd interop test binary for WPA2-PSK path.
src/supplicant/test_supplicant_hostapd_peap.c hostapd interop test binary for PEAP/MSCHAPv2 path.
src/supplicant/test_supplicant_hostapd_sae.c nl80211 external-auth hostapd interop test binary for SAE.
tools/hostapd/README.md Documents hostapd-based interop harness setup/targets/flags.
tools/hostapd/run_hostapd_test.sh Runner for wired hostapd interop (veth pair).
tools/hostapd/run_hwsim_psk_test.sh Runner for mac80211_hwsim WPA2-PSK interop (nl80211 + hostapd).
tools/hostapd/run_hwsim_sae_test.sh Runner for mac80211_hwsim SAE interop attempt (documents SoftMAC limitation).
tools/hostapd/hostapd.conf.template hostapd wired-mode EAP server template for interop harness.
tools/hostapd/hostapd_psk.conf.template hostapd PSK template for wired path (documented limitation).
tools/hostapd/hostapd_psk_hwsim.conf.template hostapd nl80211 WPA2-PSK AP template for hwsim path.
tools/hostapd/hostapd_sae_hwsim.conf.template hostapd nl80211 WPA3-SAE AP template for hwsim path.
tools/hostapd/eap_users EAP users file for EAP-TLS interop.
tools/hostapd/eap_users_peap EAP users file for PEAP/MSCHAPv2 interop.
tools/hostapd/nl80211_connect.c Minimal libnl nl80211 client to associate STA with CONTROL_PORT for external EAPOL handling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/wolfip.c
Comment thread src/test/unit/unit_tests_dns_dhcp.c
Comment thread tools/hostapd/run_hostapd_test.sh
Comment thread tools/hostapd/run_hostapd_test.sh Outdated
Comment thread tools/hostapd/hostapd.conf.template
Comment thread src/supplicant/test_supplicant_hostapd.c
Comment thread src/supplicant/eap.h
Comment thread src/supplicant/eap.h
@dgarske dgarske force-pushed the supplicant branch 2 times, most recently from efe6635 to d71bf94 Compare June 17, 2026 18:25
@dgarske dgarske requested a review from Copilot June 17, 2026 18:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 90 out of 90 changed files in this pull request and generated 5 comments.

Comment thread src/supplicant/eapol.c
Comment on lines +94 to +99
/* 802.1X header. */
body_len = (uint16_t)(KEYBODY_FIXED_LEN + key_data_len);
out[0] = EAPOL_PROTO_VER;
out[1] = EAPOL_TYPE_KEY;
eapol_wr16(&out[2], body_len);

Comment thread src/supplicant/test_eap_certs.h Outdated
Comment on lines +31 to +55
snprintf(cmd, sizeof(cmd),
"set -e; mkdir -p %s; cd %s; "
"openssl ecparam -name prime256v1 -genkey -noout -out ca.key 2>/dev/null; "
"openssl req -x509 -new -key ca.key -sha256 -days 365 -out ca.crt "
"-subj '/CN=wolfIP EAP Test CA' 2>/dev/null; "
"openssl x509 -in ca.crt -outform DER -out ca.der 2>/dev/null; "
"openssl ecparam -name prime256v1 -genkey -noout -out server.key 2>/dev/null; "
"openssl req -new -key server.key -out server.csr "
"-subj '/CN=auth.wolfip.local' 2>/dev/null; "
"openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key "
"-CAcreateserial -out server.crt -days 365 -sha256 "
"-extfile <(printf 'subjectAltName=DNS:auth.wolfip.local') 2>/dev/null; "
"openssl pkcs8 -topk8 -nocrypt -in server.key -outform DER -out server.key.der 2>/dev/null; "
"openssl x509 -in server.crt -outform DER -out server.der 2>/dev/null; "
"openssl ecparam -name prime256v1 -genkey -noout -out client.key 2>/dev/null; "
"openssl req -new -key client.key -out client.csr "
"-subj '/CN=alice@wolfip.local' 2>/dev/null; "
"openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key "
"-CAcreateserial -out client.crt -days 365 -sha256 "
"-extfile <(printf 'extendedKeyUsage=clientAuth') 2>/dev/null; "
"openssl pkcs8 -topk8 -nocrypt -in client.key -outform DER -out client.key.der 2>/dev/null; "
"openssl x509 -in client.crt -outform DER -out client.der 2>/dev/null",
EAP_TEST_CERT_DIR, EAP_TEST_CERT_DIR);
snprintf(bash_cmd, sizeof(bash_cmd), "/bin/bash -c \"%s\"", cmd);
return (system(bash_cmd) == 0) ? 0 : -1;
Comment on lines +4 to +6
# Drive the wolfIP supplicant against a real hostapd EAP server over a
# Linux TAP device. Validates EAP-TLS framing, identity exchange, TLS
# handshake, and EAP-Success against a non-wolfSSL implementation.
Comment on lines +16 to +32
#include "wolfip.h"

#ifdef __cplusplus
extern "C" {
#endif

/* Populate an ll_dev with the CYW43439 send/poll callbacks and
* wifi_ops vtable. Reads the radio's MAC into ll->mac. Returns 0 on
* success - the caller must have already brought the radio up via
* cyw43_init() + cyw43_wifi_up(). */
int cyw43_wifi_attach(struct wolfIP_ll_dev *ll);

/* Redirect inbound EAPOL (0x888E) to the host supplicant's callback
* while leaving 802.3 data on the wolfIP path. Call after attach once
* the supplicant context exists. */
void cyw43_wifi_route_eapol(cyw43_eapol_cb_t eapol_cb, void *ctx);

Comment on lines +36 to +39
/* The driver presents an EAPOL payload (no MAC header) on the
* F2 BDC channel. wolfIP's 0x888E demux at src/wolfip.c:8883
* expects a full Ethernet frame, so we synthesise the MAC header
* here using the radio's MAC + the BSSID. */
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.

2 participants