Hello again, I think the implementation of GCM cipher should respect the > specification of GCM mode. Before authentication tag get checked, no > plaintext should be released to application. See section 7.0 of GCM spec > (NIST SP-800-38D). >
Wow! Strictly speaking, it seems like the GCM spec actually says that: "In Step 8, the result of Step 7 is compared with the authentication tag that was received as an input: if they are identical, then the plaintext is returned; otherwise, FAIL is returned". So I guess we are at a deadlock: - Implementing it so that it can be used in practice (esp. for large files) does not comply with the specification, b/c it returns unauthenticated bytes and only throws a bad tag exception at the end - And implementing it as defined per specification is theoretically correct, but completely unusable for large files, because it requires a memory buffer of the size of the file Before this dies out entirely (again), here's what I understand is the status quo: - Using javax.crypto.CipherInputStream with a cipher in GCM mode and the BC provider is insecure, because tampering is possible! - Using javax.crypto.CipherInputStream with a cipher in GCM mode and the SunJCE provider (JDK8+) is secure, but cannot be used large files, because it will buffer all data until the tag is verified (as defined by the GCM spec) [1] - Using org.bouncycaslte.crypto.io.CipherInputStream with a cipher in GCM mode and the BC provider is secure and can be used for large files. However it does not work exactly like the GCM spec defined; namely, it returns unauthenticated data before the tag has been checked. Do you think it would be possible to at least mention possible issues like this in the JavaDoc for CipherInputStream? Thanks for the interesting discussion! Best Philipp [1] http://hg.openjdk.java.net/jdk8/build/jdk/file/687fd7c7986d/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java