How to implement aes{128,256)-gcm at openssh.com.
Jakub Jelen
jjelen at redhat.com
Fri Jul 14 10:42:58 CEST 2023
On 7/14/23 08:04, Stef Bon wrote:
> Thanks a lot for answering,
>
> The tag, can you compare it with the hmac integrity code?
The tag is conceptually same as the hmac, but for GCM it is part of the
"cipher".
> And, I cannot read that directly from the code from libssh, it is
> placed directly like the hmac code after the encrypted message?
Correct. As visible from
https://datatracker.ietf.org/doc/html/rfc5647#section-5.2 the Tag is
placed directly in the mac field at the end of the binary packet.
> The iv, according to the libssh code is like:
>
> 4B fixed iv
> 8B packet counter
> 4B block counter
Correct. This is what is in the RFC:
https://datatracker.ietf.org/doc/html/rfc5647#section-7.1
> The function gcry_cipher_authenticate adds the blockcounter after the
> first 12 bytes.
I think the AAD used in here is only the packet length. See the RFC,
under AAD, which is processed by the `gcry_cipher_authenticate`
function, we have only the packet length (which is different from the
counters):
https://datatracker.ietf.org/doc/html/rfc5647#section-7.2
> I cannot see the iv is 12 bytes long (and libgcrypt copies it to
> another buffer of 16 bytes) or it is 16 bytes already and libgcrypt
> uses that without copying. Can someone shine a light here?
The GCM has two counters, one invocation counter and one packet counter.
The libgcrypt is able to handle the block counter in the last 4 bytes,
but not the packet counter as it does not have any information about the
packet boundary, so what we do in libssh is:
1) Restore the IV to the saved value (all 16 bytes) using
gcry_cipher_setiv. This effectively increments the packet counter
(calculated by previous call unless its the first packet) and resets the
block counter as required by the rfc:
https://gitlab.com/libssh/libssh-mirror/-/blob/master/src/libgcrypt.c#L325
2) Increment the packet counter for the next iteration with
uint64_inc(cipher->last_iv + 4); (the +4 is pointer arithmetics to
reference the buffer as 64b unsigned int):
https://gitlab.com/libssh/libssh-mirror/-/blob/master/src/libgcrypt.c#L335
Hope it helps.
> BTW In the latest version of libgcrypt I see the function gcry_cipher_geniv(..)
> but not on the version installed on my OS (Gentoo, libgcrypt
> 1.10.2-unknown). It's not a problem, I prefer creating this iv on a
> higher level (in the code of my service).
> The aes128-gcm at openssh.com cipher uses its own source file and I can
> implement it there.
Thats what I was referring. This will likely be in the next libgcrypt
release 1.11.x so for now, the above is probably the only way to
implement this.
Regards,
--
Jakub Jelen
Crypto Team, Security Engineering
Red Hat, Inc.
More information about the Gcrypt-devel
mailing list