CVE-2026-19735
Beschrijving NL
De RFC 6528 initial-sequence-number implementatie in subsys/net/ip/tcp.c is afgeleid van elke TCP ISN van SHA-256(unique_key || four-tuple) plus een uptime-afgeleide offset, waarbij unique_key een 128-bits geheim is dat eenmaal is ingevuld door sys_csrand_get(). De retourwaarde van dat gesprek werd weggegooid en de eenmaal bewaker werd op true vergrendeld, zelfs wanneer het gesprek mislukte. Omdat sys_csrand_get() de bestemmingsbuffer onaangeroerd laat bij falen (het verspreidt opzettelijk de entropie-stuurprogrammafout in plaats van de buffer te vullen), liet een enkele mislukte aanroep unique_key achter als de volledig nul BSS-inhoud voor de rest van de boot, zonder opnieuw te proberen, geen logbericht en geen terugval. Een storing van de cryptografische willekeurige bron is vereist om de zwakke toestand te bereiken — bijvoorbeeld -ENODEV/-EIO van de entropie-driver in subsys/random/random_entropy_device.c (de opmerking in de boom merkt op dat de hardware-RNG "mogelijk nog steeds entropie verzamelt tijdens vroege opstartsituaties"), of psa_generate_random() faalt in subsys/random/random_psa.c wanneer PSA-crypto niet is geïnitialiseerd of wordt ondersteund door een Bluetooth-HCI-entropieapparaat dat nog niet is ingeschakeld. De eerste TCP-verbinding is wat sleutelgeneratie activeert, dus een externe peer die onmiddellijk na het opstarten een luisterpoort bereikt, of die een reboot kan uitlokken, heeft indirecte invloed op de vraag of de generatie samenvalt met dat venster. tcp_init_isn() wordt aangeroepen voor elke passieve open in tcp_conn_new() en elke actieve open in net_tcp_connect(), dus de vergiftigde sleutel regelt alle TCP-verbindingen voor die boot. Met een nul-toets wordt de ISN een openbare functie van de viervoudige verbinding plus een apparaatbrede tijdverschuiving. Een off-path-aanvaller kan de hash-termijn offline berekenen voor elke vier-tupel en de gedeelde tijdsverschuiving herstellen van een enkele waargenomen ISN, waarna de ISN die het apparaat voor andere vier-tupels zal kiezen voorspelbaar is. Dat verslaat precies de bescherming die RFC 6528 biedt: blinde TCP-verbindingsspoofing tegen peers die het bronadres vertrouwen, en blinde gegevensinjectie in of reset van verbindingen waarvan het viervoudige kan worden geraden. Apparaten waarvan de entropiebron nooit fouten bevatte, bevonden zich nooit in de zwakke toestand. De oplossing verplaatst het genereren van sleutels naar een enkele bewaakte helper die alleen op succes klikt, de fout anders registreert en tcp_init_isn() terug laat vallen op sys_rand32_get() — het gedrag dat al wordt gebruikt wanneer CONFIG_net_TCP_ISN_RFC6528 is uitgeschakeld — in plaats van hashing met een bekende constante sleutel.
Origineel (Engels) tonen
The RFC 6528 initial-sequence-number implementation in subsys/net/ip/tcp.c derived every TCP ISN from SHA-256(unique_key || four-tuple) plus a uptime-derived offset, where unique_key is a 128-bit secret filled once by sys_csrand_get(). The return value of that call was discarded and the once guard was latched to true even when the call failed. Because sys_csrand_get() leaves the destination buffer untouched on failure (it deliberately propagates the entropy-driver error rather than filling the buffer), a single failed call left unique_key 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/random_entropy_device.c (the in-tree comment notes that the hardware RNG "might still be gathering entropy during early boot situations"), or psa_generate_random() failing in subsys/random/random_psa.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. tcp_init_isn() is called for every passive open in tcp_conn_new() and every active open in net_tcp_connect(), 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 tcp_init_isn() fall back to sys_rand32_get() — the behaviour already used when CONFIG_NET_TCP_ISN_RFC6528 is disabled — instead of hashing with a known-constant key.