[v3] OpenVPN: New AES-GCM cipher for N2N and RW

Message ID 1519566589-18901-1-git-send-email-erik.kapfer@ipfire.org
State Accepted
Commit 52f61e496df86f1a70fa9d468d64e756bdb66f4d
Headers
Series [v3] OpenVPN: New AES-GCM cipher for N2N and RW |

Commit Message

Peter Müller via Development Feb. 26, 2018, 12:49 a.m. UTC
  AES-GCM 128, 196 and 256 bit has been added to Net-to-Net and Roadwarrior section.

HMAC selection for N2N will be disabled if AES-GCM is used since GCM provides an own message authentication (GMAC).
    'auth *' line in N2N.conf will be deleted appropriately if AES-GCM is used since '--tls-auth' is not available for N2N.
HMAC selection menu for Roadwarriors is still available since '--tls-auth' is available for RWs
    which uses the configuered HMAC even AES-GCM has been applied.

Signed-off-by: Erik Kapfer <erik.kapfer@ipfire.org>
---
 html/cgi-bin/ovpnmain.cgi | 84 ++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 69 insertions(+), 15 deletions(-)
  

Comments

Peter Müller via Development Feb. 26, 2018, 4:06 a.m. UTC | #1
Hi,

I suppose this looks alright.

Does OpenVPN 2.4 support ChaCha20-Poly1305, too?

-Michael

On Sun, 2018-02-25 at 14:49 +0100, Erik Kapfer via Development wrote:
> AES-GCM 128, 196 and 256 bit has been added to Net-to-Net and Roadwarrior section.
> 
> HMAC selection for N2N will be disabled if AES-GCM is used since GCM provides an own message authentication (GMAC).
>     'auth *' line in N2N.conf will be deleted appropriately if AES-GCM is used since '--tls-auth' is not available for N2N.
> HMAC selection menu for Roadwarriors is still available since '--tls-auth' is available for RWs
>     which uses the configuered HMAC even AES-GCM has been applied.
> 
> Signed-off-by: Erik Kapfer <erik.kapfer@ipfire.org>
> ---
>  html/cgi-bin/ovpnmain.cgi | 84 ++++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 69 insertions(+), 15 deletions(-)
> 
> diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi
> index c52e8ba..ff3d055 100644
> --- a/html/cgi-bin/ovpnmain.cgi
> +++ b/html/cgi-bin/ovpnmain.cgi
> @@ -970,12 +970,18 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
>    print SERVERCONF "dh ${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}\n";
>    print SERVERCONF "# Cipher\n"; 
>    print SERVERCONF "cipher $cgiparams{'DCIPHER'}\n";
> -  if ($cgiparams{'DAUTH'} eq '') {
> -	print SERVERCONF "auth SHA1\n";
> +
> +  # If GCM cipher is used, do not use --auth
> +  if (($cgiparams{'DCIPHER'} eq 'AES-256-GCM') ||
> +      ($cgiparams{'DCIPHER'} eq 'AES-192-GCM') ||
> +      ($cgiparams{'DCIPHER'} eq 'AES-128-GCM')) {
> +    print SERVERCONF unless "# HMAC algorithm\n";
> +    print SERVERCONF unless "auth $cgiparams{'DAUTH'}\n";
>    } else {
> -	print SERVERCONF "# HMAC algorithm\n";
> -	print SERVERCONF "auth $cgiparams{'DAUTH'}\n";
> +    print SERVERCONF "# HMAC algorithm\n";
> +    print SERVERCONF "auth $cgiparams{'DAUTH'}\n";
>    }
> +
>    if ($cgiparams{'COMPLZO'} eq 'on') {
>     print SERVERCONF "# Enable Compression\n";
>     print SERVERCONF "comp-lzo\n";
> @@ -1076,12 +1082,18 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
>    print CLIENTCONF "# Cipher\n"; 
>    print CLIENTCONF "cipher $cgiparams{'DCIPHER'}\n";
>    print CLIENTCONF "pkcs12 ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12\r\n";
> -  if ($cgiparams{'DAUTH'} eq '') {
> -	print CLIENTCONF "auth SHA1\n";
> +
> +  # If GCM cipher is used, do not use --auth
> +  if (($cgiparams{'DCIPHER'} eq 'AES-256-GCM') ||
> +      ($cgiparams{'DCIPHER'} eq 'AES-192-GCM') ||
> +      ($cgiparams{'DCIPHER'} eq 'AES-128-GCM')) {
> +    print CLIENTCONF unless "# HMAC algorithm\n";
> +    print CLIENTCONF unless "auth $cgiparams{'DAUTH'}\n";
>    } else {
> -	print CLIENTCONF "# HMAC algorithm\n";
> -	print CLIENTCONF "auth $cgiparams{'DAUTH'}\n";
> +    print CLIENTCONF "# HMAC algorithm\n";
> +    print CLIENTCONF "auth $cgiparams{'DAUTH'}\n";
>    }
> +
>    if ($cgiparams{'COMPLZO'} eq 'on') {
>     print CLIENTCONF "# Enable Compression\n";
>     print CLIENTCONF "comp-lzo\n";
> @@ -2198,13 +2210,18 @@ if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
>  	 print CLIENTCONF "pkcs12 ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12\r\n";
>       $zip->addFile( "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12", "$confighash{$cgiparams{'KEY'}}[1].p12") or die "Can't add file $confighash{$cgiparams{'KEY'}}[1].p12\n";
>     }
> -   if ($confighash{$cgiparams{'KEY'}}[39] eq '') {
> -	print CLIENTCONF "# HMAC algorithm\n";
> -	print CLIENTCONF "auth SHA1\n";
> +
> +   # If GCM cipher is used, do not use --auth
> +   if (($confighash{$cgiparams{'KEY'}}[40] eq 'AES-256-GCM') ||
> +       ($confighash{$cgiparams{'KEY'}}[40] eq 'AES-192-GCM') ||
> +       ($confighash{$cgiparams{'KEY'}}[40] eq 'AES-128-GCM')) {
> +        print CLIENTCONF unless "# HMAC algorithm\n";
> +        print CLIENTCONF unless "auth $confighash{$cgiparams{'KEY'}}[39]\n";
>     } else {
> -   print CLIENTCONF "# HMAC algorithm\n";
> -   print CLIENTCONF "auth $confighash{$cgiparams{'KEY'}}[39]\n";
> +        print CLIENTCONF "# HMAC algorithm\n";
> +        print CLIENTCONF "auth $confighash{$cgiparams{'KEY'}}[39]\n";
>     }
> +
>     if ($confighash{$cgiparams{'KEY'}}[30] eq 'on') {
>     print CLIENTCONF "# Enable Compression\n";
>     print CLIENTCONF "comp-lzo\n";
> @@ -4544,6 +4561,9 @@ if ($cgiparams{'TYPE'} eq 'net') {
>      }
>      $checked{'PMTU_DISCOVERY'}{$cgiparams{'PMTU_DISCOVERY'}} = 'checked=\'checked\'';
>  
> +    $selected{'DCIPHER'}{'AES-256-GCM'} = '';
> +    $selected{'DCIPHER'}{'AES-192-GCM'} = '';
> +    $selected{'DCIPHER'}{'AES-128-GCM'} = '';
>      $selected{'DCIPHER'}{'CAMELLIA-256-CBC'} = '';
>      $selected{'DCIPHER'}{'CAMELLIA-192-CBC'} = '';
>      $selected{'DCIPHER'}{'CAMELLIA-128-CBC'} = '';
> @@ -4629,6 +4649,15 @@ if ($cgiparams{'TYPE'} eq 'net') {
>  	    } else {
>  		print "<td width='25%'><input type='text' name='NAME' value='$cgiparams{'NAME'}' maxlength='20' /></td>";
>  	    }
> +
> +		# If GCM ciphers are in usage, HMAC menu is disabled
> +		my $hmacdisabled;
> +		if (($confighash{$cgiparams{'KEY'}}[40] eq 'AES-256-GCM') ||
> +			($confighash{$cgiparams{'KEY'}}[40] eq 'AES-192-GCM') ||
> +			($confighash{$cgiparams{'KEY'}}[40] eq 'AES-128-GCM')) {
> +				$hmacdisabled = "disabled='disabled'";
> +		};
> +
>  	    print <<END;
>  		    <td width='25%'>&nbsp;</td>
>  		    <td width='25%'>&nbsp;</td></tr>	
> @@ -4707,7 +4736,10 @@ if ($cgiparams{'TYPE'} eq 'net') {
>  	</tr>
>  
>  	<tr><td class='boldbase'>$Lang::tr{'cipher'}</td>
> -		<td><select name='DCIPHER'>
> +		<td><select name='DCIPHER'  id="n2ncipher" required>
> +				<option value='AES-256-GCM'		$selected{'DCIPHER'}{'AES-256-GCM'}>AES-GCM (256 $Lang::tr{'bit'})</option>
> +				<option value='AES-192-GCM'		$selected{'DCIPHER'}{'AES-192-GCM'}>AES-GCM (192 $Lang::tr{'bit'})</option>
> +				<option value='AES-128-GCM'		$selected{'DCIPHER'}{'AES-128-GCM'}>AES-GCM (128 $Lang::tr{'bit'})</option>
>  				<option value='CAMELLIA-256-CBC'	$selected{'DCIPHER'}{'CAMELLIA-256-CBC'}>CAMELLIA-CBC (256 $Lang::tr{'bit'})</option>
>  				<option value='CAMELLIA-192-CBC'	$selected{'DCIPHER'}{'CAMELLIA-192-CBC'}>CAMELLIA-CBC (192 $Lang::tr{'bit'})</option>
>  				<option value='CAMELLIA-128-CBC'	$selected{'DCIPHER'}{'CAMELLIA-128-CBC'}>CAMELLIA-CBC (128 $Lang::tr{'bit'})</option>
> @@ -4724,7 +4756,7 @@ if ($cgiparams{'TYPE'} eq 'net') {
>  		</td>
>  
>  		<td class='boldbase'>$Lang::tr{'ovpn ha'}:</td>
> -		<td><select name='DAUTH'>
> +		<td><select name='DAUTH' id="n2nhmac" $hmacdisabled>
>  				<option value='whirlpool'		$selected{'DAUTH'}{'whirlpool'}>Whirlpool (512 $Lang::tr{'bit'})</option>
>  				<option value='SHA512'			$selected{'DAUTH'}{'SHA512'}>SHA2 (512 $Lang::tr{'bit'})</option>
>  				<option value='SHA384'			$selected{'DAUTH'}{'SHA384'}>SHA2 (384 $Lang::tr{'bit'})</option>
> @@ -4738,6 +4770,22 @@ if ($cgiparams{'TYPE'} eq 'net') {
>  END
>  ;
>  	}
> +
> +#### JAVA SCRIPT ####
> +# Validate N2N cipher. If GCM will be used, HMAC menu will be disabled onchange
> +print<<END;
> +	<script>
> +		var disable_options = false;
> +		document.getElementById('n2ncipher').onchange = function () {
> +			if((this.value == "AES-256-GCM"||this.value == "AES-192-GCM"||this.value == "AES-128-GCM")) {
> +				document.getElementById('n2nhmac').setAttribute('disabled', true);
> +			} else {
> +				document.getElementById('n2nhmac').removeAttribute('disabled');
> +			}
> +		}
> +	</script>
> +END
> +
>  #jumper
>  	print "<tr><td class='boldbase'>$Lang::tr{'remark title'}</td>";
>  	print "<td colspan='3'><input type='text' name='REMARK' value='$cgiparams{'REMARK'}' size='55' maxlength='50' /></td></tr></table>";
> @@ -5109,6 +5157,9 @@ END
>      $selected{'DPROTOCOL'}{'tcp'} = '';
>      $selected{'DPROTOCOL'}{$cgiparams{'DPROTOCOL'}} = 'SELECTED';
>  
> +    $selected{'DCIPHER'}{'AES-256-GCM'} = '';
> +    $selected{'DCIPHER'}{'AES-192-GCM'} = '';
> +    $selected{'DCIPHER'}{'AES-128-GCM'} = '';
>      $selected{'DCIPHER'}{'CAMELLIA-256-CBC'} = '';
>      $selected{'DCIPHER'}{'CAMELLIA-192-CBC'} = '';
>      $selected{'DCIPHER'}{'CAMELLIA-128-CBC'} = '';
> @@ -5205,6 +5256,9 @@ END
>  
>  		<td class='boldbase' nowrap='nowrap'>$Lang::tr{'cipher'}</td>
>  		<td><select name='DCIPHER'>
> +				<option value='AES-256-GCM' $selected{'DCIPHER'}{'AES-256-GCM'}>AES-GCM (256 $Lang::tr{'bit'})</option>
> +				<option value='AES-192-GCM' $selected{'DCIPHER'}{'AES-192-GCM'}>AES-GCM (192 $Lang::tr{'bit'})</option>
> +				<option value='AES-128-GCM' $selected{'DCIPHER'}{'AES-128-GCM'}>AES-GCM (128 $Lang::tr{'bit'})</option>
>  				<option value='CAMELLIA-256-CBC' $selected{'DCIPHER'}{'CAMELLIA-256-CBC'}>CAMELLIA-CBC (256 $Lang::tr{'bit'})</option>
>  				<option value='CAMELLIA-192-CBC' $selected{'DCIPHER'}{'CAMELLIA-192-CBC'}>CAMELLIA-CBC (192 $Lang::tr{'bit'})</option>
>  				<option value='CAMELLIA-128-CBC' $selected{'DCIPHER'}{'CAMELLIA-128-CBC'}>CAMELLIA-CBC (128 $Lang::tr{'bit'})</option>
  
Peter Müller via Development Feb. 26, 2018, 5:48 p.m. UTC | #2
Hi Michael,

Am Sonntag, den 25.02.2018, 17:06 +0000 schrieb Michael Tremer via
Development:
> Hi,
> 
> I suppose this looks alright.
OK

> 
> Does OpenVPN 2.4 support ChaCha20-Poly1305, too?
Yes, but i think only via the '--tls-cipher' directive which IPFire
currently do not supports via WUI. Made a quick try over the
server.conf.local and the additional configuration.

server.conf.local entries:

tls-version-min 1.2
tls-cipher TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256

whereby the server logs points the following out: 

Feb 26 07:19:47 ipfire-prime openvpnserver[10190]:   cipher_list = 'TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256'

But in general we step into a new crypto era with OpenVPN since ECC is now fully integrated in OpenVPN.

Under the hood we will discover now also ECDHE for the control channel without changing anything so the EC crypto is now partly available 
with Core 120.

But pure elliptic curve crypto is also possible e.g.
https://forums.openvpn.net/viewtopic.php?t=23227
but this would be a huge amount of changes in ovpnmain.cgi but may it is worth it. Let´s see...

> 
> -Michael

Greetings,

Erik
  
Peter Müller via Development Feb. 26, 2018, 9:24 p.m. UTC | #3
Hi,

some ECC in OpenVPN would be really nice. We have that in IPsec for quite a
while now and it makes the tunnels come up a lot faster and we can assume that
it is more secure, too.

ChaCha20-Poly1305 is quite interesting, too. It is an AEAD just like AES-*-GCM.
It is supposed to be really fast on mobile devices and an alternative to AES. We
only have one other alternative to AES which is Camellia. But that one does not
seem to receive a lot of love these days.

In contrast to Camellia, AES is usually hardware-accelerated whereas ChaCha20
can be implemented very efficiently in software that it does not consume too
much CPU time at all. Perfect for mobile to save battery life.

Probably there is not very good support for ChaCha20-Poly1305 out there. So AES
will be the default, but we would have a very good alternative for anyone who
know what they are doing.

Best,
-Michael

On Mon, 2018-02-26 at 07:48 +0100, ummeegge wrote:
> Hi Michael,
> 
> Am Sonntag, den 25.02.2018, 17:06 +0000 schrieb Michael Tremer via
> Development:
> > Hi,
> > 
> > I suppose this looks alright.
> 
> OK
> 
> > 
> > Does OpenVPN 2.4 support ChaCha20-Poly1305, too?
> 
> Yes, but i think only via the '--tls-cipher' directive which IPFire
> currently do not supports via WUI. Made a quick try over the
> server.conf.local and the additional configuration.
> 
> server.conf.local entries:
> 
> tls-version-min 1.2
> tls-cipher TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256
> 
> whereby the server logs points the following out: 
> 
> Feb 26 07:19:47 ipfire-prime openvpnserver[10190]:   cipher_list = 'TLS-ECDHE-
> RSA-WITH-CHACHA20-POLY1305-SHA256'
> 
> But in general we step into a new crypto era with OpenVPN since ECC is now
> fully integrated in OpenVPN.
> 
> Under the hood we will discover now also ECDHE for the control channel without
> changing anything so the EC crypto is now partly available 
> with Core 120.
> 
> But pure elliptic curve crypto is also possible e.g.
> https://forums.openvpn.net/viewtopic.php?t=23227
> but this would be a huge amount of changes in ovpnmain.cgi but may it is worth
> it. Let´s see...
> 
> > 
> > -Michael
> 
> Greetings,
> 
> Erik
>
  
Peter Müller via Development Feb. 27, 2018, 5:23 p.m. UTC | #4
Hi Michael,

Am Montag, den 26.02.2018, 10:24 +0000 schrieb Michael Tremer via
Development:
> Hi,
> 
> some ECC in OpenVPN would be really nice. We have that in IPsec for
> quite a
> while now and it makes the tunnels come up a lot faster and we can
> assume that
> it is more secure, too.
I can confirm this here too, the key exchange on IPFires updated
OpenVPN looks now like this

Control Channel: TLSv1.2, cipher TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384,
8192 bit RSA

even i used 8192 bit in my testing scenario (normally 2048 bit) the
connection build up and the key exchange is really fast.

> 
> ChaCha20-Poly1305 is quite interesting, too. It is an AEAD just like
> AES-*-GCM.
> It is supposed to be really fast on mobile devices and an alternative
> to AES. We
> only have one other alternative to AES which is Camellia. But that
> one does not
> seem to receive a lot of love these days.
Seed is also available which did not marked as 'weak' but possibly not as widely used as the others 
i think. A modern cipher usage from Mozilla can be found in here --> 
https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
whereby there are some limitations for IPFire since we do not have currently
the possiblity for ECDSA instead of RSA, also OpenVPN limits at this time character lenght to 
256 'Maximum optione line length (256) exceeded' which should be a known bug and also a fixed one
https://community.openvpn.net/openvpn/ticket/631
but it appears again in 2.4.4 . Checked it and this

ipfire-server openvpnserver[16775]:   cipher_list = 'TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384:TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256:TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256:TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256'

was the maximum. 

> 
> In contrast to Camellia, AES is usually hardware-accelerated whereas
> ChaCha20
> can be implemented very efficiently in software that it does not
> consume too
> much CPU time at all. Perfect for mobile to save battery life.
> 
> Probably there is not very good support for ChaCha20-Poly1305 out
> there. So AES
> will be the default, but we would have a very good alternative for
> anyone who
> know what they are doing.
If someone wants to use ChaCha20-Poly1305 this should be no problem via
via the "Additional configuration".

May we should set also AES-256-GCM as default cipher instead of AES-
256-CBC in ovpnmain.cgi ?!

ECDSA instead of RSA might be also worth to think about but as i said,
this implies huge changes.

> 
> Best,
> -Michael
> 
> On Mon, 2018-02-26 at 07:48 +0100, ummeegge wrote:
> > 
> > Hi Michael,
> > 
> > Am Sonntag, den 25.02.2018, 17:06 +0000 schrieb Michael Tremer via
> > Development:
> > > 
> > > Hi,
> > > 
> > > I suppose this looks alright.
> > OK
> > 
> > > 
> > > 
> > > Does OpenVPN 2.4 support ChaCha20-Poly1305, too?
> > Yes, but i think only via the '--tls-cipher' directive which IPFire
> > currently do not supports via WUI. Made a quick try over the
> > server.conf.local and the additional configuration.
> > 
> > server.conf.local entries:
> > 
> > tls-version-min 1.2
> > tls-cipher TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256
> > 
> > whereby the server logs points the following out: 
> > 
> > Feb 26 07:19:47 ipfire-prime openvpnserver[10190]:   cipher_list =
> > 'TLS-ECDHE-
> > RSA-WITH-CHACHA20-POLY1305-SHA256'
> > 
> > But in general we step into a new crypto era with OpenVPN since ECC
> > is now
> > fully integrated in OpenVPN.
> > 
> > Under the hood we will discover now also ECDHE for the control
> > channel without
> > changing anything so the EC crypto is now partly available 
> > with Core 120.
> > 
> > But pure elliptic curve crypto is also possible e.g.
> > https://forums.openvpn.net/viewtopic.php?t=23227
> > but this would be a huge amount of changes in ovpnmain.cgi but may
> > it is worth
> > it. Let´s see...
> > 
> > > 
> > > 
> > > -Michael
> > Greetings,
> > 
> > Erik
> >
  

Patch

diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi
index c52e8ba..ff3d055 100644
--- a/html/cgi-bin/ovpnmain.cgi
+++ b/html/cgi-bin/ovpnmain.cgi
@@ -970,12 +970,18 @@  unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
   print SERVERCONF "dh ${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}\n";
   print SERVERCONF "# Cipher\n"; 
   print SERVERCONF "cipher $cgiparams{'DCIPHER'}\n";
-  if ($cgiparams{'DAUTH'} eq '') {
-	print SERVERCONF "auth SHA1\n";
+
+  # If GCM cipher is used, do not use --auth
+  if (($cgiparams{'DCIPHER'} eq 'AES-256-GCM') ||
+      ($cgiparams{'DCIPHER'} eq 'AES-192-GCM') ||
+      ($cgiparams{'DCIPHER'} eq 'AES-128-GCM')) {
+    print SERVERCONF unless "# HMAC algorithm\n";
+    print SERVERCONF unless "auth $cgiparams{'DAUTH'}\n";
   } else {
-	print SERVERCONF "# HMAC algorithm\n";
-	print SERVERCONF "auth $cgiparams{'DAUTH'}\n";
+    print SERVERCONF "# HMAC algorithm\n";
+    print SERVERCONF "auth $cgiparams{'DAUTH'}\n";
   }
+
   if ($cgiparams{'COMPLZO'} eq 'on') {
    print SERVERCONF "# Enable Compression\n";
    print SERVERCONF "comp-lzo\n";
@@ -1076,12 +1082,18 @@  unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
   print CLIENTCONF "# Cipher\n"; 
   print CLIENTCONF "cipher $cgiparams{'DCIPHER'}\n";
   print CLIENTCONF "pkcs12 ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12\r\n";
-  if ($cgiparams{'DAUTH'} eq '') {
-	print CLIENTCONF "auth SHA1\n";
+
+  # If GCM cipher is used, do not use --auth
+  if (($cgiparams{'DCIPHER'} eq 'AES-256-GCM') ||
+      ($cgiparams{'DCIPHER'} eq 'AES-192-GCM') ||
+      ($cgiparams{'DCIPHER'} eq 'AES-128-GCM')) {
+    print CLIENTCONF unless "# HMAC algorithm\n";
+    print CLIENTCONF unless "auth $cgiparams{'DAUTH'}\n";
   } else {
-	print CLIENTCONF "# HMAC algorithm\n";
-	print CLIENTCONF "auth $cgiparams{'DAUTH'}\n";
+    print CLIENTCONF "# HMAC algorithm\n";
+    print CLIENTCONF "auth $cgiparams{'DAUTH'}\n";
   }
+
   if ($cgiparams{'COMPLZO'} eq 'on') {
    print CLIENTCONF "# Enable Compression\n";
    print CLIENTCONF "comp-lzo\n";
@@ -2198,13 +2210,18 @@  if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
 	 print CLIENTCONF "pkcs12 ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12\r\n";
      $zip->addFile( "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12", "$confighash{$cgiparams{'KEY'}}[1].p12") or die "Can't add file $confighash{$cgiparams{'KEY'}}[1].p12\n";
    }
-   if ($confighash{$cgiparams{'KEY'}}[39] eq '') {
-	print CLIENTCONF "# HMAC algorithm\n";
-	print CLIENTCONF "auth SHA1\n";
+
+   # If GCM cipher is used, do not use --auth
+   if (($confighash{$cgiparams{'KEY'}}[40] eq 'AES-256-GCM') ||
+       ($confighash{$cgiparams{'KEY'}}[40] eq 'AES-192-GCM') ||
+       ($confighash{$cgiparams{'KEY'}}[40] eq 'AES-128-GCM')) {
+        print CLIENTCONF unless "# HMAC algorithm\n";
+        print CLIENTCONF unless "auth $confighash{$cgiparams{'KEY'}}[39]\n";
    } else {
-   print CLIENTCONF "# HMAC algorithm\n";
-   print CLIENTCONF "auth $confighash{$cgiparams{'KEY'}}[39]\n";
+        print CLIENTCONF "# HMAC algorithm\n";
+        print CLIENTCONF "auth $confighash{$cgiparams{'KEY'}}[39]\n";
    }
+
    if ($confighash{$cgiparams{'KEY'}}[30] eq 'on') {
    print CLIENTCONF "# Enable Compression\n";
    print CLIENTCONF "comp-lzo\n";
@@ -4544,6 +4561,9 @@  if ($cgiparams{'TYPE'} eq 'net') {
     }
     $checked{'PMTU_DISCOVERY'}{$cgiparams{'PMTU_DISCOVERY'}} = 'checked=\'checked\'';
 
+    $selected{'DCIPHER'}{'AES-256-GCM'} = '';
+    $selected{'DCIPHER'}{'AES-192-GCM'} = '';
+    $selected{'DCIPHER'}{'AES-128-GCM'} = '';
     $selected{'DCIPHER'}{'CAMELLIA-256-CBC'} = '';
     $selected{'DCIPHER'}{'CAMELLIA-192-CBC'} = '';
     $selected{'DCIPHER'}{'CAMELLIA-128-CBC'} = '';
@@ -4629,6 +4649,15 @@  if ($cgiparams{'TYPE'} eq 'net') {
 	    } else {
 		print "<td width='25%'><input type='text' name='NAME' value='$cgiparams{'NAME'}' maxlength='20' /></td>";
 	    }
+
+		# If GCM ciphers are in usage, HMAC menu is disabled
+		my $hmacdisabled;
+		if (($confighash{$cgiparams{'KEY'}}[40] eq 'AES-256-GCM') ||
+			($confighash{$cgiparams{'KEY'}}[40] eq 'AES-192-GCM') ||
+			($confighash{$cgiparams{'KEY'}}[40] eq 'AES-128-GCM')) {
+				$hmacdisabled = "disabled='disabled'";
+		};
+
 	    print <<END;
 		    <td width='25%'>&nbsp;</td>
 		    <td width='25%'>&nbsp;</td></tr>	
@@ -4707,7 +4736,10 @@  if ($cgiparams{'TYPE'} eq 'net') {
 	</tr>
 
 	<tr><td class='boldbase'>$Lang::tr{'cipher'}</td>
-		<td><select name='DCIPHER'>
+		<td><select name='DCIPHER'  id="n2ncipher" required>
+				<option value='AES-256-GCM'		$selected{'DCIPHER'}{'AES-256-GCM'}>AES-GCM (256 $Lang::tr{'bit'})</option>
+				<option value='AES-192-GCM'		$selected{'DCIPHER'}{'AES-192-GCM'}>AES-GCM (192 $Lang::tr{'bit'})</option>
+				<option value='AES-128-GCM'		$selected{'DCIPHER'}{'AES-128-GCM'}>AES-GCM (128 $Lang::tr{'bit'})</option>
 				<option value='CAMELLIA-256-CBC'	$selected{'DCIPHER'}{'CAMELLIA-256-CBC'}>CAMELLIA-CBC (256 $Lang::tr{'bit'})</option>
 				<option value='CAMELLIA-192-CBC'	$selected{'DCIPHER'}{'CAMELLIA-192-CBC'}>CAMELLIA-CBC (192 $Lang::tr{'bit'})</option>
 				<option value='CAMELLIA-128-CBC'	$selected{'DCIPHER'}{'CAMELLIA-128-CBC'}>CAMELLIA-CBC (128 $Lang::tr{'bit'})</option>
@@ -4724,7 +4756,7 @@  if ($cgiparams{'TYPE'} eq 'net') {
 		</td>
 
 		<td class='boldbase'>$Lang::tr{'ovpn ha'}:</td>
-		<td><select name='DAUTH'>
+		<td><select name='DAUTH' id="n2nhmac" $hmacdisabled>
 				<option value='whirlpool'		$selected{'DAUTH'}{'whirlpool'}>Whirlpool (512 $Lang::tr{'bit'})</option>
 				<option value='SHA512'			$selected{'DAUTH'}{'SHA512'}>SHA2 (512 $Lang::tr{'bit'})</option>
 				<option value='SHA384'			$selected{'DAUTH'}{'SHA384'}>SHA2 (384 $Lang::tr{'bit'})</option>
@@ -4738,6 +4770,22 @@  if ($cgiparams{'TYPE'} eq 'net') {
 END
 ;
 	}
+
+#### JAVA SCRIPT ####
+# Validate N2N cipher. If GCM will be used, HMAC menu will be disabled onchange
+print<<END;
+	<script>
+		var disable_options = false;
+		document.getElementById('n2ncipher').onchange = function () {
+			if((this.value == "AES-256-GCM"||this.value == "AES-192-GCM"||this.value == "AES-128-GCM")) {
+				document.getElementById('n2nhmac').setAttribute('disabled', true);
+			} else {
+				document.getElementById('n2nhmac').removeAttribute('disabled');
+			}
+		}
+	</script>
+END
+
 #jumper
 	print "<tr><td class='boldbase'>$Lang::tr{'remark title'}</td>";
 	print "<td colspan='3'><input type='text' name='REMARK' value='$cgiparams{'REMARK'}' size='55' maxlength='50' /></td></tr></table>";
@@ -5109,6 +5157,9 @@  END
     $selected{'DPROTOCOL'}{'tcp'} = '';
     $selected{'DPROTOCOL'}{$cgiparams{'DPROTOCOL'}} = 'SELECTED';
 
+    $selected{'DCIPHER'}{'AES-256-GCM'} = '';
+    $selected{'DCIPHER'}{'AES-192-GCM'} = '';
+    $selected{'DCIPHER'}{'AES-128-GCM'} = '';
     $selected{'DCIPHER'}{'CAMELLIA-256-CBC'} = '';
     $selected{'DCIPHER'}{'CAMELLIA-192-CBC'} = '';
     $selected{'DCIPHER'}{'CAMELLIA-128-CBC'} = '';
@@ -5205,6 +5256,9 @@  END
 
 		<td class='boldbase' nowrap='nowrap'>$Lang::tr{'cipher'}</td>
 		<td><select name='DCIPHER'>
+				<option value='AES-256-GCM' $selected{'DCIPHER'}{'AES-256-GCM'}>AES-GCM (256 $Lang::tr{'bit'})</option>
+				<option value='AES-192-GCM' $selected{'DCIPHER'}{'AES-192-GCM'}>AES-GCM (192 $Lang::tr{'bit'})</option>
+				<option value='AES-128-GCM' $selected{'DCIPHER'}{'AES-128-GCM'}>AES-GCM (128 $Lang::tr{'bit'})</option>
 				<option value='CAMELLIA-256-CBC' $selected{'DCIPHER'}{'CAMELLIA-256-CBC'}>CAMELLIA-CBC (256 $Lang::tr{'bit'})</option>
 				<option value='CAMELLIA-192-CBC' $selected{'DCIPHER'}{'CAMELLIA-192-CBC'}>CAMELLIA-CBC (192 $Lang::tr{'bit'})</option>
 				<option value='CAMELLIA-128-CBC' $selected{'DCIPHER'}{'CAMELLIA-128-CBC'}>CAMELLIA-CBC (128 $Lang::tr{'bit'})</option>