Harden wolfSSL and wolfSSH validation

Enable validated ECC imports and X25519 all-zero rejection through
PUBLIC build policy. Tighten wolfSSH parser bounds, overflow handling,
and signature framing with guard-page and crypto vector contracts.
This commit is contained in:
2026-09-15 23:54:39 +02:00
parent c010e1a1d5
commit 4d3bb490c9
17 changed files with 1495 additions and 99 deletions
+8 -6
View File
@@ -105,9 +105,10 @@ The existing global five-verifications/60-second fixed window is unchanged: malf
## 9D maintenance and lifecycle — in progress
- [Security operations](security_operations.md) supplies source-checked provisioning, explicit-save, account/key/identity rotation, recovery, reconstruction and approved erase/decommissioning procedures. There is no implemented configuration backup/export or private-identity restore workflow. Commands and checklists are not device execution evidence; the user will validate Phase 9 as a whole.
- [wolfSSL/wolfSSH review and implementation addendum](wolf_security_review.md): the **CVE-2025-12888** Xtensa mitigation now selects `CURVE25519_SMALL` and `ED25519_SMALL` consistently for wolfSSL and consumers. The PUBLIC forced-include resolved-settings guard rejects missing small implementations, X25519 blinding (incompatible with small in this pinned version), and unreviewed Curve448/Ed448 enablement. **Still open:** server-recommended message-order correction for **CVE-2025-14942**, parser/ECC review and broader API/feature applicability. No server credential-leak or invalid-curve exploit is demonstrated; target timing/interoperability remains untested.
- [wolfSSL/wolfSSH review and implementation addendum](wolf_security_review.md): the **CVE-2025-12888** Xtensa mitigation now selects `CURVE25519_SMALL` and `ED25519_SMALL` consistently for wolfSSL and consumers. The PUBLIC forced-include resolved-settings guard rejects missing small implementations, X25519 blinding (incompatible with small in this pinned version), and unreviewed Curve448/Ed448 enablement. The existing generated wolfSSH override now bounds IGNORE/service strings, rejects zero-capacity string output and channel-window overflow, corrects ECC/Ed25519 key/signature labels, and enforces exact signature framing (ECC nested r/s bounds plus inner/outer consumption; Ed25519 outer consumption). These are PR892/881/880 subsets plus local framing corrections, not full backports; password wiping/async retention remain unchanged. PUBLIC `WOLFSSL_VALIDATE_ECC_IMPORT` and `WOLFSSL_ECDHX_SHARED_NOT_ZERO` now enable P-256 import validation and X25519 all-zero-result rejection, with effective production flags confirmed and fail-closed backend guards. See [key-validation evidence](ssh_key_validation_review.md) and [parser scope/limits](../tests/wolfssh_parser_contract/README.md). **Still open:** server-recommended message-order correction for **CVE-2025-14942**, PR899/deferred parsers, service/key-blob semantics and broader API applicability. Current raw SSH digest construction does not expose the reviewed short-digest/OID trigger; generic PR10131 API hardening is not backported. No exploit or whole-library clearance is demonstrated; added validation CPU/allocation cost and target interoperability remain unmeasured.
- [Focused IDF review and implementation addendum](idf_security_review.md): pinned backports now implement DHCP option bounds (**CVE-2026-45160**), TLS 1.2 EMS failure return (**CVE-2026-50581**) and X.509 OID allocation-failure handling (**CVE-2026-34874**). Explicit nested-target validation places the mbedTLS edits on `mbedtls`/`mbedx509`, retaining source properties and exactly-one-source checks. WS negotiation **CVE-2026-45541** and ASN.1 named-data **CVE-2025-48965** remain unpatched with the review's qualified applicability, not blanket closure.
- [Dependency license inventory](dependency_licenses.md) is a bounded engineering inventory, not legal or distribution clearance. All seven generated sources now carry prominent modification notices dated **2026-09-15**, with upstream notices retained, including both mbedTLS dual-license headers. That narrow finding is resolved. Radio-blob corresponding-source/exception questions, actual firmware/device/browser notice delivery, preferred-source packaging, wolfSSH package-license discrepancy and icon provenance/full-license work remain open. Existing repository notices alone are not a complete release bundle.
- **Ordering is not fixed.** A temporary coherent PR793/819/840/855/921 backport attempt retained no changes: manual prerequisites and nonblocking `SendNewKeys`/`WS_WANT_WRITE` skipping `SendExtInfo` continuation, plus `extInfoSent` rekey semantics, remain unresolved. Official registry 1.5.0/5.9.2 queries returned 404 on 2026-09-15 despite upstream tags existing. Follow the [actionable ordering strategy](wolf_security_review.md#ordering-blocker-and-actionable-next-strategy): evaluate immutable upstream snapshots with reviewed packaging or audit a complete prerequisite-aware backport; require partial-send/EXT_INFO/initial-KEX/rekey and negative ordering tests before closure.
- No dependency versions were upgraded. Beyond the implemented backports above, proposed upgrades/backports remain candidates, not approved compatible versions. Re-audit coherent source/header changes, effective compile policy, exact-hash overrides and callback/parser contracts, then obtain host/build and whole-phase target evidence. 9A9C passes below are historical scoped evidence, not closure of these newly recorded findings.
Secure boot and encrypted NVS remain excluded. No runbook, advisory report or license inventory establishes production readiness or authorizes a destructive device operation.
@@ -130,18 +131,19 @@ Raw flash, RAM and dumps can contain Wi-Fi passwords, private keys, password ver
### Mitigation host/build evidence — 2026-09-15
Supplied parent results (not rerun for this documentation update): `pio run` **PASS**, **94,340 B linked RAM / 1,767,217 B flash**. Against the historical 9C build below, RAM is unchanged and flash is **64,092 B smaller**. Linked size is not runtime headroom or timing evidence.
Supplied parent results (not rerun for this documentation update): `pio run` **PASS**, **94,340 B linked RAM / 1,768,949 B flash**. RAM is unchanged and flash is **1,732 B larger** than the preceding 1,767,217 B mitigation build. Linked size is not runtime headroom or timing evidence.
All four parent commands passed:
All five parent commands passed (crypto policy in strict mode, without candidate injection):
```sh
CCACHE_DISABLE=1 python3 tests/sdk_security_overrides/run.py --build-dir .pio/build/esp32-s3-devkitc-1-n16r8
CCACHE_DISABLE=1 python3 tests/wolf_crypto_policy/run.py
CCACHE_DISABLE=1 python3 tests/wolfssh_parser_contract/run.py
CCACHE_DISABLE=1 python3 tests/wolfssh_auth_contract/run.py
CCACHE_DISABLE=1 python3 tests/ssh_protocol_policy/run.py
```
The independent reviewer reports the first two suites passed with no blocking implementation defects. Documentation verification separately matched all seven existing generated files to pinned originals plus checked-in edits/notices and checked retained mbedTLS license headers. This is scoped implementation/host/build evidence, not completed wolfSSH ordering/parser/ECC review, license packaging clearance or whole-phase acceptance. No target evidence, upgrade, asset regeneration or device operation is claimed.
Independent review found no blocker in the scoped changes. The parser suite passed **3,124 cases per stack mode (two modes)** with guard pages/UBSan trap instrumentation and **six rejected guard-removal mutations**; its crypto doubles establish parser gating, not signature arithmetic. The auth suite passed **135 cases**. Strict crypto tests run real vendor arithmetic/ASN vectors, independently compare seven audited source bodies with exact parser deltas, and check twelve production translation units plus negative policy cases. Effective ECC/X25519 flags were confirmed. SDK override validation includes actual seven-source build registration. This is scoped implementation/host/build evidence, not ordering closure, exhaustive parser/crypto review, license clearance or whole-phase acceptance. No target evidence, upgrade, asset regeneration or device operation is claimed.
### Host and build — historical passes 2026-09-15 (9A9C)
@@ -189,14 +191,14 @@ Retain these checks for the user's final whole-phase test session; do not stop i
#### Protocol compatibility and allocation-failure recovery
1. Verify both allowed TLS suites and both SSH GCM ciphers using compatible clients; force excluded CBC/CTR/other-only offers and confirm rejection. Exercise both SSH KEX choices and both user-key types, initial handshake and rekey, plus TLS renegotiation rejection. Retain UART0 access; do not rotate identities to work around an algorithm mismatch.
2. With synthetic credentials, test truncated/oversized SSH password and change-password packets: no authentication callback for malformed fields, no crash, bounded disconnect/recovery. Host canary assertions are not real encrypted-packet coverage.
2. With synthetic credentials, test truncated/oversized SSH password and change-password packets: no authentication callback for malformed fields, no crash, bounded disconnect/recovery. Include malformed IGNORE/service strings, window overflow, ECC/Ed25519 labels and nested/trailing signature bytes, invalid P-256 points and low-order X25519 inputs. Measure added import-validation latency/allocation/stack cost, host-key loading and handshake deadlines under repeated KEX/rekey and combined load. Host canary/vector assertions are not real encrypted-packet coverage.
3. Exercise HTTPS failed-start, post-handshake allocation failure, normal/failed-stop retry and split-header scratch allocation failure on a separately reviewed fault-injection image. Observe recovery/no accumulating allocation loss without exporting keys or RAM. Failed stop must not prematurely free live TLS state.
4. Repeatedly start/stop HTTPS and SSH and stress header parsing/authentication under the full transport mix. Capture internal/DMA/PSRAM free/minimum/largest-block and stack margins alongside serial/broker loss counters. Specifically measure old-plus-new allocation peaks and secure-free CPU cost; previous very low internal minima remain important.
5. Verify exhausted web login returns early without stalled-body work, clears the used pre-login challenge, and recovers after the documented window. Check malformed requests below quota and correct credentials for normal behavior; do not infer fairness from a rate-limit pass.
## Staged next work
- **Continue 9D maintenance and lifecycle.** Resolve the [open advisory priorities](wolf_security_review.md#release-decision--current-path-priorities), finish broader dependency coverage beyond the bounded IDF/mbedTLS review and three implemented backports, and address the [release source/notice work](dependency_licenses.md#actionable-release-work-not-performed). Runbooks are documented, not rehearsed; remaining mitigations/reviews, distribution clearance and whole-phase acceptance remain outstanding.
- **Continue 9D maintenance and lifecycle.** Execute the [ordering strategy and remaining advisory work](wolf_security_review.md#ordering-blocker-and-actionable-next-strategy), finish broader dependency coverage beyond the bounded IDF/mbedTLS review and three implemented backports, and address the [release source/notice work](dependency_licenses.md#actionable-release-work-not-performed). Runbooks are documented, not rehearsed; remaining mitigations/reviews, distribution clearance and whole-phase acceptance remain outstanding.
- **Retained evidence limits:** 9C completes a bounded cleanup/protocol review, not every-library-copy zeroization. Live inline residue, compaction tails, hardware/stack intermediates, global admission starvation and resource/interop measurements remain documented limitations or combined target gates. Any additional hardening must preserve owner lifetimes and bounded recovery.
- **Phase 10: OTA trust.** Define independent image-signature verification, trust-anchor provisioning, rotation/revocation, rollback/downgrade and recovery policy without secure boot. Authenticated transport alone is not image-signing policy, and OTA signature checks cannot prevent physical firmware replacement.