CVE-2026-19735: Predictable TCP initial sequence numbers when the RFC 6528 secret key generation fails silently in the Zephyr TCP stack
The RFC 6528 initial-sequence-number implementation in subsys/net/ip/tcp.c derived every TCP ISN from SHA-256(uniquekey || four-tuple) plus a uptime-derived offset, where uniquekey is a 128-bit secret filled once by syscsrandget(). The return value of that call was discarded and the once guard was latched to true even when the call failed. Because syscsrandget() leaves the destination buffer untouched on failure (it deliberately propagates the entropy-driver error rather than filling the buffer), a single failed call left uniquekey as its all-zero BSS content for the remainder of the boot, with no retry, no log message and no fallback.
A failure of the cryptographic random source is required to reach the weak state — for example -ENODEV/-EIO from the entropy driver in subsys/random/randomentropydevice.c (the in-tree comment notes that the hardware RNG "might still be gathering entropy during early boot situations"), or psageneraterandom() failing in subsys/random/randompsa.c when PSA crypto is not initialised or is backed by a Bluetooth-HCI entropy device that is not yet up. The first TCP connection is what triggers key generation, so a remote peer that reaches a listening port immediately after boot, or that can provoke a reboot, has indirect influence over whether generation coincides with that window. tcpinitisn() is called for every passive open in tcpconnnew() and every active open in nettcpconnect(), so the poisoned key governs all TCP connections for that boot.
With an all-zero key the ISN becomes a public function of the connection four-tuple plus a device-wide time offset. An off-path attacker can compute the hash term offline for any four-tuple and recover the shared time offset from a single observed ISN, after which the ISN the device will pick for other four-tuples is predictable. That defeats exactly the protection RFC 6528 provides: blind TCP connection spoofing against peers that trust the source address, and blind data injection into or reset of connections whose four-tuple can be guessed. Devices whose entropy source never errors were never in the weak state.
The fix moves key generation into a single guarded helper that latches only on success, logs the error otherwise, and makes tcpinitisn() fall back to sysrand32get() — the behaviour already used when CONFIGNETTCPISNRFC6528 is disabled — instead of hashing with a known-constant key.
Affected Software
Event History
Frequently Asked Questions
Under what conditions does the weak state occur?
It requires sys_csrand_get() to fail when the TCP stack first generates its secret key. Examples described include an unavailable or failing entropy driver during early boot, PSA crypto not being initialized, or a Bluetooth-HCI entropy source that is not yet up.
How long does the condition persist after the random-source failure?
The all-zero key remains in use for the rest of the boot. The initialization guard is set even on failure, so there is no retry, fallback, or later replacement of the key.
Which TCP activity can trigger the condition?
The first TCP connection triggers key generation. A remote peer able to reach a listening service can therefore cause the initial attempt while the random source is failing or not ready.
Can operators rely on logs to determine whether this occurred?
No. The random-source return value was discarded, and the described behavior produces no log message, so a lack of logging does not indicate that key generation succeeded.