[Bug 263379] [regression] [ipsec] compatibility broken between stable/12 and stable/13 opencrypto in AEAD mode

From: <bugzilla-noreply_at_freebsd.org>
Date: Mon, 18 Apr 2022 18:08:14 UTC

--- Comment #3 from John Baldwin <jhb@FreeBSD.org> ---
So the issue with the setkey manpage is it was written before AEAD algorithms
were a thing and when you always had to use Encrypt-then-Auth (ETA)
combinations of distinct ciphers and MACs.  In general when using an AEAD
algorithm like AES-GCM, AES-CCM, or Chacha20-Poly1305, you provide a single key
that is then used to generate keys for both the cipher (AES-CTR for AES-GCM/CCM
and Chacha20 for Chacha20-Poly1305) and the MAC (GMAC, CBC-MAC, and Poly1305,
respectively).  For those three AEAD ciphers, the cipher is a stream cipher and
the key stream block for a given counter value is used as the key of the MAC.

The fact that stable/12 let you construct this combination is a long-standing
bug in cryptosoft.c and there's no way to express the combination of the
AES-CTR "side" of AES-GCM combined with some other MAC in stable/13 and later. 
For the purposes of upgrading, you could switch your existing 12.x hosts to use
a supported cipher first prior to upgrading.  I would suggest just using -E
aes-gcm-16 and dropping the -A entirely.

Unfortunately, the AES-CTR cipher defined for IPsec does not permit setting all
16 bytes of the nonce and instead mandates that the low 4 bytes define a 32-bit
counter starting at 1 (whereas AES-GCM uses block 1 internally and starts
encrypting with the low 4 bytes set to block 2 for the AES-CTR "part"), so
there isn't a way to recreate the thing stable/12 is doing by using -E aes-ctr
combined with the existing -A.  It might be possible to do this though using a
local hack that would let you use -E aes-ctr in place of -E aes-gcm-16.  You
would keep the same key for -E, but just change it to use 'aes-ctr' and then
apply this patch:

diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c
index ee363a7c911a..465716c3ea7c 100644
--- a/sys/netipsec/xform_esp.c
+++ b/sys/netipsec/xform_esp.c
@@ -455,7 +455,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip,
int protoff)
                    _KEYLEN(sav->key_enc) - 4, 4);
                m_copydata(m, skip + hlen - sav->ivlen, sav->ivlen, &ivp[4]);
                if (SAV_ISCTR(sav)) {
-                       be32enc(&ivp[sav->ivlen + 4], 1);
+                       be32enc(&ivp[sav->ivlen + 4], 2);
                crp->crp_flags |= CRYPTO_F_IV_SEPARATE;
        } else if (sav->ivlen != 0)
@@ -880,7 +880,7 @@ esp_output(struct mbuf *m, struct secpolicy *sp, struct
secasvar *sav,
                    _KEYLEN(sav->key_enc) - 4, 4);
                be64enc(&ivp[4], cntr);
                if (SAV_ISCTR(sav)) {
-                       be32enc(&ivp[sav->ivlen + 4], 1);
+                       be32enc(&ivp[sav->ivlen + 4], 2);
                m_copyback(m, skip + hlen - sav->ivlen, sav->ivlen, &ivp[4]);
                crp->crp_flags |= CRYPTO_F_IV_SEPARATE;

This breaks the "official" AES-CTR defined in RFC 3686 (so it can't be
committed), but you could try applying this locally and keeping it as a local
patch if it works until you are able to migrate existing hosts to using a
supported cipher suite.

I can work on clarifying the language in the setkey(8) manual page to clarify
that -A should not be used with AEAD ciphers.

You are receiving this mail because:
You are on the CC list for the bug.