Skip to content

CVE‐2026‐71884

David Hook edited this page Oct 2, 2026 · 1 revision

Title: Packet CTR reports a full success length after the counter is exhausted.

Issue affecting: BC-LTS before 2.73.13 (from 2.73.4), on Intel platforms with native support enabled.

Fixed versions: BC-LTS 2.73.13.

Platform affected: Java 8 and later, x86 / x86-64 with the native library in use.

Bouncy Castle for Java (bcprov) is not affected — it ships no native implementations, and the one-shot packet ciphers exist only in the LTS distribution.

In CTR mode the IV and the block counter share one 16-byte block, so a longer IV leaves a shorter counter. An IV of 13 to 15 bytes leaves a counter of 1 to 3 bytes, which can address only 256, 65536 or 16777216 blocks; a caller-sized input can run past that, at which point the counter wraps and the keystream starts repeating from the beginning of the same packet.

The streaming path validates twice, at init and again as bytes are processed, and the portable AESCTRPacketCipher rejects an over-long request outright with "Counter in CTR/SIC mode out of range.". The native one-shot path has a single entry point and has to do all of its validation there — and it never checked the IV-derived counter range at all. It encrypted the whole input with a keystream that repeated, and then returned the full input length, reporting success for every byte.

Two segments of the message were therefore encrypted under the same keystream. Their XOR is the XOR of the two plaintexts, so an observer who holds only the ciphertext can recover them by standard means, without the key. The caller had no signal that anything was wrong: no exception, and a returned length that matched what was asked for.

ctr_pc_process_packet now preflights the counter range before any output is written — for a counter of 1 to 3 bytes it computes the addressable byte count and rejects a longer request with "Counter in CTR/SIC mode out of range.", matching the portable implementation — so the operation is failure-atomic and never reports success for bytes it did not correctly transform. A counter of four bytes or more cannot be exhausted by a Java int length and is unaffected, as is a full 16-byte IV, where the counter range is the caller's responsibility.

Clone this wiki locally