-
Notifications
You must be signed in to change notification settings - Fork 1.3k
CVE‐2026‐71883
Title: Native AES packet cipher returns the raw AES key on an alias.
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.
The packet ciphers take the key, the IV, the additional authenticated data, the input and the output in a single JNI call, which gives them an aliasing hazard the streaming bridges do not have: nothing stops an application passing the same Java array as both an input and the destination. Encrypting in place over KeyParameter.getKey() is the case that matters.
The JNI entry points took the read-only arrays through GetByteArrayElements and released them with ReleaseByteArrayElements(..., 0). Mode 0 commits the native copy back into the Java array, and on a JVM that hands out a copy rather than a pin, that copy still holds the key bytes as they were read in. The output is taken through a separate critical region and released first, so the ordering was: write the ciphertext into the output array, commit it, then commit the stale key over the top of it.
An application that encrypted in place over its own key array therefore received the raw AES key where it expected ciphertext — and the call still returned the correct output length, so nothing in the API indicated that anything had gone wrong. Whatever the application then did with that buffer, it did with the key: transmitted it, wrote it to disk, or handed it to a peer as the message.
All six affected entry points — cbc_pc_jni.c, ccm_pc_jni.c, cfb_pc_jni.c, ctr_pc_jni.c, gcm_pc_jni.c and gcm_siv_pc_jni.c — now release every read-only input array with the new release_bytearray_ctx_unchanged, which uses JNI_ABORT and so frees the native copy without copying it back. Mode 0 is now reserved for arrays the native code actually wrote. The pure-Java packet ciphers and the streaming native modes were never affected.