Hi Sid,
Incrementing of the counter is described in the spec (http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf) as follows: "Successive counter values are generated using the function incr(), which treats the rightmost 32 bits of its argument as a nonnegative integer with the least significant bit on the right, and increments this value modulo 2**32. More formally, the value of incr(F || I) is F || (I + 1 mod 2**32)."

Whilst counter values should not be reused (GCM limits the message length to just under 2**32 blocks - see Table 2), they may still "wrap around", so the loop must be explicitly limited to the last 4 bytes. Where the nonce is exactly 96 bits, the counter starts at 1, so it won't overflow, but for nonces of other lengths the counter is initialised to the output of the hash function and so the guard is necessary.

Regards,
Pete Dettman


On 11/03/2013 1:56 AM, Sid Shetye wrote:
Inside

Org.BouncyCastle.Crypto.Modes.GcmBlockCipher

I see:

         private byte[] GetNextCounterBlock()
         {
             for (int i = 15; i >= 12; --i)
             {
                 if (++_counter[i] != 0) break;
             }

             var tmp = new byte[BlockSize];
             // TODO Sure would be nice if ciphers could operate on int[]
             _cipher.ProcessBlock(_counter, 0, tmp, 0);
             return tmp;
         }

Questions:
1. Why do we only increment the top 4 bytes and not the entire block (...
;i>=0;...)? The early break maintains the performance of doing minimum work
as needed. Granted this hard coded limit is very very high at 2^(32+128)
bytes (32 for 4 bytes and 128 for the block size) but the hard coding just
stood out.
2. Why do we increment the top bytes and not the bottom bytes? I presume
increment should operate on the LSBs. Unless the byte order is flipped ...

Thanks
Sid





Reply via email to