Repository navigation
Conversation
hubot
pushed a commit
that referenced
this pull request
Oct 23, 2026
… payload rather than the input less 16 bytes, and the B0 length field is written as exactly q bytes, relates to github #2499.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CCMBlockCipher.processPacket(core/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java:278) refuses a payload of 2^(8q) bytes or more, q being 15 minus the nonce length (NIST SP 800-38C sec. A.1). On decryption it first subtractsinputAdjustmentfrominLen(:303), and onmainthat is the constant1 /* flags */ + 15 /* n + q */(:300), under the comment "input includes 16 additional bytes: CCM flags and n+q values." The decryption input is the payload followed by the tag, not B0, so the bytes to subtract aremacSize. The two agree only for a 16 byte tag, which is all the boundary loop added with the fix for #1570 (5c19683) covers (CCMTest.java:165).With a shorter tag t, decryption admits payloads of up to 2^(8q) + 15 - t bytes, where encryption stops at 2^(8q) - 1, and
calculateMac(:411) writes that length into B0 with a loop (:435) that runs until the length is zero, not for q bytes, so the extra length byte overwrites the last nonce byte.Reproduced on released 1.86 and the 1.87-SNAPSHOT beta (1.87.0.20737);
mainhas the same source. With a 13 byte nonce (q = 2) and an 8 byte tag, a 65536 or 65543 byte payload tagged over that B0 decrypts to the plaintext throughprocessPacketandprocessBytes/doFinal, the 65543 byte one also through the provider'sAES/CCM/NoPadding. 65544 bytes is refused withIllegalStateException"CCM packet too large for choice of q", as is 65536 bytes on encryption for every tag length. Such a ciphertext needs a tag made under the key over that malformed B0, which BC's own encryption never produces, so this is a consistency fix, not a security one.This change:
inputAdjustment = macSizeon decryption (:300), so both directions apply the same limit and an over-limit ciphertext is refused before its tag is checked, with theIllegalStateExceptionencryption already throws; andpayloadLengthLimitTesttoCCMTest: the largest payload round-trips with a 64 bit tag, one byte more is refused on encryption, and a ciphertext carrying 2^16 payload bytes is refused on decryption before the tag check for tags of 32 to 128 bits.A ciphertext in that window that fails its tag now gets
IllegalStateExceptioninstead ofInvalidCipherTextException"mac check in CCM failed" (AEADBadTagExceptionthrough the provider), as longer input already does. Payloads within the limit, and all 16 byte tags, are unaffected.The new test fails without the change (
over-limit ciphertext reached the tag check, tag length 32) and passes with it; the existingCCMTestchecks still pass. Across the core and provRegressionTest.testsarrays onlyCCMTestchanges status (without a bc-test-data checkout, the 22 core and 5 prov entries that need it could not run).:core:checkstyleMainis clean.Base tree only: one
CCMBlockCipher.java, noMETA-INF/versionscopy, nomodule-infoor OSGi change. A release-note entry is included, happy to move it to another block.