# Encrypting more than ~64GiB with AES-GCM - Integrity

I'm looking for solution to encrypt more than acceptable limit ~64GiB under same key with AES-GCM. I know I'm obligated to exchange nonces for each next ~64GiB chunk, but there is one thing that is bothering me. I need to keep also integrity of order of ~64GiB blocks, to disable block swaps. I was thinking about adding previous auth tag as AAD to next block. Is it enough? I can't find answer for this question anywere.

Thanks for help

The nonce is included in the computation of the tag.

If the nonce is incremented after each message, chunks cannot be reordered or duplicated. If the third message is expected to have been encrypted with nonce 3, the tag verification is not going to pass if a message encrypted with nonce 2 is provided instead.

One thing you need to detect, though, is when the last message has been received. It can be achieved by reserving a bit of the nonce to indicate this, as in the STREAM construction.

If the nonce is effectively a chunk index, the key can only be used once, as you don't want a (key, nonce) pair to repeat, especially with different messages.

So, you either need to use unique keys, or reserve part of the nonce as an IV (or message -not chunk- index), and the rest as a chunk index.

Individual chunks should have a reasonable size, if only because you don't want to download, store and verify 64 GB to finally discard everything due to a tag that doesn't verify. 16 KB and 64 KB are common sizes.

And, especially with AES-GCM, you may also want to frequently do key rotation.

If this is an option, just use TLS that will take care of all these things.

If you don't want to use TLS, but AES-GCM is not mandatory, a construction such as xchacha20-poly1305 is easier to use safely with large messages.

If you don't want to use TLS, and want to use AES-GCM, use the STREAM construction.

If you don't want to use TLS, AES-GCM is not a requirement, and you don't want to write the code, use libsodium's secretstream construction.

For more practical details on this topic, see Encrypting a set of related messages .

• Thank's for answer but that's not what I'was asking for. Maybe this picture will clarify my problem. link. I want to keep integrity of order of chunks, to avoid situation that chunk swap will lead to successful integrity verification during decryption. I also need cutting edge performance thats why im willing to use aes-gcm + hardware aes support. – user66005 Jun 18 '19 at 14:55
• If the nonce is incremented after each chunk, it doesn't have to be attached to the ciphertext. The decryption function will set it to an incrementing counter just like the encryption one. If chunks are swapped (or missing, or duplicated), tag verification will immediately fail, as it will be computed with a different nonce. – Frank Denis Jun 18 '19 at 15:18
• I think I understand what you mean. How can I increment nounce in technical point of view? It's 96 bits length where the rest 32 are used as cipher counter. Which part shall I increment? 96 bits wide or 32? – user66005 Jun 20 '19 at 9:19
• If you have a 96 bit IV, this is what you should increment. The implementation will take care of incrementing the internal counter. But I'd still recommend you use an existing implementation of stream encryption. (by the way, the word is "nonce" - number used once, not "nounce"). – Frank Denis Jun 20 '19 at 10:14
• You right "nonce" :). You clarified me some things. What about digital signing encrypted data in this scheme. I will have a lot of tags, e.g. assuming one tag every 64 KiB of encrypted data. It's rather bad solution to sign every tag of file, I don't want to check signature so often. Signing entire file after encryption will be slow. Can I add previous chunk tag as aad to next chunk and than sign only the last one? Seems cryptographicly correct. – user66005 Jun 20 '19 at 11:01