bc-java icon indicating copy to clipboard operation
bc-java copied to clipboard

Larger 3DES encrypted PGP files fail to decrypt using bc-fips 2.0.0

Open HubertOT opened this issue 7 months ago • 4 comments

Since the upgrade of bc-fips 1.0.x to bc-fips 2.0.0 larger 3DES PGP encrypted files fail to decrypt with stack trace: java.lang.IllegalStateException: attempt to process more than 65536 blocks with 2-Key TripleDES at org.bouncycastle.crypto.fips.DesEdeEngine.processBlock(Unknown Source) at org.bouncycastle.crypto.internal.modes.CFBBlockCipher.decryptByte(Unknown Source) at org.bouncycastle.crypto.internal.modes.CFBBlockCipher.calculateByte(Unknown Source) at org.bouncycastle.crypto.internal.StreamBlockCipher.processBytes(Unknown Source) at org.bouncycastle.crypto.internal.io.CipherOutputStreamImpl.write(Unknown Source) at org.bouncycastle.crypto.UpdateOutputStream.update(Unknown Source) at org.bouncycastle.jcajce.provider.BaseCipher.engineUpdate(Unknown Source) at java.base/javax.crypto.Cipher.update(Cipher.java:1872) at org.bouncycastle.jcajce.io.CipherInputStream.nextChunk(Unknown Source) at org.bouncycastle.jcajce.io.CipherInputStream.read(Unknown Source) at org.bouncycastle.bcpg.BCPGInputStream.read(Unknown Source) at org.bouncycastle.openpgp.PGPEncryptedData$TruncatedStream.read(Unknown Source) at org.bouncycastle.util.io.TeeInputStream.read(Unknown Source) at org.bouncycastle.bcpg.BCPGInputStream.read(Unknown Source) at org.bouncycastle.openpgp.PGPCompressedData$1.fill(Unknown Source) at java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158) at org.bouncycastle.bcpg.BCPGInputStream.read(Unknown Source) at org.bouncycastle.bcpg.BCPGInputStream$PartialInputStream.read(Unknown Source) at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:244) at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:263) at org.bouncycastle.bcpg.BCPGInputStream.read(Unknown Source)

Smaller (<512Kb) 3DES encrypted files decrypt successfully.

Questions:

  1. Why does a ‘forEncryption’ limit block decryption in DesEdeEngine, this seems a bug? (Is cipher.init(true, ...) a bug, in init() in org.bouncycastle.crypto.internal.modes.CFBBlockCipher etc., especially seeing that e.g. CBCBlockCipher does cipher.init(encrypting, ...) instead?)
  2. Why does TripleDES encryption have an 8 MB = 1M blocks limit, in BCFIPS 1.0.x, in org.bouncycastle.crypto.fips.DesEdeEngine in processBlock()? (bcprov doesn’t have it, it seems?) Where is this documented?
  3. Why was this limit changed, to 512 KB = 65,536 blocks, in BCFIPS 2.0.0+? Is this related to the switch to FIPS 140-3 (from FIPS 140-2)? Where is this documented?

HubertOT avatar May 23 '25 04:05 HubertOT

Consult NIST.SP.800-131Ar2 Section 2 for the restrictions on TDEA ("TripleDES").

Yes, it is correct for CFBBlockCipher to always init the underlying DesEdeEngine in forward (encryption) mode; that is how CFB works.

However, given that the TDEA restriction is in relation to "applying cryptographic protection", my first impression is that it is overly zealous to apply this restriction when the DesEdeEngine is being used as a part of CFB decryption.

Thanks for the report, we will look into this further.

peterdettman avatar May 23 '25 05:05 peterdettman

Please note, new data encryption in FIPS applications has been disallowed since December 2023.

If this is legacy data I would recommend using the regular BC provider which does not currently enforce the limit, but will likely have to eventually as, at least in a FIPS context at the moment, use of TDEA on larger files is regarded as unsafe and that the limit was introduced in SP 800-67 Rev 2 in 2017. If the data is recently encrypted you need to go to whoever it is that is sending the files to you and tell them to stop. Note that "recently" means any time after November 2017.

dghgit avatar May 26 '25 02:05 dghgit

@dghgit Thanks! (In this specific case we use bc-fips in a non-FIPS environment.)

That answers question # 2. And question # 1 was answered / is being looked at by @peterdettman.

We are still curious about question # 3. In terms of that spec you pointed us to, what we are curious about is why BCFIPS 2.0.0, when it allows 3DES = TDEA, is more strict than that NIST SP 800-67 Rev. 2? That standard, when it was still in force up until 2023, allowed 1 << 20 blocks, and BCFIPS 1.0.* implemented that, but BCFIPS 2.0.0 lowered that to 1 << 16.

(I did see a prerelease version of BC-FJA-SecurityPolicy-2.0.0.pdf with a footnote that says that for Triple-DES, a "216 block limit is enforced by the module, 2-key encryption is disabled.")

marnix avatar May 26 '25 11:05 marnix

FIPS 140-3 Implementation Guidance "Section W.3 (was C.G) SP 800-67rev2 Limit on the Number of Encryptions with the Same Triple-DES Key" reduced it 1 << 16.

There was some allowance in the IG for use with IETF protocols if they were explicitly listed in the security policy, however there are a few caveats, and even this Section is withdrawn from April 18th 2025 (so yes, over a month ago). Our lab's advice, which I still agree with, is if we had left 1 << 20 in place, we would be facing a move onto the historical list if we didn't reduce it to 1 << 16 by the withdrawal date, which would have meant doing a module update. From the points of view that the cipher was going to be disallowed in FIPS from the start of 2024, that the 1 << 20 limit offered in some circumstances by the IG was at best a temporary stay of execution, and there was a fallback using regular BC, it did not seem worth trying to preserve 1 << 20, and certainly feedback we got from people who were using the early access module at the time did not indicate this was going to be an issue.

I appreciate this is tough pill for some to swallow, but Triple-DES is dead. ACVP still allows for testing decryption, but the moment they drop that the only thing that will happen if we do a module update will be that we will be told to remove Triple-DES from approved mode altogether, and this is coming. There's an update to AES on the way to expand the block size to 256 bits, I can't see anyway at this stage that use of a 64 bit block size cipher can survive for much longer.

And as I have already mentioned, in a FIPS context, no one is supposed to have been encrypting data with T-DES since end of 2023 at all, so for FIPS BC the real question isn't about the number of blocks, the question is why is the cipher in use at all?

dghgit avatar May 26 '25 14:05 dghgit

Appears resolved. Farewell Triple-DES...

dghgit avatar Aug 13 '25 04:08 dghgit