CVE-2026-59644 Overview
CVE-2026-59644 is a denial-of-service vulnerability in Bouncy Castle for Java versions before 1.85. The flaw resides in the Messaging Layer Security (MLS) implementation, where the hash-ratchet honours an arbitrary 32-bit generation counter supplied by the sender. An attacker who can deliver a crafted MLS message can force the receiver to execute up to 2^32 HKDF-derivation steps, exhausting CPU resources. The issue is tracked under CWE-834: Excessive Iteration and affects any Java application that uses the Bouncy Castle MLS library for group messaging.
Critical Impact
Remote attackers can trigger unbounded key derivation with a single crafted message, exhausting CPU on the receiving MLS endpoint without authentication.
Affected Products
- Bouncy Castle for Java, all versions before 1.85
- org.bouncycastle.mls.GroupKeySet component (MLS module)
- Java applications using Bouncy Castle MLS group messaging APIs
Discovery Timeline
- 2026-08-03 - CVE CVE-2026-59644 published to NVD
- 2026-08-04 - Last updated in NVD database
Technical Details for CVE-2026-59644
Vulnerability Analysis
Bouncy Castle's MLS implementation uses a hash ratchet to derive per-message encryption keys. Each message carries a generation counter, and the receiver advances the ratchet one HKDF-derivation step per skipped generation to reach the requested key. The pre-1.85 implementation accepts the full 32-bit generation value from the wire without bounding the forward gap.
An authenticated group member can send a message whose generation counter jumps far ahead of the current ratchet state. The receiver then performs up to 2^32 sequential HKDF derivations to catch up. This drives CPU utilisation on the receiver to saturation and blocks the MLS processing thread.
The vulnerability affects availability only. Confidentiality and integrity of MLS traffic are not impacted, because the generation counter is authenticated as part of the sender's framing.
Root Cause
The root cause is the absence of an upper bound on forward ratchet steps in HashRatchet.get(generation). Legitimate protocol gaps caused by out-of-order delivery are small, typically fewer than a handful of steps. The implementation trusted the sender-supplied counter without validating it against a realistic upper bound.
Attack Vector
A network-adjacent attacker who is a member of an MLS group, or who can inject an authenticated MLS ciphertext, sends a message with a maximal generation value. The receiver's HashRatchet enters a tight HKDF loop and consumes CPU until it either completes or the process is terminated. No user interaction is required.
// Source: https://github.com/bcgit/bc-java/commit/610d8757d855afe197df0de6d831cb75c81e3b9f
// Patch in mls/src/main/java/org/bouncycastle/mls/GroupKeySet.java
public class HashRatchet
{
+ // get(generation) advances one HKDF-derivation step per skipped generation, and the requested
+ // generation arrives (authenticated) from the wire. Cap the forward gap so a crafted generation
+ // cannot drive unbounded key derivation (CPU exhaustion); legitimate gaps are far smaller.
+ private static final int MAX_FORWARD_RATCHET_STEPS = 1 << 16;
+
final int keySize;
final int nonceSize;
Secret nextSecret;
The fix caps MAX_FORWARD_RATCHET_STEPS at 1 << 16 (65,536), which is well above any legitimate gap but bounds worst-case CPU cost.
Detection Methods for CVE-2026-59644
Indicators of Compromise
- Sustained 100% CPU utilisation on a single JVM thread processing MLS messages
- Java thread dumps showing repeated frames inside HashRatchet.get or HKDF derivation routines
- MLS message logs containing generation counter values that are orders of magnitude ahead of the current ratchet state
Detection Strategies
- Inventory Java applications and container images for bcprov, bctls, or bcmls JAR files at versions below 1.85 using software composition analysis.
- Add runtime instrumentation or logging around MLS message handling to record inbound generation counters and flag deltas above a small threshold, for example 1,024.
- Correlate sudden CPU spikes on MLS-processing services with recent inbound message events from specific group members.
Monitoring Recommendations
- Monitor JVM CPU time per thread and alert when a single thread exceeds a sustained utilisation threshold for more than 30 seconds.
- Log and centralise MLS framing metadata, including sender identifier and generation counter, so that anomalous jumps can be investigated after the fact.
- Track dependency updates for org.bouncycastle:bcprov-* and related artifacts in CI pipelines to confirm the fixed 1.85 baseline is enforced.
How to Mitigate CVE-2026-59644
Immediate Actions Required
- Upgrade Bouncy Castle for Java to version 1.85 or later across all applications, services, and container images.
- Audit third-party libraries and frameworks that bundle Bouncy Castle transitively, and force-override the version where dependency resolution pulls in an older artifact.
- Restart JVM processes after upgrading to ensure the patched HashRatchet class is loaded.
Patch Information
The fix is available in Bouncy Castle for Java 1.85. See the GitHub commit details and the CVE-2026-59644 wiki entry for the upstream advisory. The patch introduces MAX_FORWARD_RATCHET_STEPS = 1 << 16 in GroupKeySet.java to cap forward ratchet advancement.
Workarounds
- If immediate upgrade is not feasible, wrap MLS message processing in a bounded executor with a per-message CPU or wall-clock timeout to contain runaway derivations.
- Reject or quarantine inbound MLS messages whose generation counter exceeds the current ratchet state by more than a small application-defined limit before passing them to Bouncy Castle.
- Restrict MLS group membership to trusted principals until the patched version is deployed, reducing the population of endpoints that can send crafted messages.
# Maven dependency override to enforce the patched version
mvn dependency:tree | grep bouncycastle
# Force Bouncy Castle 1.85 in pom.xml <dependencyManagement>
# <dependency>
# <groupId>org.bouncycastle</groupId>
# <artifactId>bcprov-jdk18on</artifactId>
# <version>1.85</version>
# </dependency>
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

