This encryption mode is described in [AES-GCM].
One of the undesirable properties of AES-GCM is that reusing the same IV for the same key leaks the authentication key [Joux-Gcm]. Typically, implementations can't enforce that users don't repeat IVs unless they use restricted interfaces. However, implementations should at least avoid features that increase the probability of incorrect usages.
One such dangerors featur in JCA is that the default behaviour of Cipher.doFinal is to reinitialize the cipher with the same parameters as the last encryption. For AES-GCM this behaviour would imply that the authencation key is leaked. Therefore, any reasonable implementation of AES-GCM should not allow two encryptions without an explicit initialization of the IV.
The expected behaviour of OpenJDK can be derived from the tests in jdk/test/com/sun/crypto/provider/Cipher/AES/TestGCMKeyAndIvCheck.java: OpenJDK does not allow two consecutive initializations for encryption with the same key and IV.
The counter value in AES-GCM wraps around after
Incrementing counters in AES-GCM is different than incrementing counters in
AES-CTR. AES-GCM increments counters modulo
0xffffffffffffffffffffffffffffffff
then the counter for the next block in AES-GCM is
0xffffffffffffffffffffffff00000000
But for AES-CTR the counter for the next block is
0x00000000000000000000000000000000
For AES-GCM the typical IV size is 12 bytes. For this size of the IV the counter
starts as IV || 00000001
. AES-GCM allows no ciphertexts longer than
When an implementation of AES-GCM is handling CTR overflows incorrectly (e.g.
reuses code from an AES-CTR implementation) then encrypting with an IV of size
other than 12 bytes may result in incorrect ciphertext. This happens on average
once every
Encrypting with a faulty version of the code results in incorrect ciphertext, which can be decrypted again with the same faulty version of the code. When trying to decrypt with a correct version of AES-GCM then the authentication passes (since the authentication tag is computed over the ciphertext and thus unaffected by incorrect encryption), but the decrypted plaintext is incorrect. The situation where encryption is correct, but decryption is faulty is similar: the authentication passes, but the plaintext is wrong.
Besides returing incorrect plaintext, this bug can leak the authentication key.
One scenario where this bug is exploitable is the following: We assume that
there is a client-server scenario where either the client or the server use a
faulty encryption rsp. decryption (but not both). We assume that the client
sends AES-GCM encrypted messages of about 1 MB (i.e. 0x????????????????????ffff????
, where ? or unknown nibbles. The initial
counter J0 is computed over
If the size of the encrypted messages is smaller, then less corrupt messages are necessary but more encryptions are necessary until sufficiently many bugs occur. The attack is a bit simpler if an attacker also learns the approx. position where the decrypted plaintext starts to become incorrect. Overall, approx. 200-600 GB of data needs to be encrypted with the same key so that the attack here gets enough information to derive the authentication key.
The attack above is just one way to exploit the weakness. Other attack scenarios might be possible, but I haven't explored them. In particular the attack above is passive. The attacker just needs the ability to observe an encrypted connection. The tag size is irrelevant.
Under the assumption that chosen ciphertext attacks are possible it might be possible to combine the attack above with Fergusons attack https://csrc.nist.gov/csrc/media/projects/block-cipher-techniques/documents/bcm/comments/cwc-gcm/ferguson2.pdf and attack connections with frequent key rotations.
Since GHASH is linear function it easy to construct test vectors where the
counter overflow occurs within the first few increments. (I.e. one fixes
key : "00112233445566778899aabbccddeeff",
iv : "dd9d0b4a0c3d681524bffca31d907661",
aad : "",
msg : "00000000000000000000000000000000000000000000000000000000000000000000000000000000",
ct : "64b19314c31af45accdf7e3c4db79f0d948ca37a8e6649e88aeffb1c598f3607007702417ea0e0bc",
tag : "5281efc7f13ac8e14ccf5dca7bfbfdd1",
The AES-GCM implementation in jdk9 handled CTR overflows incorrectly [CVE-2018-2972].
AES-GCM allows IVs of bit length
Disallowing IVs of length 0 is necessary. If an empty IV is used then the tag is an evaluation of a polynomial with the hash subkey as the value. Since the polynomial can be derived from the ciphertext it is known to an attacker. Therefore, any message encrypted with an empty IV leaks the hash subkey. In particular, encrypting an empty plaintext with an empty IV results in a ciphertext having a tag that is equal to the hash subkey used in AES-GCM. I.e. both are the same as encrypting an all zero block.