Add Phase 9C security hardening

Generate exact-hash SDK source overrides without modifying dependencies.
Harden
SSH allocation and algorithm policy, tighten web authentication cleanup,
and add
focused host contract tests and documentation.
This commit is contained in:
2026-09-15 22:12:57 +02:00
parent 751dfb9ddb
commit cdc9c7335a
41 changed files with 3597 additions and 89 deletions
+59
View File
@@ -0,0 +1,59 @@
# SSH memory hook tests
Run from the repository root:
```sh
CCACHE_DISABLE=1 python3 tests/ssh_memory/run.py
```
Optionally verify the installed, audited SDK source contract too (no downloads):
```sh
CCACHE_DISABLE=1 python3 tests/ssh_memory/run.py --idf-path /home/mscholz/.platformio/packages/framework-espidf
```
The runner compiles the actual `src/ssh_memory.c` and extracts the actual volatile
`secure_wipe()` body from `src/secure_random.c`. Only SDK headers and heap calls
are doubled. Temporary build files stay outside the repository. `CC` and `CFLAGS`
are supported; the runner also forces `CCACHE_DISABLE=1` for child processes.
Coverage:
- NULL free, malloc/realloc NULL and zero-size delegation, secure zero-size free.
- Rounded usable capacity larger than the original request; whole-capacity wipe
checked **before** the fake heap actually frees the backing allocation.
- Equal-capacity and shrink pointer retention, discarded-tail wiping, unchanged
prefix, retained capacity and logical regrowth without allocation.
- Growth copies every byte of the old usable extent, including rounding, without
over-copying into the new suffix. Both allocations are live during growth.
- PSRAM-first/internal-fallback capability order on every allocation; successful
fallback and migration back to preferred PSRAM on a later growth.
- Failed allocation/growth leaves the old pointer and full contents live and
unchanged, with no SDK realloc fallback (none is supplied by the test).
- Base-pointer-only extent queries, live-pointer checks, aligned payloads and
prefix/suffix guards, request sizes unchanged including `SIZE_MAX`.
- Six rejected poisoning configurations, explicit-zero inactive options, and
four rejected IDF versions. The supported profile is unpoisoned IDF 5.5.0.
- Optional exact normalized function-body contracts for installed heap extent
queries/TLSF size accessor, public declaration and implementation alias; compile
the module with the installed IDF version header. This is a narrow source
contract check, not execution of the target SDK heap or a complete heap audit.
## Integration and limits
The parent must add `ssh_memory.c` to its build and register these three hooks
before wolfSSH/wolfSSL allocations begin. This change does not integrate them.
There are no production headers preceding allocations, metadata tables, locks or
additional tasks. Allocator alignment and allocation-size failure semantics are
preserved by passing the size straight to `heap_caps_malloc_prefer()`. A shrink
retains capacity rather than reclaiming heap; growth temporarily needs old plus
new allocations. PSRAM remains preferred, but internal fallback can transiently
need the full new allocation while the old one is still live. No runtime reserve
or hardware performance claim follows from these host tests.
Heap poisoning is deliberately unsupported: its canary layout is not compatible
with blindly wiping a rounded extent. The version guard requires re-audit on SDK
updates. Cleanup covers retired allocations and explicit realloc tails, not
still-live library buffers, parser spans, stack temporaries or all library
secrets. Hardware validation is deferred to whole-phase testing.