I was looking at RFC5647: AES Galois Counter Mode for the Secure Shell Transport Layer Protocol and had some questions about section 7.1 "IV and Counter Management". Here's that section:
7. Processing Binary Packets in AES-GCM Secure Shell
7.1. IV and Counter Management
With AES-GCM, the 12-octet IV is broken into two fields: a 4-octet
fixed field and an 8-octet invocation counter field. The invocation
field is treated as a 64-bit integer and is incremented after each
invocation of AES-GCM to process a binary packet.
uint32 fixed; // 4 octets
uint64 invocation_counter; // 8 octets
Figure 3: Structure of an SSH AES-GCM Nonce
AES-GCM produces a keystream in blocks of 16-octets that is used to
encrypt the plaintext. This keystream is produced by encrypting the
following 16-octet data structure:
uint32 fixed; // 4 octets
uint64 invocation_counter; // 8 octets
uint32 block_counter; // 4 octets
Figure 4: Structure of an AES Input for SSH AES-GCM
The block_counter is initially set to one (1) and incremented as each
block of key is produced.
The reader is reminded that SSH requires that the data to be
encrypted MUST be padded out to a multiple of the block size
(16-octets for AES-GCM).
So let's say you invoke AES GCM twice and that the invocation counter is 0 (for simplicity sake). The first invocation encrypts two blocks and the second invocation encrypts one. What would be the source material for the encrypted keystream the second invocation?
For the first invocation, first block, it'd be this:
uint32 fixed;
uint64 0;
uint32 1;
For the first invocation, second block, it'd be this:
uint32 fixed;
uint64 0;
uint32 2;
For the second invocation, first (only) block, does the block_counter advance, as well, or does it reset? Here's what it'd be in the case of the former:
uint32 fixed;
uint64 1;
uint32 3;
Here's what it'd be in the case of the latter:
uint32 fixed;
uint64 1;
uint32 0;
eg. is the block_counter reset or incremented when the invocation_counter incremented?
Also, unless I'm mistaken, this approach breaks with tradition for SSH encryption in that encrypt(S1) || encrypt(S2) == encrypt(S1 || S2)
(where ||
is the concatenation operation). That's how pretty much how it works with every other symmetric cipher for SSH but not this one.