Re: iked(8): AES_GCM ciphers for IKE
On Thu, May 14, 2020 at 10:07:30PM +0200, Tobias Heider wrote: > Hi, > > currently iked(8) supports AES-GCM only for ESP. > The diff below adds the ENCR_AES_GCM_16 and ENCR_AES_GCM_12 variants for IKE. > (for more information see [1] and [2]). > Both variants support the 128, 196, and 256 bit key lengths. > > The new new ciphers can be configured with: > - aes-128-gcm, aes-196-gcm and aes-256-gcm for ENCR_AES_GCM_16 > - aes-128-gcm-12, aes-196-gcm-12 and aes-256-gcm-12 for ENCR_AES_GCM_12 > > It would be nice if we could get some interop testing with different IKEv2 > implementations. I have so far successfully tested strongswan <-> iked and > of course iked <-> iked. > > Feedback welcome ;) > > [1] https://tools.ietf.org/html/rfc5282 > [2] > https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml#ikev2-parameters-5 Here is the latest revision of the diff with a few more comments and without aes-192-gcm. We have so far successfully tested against iked, strongswan and juniper srx. ok? Index: crypto.c === RCS file: /cvs/src/sbin/iked/crypto.c,v retrieving revision 1.27 diff -u -p -r1.27 crypto.c --- crypto.c14 May 2020 15:08:30 - 1.27 +++ crypto.c26 May 2020 12:58:28 - @@ -92,7 +92,7 @@ hash_new(uint8_t type, uint16_t id) struct iked_hash*hash; const EVP_MD*md = NULL; HMAC_CTX*ctx = NULL; - int length = 0, fixedkey = 0, trunc = 0; + int length = 0, fixedkey = 0, trunc = 0, isaead = 0; switch (type) { case IKEV2_XFORMTYPE_PRF: @@ -156,6 +156,14 @@ hash_new(uint8_t type, uint16_t id) length = SHA512_DIGEST_LENGTH; trunc = 32; break; + case IKEV2_XFORMAUTH_AES_GCM_12: + length = 12; + isaead = 1; + break; + case IKEV2_XFORMAUTH_AES_GCM_16: + length = 16; + isaead = 1; + break; case IKEV2_XFORMAUTH_NONE: case IKEV2_XFORMAUTH_DES_MAC: case IKEV2_XFORMAUTH_KPDK_MD5: @@ -177,7 +185,7 @@ hash_new(uint8_t type, uint16_t id) print_map(id, ikev2_xformtype_map)); break; } - if (md == NULL) + if (!isaead && md == NULL) return (NULL); if ((hash = calloc(1, sizeof(*hash))) == NULL) { @@ -192,6 +200,10 @@ hash_new(uint8_t type, uint16_t id) hash->hash_trunc = trunc; hash->hash_length = length; hash->hash_fixedkey = fixedkey; + hash->hash_isaead = isaead; + + if (isaead) + return (hash); if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { log_debug("%s: alloc hash ctx", __func__); @@ -276,6 +288,7 @@ cipher_new(uint8_t type, uint16_t id, ui const EVP_CIPHER*cipher = NULL; EVP_CIPHER_CTX *ctx = NULL; int length = 0, fixedkey = 0, ivlength = 0; + int saltlength = 0, authid = 0; switch (type) { case IKEV2_XFORMTYPE_ENCR: @@ -309,6 +322,36 @@ cipher_new(uint8_t type, uint16_t id, ui ivlength = EVP_CIPHER_iv_length(cipher); fixedkey = EVP_CIPHER_key_length(cipher); break; + case IKEV2_XFORMENCR_AES_GCM_16: + case IKEV2_XFORMENCR_AES_GCM_12: + switch (id_length) { + case 128: + cipher = EVP_aes_128_gcm(); + break; + case 256: + cipher = EVP_aes_256_gcm(); + break; + default: + log_debug("%s: invalid key length %d" + " for cipher %s", __func__, id_length, + print_map(id, ikev2_xformencr_map)); + break; + } + if (cipher == NULL) + break; + switch(id) { + case IKEV2_XFORMENCR_AES_GCM_16: + authid = IKEV2_XFORMAUTH_AES_GCM_16; + break; + case IKEV2_XFORMENCR_AES_GCM_12: + authid = IKEV2_XFORMAUTH_AES_GCM_12; + break; + } + length = EVP_CIPHER_block_size(cipher); + ivlength = 8; + saltlength = 4; + fixedkey = EVP_CIPHER_key_length(cipher) + saltlength; +
Re: iked(8): AES_GCM ciphers for IKE
On Fri, May 15, 2020 at 01:59:35AM +0200, Tobias Heider wrote: > On Thu, May 14, 2020 at 10:47:52PM +0200, Tobias Heider wrote: > > On Thu, May 14, 2020 at 10:07:30PM +0200, Tobias Heider wrote: > > > Hi, > > > > > > currently iked(8) supports AES-GCM only for ESP. > > > The diff below adds the ENCR_AES_GCM_16 and ENCR_AES_GCM_12 variants for > > > IKE. > > > (for more information see [1] and [2]). > > > Both variants support the 128, 196, and 256 bit key lengths. > > > > > > The new new ciphers can be configured with: > > > - aes-128-gcm, aes-196-gcm and aes-256-gcm for ENCR_AES_GCM_16 > > > - aes-128-gcm-12, aes-196-gcm-12 and aes-256-gcm-12 for ENCR_AES_GCM_12 > > Small typo: it's 192, not 196. > > > > > > > It would be nice if we could get some interop testing with different IKEv2 > > > implementations. I have so far successfully tested strongswan <-> iked > > > and > > > of course iked <-> iked. > > > > > > Feedback welcome ;) It works with a Juniper SRX on the other side. I tested with this iked.conf: ikev2 "srx1" active esp \ from 192.168.100.0/24 to 192.168.111.0/24 \ local 10.0.0.2 peer 10.0.0.1 \ ikesa enc aes-128-gcm group ecp256 \ childsa enc aes-128-gcm group ecp256 \ srcid 10.0.0.2 dstid 10.0.0.1 \ psk "Secret1" > > > > > > [1] https://tools.ietf.org/html/rfc5282 > > > [2] > > > https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml#ikev2-parameters-5 > > > > > > > whoops, previous diff was broken. > > > > Another update because it seems parse_xf matches substrings instead of the > full transform type name, which means I had to change the order of ikeencxfs > members or 'aes-128-gcm' will always match 'aes-128-gcm-12' ... > > Index: crypto.c > === > RCS file: /cvs/src/sbin/iked/crypto.c,v > retrieving revision 1.27 > diff -u -p -r1.27 crypto.c > --- crypto.c 14 May 2020 15:08:30 - 1.27 > +++ crypto.c 14 May 2020 23:55:13 - > @@ -92,7 +92,7 @@ hash_new(uint8_t type, uint16_t id) > struct iked_hash*hash; > const EVP_MD*md = NULL; > HMAC_CTX*ctx = NULL; > - int length = 0, fixedkey = 0, trunc = 0; > + int length = 0, fixedkey = 0, trunc = 0, isaead = > 0; > > switch (type) { > case IKEV2_XFORMTYPE_PRF: > @@ -156,6 +156,14 @@ hash_new(uint8_t type, uint16_t id) > length = SHA512_DIGEST_LENGTH; > trunc = 32; > break; > + case IKEV2_XFORMAUTH_AES_GCM_12: > + length = 12; > + isaead = 1; > + break; > + case IKEV2_XFORMAUTH_AES_GCM_16: > + length = 16; > + isaead = 1; > + break; > case IKEV2_XFORMAUTH_NONE: > case IKEV2_XFORMAUTH_DES_MAC: > case IKEV2_XFORMAUTH_KPDK_MD5: > @@ -177,7 +185,7 @@ hash_new(uint8_t type, uint16_t id) > print_map(id, ikev2_xformtype_map)); > break; > } > - if (md == NULL) > + if (!isaead && md == NULL) > return (NULL); > > if ((hash = calloc(1, sizeof(*hash))) == NULL) { > @@ -192,6 +200,10 @@ hash_new(uint8_t type, uint16_t id) > hash->hash_trunc = trunc; > hash->hash_length = length; > hash->hash_fixedkey = fixedkey; > + hash->hash_isaead = isaead; > + > + if (isaead) > + return (hash); > > if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { > log_debug("%s: alloc hash ctx", __func__); > @@ -276,6 +288,7 @@ cipher_new(uint8_t type, uint16_t id, ui > const EVP_CIPHER*cipher = NULL; > EVP_CIPHER_CTX *ctx = NULL; > int length = 0, fixedkey = 0, ivlength = 0; > + int saltlength = 0, authid = 0; > > switch (type) { > case IKEV2_XFORMTYPE_ENCR: > @@ -309,6 +322,39 @@ cipher_new(uint8_t type, uint16_t id, ui > ivlength = EVP_CIPHER_iv_length(cipher); > fixedkey = EVP_CIPHER_key_length(cipher); > break; > + case IKEV2_XFORMENCR_AES_GCM_16: > + case IKEV2_XFORMENCR_AES_GCM_12: > + switch (id_length) { > + case 128: > + cipher = EVP_aes_128_gcm(); > + break; > + case 192: > + cipher = EVP_aes_192_gcm(); > + break; > + case 256: > + cipher = EVP_aes_256_gcm(); > + break; > + default: > + log_debug("%s: invalid key length %d" > + " f
Re: iked(8): AES_GCM ciphers for IKE
On Sat, May 16, 2020 at 02:24:45PM +0200, Christian Weisgerber wrote: > Tobias Heider: > > > currently iked(8) supports AES-GCM only for ESP. > > The diff below adds the ENCR_AES_GCM_16 and ENCR_AES_GCM_12 variants for > > IKE. > > (for more information see [1] and [2]). > > Both variants support the 128, 196, and 256 bit key lengths. > > > > The new new ciphers can be configured with: > > - aes-128-gcm, aes-196-gcm and aes-256-gcm for ENCR_AES_GCM_16 > > - aes-128-gcm-12, aes-196-gcm-12 and aes-256-gcm-12 for ENCR_AES_GCM_12 > > Is there a compelling reason to implement the GCM_12 variants? Only that it's actually used in the wild. I added them because I am forced to have them for compatibility. Dropping them would force me to maintain a local diff, which I would of course like to avoid. > I remember that truncating integrity tags is problematic for GCM. > That probably doesn't matter for small IKE exchanges, but then again > four extra bytes per packet don't matter either. According to > RFC5282, full length tags MUST be supported anyway, truncated ones > are optional. I know NIST recommends a limit in message size and operations per key for the 32 and 64 bit truncated versions in [1]. The AES_GCM_12 tag seems to be long enough to make attacks considerably harder (although I agree that the non truncated version should always be preferred). > > RFC5282 also says that AES-192 is NOT RECOMMENDED. > Fair enough, I think we can live without those. - Tobias [1] https://csrc.nist.gov/publications/detail/sp/800-38d/final
Re: iked(8): AES_GCM ciphers for IKE
Tobias Heider: > currently iked(8) supports AES-GCM only for ESP. > The diff below adds the ENCR_AES_GCM_16 and ENCR_AES_GCM_12 variants for IKE. > (for more information see [1] and [2]). > Both variants support the 128, 196, and 256 bit key lengths. > > The new new ciphers can be configured with: > - aes-128-gcm, aes-196-gcm and aes-256-gcm for ENCR_AES_GCM_16 > - aes-128-gcm-12, aes-196-gcm-12 and aes-256-gcm-12 for ENCR_AES_GCM_12 Is there a compelling reason to implement the GCM_12 variants? I remember that truncating integrity tags is problematic for GCM. That probably doesn't matter for small IKE exchanges, but then again four extra bytes per packet don't matter either. According to RFC5282, full length tags MUST be supported anyway, truncated ones are optional. RFC5282 also says that AES-192 is NOT RECOMMENDED. So I think only aes-128-gcm and aes-256-gcm should be added. While adding the other variants is simple, there is no value in supporting them; they just add more configuration buttons. -- Christian "naddy" Weisgerber na...@mips.inka.de
Re: iked(8): AES_GCM ciphers for IKE
On Fri, May 15, 2020 at 01:59:35AM +0200, Tobias Heider wrote: > On Thu, May 14, 2020 at 10:47:52PM +0200, Tobias Heider wrote: > > On Thu, May 14, 2020 at 10:07:30PM +0200, Tobias Heider wrote: > > > Hi, > > > > > > currently iked(8) supports AES-GCM only for ESP. > > > The diff below adds the ENCR_AES_GCM_16 and ENCR_AES_GCM_12 variants for > > > IKE. > > > (for more information see [1] and [2]). > > > Both variants support the 128, 196, and 256 bit key lengths. > > > > > > The new new ciphers can be configured with: > > > - aes-128-gcm, aes-196-gcm and aes-256-gcm for ENCR_AES_GCM_16 > > > - aes-128-gcm-12, aes-196-gcm-12 and aes-256-gcm-12 for ENCR_AES_GCM_12 > > Small typo: it's 192, not 196. > > > > > > > It would be nice if we could get some interop testing with different IKEv2 > > > implementations. I have so far successfully tested strongswan <-> iked > > > and > > > of course iked <-> iked. > > > > > > Feedback welcome ;) > > > > > > [1] https://tools.ietf.org/html/rfc5282 > > > [2] > > > https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml#ikev2-parameters-5 > > > > > > > whoops, previous diff was broken. > > > > Another update because it seems parse_xf matches substrings instead of the > full transform type name, which means I had to change the order of ikeencxfs > members or 'aes-128-gcm' will always match 'aes-128-gcm-12' ... > > Index: crypto.c > === > RCS file: /cvs/src/sbin/iked/crypto.c,v > retrieving revision 1.27 > diff -u -p -r1.27 crypto.c > --- crypto.c 14 May 2020 15:08:30 - 1.27 > +++ crypto.c 14 May 2020 23:55:13 - > @@ -92,7 +92,7 @@ hash_new(uint8_t type, uint16_t id) > struct iked_hash*hash; > const EVP_MD*md = NULL; > HMAC_CTX*ctx = NULL; > - int length = 0, fixedkey = 0, trunc = 0; > + int length = 0, fixedkey = 0, trunc = 0, isaead = > 0; > > switch (type) { > case IKEV2_XFORMTYPE_PRF: > @@ -156,6 +156,14 @@ hash_new(uint8_t type, uint16_t id) > length = SHA512_DIGEST_LENGTH; > trunc = 32; > break; > + case IKEV2_XFORMAUTH_AES_GCM_12: > + length = 12; > + isaead = 1; > + break; > + case IKEV2_XFORMAUTH_AES_GCM_16: > + length = 16; > + isaead = 1; > + break; > case IKEV2_XFORMAUTH_NONE: > case IKEV2_XFORMAUTH_DES_MAC: > case IKEV2_XFORMAUTH_KPDK_MD5: > @@ -177,7 +185,7 @@ hash_new(uint8_t type, uint16_t id) > print_map(id, ikev2_xformtype_map)); > break; > } > - if (md == NULL) > + if (!isaead && md == NULL) > return (NULL); > > if ((hash = calloc(1, sizeof(*hash))) == NULL) { > @@ -192,6 +200,10 @@ hash_new(uint8_t type, uint16_t id) > hash->hash_trunc = trunc; > hash->hash_length = length; > hash->hash_fixedkey = fixedkey; > + hash->hash_isaead = isaead; > + > + if (isaead) > + return (hash); > > if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { > log_debug("%s: alloc hash ctx", __func__); > @@ -276,6 +288,7 @@ cipher_new(uint8_t type, uint16_t id, ui > const EVP_CIPHER*cipher = NULL; > EVP_CIPHER_CTX *ctx = NULL; > int length = 0, fixedkey = 0, ivlength = 0; > + int saltlength = 0, authid = 0; > > switch (type) { > case IKEV2_XFORMTYPE_ENCR: > @@ -309,6 +322,39 @@ cipher_new(uint8_t type, uint16_t id, ui > ivlength = EVP_CIPHER_iv_length(cipher); > fixedkey = EVP_CIPHER_key_length(cipher); > break; > + case IKEV2_XFORMENCR_AES_GCM_16: > + case IKEV2_XFORMENCR_AES_GCM_12: > + switch (id_length) { > + case 128: > + cipher = EVP_aes_128_gcm(); > + break; > + case 192: > + cipher = EVP_aes_192_gcm(); > + break; > + case 256: > + cipher = EVP_aes_256_gcm(); > + break; > + default: > + log_debug("%s: invalid key length %d" > + " for cipher %s", __func__, id_length, > + print_map(id, ikev2_xformencr_map)); > + break; > + } > + if (cipher == NULL) > + break; > + switch(id) { > + case IKEV2_XFORMENCR_AES_GCM_16: >
Re: iked(8): AES_GCM ciphers for IKE
On Thu, May 14, 2020 at 10:47:52PM +0200, Tobias Heider wrote: > On Thu, May 14, 2020 at 10:07:30PM +0200, Tobias Heider wrote: > > Hi, > > > > currently iked(8) supports AES-GCM only for ESP. > > The diff below adds the ENCR_AES_GCM_16 and ENCR_AES_GCM_12 variants for > > IKE. > > (for more information see [1] and [2]). > > Both variants support the 128, 196, and 256 bit key lengths. > > > > The new new ciphers can be configured with: > > - aes-128-gcm, aes-196-gcm and aes-256-gcm for ENCR_AES_GCM_16 > > - aes-128-gcm-12, aes-196-gcm-12 and aes-256-gcm-12 for ENCR_AES_GCM_12 Small typo: it's 192, not 196. > > > > It would be nice if we could get some interop testing with different IKEv2 > > implementations. I have so far successfully tested strongswan <-> iked and > > of course iked <-> iked. > > > > Feedback welcome ;) > > > > [1] https://tools.ietf.org/html/rfc5282 > > [2] > > https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml#ikev2-parameters-5 > > > > whoops, previous diff was broken. > Another update because it seems parse_xf matches substrings instead of the full transform type name, which means I had to change the order of ikeencxfs members or 'aes-128-gcm' will always match 'aes-128-gcm-12' ... Index: crypto.c === RCS file: /cvs/src/sbin/iked/crypto.c,v retrieving revision 1.27 diff -u -p -r1.27 crypto.c --- crypto.c14 May 2020 15:08:30 - 1.27 +++ crypto.c14 May 2020 23:55:13 - @@ -92,7 +92,7 @@ hash_new(uint8_t type, uint16_t id) struct iked_hash*hash; const EVP_MD*md = NULL; HMAC_CTX*ctx = NULL; - int length = 0, fixedkey = 0, trunc = 0; + int length = 0, fixedkey = 0, trunc = 0, isaead = 0; switch (type) { case IKEV2_XFORMTYPE_PRF: @@ -156,6 +156,14 @@ hash_new(uint8_t type, uint16_t id) length = SHA512_DIGEST_LENGTH; trunc = 32; break; + case IKEV2_XFORMAUTH_AES_GCM_12: + length = 12; + isaead = 1; + break; + case IKEV2_XFORMAUTH_AES_GCM_16: + length = 16; + isaead = 1; + break; case IKEV2_XFORMAUTH_NONE: case IKEV2_XFORMAUTH_DES_MAC: case IKEV2_XFORMAUTH_KPDK_MD5: @@ -177,7 +185,7 @@ hash_new(uint8_t type, uint16_t id) print_map(id, ikev2_xformtype_map)); break; } - if (md == NULL) + if (!isaead && md == NULL) return (NULL); if ((hash = calloc(1, sizeof(*hash))) == NULL) { @@ -192,6 +200,10 @@ hash_new(uint8_t type, uint16_t id) hash->hash_trunc = trunc; hash->hash_length = length; hash->hash_fixedkey = fixedkey; + hash->hash_isaead = isaead; + + if (isaead) + return (hash); if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { log_debug("%s: alloc hash ctx", __func__); @@ -276,6 +288,7 @@ cipher_new(uint8_t type, uint16_t id, ui const EVP_CIPHER*cipher = NULL; EVP_CIPHER_CTX *ctx = NULL; int length = 0, fixedkey = 0, ivlength = 0; + int saltlength = 0, authid = 0; switch (type) { case IKEV2_XFORMTYPE_ENCR: @@ -309,6 +322,39 @@ cipher_new(uint8_t type, uint16_t id, ui ivlength = EVP_CIPHER_iv_length(cipher); fixedkey = EVP_CIPHER_key_length(cipher); break; + case IKEV2_XFORMENCR_AES_GCM_16: + case IKEV2_XFORMENCR_AES_GCM_12: + switch (id_length) { + case 128: + cipher = EVP_aes_128_gcm(); + break; + case 192: + cipher = EVP_aes_192_gcm(); + break; + case 256: + cipher = EVP_aes_256_gcm(); + break; + default: + log_debug("%s: invalid key length %d" + " for cipher %s", __func__, id_length, + print_map(id, ikev2_xformencr_map)); + break; + } + if (cipher == NULL) + break; + switch(id) { + case IKEV2_XFORMENCR_AES_GCM_16: + authid = IKEV2_XFORMAUTH_AES_GCM_16; + break; + case IKEV2_XFORMENCR_AES_GCM_12: +
Re: iked(8): AES_GCM ciphers for IKE
Looks like you are missing the previous commit: https://marc.info/?l=openbsd-cvs&m=158946893417378&w=2
Re: iked(8): AES_GCM ciphers for IKE
On Thu, May 14, 2020 at 10:47:52PM +0200, Tobias Heider wrote: > On Thu, May 14, 2020 at 10:07:30PM +0200, Tobias Heider wrote: > > Hi, > > > > currently iked(8) supports AES-GCM only for ESP. > > The diff below adds the ENCR_AES_GCM_16 and ENCR_AES_GCM_12 variants for > > IKE. > > (for more information see [1] and [2]). > > Both variants support the 128, 196, and 256 bit key lengths. > > > > The new new ciphers can be configured with: > > - aes-128-gcm, aes-196-gcm and aes-256-gcm for ENCR_AES_GCM_16 > > - aes-128-gcm-12, aes-196-gcm-12 and aes-256-gcm-12 for ENCR_AES_GCM_12 > > > > It would be nice if we could get some interop testing with different IKEv2 > > implementations. I have so far successfully tested strongswan <-> iked and > > of course iked <-> iked. > > > > Feedback welcome ;) > > > > [1] https://tools.ietf.org/html/rfc5282 > > [2] > > https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml#ikev2-parameters-5 > > > > whoops, previous diff was broken. > > Index: crypto.c > === > RCS file: /cvs/src/sbin/iked/crypto.c,v > retrieving revision 1.27 > diff -u -p -r1.27 crypto.c > --- crypto.c 14 May 2020 15:08:30 - 1.27 > +++ crypto.c 14 May 2020 20:43:27 - > @@ -92,7 +92,7 @@ hash_new(uint8_t type, uint16_t id) > struct iked_hash*hash; > const EVP_MD*md = NULL; > HMAC_CTX*ctx = NULL; > - int length = 0, fixedkey = 0, trunc = 0; > + int length = 0, fixedkey = 0, trunc = 0, isaead = > 0; > > switch (type) { > case IKEV2_XFORMTYPE_PRF: > @@ -156,6 +156,14 @@ hash_new(uint8_t type, uint16_t id) > length = SHA512_DIGEST_LENGTH; > trunc = 32; > break; > + case IKEV2_XFORMAUTH_AES_GCM_12: > + length = 12; > + isaead = 1; > + break; > + case IKEV2_XFORMAUTH_AES_GCM_16: > + length = 16; > + isaead = 1; > + break; > case IKEV2_XFORMAUTH_NONE: > case IKEV2_XFORMAUTH_DES_MAC: > case IKEV2_XFORMAUTH_KPDK_MD5: > @@ -177,7 +185,7 @@ hash_new(uint8_t type, uint16_t id) > print_map(id, ikev2_xformtype_map)); > break; > } > - if (md == NULL) > + if (!isaead && md == NULL) > return (NULL); > > if ((hash = calloc(1, sizeof(*hash))) == NULL) { > @@ -192,6 +200,10 @@ hash_new(uint8_t type, uint16_t id) > hash->hash_trunc = trunc; > hash->hash_length = length; > hash->hash_fixedkey = fixedkey; > + hash->hash_isaead = isaead; > + > + if (isaead) > + return (hash); > > if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { > log_debug("%s: alloc hash ctx", __func__); > @@ -276,6 +288,7 @@ cipher_new(uint8_t type, uint16_t id, ui > const EVP_CIPHER*cipher = NULL; > EVP_CIPHER_CTX *ctx = NULL; > int length = 0, fixedkey = 0, ivlength = 0; > + int saltlength = 0, authid = 0; > > switch (type) { > case IKEV2_XFORMTYPE_ENCR: > @@ -309,6 +322,39 @@ cipher_new(uint8_t type, uint16_t id, ui > ivlength = EVP_CIPHER_iv_length(cipher); > fixedkey = EVP_CIPHER_key_length(cipher); > break; > + case IKEV2_XFORMENCR_AES_GCM_16: > + case IKEV2_XFORMENCR_AES_GCM_12: > + switch (id_length) { > + case 128: > + cipher = EVP_aes_128_gcm(); > + break; > + case 192: > + cipher = EVP_aes_192_gcm(); > + break; > + case 256: > + cipher = EVP_aes_256_gcm(); > + break; > + default: > + log_debug("%s: invalid key length %d" > + " for cipher %s", __func__, id_length, > + print_map(id, ikev2_xformencr_map)); > + break; > + } > + if (cipher == NULL) > + break; > + switch(id) { > + case IKEV2_XFORMENCR_AES_GCM_16: > + authid = IKEV2_XFORMAUTH_AES_GCM_16; > + break; > + case IKEV2_XFORMENCR_AES_GCM_12: > + authid = IKEV2_XFORMAUTH_AES_GCM_12; > + break; > + } > + length = EVP_CIPHER_block_size(cipher); > + ivleng
Re: iked(8): AES_GCM ciphers for IKE
On Thu, May 14, 2020 at 10:07:30PM +0200, Tobias Heider wrote: > Hi, > > currently iked(8) supports AES-GCM only for ESP. > The diff below adds the ENCR_AES_GCM_16 and ENCR_AES_GCM_12 variants for IKE. > (for more information see [1] and [2]). > Both variants support the 128, 196, and 256 bit key lengths. > > The new new ciphers can be configured with: > - aes-128-gcm, aes-196-gcm and aes-256-gcm for ENCR_AES_GCM_16 > - aes-128-gcm-12, aes-196-gcm-12 and aes-256-gcm-12 for ENCR_AES_GCM_12 > > It would be nice if we could get some interop testing with different IKEv2 > implementations. I have so far successfully tested strongswan <-> iked and > of course iked <-> iked. > > Feedback welcome ;) > > [1] https://tools.ietf.org/html/rfc5282 > [2] > https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml#ikev2-parameters-5 > whoops, previous diff was broken. Index: crypto.c === RCS file: /cvs/src/sbin/iked/crypto.c,v retrieving revision 1.27 diff -u -p -r1.27 crypto.c --- crypto.c14 May 2020 15:08:30 - 1.27 +++ crypto.c14 May 2020 20:43:27 - @@ -92,7 +92,7 @@ hash_new(uint8_t type, uint16_t id) struct iked_hash*hash; const EVP_MD*md = NULL; HMAC_CTX*ctx = NULL; - int length = 0, fixedkey = 0, trunc = 0; + int length = 0, fixedkey = 0, trunc = 0, isaead = 0; switch (type) { case IKEV2_XFORMTYPE_PRF: @@ -156,6 +156,14 @@ hash_new(uint8_t type, uint16_t id) length = SHA512_DIGEST_LENGTH; trunc = 32; break; + case IKEV2_XFORMAUTH_AES_GCM_12: + length = 12; + isaead = 1; + break; + case IKEV2_XFORMAUTH_AES_GCM_16: + length = 16; + isaead = 1; + break; case IKEV2_XFORMAUTH_NONE: case IKEV2_XFORMAUTH_DES_MAC: case IKEV2_XFORMAUTH_KPDK_MD5: @@ -177,7 +185,7 @@ hash_new(uint8_t type, uint16_t id) print_map(id, ikev2_xformtype_map)); break; } - if (md == NULL) + if (!isaead && md == NULL) return (NULL); if ((hash = calloc(1, sizeof(*hash))) == NULL) { @@ -192,6 +200,10 @@ hash_new(uint8_t type, uint16_t id) hash->hash_trunc = trunc; hash->hash_length = length; hash->hash_fixedkey = fixedkey; + hash->hash_isaead = isaead; + + if (isaead) + return (hash); if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { log_debug("%s: alloc hash ctx", __func__); @@ -276,6 +288,7 @@ cipher_new(uint8_t type, uint16_t id, ui const EVP_CIPHER*cipher = NULL; EVP_CIPHER_CTX *ctx = NULL; int length = 0, fixedkey = 0, ivlength = 0; + int saltlength = 0, authid = 0; switch (type) { case IKEV2_XFORMTYPE_ENCR: @@ -309,6 +322,39 @@ cipher_new(uint8_t type, uint16_t id, ui ivlength = EVP_CIPHER_iv_length(cipher); fixedkey = EVP_CIPHER_key_length(cipher); break; + case IKEV2_XFORMENCR_AES_GCM_16: + case IKEV2_XFORMENCR_AES_GCM_12: + switch (id_length) { + case 128: + cipher = EVP_aes_128_gcm(); + break; + case 192: + cipher = EVP_aes_192_gcm(); + break; + case 256: + cipher = EVP_aes_256_gcm(); + break; + default: + log_debug("%s: invalid key length %d" + " for cipher %s", __func__, id_length, + print_map(id, ikev2_xformencr_map)); + break; + } + if (cipher == NULL) + break; + switch(id) { + case IKEV2_XFORMENCR_AES_GCM_16: + authid = IKEV2_XFORMAUTH_AES_GCM_16; + break; + case IKEV2_XFORMENCR_AES_GCM_12: + authid = IKEV2_XFORMAUTH_AES_GCM_12; + break; + } + length = EVP_CIPHER_block_size(cipher); + ivlength = 8; + saltlength = 4; + fixedkey = EVP_CIPHER_key_length(cipher) + saltlength; + b
iked(8): AES_GCM ciphers for IKE
Hi, currently iked(8) supports AES-GCM only for ESP. The diff below adds the ENCR_AES_GCM_16 and ENCR_AES_GCM_12 variants for IKE. (for more information see [1] and [2]). Both variants support the 128, 196, and 256 bit key lengths. The new new ciphers can be configured with: - aes-128-gcm, aes-196-gcm and aes-256-gcm for ENCR_AES_GCM_16 - aes-128-gcm-12, aes-196-gcm-12 and aes-256-gcm-12 for ENCR_AES_GCM_12 It would be nice if we could get some interop testing with different IKEv2 implementations. I have so far successfully tested strongswan <-> iked and of course iked <-> iked. Feedback welcome ;) [1] https://tools.ietf.org/html/rfc5282 [2] https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml#ikev2-parameters-5 Index: crypto.c === RCS file: /cvs/src/sbin/iked/crypto.c,v retrieving revision 1.26 diff -u -p -r1.26 crypto.c --- crypto.c22 Apr 2020 17:26:54 - 1.26 +++ crypto.c14 May 2020 20:00:28 - @@ -92,7 +92,7 @@ hash_new(uint8_t type, uint16_t id) struct iked_hash*hash; const EVP_MD*md = NULL; HMAC_CTX*ctx = NULL; - int length = 0, fixedkey = 0, trunc = 0; + int length = 0, fixedkey = 0, trunc = 0, isaead = 0; switch (type) { case IKEV2_XFORMTYPE_PRF: @@ -156,6 +156,14 @@ hash_new(uint8_t type, uint16_t id) length = SHA512_DIGEST_LENGTH; trunc = 32; break; + case IKEV2_XFORMAUTH_AES_GCM_12: + length = 12; + isaead = 1; + break; + case IKEV2_XFORMAUTH_AES_GCM_16: + length = 16; + isaead = 1; + break; case IKEV2_XFORMAUTH_NONE: case IKEV2_XFORMAUTH_DES_MAC: case IKEV2_XFORMAUTH_KPDK_MD5: @@ -177,7 +185,7 @@ hash_new(uint8_t type, uint16_t id) print_map(id, ikev2_xformtype_map)); break; } - if (md == NULL) + if (!isaead && md == NULL) return (NULL); if ((hash = calloc(1, sizeof(*hash))) == NULL) { @@ -192,6 +200,10 @@ hash_new(uint8_t type, uint16_t id) hash->hash_trunc = trunc; hash->hash_length = length; hash->hash_fixedkey = fixedkey; + hash->hash_isaead = isaead; + + if (isaead) + return (hash); if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { log_debug("%s: alloc hash ctx", __func__); @@ -276,6 +288,7 @@ cipher_new(uint8_t type, uint16_t id, ui const EVP_CIPHER*cipher = NULL; EVP_CIPHER_CTX *ctx = NULL; int length = 0, fixedkey = 0, ivlength = 0; + int saltlength = 0, authid = 0; switch (type) { case IKEV2_XFORMTYPE_ENCR: @@ -309,6 +322,39 @@ cipher_new(uint8_t type, uint16_t id, ui ivlength = EVP_CIPHER_iv_length(cipher); fixedkey = EVP_CIPHER_key_length(cipher); break; + case IKEV2_XFORMENCR_AES_GCM_16: + case IKEV2_XFORMENCR_AES_GCM_12: + switch (id_length) { + case 128: + cipher = EVP_aes_128_gcm(); + break; + case 192: + cipher = EVP_aes_192_gcm(); + break; + case 256: + cipher = EVP_aes_256_gcm(); + break; + default: + log_debug("%s: invalid key length %d" + " for cipher %s", __func__, id_length, + print_map(id, ikev2_xformencr_map)); + break; + } + if (cipher == NULL) + break; + switch(id) { + case IKEV2_XFORMENCR_AES_GCM_16: + authid = IKEV2_XFORMAUTH_AES_GCM_16; + break; + case IKEV2_XFORMENCR_AES_GCM_12: + authid = IKEV2_XFORMAUTH_AES_GCM_12; + break; + } + length = EVP_CIPHER_block_size(cipher); + ivlength = 8; + saltlength = 4; + fixedkey = EVP_CIPHER_key_length(cipher) + saltlength; + break; case IKEV2_XFORMENCR_DES_IV64: case IKEV2_XFORMENCR_DES: case IKEV2_XFORMENCR_RC5: @@ -