Apply Phase 9D security mitigations

- Add fail-closed wolfSSL small-math policy and vectors
- Backport DHCP, EMS, and X.509 allocation fixes
- Extend source override validation and operational documentation
This commit is contained in:
2026-09-15 23:06:23 +02:00
parent cdc9c7335a
commit c010e1a1d5
22 changed files with 1562 additions and 38 deletions
+55 -9
View File
@@ -15,6 +15,9 @@ configuration; there is no unpatched fallback or automatic hash repinning.
Derived **full files**, retaining the original copyright/license notices, live
only at `<CMAKE_BINARY_DIR>/security_overrides/<entry-name>/<basename>`.
Every generated source is centrally prefixed with an explicit
`Modified by the ESP32_serial_swiss_army_knife project on 2026-09-15` notice.
This is separate from, and does not rewrite or replace, upstream notices.
The manifest and derived files are atomically replaced only when their bytes
change. Output paths cannot escape the binary tree or alias SDK/source files.
CMake tracks the generator, version header, originals, and derived sources for
@@ -51,7 +54,7 @@ Source generator expressions are rejected rather than guessed through.
ECDSA/AES/GCM/SHA features are compile-guarded. IDF dynamic buffers are rejected
because their destructor bypasses the audited upstream record-buffer wipe.
`set_client_config()` and the shared handle/setup path are unchanged.
- `wolfssl__wolfssh:src/internal.c`: the fourth override pins wolfSSH 1.4.20's
- `wolfssl__wolfssh:src/internal.c`: pins wolfSSH 1.4.20's
original source SHA256 to
`81ff1f9166708abd5c2911e9fe57c0aee01c88b5d3f68c909ee8a856d37f36a9`.
`GetSize()` bounds password and new-password fields before authentication;
@@ -61,6 +64,26 @@ Source generator expressions are rejected rather than guessed through.
an async secret-lifetime/wipe guarantee. Generated parser/control-flow tests
live in `tests/wolfssh_auth_contract/`.
- `lwip:apps/dhcpserver/dhcpserver.c`: PAD/END handling, length-byte and
declared-payload bounds, minimum message-type/requested-IP lengths, validated
advancement. Backport of official
[d51b1076092487e533eadf8b48c9c8579d3a6712](https://github.com/espressif/esp-idf/commit/d51b1076092487e533eadf8b48c9c8579d3a6712.patch).
The only behavioral-code deviation is using equivalent remaining-length
comparisons rather than constructing pointers beyond the input object.
Original copyright years stay unchanged under the separate modification notice.
- Nested `mbedtls:ssl_tls.c`: propagate `calc_verify()` failure immediately,
before PRF/master-secret derivation. Exact TLS 1.2 hunk of
[f595df4569c1a1650ad9d077e2f2e819e9f1dddb](https://github.com/Mbed-TLS/mbedtls/commit/f595df4569c1a1650ad9d077e2f2e819e9f1dddb.patch).
EMS remains enabled. This does **not** backport that commit's TLS 1.3 hunk.
- Nested `mbedx509:x509_create.c`: reject known-attribute OID allocation failure
before `memcpy()`, returning `MBEDTLS_ERR_X509_ALLOC_FAILED`. Exact guard from
[bfaf4a47fd33da860796feaba6235847acb71127](https://github.com/Mbed-TLS/mbedtls/commit/bfaf4a47fd33da860796feaba6235847acb71127.patch).
These three patches were fetched from the official repositories and compared
with the installed pinned sources on 2026-09-15. No dependency versions or
existing original-source hashes changed. The optional WS subprotocol backport
and separate ASN.1 repeated-OID/empty-value correction are **not** implemented.
Clients that cannot negotiate this server profile will no longer connect.
Live interoperability and resource/latency testing remain hardware gates.
These corrections do not claim comprehensive zeroization of every TLS/library
@@ -75,14 +98,18 @@ Add an `Entry` to `tools/security_overrides.py:ENTRIES` with:
- `root="idf"` for installed IDF sources, or `root="project"` for project/vendor
sources;
- exact relative `source`, full reviewed `sha256`, and a tuple of `Edit(old,new)`
exact-once substitutions.
exact-once substitutions;
- optional `target` for the explicitly supported `mbedtls`, `mbedx509` or
`mbedcrypto` nested library under component `mbedtls`. Empty selects the
component's `COMPONENT_LIB` as before. CMake validates the nested target exists,
is not imported/an alias, and belongs to the installed mbedTLS library directory.
`render_entry()` validates/patches an entry; `generate()` accepts an explicit
entry tuple as well as the default registry. The manifest maps each entry to
its component, original and derived source. CMake's
`sak_security_replace_source(component original generated)` handles replacement
without backend assumptions. The current registry uses this for three IDF
sources and the project-managed wolfSSH source described above. Update the
its component, optional nested target, original and derived source. CMake's
`sak_security_replace_source(component original generated nested_target)` handles
replacement on the actual source owner, not the IDF mbedTLS wrapper. The current
registry has six IDF sources and one project-managed wolfSSH source. Update the
corresponding library-specific feature/behavior tests when extending the registry. Multiple
sources in the same real component are supported by the replacement function.
@@ -98,7 +125,8 @@ python3 tests/sdk_security_overrides/run.py --build-dir .pio/build/esp32-s3-devk
Optional `--idf-path` selects an existing installed SDK. Tests need host `cc`,
CMake and Ninja; they install nothing, use temporary directories under `.pio/`, and never edit
the selected SDK. The second command also checks the existing real firmware
the selected SDK. Run the second command **after the parent runs `pio run`**;
old generated copies lack the new entries/notice and must not pass. It checks real firmware
Ninja registration: exactly one compilation of each derived source, no original
compilation, and exact generated bytes. It does **not** run a firmware build.
@@ -106,7 +134,8 @@ Coverage:
- Generator full-source hashes, version, missing/duplicate/ambiguous inputs,
exact edit counts, validation-before-output, unchanged-byte/mtime idempotence,
unsafe output rejection, and preserved upstream notices.
unsafe output rejection, centrally applied dated modification notice exactly
once on every source, and preserved upstream opening notices.
- Extracted **patched actual functions**, not reimplemented cleanup logic:
HTTPS allocation failure matrix; handshake failure; post-handshake allocation
failure; HTTPD start failure; normal close/stop; failed stop preserving ownership.
@@ -123,8 +152,25 @@ Coverage:
version limits, renegotiation enabled/compiled-out variants, untouched default
and caller-provided client suites. Every required feature is individually
removed in compile-failure tests; dynamic-buffer enablement also fails.
- Extracted DHCP parser: 196,623 guard-page cases covering empty/lone-code,
every option code/length with truncated and complete payloads, PAD, END, short
type/IP, DISCOVER/REQUEST/DECLINE/RELEASE, renew, matching/mismatching IP.
Compare the remaining-length variant with upstream pointer-form checks on
safely padded backing storage; post-loop state behavior is retained.
- Extracted TLS master calculation: SHA-256/SHA-384-sized transcript doubles,
untouched output and no PRF on hash failure (including unchanged length 64),
successful EMS, PRF failure, non-EMS and resumed-session behavior. This does not
execute actual hashes, the full handshake driver, or its failure destructor.
- Extracted X.509 parser and its actual attribute table/helpers, compiled against
installed mbedTLS headers: fault each allocation across separate subject/issuer
lists, partial-list cleanup, second-attribute OID failure, and successful retry.
Named-data storage/free are allocation-counted doubles; certificate signing,
writer destruction, persistence/publication and old-identity retention are not
exercised here. The three new C harnesses use UBSan trap instrumentation;
this does not require the host UBSan runtime.
- The actual CMake include under fake IDF target discovery, including missing and
duplicate sources/targets. A separate real host compile tests the project-root
duplicate sources/targets, nested target owner validation, and exact Ninja
compilation registration on both `mbedtls` and `mbedx509` (not their wrapper). A separate real host compile tests the project-root
extension, child-directory relative `SOURCES`, quoted and source-specific
includes, source/target flags and per-config source definitions. Changing that
fixture's original file makes the next ordinary build reconfigure and reject