StrongSwan: Encryption not supported

Introduction

IPSec always sounded like a nightmare to me, at least, as a long time user of OpenVPN I never understood why it is so complicated.

But hello GCE, AWS and customer asking me to join on-premise networks to their cloud provider. There’s no alternative here, but IPSec. If you don’t want to do it on Cisco (or assimilated devices) there’s StrongSwan on Linux but there’s a huge pitfall and I wanted to write about it.

Usually, you start having cipher negotiation issue and StrongSwan logging is to say the least, not helpful.

Debian tricked me

Today I was connecting a Google Cloud to a Debian-based gateway with StrongSwan and as expected I got cipher issue:

ipsec up gce-vpn

 initiating IKE_SA gce-vpn[282] to 1.2.3.4
 generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(REDIR_SUP) ]
 sending packet: from 127.0.0.1[500] to 1.2.3.4[500] (874 bytes)
 received packet: from 1.2.3.4[500] to 127.0.0.1[500] (712 bytes)
 parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(MULT_AUTH) ]
 selected proposal: IKE:AES_GCM_16_256/PRF_HMAC_SHA2_512/MODP_4096
 ENCRYPTION_ALGORITHM AES_GCM_16 (key size 256) not supported!
 key derivation failed
 establishing connection 'gce-vpn' failed

So the first question was, is AES_GCM_16 not supported on my side or on Google side ? Cryptic messages did not help but I assumed it was on my side as when it comes from the other side the message is usually “NO_PROPOSAL_CHOSEN”.

How do I check supported ciphers ?

ipsec listalgs

List of registered IKE algorithms:
 encryption: AES_CBC[aes] RC2_CBC[rc2]
   integrity:  AES_XCBC_96[xcbc] HMAC_SHA1_96[hmac] HMAC_SHA1_128[hmac] HMAC_SHA1_160[hmac] HMAC_MD5_96[hmac]
               HMAC_MD5_128[hmac] HMAC_SHA2_256_128[hmac] HMAC_SHA2_256_256[hmac] HMAC_SHA2_384_192[hmac]
               HMAC_SHA2_384_384[hmac] HMAC_SHA2_512_256[hmac] HMAC_SHA2_512_512[hmac]
   aead:      
   hasher:     HASH_SHA1[sha1] HASH_SHA2_224[sha2] HASH_SHA2_256[sha2] HASH_SHA2_384[sha2] HASH_SHA2_512[sha2]
               HASH_MD5[md5]
   prf:        PRF_KEYED_SHA1[sha1] PRF_FIPS_SHA1_160[fips-prf] PRF_AES128_XCBC[xcbc] PRF_HMAC_SHA1[hmac]
               PRF_HMAC_MD5[hmac] PRF_HMAC_SHA2_256[hmac] PRF_HMAC_SHA2_384[hmac] PRF_HMAC_SHA2_512[hmac]
   xof:        XOF_MGF1_SHA1[mgf1] XOF_MGF1_SHA224[mgf1] XOF_MGF1_SHA256[mgf1] XOF_MGF1_SHA384[mgf1]
               XOF_MGF1_SHA512[mgf1]
   dh-group:   MODP_3072[gmp] MODP_4096[gmp] MODP_6144[gmp] MODP_8192[gmp] MODP_2048[gmp] MODP_2048_224[gmp]
               MODP_2048_256[gmp] MODP_1536[gmp] MODP_1024[gmp] MODP_1024_160[gmp] MODP_768[gmp] MODP_CUSTOM[gmp]
   random-gen: RNG_STRONG[random] RNG_TRUE[random]
   nonce-gen:  [nonce]

Indeed, I cannot see anything related to GCM, looks being the root of my issue.

Investigations and resolution

I wanted to verify first if this cipher is supposed to be supported by StrongWan and found the answer here:

https://wiki.strongswan.org/projects/strongswan/wiki/IKEv2CipherSuites

It needs “aes” and “gcm” plugins, so let’s read more about StrongSwan plugins

https://wiki.strongswan.org/projects/strongswan/wiki/PluginList

Ok that’s interresting. Aes should be ok, but gcm is disabled by default. I need to check what Debian did here, and verify the gcm plugin is enabled.

Debian developers usually store their packaging files on Debian’s internal public GitLab server which is called Salsa. Strongswan packaging is hosted here, so it was easy to check:

https://salsa.debian.org/debian/strongswan/blob/debian/master/debian/rules

debian/rules file is in charge of building the package, so this is what you want to check for options passed ton autotools configure script. Here we can clearly see gcm plugin is explicitly enabled.

I also checked debian/changelog to be sure it was already enabled in the stable version of the package which is available on Debian Buster, and yes, it was…

So why do I missed it ?

I check installed strongswan packages and found *libstrongswan*, let’s see it content

dpkg -L libstrongswan

[...]
/usr/lib/ipsec/plugins/libstrongswan-aes.so
/usr/lib/ipsec/plugins/libstrongswan-attr.so
/usr/lib/ipsec/plugins/libstrongswan-constraints.so
[...]

This is very interesting ! The aes plugin file is here, but no gcm one. Let’s check if it’s available (i’ll just guess its name) anywhere in the Debian archive ?

apt install apt-file
apt-file update
apt-file search libstrongswan-gcm.so

libstrongswan-standard-plugins: /usr/lib/ipsec/plugins/libstrongswan-gcm.so

I felt stupid here… This is quite common in Debian to separate the “standard” files from the “minimal” ones.

After installing the package and restarting strongswan the list of supported cipher is quite different:

apt install libstrongswan-standard-plugins
systemctl restart strongswan
ipsec listalgs

List of registered IKE algorithms:
 encryption: AES_CBC[aesni] AES_CTR[aesni] RC2_CBC[rc2] 3DES_CBC[openssl] CAMELLIA_CBC[openssl] CAST_CBC[openssl]
               BLOWFISH_CBC[openssl] DES_CBC[openssl] DES_ECB[openssl] NULL[openssl]
   integrity:  AES_XCBC_96[aesni] AES_CMAC_96[aesni] HMAC_MD5_96[openssl] HMAC_MD5_128[openssl] HMAC_SHA1_96[openssl]
               HMAC_SHA1_128[openssl] HMAC_SHA1_160[openssl] HMAC_SHA2_256_128[openssl] HMAC_SHA2_256_256[openssl]
               HMAC_SHA2_384_192[openssl] HMAC_SHA2_384_384[openssl] HMAC_SHA2_512_256[openssl]
               HMAC_SHA2_512_512[openssl] CAMELLIA_XCBC_96[xcbc]
   aead:       AES_CCM_8[aesni] AES_CCM_12[aesni] AES_CCM_16[aesni] AES_GCM_8[aesni] AES_GCM_12[aesni] AES_GCM_16[aesni]
   hasher:     HASH_SHA1[sha1] HASH_SHA2_224[sha2] HASH_SHA2_256[sha2] HASH_SHA2_384[sha2] HASH_SHA2_512[sha2]
               HASH_MD5[md5] HASH_MD4[openssl] HASH_IDENTITY[openssl]
   prf:        PRF_AES128_XCBC[aesni] PRF_AES128_CMAC[aesni] PRF_KEYED_SHA1[sha1] PRF_HMAC_MD5[openssl]
               PRF_HMAC_SHA1[openssl] PRF_HMAC_SHA2_256[openssl] PRF_HMAC_SHA2_384[openssl] PRF_HMAC_SHA2_512[openssl]
               PRF_FIPS_SHA1_160[fips-prf] PRF_CAMELLIA128_XCBC[xcbc]
   xof:        XOF_MGF1_SHA1[mgf1] XOF_MGF1_SHA224[mgf1] XOF_MGF1_SHA256[mgf1] XOF_MGF1_SHA384[mgf1]
               XOF_MGF1_SHA512[mgf1]
   dh-group:   ECP_256[openssl] ECP_384[openssl] ECP_521[openssl] ECP_224[openssl] ECP_192[openssl] ECP_256_BP[openssl]
               ECP_384_BP[openssl] ECP_512_BP[openssl] ECP_224_BP[openssl] MODP_3072[openssl] MODP_4096[openssl]
               MODP_6144[openssl] MODP_8192[openssl] MODP_2048[openssl] MODP_2048_224[openssl] MODP_2048_256[openssl]
               MODP_1536[openssl] MODP_1024[openssl] MODP_1024_160[openssl] MODP_768[openssl] MODP_CUSTOM[openssl]
               CURVE_25519[openssl] CURVE_448[openssl]
   random-gen: RNG_WEAK[openssl] RNG_STRONG[random] RNG_TRUE[random]
   nonce-gen:  [nonce]

And the VPN now works !

Leave a Reply

Your email address will not be published. Required fields are marked *