- Add fail-closed wolfSSL small-math policy and vectors - Backport DHCP, EMS, and X.509 allocation fixes - Extend source override validation and operational documentation
4.9 KiB
Bounded CVE-2025-12888 mitigation
Scope: project-owned build configuration only, retaining wolfSSL 5.8.2~1 and wolfSSH 1.4.20 pins and unmodified managed sources. This is not an upstream upgrade, blanket security clearance, or mitigation of other listed advisories.
Upstream and installed evidence
On 2026-09-15, inspected official
PR9275 files
(PR, head reported by the files
API: c161cbd9f3fa1247382bb5b6269c7379222cabf5). Its settings.h patch
selects CURVE25519_SMALL, ED25519_SMALL, CURVE448_SMALL, and ED448_SMALL
under __xtensa__: Xtensa compilers have generated non-constant-time assembly
from the fast C implementation; upstream says the small implementation is not
known to have those issues. This is upstream mitigation guidance, not proof of
constant-time execution on our compiler/device.
Installed include/user_settings.h enables X25519 and Ed25519. Installed
wolfssl/wolfcrypt/settings.h automatically enables X25519 blinding only for
non-small math; wolfcrypt/src/curve25519.c rejects blinding with small math.
fe_low_mem.c and ge_low_mem.c provide the small implementations and already
have entries in the production compilation database. Small flags change public
key layout/signatures: never mix old library objects with newly compiled callers.
Root CMakeLists.txt sets both small flags before component processing, alongside
the existing global crypto controls. cmake/wolf_crypto_policy.cmake attaches a
forced-include resolved-settings guard to wolfSSL with PUBLIC propagation to its
consumers, including wolfSSH and application code. The guard rejects missing
algorithms/small flags, incompatible blinding, and future 448 enablement pending
explicit review. No blinding-disable macro or vendor source patch is needed.
RNG callback and software AES/SHA settings remain unchanged.
Commands
From the repository root, after the parent regenerates/builds the firmware:
python3 tests/wolf_crypto_policy/run.py
Optional explicit database:
python3 tests/wolf_crypto_policy/run.py --compile-commands .pio/build/esp32-s3-devkitc-1-n16r8/compile_commands.json
Strict mode requires the actual compile commands to carry the policy guard and
uses their actual compiler, include paths and definitions without adding small
flags. Missing/ambiguous entries, absent policy, wrong architecture, incompatible
macros, compiler errors and failed vectors fail the test. It preprocesses and
syntax-checks ten translation units: Curve25519, Ed25519, fast and small field/group
math, wolfSSH ssh.c, generated wolfSSH internal.c, application transport and
security. Two additional actual-settings checks remove each small flag and must
fail. It does not modify generated sources or compile databases.
Before the parent reconfigures, explicitly test the candidate using old commands:
python3 tests/wolf_crypto_policy/run.py --candidate
This injects the two small flags and the guard and labels its output CANDIDATE replay, not production configuration evidence. It does not run CMake/PlatformIO. Host-only subset:
python3 tests/wolf_crypto_policy/run.py --host-only
All modes run eight guard matrix cases and compile the installed vendor small
implementations into a temporary host executable: RFC7748 section 6.1 X25519
shared secret, RFC8032 section 7.1 test 1 Ed25519 empty-message verification, and
rejection of a corrupted signature. Host settings are deliberately minimal,
with streaming verification enabled and unused functions garbage-collected;
they are not the ESP-IDF runtime/entropy/hardware configuration. No synthetic
implementation substitutes for the tested arithmetic. Requirements: Python 3,
cc/linker, installed managed component; target checks also require the existing
Xtensa toolchain, generated headers and compile database. Commands are bounded;
temporary outputs are removed automatically.
Validation and remaining gates
Implemented validation: candidate replay passed all ten macro/syntax checks, eight guard cases, two real-settings rejection cases, and the three host vector checks. Initial host harness compilation exposed a disabled SHA256 declaration dependency and omitted small-math source files; the harness was corrected to use the installed small source files explicitly.
The parent must run the normal full build and then strict mode above. A build was explicitly not run for this task. Existing compile-database success alone would not prove the linked/flashed image matches it. No device operations were run. Still required: target SSH X25519 negotiation, Ed25519 authentication, rekey, combined service load, stack/heap reserves and handshake latency/deadline checks. Small implementations may reduce performance; no target timing, side-channel measurement, interoperability or resource claim is made. Host vectors are narrow correctness checks, not exhaustive cryptographic validation.