Re: iked(8): AES_GCM ciphers for IKE

2020-05-26 Thread Tobias Heider
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

2020-05-20 Thread Remi Locherer
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

2020-05-18 Thread Tobias Heider
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

2020-05-16 Thread Christian Weisgerber
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

2020-05-16 Thread Stephan Mending
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

2020-05-14 Thread Tobias Heider
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

2020-05-14 Thread Tobias Heider
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

2020-05-14 Thread Stephan Mending
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

2020-05-14 Thread Tobias Heider
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

2020-05-14 Thread Tobias Heider
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:
@@ -