Files
ESP32_Serial_Swiss_Army_Knife/docs/wifi_security_update_plan.md
T
Commander1024 cdc4d4a8df Add Phase 9 validation and advisory review
Record the finite dependency search, Wi-Fi maintenance blocker, and
pinned
icon provenance. Add bounded host orchestration and fixture coverage,
and
update release documentation with current evidence.
2026-09-16 16:26:46 +02:00

21 KiB
Raw Blame History

Wi-Fi management-frame security update plan

Review date: 2026-09-16. Focused documentation-only follow-up to dependency advisory coverage. No correction implemented, exploit reproduced, build run, device accessed, or upgrade approved. This document is the only file owned/created by this review; existing concurrent work is untouched.

Decision

Prefer a complete, immutable Espressif IDF 5.5 maintenance-release bundle, integrated through a compatible pinned PlatformIO package/toolchain, over transplanting Wi-Fi archives into IDF 5.5.0. IDF 5.5.3 is the verified fix-bearing reference candidate/minimum demonstrated release here, not a recommendation to deploy it in preference to all later maintenance releases. The earlier coverage records 5.5.4/5.5.5; selecting a newer deployment candidate requires the same immutable provenance and compatibility gates below, not a repeat broad advisory audit.

Do not change PMF/WPA3 policy as an automatic mitigation. Do not replace only libnet80211.a, edit only a callback declaration, relax source guards, or overwrite the installed SDK. Current PMF-capable SoftAP exposure remains open pending implementation and target validation.

Current applicability and trigger limits

Rechecked authoritative source src/wifi_manager.c:315363:

  • SoftAP uses WIFI_AUTH_WPA2_WPA3_PSK, four clients, pmf_cfg.capable=true, required=false, WPA3_SAE_PWE_BOTH. AP/APSTA are real supported paths, including live fallback transitions (set_runtime_ap_enabled). Optional PMF is not PMF disabled.
  • Station uses PMF capability in both profiles; mixed has WPA2 minimum/optional PMF, WPA3 requires PMF. Do not downgrade station profiles to address a demonstrated SoftAP trigger.
  • Existing generated sdkconfig.h identifies ESP32-S3 and enables SoftAP, WPA3 SAE, SoftAP SAE, SAE H2E and SAE-PK support. This is build metadata, not proof of a running device's current mode or negotiated association.
  • Architecture: the permanent Wi-Fi manager owns driver operations and bounded events; application NVS is authoritative, driver storage is RAM-only, AP policy is off/fallback/always. Working edits require explicit save. Preserve manager ownership, secret wiping and secret-free status. UART0 recovery and native USB UART1 access must remain independent of network success. Broker single-writer/multiple-isolated-observer behavior is unchanged.

The official contained fix says that when the supplicant sends an authentication response for an already-connected station, with keys installed after a successful four-way handshake, management encryption was selected from bss->pmf_enable without checking whether the frame was robust. The encryption code assumed header space that had not been allocated, causing memory corruption. The fix checks robust-management-frame status before encryption.

This supports a current-feature exposure candidate when SoftAP is active with the relevant station/key/PMF state. Radio delivery of the relevant management exchange, rather than application HTTPS/SSH authentication, is the pertinent access path (inference from the described Wi-Fi operation). The public text does not establish whether an attacker must know the PSK, personally complete association, or can spoof an existing station's exchange. It supplies no packet-level proof, CVSS, reliable arbitrary-code-execution claim, or exhaustive affected-mode matrix. Do not characterize this as proven unauthenticated remote exploitation, nor assume application login protects it. STA-only exclusion is limited to the described AP-response path, not a blanket clean bill for the opaque bundle.

The same vendor change also fixes an RSN-IE length/allocation mismatch, deauthentication-reason parsing, and default SAE PWE values. The project's short configured IE set has not been shown to trigger the allocation issue; do not conflate that uncertainty with the established old ABI/bundle identity.

Official immutable provenance

Official sources fetched in this review:

  1. 5.5.3 release, also release API: explicitly names the management-frame memory-corruption correction under a3927641.
  2. Merge commit, checked through its official commit API: a3927641bfd0aedfaab3514cba3d7fb01378ce4d. Its title emphasizes SAE defaults; the title alone omits the security detail.
  3. Contained fix patch: caf4cad3b422be5c2f93afeff4cd07796a262b46, “Backport some wifi fixes,” with the trigger explanation. This is the merge's second parent, not a conflicting identification.
  4. Annotated release tag object: tag object b31fcc7a314a44ad992b58f589f7d1d8a4fadff6 resolves to IDF commit 2c211b236707889e8400c4dc5644dd5c4ee071e0. Immutable comparison reports ahead 195 / behind 0, establishing inclusion of the merge.

Exact published source/ABI delta

The fix changes four paths:

Path relative to IDF Published change
components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h wpa_funcs.wpa_ap_get_wpa_ie: uint8_t *(*)(uint8_t *len) becomes uint8_t *(*)(size_t *len)
components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c Matching callback implementation takes size_t *ie_len; assignment from hapd->wpa_auth->wpa_ie_len remains
components/esp_wifi/lib Submodule d7373a90dc3f0be841b29911e33de5f99988dbffa4e903fe43bf09a95022f9802db43d39740ccc0b
components/esp_wifi/include/esp_wifi_types_generic.h Two SAE PWE documentation comments record default WPA3_SAE_PWE_BOTH; not structure-layout changes

The installed header and callback still take uint8_t *; esp_wpa_main.c registers the callback for SoftAP. The callback slot/pointer size need not change for this to be an ABI break: the width and interpretation of the pointed-to output change (one byte versus a size_t, four bytes on ESP32-S3). Mixed old/new caller and callee can corrupt storage or leave an incorrect length. Casting the callback does not fix the contract. Both sides, including the opaque caller, must agree.

The visible C edits are the length correction/interface marker. The management-encryption fix is in the vendor binary update, not a public C hunk that can be copied into this application.

Bundle identity: baseline, fix point, release point are different

  • Installed baseline matches Wi-Fi submodule 8a1b7bbc00e895d040c5c9a6fb9d1db2bbfc7958 from IDF v5.5, not the fix's immediate predecessor d7373a90….
  • The exact fix-point bundle is a4e903fe43bf09a95022f9802db43d39740ccc0b.
  • The complete 5.5.3 release points to e0befaa593277b4e80726079fbd521b4681754c2, verified again at the immutable release commit. Wi-Fi comparison reports ahead 3 / behind 0. Do not call the fix-point bundle the final 5.5.3 bundle.

Calculated Git blob SHA-1 (blob <length>\0 plus bytes) of all seven installed S3 archives and compared against official metadata for baseline, fix point, and release point:

Archive Installed = baseline Git blob Fix-point Git blob 5.5.3-release Git blob
libcore.a ec2e76caad4c29ee92ec45432e0dc3bf946ea4c7 af63b0f8254bde084b2f474cdba1c1d63b4ae750 9f7b14a8bf6eec64973da8adc65d35b5ba9bee49
libespnow.a d4925dc7f73173077e8ed58abbbe5a59b5bb7be5 da0537c3f754a9d638fbecd4f4d806bfa66316b4 132b4f67e339ca2081d2add91c14eefa39476ff9
libmesh.a 5cd43bf5a0a0388fb6f093a154401f00227d9570 6ae30c90ba59ab949e98db89b6b51daab434a5a0 2e9dc1c8c7afbf033337b4175032e9b1161e3262
libnet80211.a 6ee20bec142638dc0a442b9642de9fa62db6ddd0 8ce8a2a6a9a753e31508bd609bf0a0d1d44c332f 2800d447ec385d33869373696ba8191292647694
libpp.a c9fc98fe529c9ff2891839fdb9a41b1189c03c49 536fd25e30a1be76ff122d93e7481f1da22e6892 8944bcad7371621045f376cf74c62fde6f368cbb
libsmartconfig.a 31518eb9336f07de14b4a71c0389217a54ed3ec7 19e8274e0961fdf88351a0dec6e0d696b8ee2b94 4dc759e25617aa00b9e12887fd092a1d5780a170
libwapi.a 0604ff76aa9134b475daf08496e03350d5ef8f09 e43863a22e93990b8a4deb7c4efc8e4c27566789 65655b6feab0572a6e8a1200946d53a21f3f4722

All installed archives match baseline; all differ from both newer bundles. This is artifact identity, not proof that every archive is linked or contains the defect. Remote binaries were not downloaded. Git IDs are provenance identifiers, not independently measured remote SHA-256 digests or a vendor signature verification.

The release API advertises the submodule-inclusive esp-idf-v5.5.3.zip, asset ID 357881088, SHA-256 d16e6b57b1df1a523aff6a1d0ef2f99cf058cb71e73f694429769eaaea171428. This is vendor-published metadata, not a locally verified download. The release is marked immutable=false; therefore pin the resolved commit/submodules and verify artifact hashes, not merely a tag URL. Espressif warns that GitHub's automatic source archives omit submodules; those are not complete SDK inputs.

PMF/WPA3 mitigation assessment

Both the v5.5 documentation source and immutable candidate documentation, plus the installed type header, establish:

  • pmf_cfg.capable is deprecated, effectively true internally. Setting it false is not a supported PMF-off mitigation.
  • required=false permits optional PMF; it does not disable it.
  • esp_wifi_disable_pmf_config() is the documented optional-PMF disable API. Disabling PMF on WPA3 or WPA2/WPA3 mixed SoftAP returns an error.
  • WPA3 mandates PMF. WPA2-only mode by itself still does not prove PMF is disabled.

No issue-specific official workaround was found in the inspected release/fix text. The API documentation explains general configuration, not an endorsement that disabling PMF safely mitigates all defects in this change. The trigger supplies a rationale that actually eliminating bss->pmf_enable could avoid the described encryption path; the opaque implementation and lifecycle have not been proved to honor that invariant across existing associations/restarts.

Consequently, a WPA2-only plus explicit PMF-disable implementation is at most an unapproved conditional workaround candidate. It would remove SAE benefits and management-frame protection, require explicit owner acceptance, documented threat trade-offs, correct manager-owned stop/reconfigure/start sequencing, checked API results, and target evidence that negotiated PMF cannot reappear across APSTA/fallback transitions. It would not repair the RSN-IE allocation defect. Do not implement it as a silent downgrade, global WPA3 Kconfig removal, or station-profile change.

If operational containment is urgently required before an update, the owner may explicitly choose existing AP-off policy (removes the described AP response path) or Wi-Fi-off (removes radio service), accepting lost network/fallback access. These are feature-withdrawal containment options, not vendor-certified workarounds or a source fix. Preserve and verify UART0/native USB access first; do not automatically persist policy changes. No containment action was taken here.

What a coherent replacement entails

Preferred: complete vendor maintenance release

Use all IDF source, private/public headers, Wi-Fi/PHY/coexistence libraries and other submodules from one resolved release, with its toolchain and Python/build requirements. Do not install final-release blobs alongside fix-point-only C edits or mix two release revisions. Preserve the application security policies separately through audited overrides.

Verified local integration constraints:

Input Current state Required next action
platformio.ini platformio/espressif32@6.12.0, ESP-IDF, ESP32-S3 N16R8 Select a supported pinned platform/framework/toolchain combination; no floating update
Installed platform platform.json Framework range ~3.50500.0; installed framework-espidf/package.json is 3.50500.0 Does not select 5.5.3; establish package provenance and adapter support before proposing a package override
Installed Xtensa toolchain 14.2.0+20241119 Candidate's immutable tools/tools.json recommends esp-14.2.0_20251107; same GCC major/minor is not identical tooling or compatibility evidence
tools/security_overrides.py verify_version() requires exactly 5.5.0; each original source has an exact SHA-256 and executable edit contract A full upgrade intentionally fails until semantic re-audit/rebase; never make the version range permissive just to build
cmake/security_overrides.cmake Exact-once source replacement, nested mbedTLS ownership checks, source-property preservation, forced PUBLIC wolfSSH ABI overlay Revalidate generated and actual compiler inputs, target identities and include order

No known-good PlatformIO 6.12 + IDF 5.5.3 package combination was established here. The installed adapter was read only for package/version/toolchain selection references, not certified for the candidate. A raw IDF Git checkout is not automatically a PlatformIO framework package. Prefer a supported platform release carrying a suitable complete SDK; otherwise a maintained, exact-pinned framework/toolchain packaging effort is a separate explicit implementation deliverable.

Re-audit all existing corrections against candidate originals, not only Wi-Fi: HTTPS cleanup/private-key release, HTTPD scratch/null-read handling, server-local TLS policy, DHCP bounds, TLS EMS failure, X.509 allocation failure; retain/revalidate wolfSSH password/parser/ordering/ABI changes and wolfCrypt settings. Mark each correction retained, rebased, or superseded with source/test evidence. Upstream fixes do not automatically supersede local lifetime/policy additions in the same source. Also retain silent-panic/no-coredump and heap-wipe policy guards. The durable architecture's older four-correction summary is not the complete current inventory; the current generator and code map are authoritative.

Contingency: vendor-supported backport onto 5.5.0

The smallest published delta against the fix's own parent is the four-path change above. The smallest proven safe delta against this project's 5.5.0 is not established.

A candidate backport must at least pair both callback changes with one complete ESP32-S3 Wi-Fi archive set from the same vendor revision, retain the vendor patch/provenance, and establish compatibility with all private Wi-Fi headers, OS adapter tables, supplicant structures/callbacks, PHY/coexistence interfaces, configuration ABI and toolchain. All seven S3 archives form the conservative replacement set; do not mix old optional archives with new ones simply because current linking omits them. This minimum set is necessary for coherent provenance, not sufficient proof of cross-baseline compatibility.

Ask Espressif for a supported 5.5.0 backport bundle or an explicit compatibility statement with its required source/header/library/toolchain prerequisites, confirming both management-frame and IE-length corrections. The immediate-parent blob pointer differs from baseline; successful linking alone cannot establish binary layout/calling-contract compatibility. Without that evidence or a complete audited dependency closure, choose the full-release path rather than treating the two C signature edits plus blobs as approved.

Bounded implementation and acceptance plan

  1. Compatibility/provenance gate first, no code change yet. Resolve one deployment release and PlatformIO delivery combination. Record immutable SDK commit, recursive submodule pins, package/toolchain identities and SHA-256 manifests. Confirm vendor inclusion of the fix. Obtain missing packaging/ABI evidence; if unavailable, report the blocker instead of guessing a framework URL or transplanting archives.
  2. Prepare isolated inputs after approval. Do not modify the user's shared installed SDK. Obtain complete vendor inputs in a dedicated location, verify provenance/hashes, and compare only relevant integration surfaces and protected-source entries. Keep existing managed components pinned where compatible; explicitly review any resolver-required changes. Review license/notice/source-delivery updates for new radio/SDK artifacts.
  3. Rebase security contracts. Implement a reviewed per-entry disposition and exact new source pins, retain fail-closed guards, and verify every generated override/forced header reaches the actual targets. Add a bundle-consistency check for the selected SDK and archive identities so an old/new mixed bundle fails deterministically. Do not enable unrelated features, regenerate web assets, migrate credentials, or alter partitions.
  4. Build/host gates in the later implementation task only. Clean candidate build with the selected toolchain; inspect linked archive paths/map, generated configuration and actual compilation inputs. Run SDK override, crypto, parser, ordering/interop, authentication/protocol, build-policy and notice validations as applicable to the resolved input changes. Record sizes and compare resource budgets; a host pass is not radio validation. Existing historical passes do not validate this candidate.
  5. Target gates under explicit device authorization. Exercise WPA2 with/without negotiated PMF and WPA3 SoftAP; authenticate/reassociate after keys are installed; cover PMF optional/required behavior, four clients, disconnect/reconnect and AP/STA/APSTA/fallback transitions. Obtain vendor regression guidance or an authorized isolated-radio reproduction for the exact trigger; ordinary reconnect tests alone do not prove vulnerability closure. Stress concurrent HTTPS/WebSocket/SSH and verify bounded recovery, heap/stack reserve, queue behavior, no secret/crash-memory disclosure, and unchanged broker isolation. Verify UART0 recovery and native USB UART1 operation while Wi-Fi fails/stops/restarts. Include persisted-config reboot tests without erasure.
  6. Release gate. Keep PMF/WPA3 security at least unchanged. Record exact artifacts and test evidence, retain a controlled recovery image and configuration backup procedure, and mark the old image as still exposed rather than calling rollback a security fix. No flash erase, upload, pin changes or deployment until separately authorized. Update durable project memory only when implemented contracts/ownership genuinely change.

Open evidence and review boundary

  • Resolved: official fix IDs/description; exact visible ABI delta; all seven installed S3 archives match baseline; distinct fix and final-release bundles; release/fix ancestry; current application configuration; PMF-disable restrictions; exact-IDF/hash guards; recommended versus installed toolchain mismatch.
  • Unresolved: supported PlatformIO delivery for the chosen maintenance release; full private ABI prerequisite closure for a 5.5.0 transplant; exact PHY/coexistence submodule pins for the candidate in this review; complete tool/Python/managed-component compatibility; opaque binary implementation correctness; packet-level attacker requirements; target/runtime/resource evidence; latest deployment-release selection.
  • A follow-up GitHub API request for candidate components/esp_phy/lib returned HTTP 403 rate limit exceeded. The sequential metadata query stopped there, so PHY/coexistence pins were not established; no inference was drawn from that failure. Already completed Wi-Fi/release/ancestry queries succeeded. Official raw documentation remained available. Do not treat this partial metadata boundary as a compatibility clearance.
  • Validation performed here: read-only local source/package/config inspection; local seven-archive Git-blob hashing; official patch/release/tag/content/comparison/toolchain/documentation reads. No broad repeated dependency audit, binary download, PlatformIO invocation, build, test suite, device operation, configuration edit, or asset generation. Documentation links/provenance do not constitute signed-vendor attestation, exhaustive security certification, or Phase 9 sign-off.