If I use for example AES-256 (GCM), and my message is bigger than 256 bit (broken into smaller 256 bit blocks for encryption), should the IV change for every 256 bits of the message?
2 Answers
The IV for GCM mode, in this case the thing we call the Nonce, is different from the IV used for the CTR mode inside of GCM.
Additionally as per the wording of your question, AES256 has a 256-bit key and a 128-bit block, not a 256-bit block, and encrypts plaintext in 128-bit increments.
For GCM, you MUST use a unique Nonce for every message. Inside GCM, the Nonce is turned into the CTR IV. If you look at kelalaka's answer, if the Nonce is 96-bits, the CTR IV is the exact same thing. If it is some other size, it converts it to a 96-bit IV using the referenced algorithm. CTR mode uses the IV plus a counter starting at 1 to generate the stream. The 96-bit IV plus the 32-bit counter equal the 128-bit input block to the cipher.
([ IV ][ctr1]) -----> [AES] -----> ([ STREAM1 ])
The output 128-bit stream block is used to encrypt the plaintext blocks. If there are multiple blocks of plaintext, only one can be encrypted with a given counter, so it is incremented by 1, and the same operation is repeated to generate the next 128-bit stream block. If the final plaintext block is shorter than 128-bits, the unused stream bits are discarded.
MESSAGE = ([ PLAINTEXT1 ][ PLAINTEXT2 ][ PLAINTEXT3 ])
AUTHDAT = additional data to authenticate
LEN_T = desired length of authentication tag
L = length_64(AUTHDAT) || length_64(MESSAGE)
NONCE = 96-bits, therefore IV=NONCE
H = AES_K(0x00000000000000000000000000000000)
ctr0 = 0x00000001, ctr1 = 0x00000002, and so on
([ IV ][ctr0]) -----> [AES] -----> ([ STREAM0 ])
([ IV ][ctr1]) -----> [AES] -----> ([ STREAM1 ])
([ IV ][ctr2]) -----> [AES] -----> ([ STREAM2 ])
([ IV ][ctr3]) -----> [AES] -----> ([ STREAM3 ])
([ PLAINTEXT1 ]) XOR ([ STREAM1 ]) = ([ CIPHERTXT1 ])
([ PLAINTEXT2 ]) XOR ([ STREAM2 ]) = ([ CIPHERTXT2 ])
([ PLAINTEXT3 ]) XOR ([ STREAM3 ]) = ([ CIPHERTXT3 ])
CIPHERTEXT= ([ CIPHERTXT1 ][ CIPHERTXT2 ][ CIPHERTXT3 ])
H = GHASH(H,AUTHDAT,CIPHERTEXT,L)
TAG = truncate_LEN_T( H XOR STREAM0 )
As many blocks are generated as required to encrypt all the plaintext, as long as the limit of GCM is not reached, which is 549,755,813,632 bits, or 256 bits less than 64GiB, as explained here.
- 13,278
- 1
- 26
- 42
AES-GCM uses the Counter (CTR) mode for AES. If you use an SP 800-38D compatible library, actually, it handles the incrementing the IV for you.
For an encryption session, once the IV is initialized the counter part (32-bit part) of the IV is incremented for the encryption of every block. The IV fot CTR mode start from 2 as mentioned Maarten's comment. Thus, encryption can be continued until the counter is reached to the maximum, that is $2^{32}-2$ AES blocks if 32-bit counter is used. Then, you have to use a new IV to continue.
The real problem is generating the IV's uniquely per session. If IV ever repeats then it is insecure so you need to make sure that the IV never repeats.
For the generation of the IV, you can use a good random source, or you can use the IV incrementally. In this case, the IV size must be 96-bit, see page 15 of SP 800-38D.
If $len(IV)=96$, then let $J_0 = IV \| 0^{31} \|1$.
Storing the last used IV and incrementing it then providing to GCM is the general practice to mitigate from a birthday attack.
If the supplied IV is not 96-bits it is processed by $\operatorname{GHASH}$. You can see how it is processed in this answer Generate J0 for GCM cipher when $len(IV)\neq96$ bits in details.
- 49,797
- 12
- 123
- 211