I'm using Golang's crypto package, crypto/aes specifically, with a 32 bytes key (so, AES-256) and the GCM method (Galois/Counter Mode).
I read from a file multiple chunks of 16384 bytes and generate a cipher block, a GCM method and a random nonce of 12 bytes.
Then, I prepend the nonce to the ciphertext in order to split them when decrypting, to access the nonce (because the size of 12 bytes is known).
One would expect that the generated ciphertext is 16384 + 12 bytes = 16396; but, when actually encrypting, I get a size of 16412 bytes, so 16 bytes are added. After I decrypt each chunk, I get the "normal" size of 16384.
Here's a fast example.
block, _ := aes.NewCipher([]byte("W9FLKnyv397R82kKuFpfp6y8usGRf49a"))
gcm, _ := cipher.NewGCM(block)
nonce = make([]byte, gcm.nonceSize()) // nonceSize is 12 bytes
_, _ = io.ReadFull(rand.Reader, nonce) // populate nonce with random data
for {
src := make([]byte, 1024 * 16) // let's hypotise this src is a chunk of a file, full of 1024 * 16 bytes, so 16384
encryptedBytes := gcm.Seal(nonce, nonce, src, nil) // this prepends the nonce to the src, thus adding 12 bytes in front of the encrypted string
/*
Now, encryptedBytes should be 16384 + 12 bytes long, but it is 16384 + 12 + 16.
If I want to decrypt a chunk of the encrypted bytes, I need to use the size of 16384 + 12 + 16 and this makes it unpractical.
*/
}
It doesn't seem to be because of padding (also because GCM does not use padding).
So, why does AES add 16 bytes to my ciphertext?