Skip to contentSkip to conversation

GOST algorithm support for OpenVPN

Openvpn-devel In review Heiko Hund 5 participants 13 messages Aug 16, 2012 – Jun 5, 2014

lore
Share & tools
lore

Heiko Hund

author
#0 lore raw

OpenSSL since version 1.0.0 supports the Russian cryptographic standard algorithms, commonly called GOST algorithms. Use of GOST in SSL/TLS is standardized by the IETF, thus openvpn is the VPN software of choice for Russian users when constrained to use GOST algorithms.

With this patch series, users can choose to use GOST by using the algorithms in the X.509 PKI and configuring openvpn with, e.g.

--engine gost
--auth gost-mac
--cipher gost89
--tls-cipher GOST2001-GOST89-GOST89

More information about the GOST algorithms can be found in IETF RFCs:

  4357  Additional Cryptographic Algorithms for Use with GOST Algorithms
  4490  GOST Algorithms with the Cryptographic Message Syntax (CMS)
  4491  GOST Algorithms with the Internet X.509 Public Key Infrastructure (PKI)
  5830  GOST 28147-89 Block Cipher and MAC Algorithms
  5831  GOST R 34.11-94 Hash Function Algorithm
  5832  GOST R 34.10-2001 Digital Signature Algorithm
author
#1 lore raw

PATCH 1/7 refine assertion to allow other modes than CBC

cipher_ctx_final() only returns an outlen in CBC mode. If CFB or OFB are used the assertion outlen == iv_len is always false.

There's no CBC mode defined for the GOST 28147-89 block cipher. Hence this patch is needed for it to work. It's needed for other ciphers like BF-CFB as well, though.

---
 src/openvpn/crypto.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
src/openvpn/crypto.c +1 -1
index ac2eecd..2f67e5e 100644
@@ -153,7 +153,7 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
 	  /* Flush the encryption buffer */
 	  ASSERT(cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen));
 	  work.len += outlen;
-	  ASSERT (outlen == iv_size);
+	  ASSERT (mode != OPENVPN_MODE_CBC || outlen == iv_size);
 
 	  /* prepend the IV to the ciphertext */
 	  if (opt->flags & CO_USE_IV)
Signature · 1 line
1.7.9.5
#2 lore raw

Re: [Openvpn-devel] [PATCH 1/7] refine assertion to allow other modes than CBC

Am 16.08.12 10:38, schrieb Heiko Hund:

Quoted 17 lines

cipher_ctx_final() only returns an outlen in CBC mode. If CFB or OFB are used the assertion outlen == iv_len is always false.

There's no CBC mode defined for the GOST 28147-89 block cipher. Hence this patch is needed for it to work. It's needed for other ciphers like BF-CFB as well, though.

---
 src/openvpn/crypto.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
src/openvpn/crypto.c +0 -0
index ac2eecd..2f67e5e 100644

src/openvpn/crypto.c openvpn_encrypt (struct buffer *buf, struct buffer work, · line 159

Quoted 8 lines
src/openvpn/crypto.c +1 -1
@@ -153,7 +153,7 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
 	  /* Flush the encryption buffer */
 	  ASSERT(cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen));
 	  work.len += outlen;
-	  ASSERT (outlen == iv_size);
+	  ASSERT (mode != OPENVPN_MODE_CBC || outlen == iv_size);
 
 	  /* prepend the IV to the ciphertext */
 	  if (opt->flags & CO_USE_IV)

I have a user of my app that also tripped over this asssert line:

Quoted 7 lines

Here is the log that pointed it to me from the server side.

Wed Jan 30 14:47:56 2013 208.54.86.158:52876 WARNING: 'cipher' is used inconsistently, local='cipher AES-128-CBC', remote='cipher AES-128-CFB'

Before that I had used cipher AES-256-CFB8, but I had forgotten the 8 on the Android.

#3 lore raw

Re: [Openvpn-devel] [PATCH 1/7] refine assertion to allow other modes than CBC

Quoted 25 lines · Arne Schwabe

Am 16.08.12 10:38, schrieb Heiko Hund:

Quoted 23 lines

cipher_ctx_final() only returns an outlen in CBC mode. If CFB or OFB are used the assertion outlen == iv_len is always false.

There's no CBC mode defined for the GOST 28147-89 block cipher. Hence this patch is needed for it to work. It's needed for other ciphers like BF-CFB as well, though.

---
 src/openvpn/crypto.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
src/openvpn/crypto.c +1 -1
index ac2eecd..2f67e5e 100644
@@ -153,7 +153,7 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
 	  /* Flush the encryption buffer */
 	  ASSERT(cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen));
 	  work.len += outlen;
-	  ASSERT (outlen == iv_size);
+	  ASSERT (mode != OPENVPN_MODE_CBC || outlen == iv_size);
 
Quoted 7 lines

src/openvpn/crypto.c openvpn_encrypt (struct buffer *buf, struct buffer work, · line 159

Quoted 3 lines
src/openvpn/crypto.c +0 -0
 	  /* prepend the IV to the ciphertext */
 	  if (opt->flags & CO_USE_IV)

I have a user of my app that also tripped over this asssert line:

eeeehhh - removing the assert is nice, but do the other ciphers actually *WORK* after that? does the test
openvpn --test-crypto
pass after that? I remember commenting out the assert for a few elliptic curve ciphers, but openvpn was still not able to encrypt/decrypt traffic successfully.

JJK

#4 lore raw

Re: [Openvpn-devel] [PATCH 1/7] refine assertion to allow other modes than CBC

Am 03.02.13 14:55, schrieb Jan Just Keijser:

Quoted 35 lines
Quoted 27 lines · Arne Schwabe

Am 16.08.12 10:38, schrieb Heiko Hund:

Quoted 25 lines

cipher_ctx_final() only returns an outlen in CBC mode. If CFB or OFB are used the assertion outlen == iv_len is always false.

There's no CBC mode defined for the GOST 28147-89 block cipher. Hence this patch is needed for it to work. It's needed for other ciphers like BF-CFB as well, though.

---
 src/openvpn/crypto.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
src/openvpn/crypto.c +1 -1
index ac2eecd..2f67e5e 100644
@@ -153,7 +153,7 @@ openvpn_encrypt (struct buffer *buf, struct
 buffer work,
       /* Flush the encryption buffer */
       ASSERT(cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen,
 &outlen));
       work.len += outlen;
-      ASSERT (outlen == iv_size);
+      ASSERT (mode != OPENVPN_MODE_CBC || outlen == iv_size);
 
Quoted 7 lines
Quoted 3 lines
       /* prepend the IV to the ciphertext */
       if (opt->flags & CO_USE_IV)

I have a user of my app that also tripped over this asssert line:

Quoted 6 lines

eeeehhh - removing the assert is nice, but do the other ciphers actually *WORK* after that? does the test
openvpn --test-crypto
pass after that? I remember commenting out the assert for a few elliptic curve ciphers, but openvpn was still not able to encrypt/decrypt traffic successfully

I have no idea of the crypto involved. But if there is a known class of cryptos that fails in this "obscure" way we should exit with error much earlier.

Arne

#5 lore raw

Re: [Openvpn-devel] [PATCH 1/7] refine assertion to allow other modes than CBC

In reply to Jan Just Keijser

ACK (see attached and below for more details).

Quoted 33 lines · Jan Just Keijser
Quoted 25 lines · Arne Schwabe

Am 16.08.12 10:38, schrieb Heiko Hund:

Quoted 23 lines

cipher_ctx_final() only returns an outlen in CBC mode. If CFB or OFB are used the assertion outlen == iv_len is always false.

There's no CBC mode defined for the GOST 28147-89 block cipher. Hence this patch is needed for it to work. It's needed for other ciphers like BF-CFB as well, though.

---
 src/openvpn/crypto.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
src/openvpn/crypto.c +1 -1
index ac2eecd..2f67e5e 100644
@@ -153,7 +153,7 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
 	  /* Flush the encryption buffer */
 	  ASSERT(cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen));
 	  work.len += outlen;
-	  ASSERT (outlen == iv_size);
+	  ASSERT (mode != OPENVPN_MODE_CBC || outlen == iv_size);
 
Quoted 7 lines

src/openvpn/crypto.c openvpn_encrypt (struct buffer *buf, struct buffer work, · line 159

Quoted 3 lines
src/openvpn/crypto.c +0 -0
 	  /* prepend the IV to the ciphertext */
 	  if (opt->flags & CO_USE_IV)

I have a user of my app that also tripped over this asssert line:

Quoted 6 lines

eeeehhh - removing the assert is nice, but do the other ciphers actually *WORK* after that? does the test
openvpn --test-crypto
pass after that? I remember commenting out the assert for a few elliptic curve ciphers, but openvpn was still not able to encrypt/decrypt traffic successfully.

I came up with (almost) the same patch to fix OFB and CFB modes last week, but then came across this almost 2 years old patch from Heiko while searching for the history on these modes in OpenVPN. I rebased it on master and ran some tests (attached the updated patch).

Manual --test-crypto and t_lpback tests for CBC, OFB and CFB, as well as the regular t_client tests for CBC succeed. Everything looks good to me.

-Steffan

From 606ed6ba90b1705de1546f4f151b524f46393082 Mon Sep 17 00:00:00 2001
From: Heiko Hund <[email protected]...>
Date: Thu, 16 Aug 2012 10:38:50 +0200
Subject: [PATCH] refine assertion to allow other modes than CBC

cipher_ctx_final() only returns an outlen in CBC mode. If CFB or OFB are used the assertion outlen == iv_len is always false.

There's no CBC mode defined for the GOST 28147-89 block cipher. Hence this patch is needed for it to work. It's needed for other ciphers like BF-CFB as well, though.

---
 src/openvpn/crypto.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
src/openvpn/crypto.c +1 -1
index c4c356d..d0dc069 100644
@@ -171,7 +171,7 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
 	  /* Flush the encryption buffer */
 	  ASSERT(cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen));
 	  work.len += outlen;
-	  ASSERT (outlen == iv_size);
+	  ASSERT (mode != OPENVPN_MODE_CBC || outlen == iv_size);
 
 	  /* prepend the IV to the ciphertext */
 	  if (opt->flags & CO_USE_IV)
Signature · 1 line
1.9.1
#6 lore raw

[Openvpn-devel] [PATCH applied] Re: refine assertion to allow other modes than CBC

Your patch has been applied to the master branch.

commit be46a2c083a6bd77754bc1674249eab583d25dac

Author: Heiko Hund
Date:   Thu Aug 16 10:38:50 2012 +0200
     refine assertion to allow other modes than CBC

     Signed-off-by: Heiko Hund <[email protected]...>
     Acked-by: Steffan Karger <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8748
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

author
#7 lore raw

PATCH 2/7 init crypto engine before SSL library

In reply to Heiko Hund

Since GOST in OpenSSL is implemented in an engine, the engine must be loaded before the SSL library is initialized for the algorithms to become available for SSL/TLS.

This delays the initialization of the ssl lib until after the options are parsed, so a possibly configured engine can be loaded before.

---
 src/openvpn/init.c    |   65 +++++++++++++++++--------------------------------
 src/openvpn/init.h    |    1 +
 src/openvpn/openvpn.c |   22 +++++++++++++++++
 3 files changed, 45 insertions(+), 43 deletions(-)
src/openvpn/init.c +22 -43
index 270ee6a..564621d 100644
@@ -589,10 +589,6 @@ init_static (void)
 {
   /* configure_path (); */
 
-#if defined(ENABLE_CRYPTO) && defined(DMALLOC)
-  crypto_init_dmalloc();
-#endif
-
   init_random_seed ();		/* init random() function, only used as
 				   source for weak random numbers */
   error_reset ();		/* initialize error.c */
@@ -612,15 +608,6 @@ init_static (void)
 
   update_time ();
 
-#ifdef ENABLE_CRYPTO
-  init_ssl_lib ();
-
-  /* init PRNG used for IV generation */
-  /* When forking, copy this to more places in the code to avoid fork
-     random-state predictability */
-  prng_init (NULL, 0);
-#endif
-
 #ifdef PID_TEST
   packet_id_interactive_test ();	/* test the sequence number code */
   return false;
@@ -699,29 +686,6 @@ init_static (void)
   }
 #endif
 
-#ifdef PRNG_TEST
-  {
-    struct gc_arena gc = gc_new ();
-    uint8_t rndbuf[8];
-    int i;
-    prng_init ("sha1", 16);
-    /*prng_init (NULL, 0);*/
-    const int factor = 1;
-    for (i = 0; i < factor * 8; ++i)
-      {
-#if 1
-	prng_bytes (rndbuf, sizeof (rndbuf));
-#else
-	ASSERT(rand_bytes (rndbuf, sizeof (rndbuf)));
-#endif
-	printf ("[%d] %s\n", i, format_hex (rndbuf, sizeof (rndbuf), 0, &gc));
-      }
-    gc_free (&gc);
-    prng_uninit ();
-    return false;
-  }
-#endif
-
 #ifdef BUFFER_LIST_AGGREGATE_TEST
   /* test buffer_list_aggregate function */
   {
@@ -798,10 +762,6 @@ init_static (void)
 void
 uninit_static (void)
 {
-#ifdef ENABLE_CRYPTO
-  free_ssl_lib ();
-#endif
-
 #ifdef ENABLE_PKCS11
   pkcs11_terminate ();
 #endif
@@ -1942,9 +1902,6 @@ key_schedule_free (struct key_schedule *ks, bool free_ssl_ctx)
 static void
 init_crypto_pre (struct context *c, const unsigned int flags)
 {
-  if (c->options.engine)
-    crypto_init_lib_engine (c->options.engine);
-
   if (flags & CF_LOAD_PERSISTED_PACKET_ID)
     {
       /* load a persisted packet-id for cross-session replay-protection */
@@ -3715,6 +3672,28 @@ test_crypto_thread (void *arg)
 #endif
 
 bool
+do_test_prng ()
+{
+#ifdef PRNG_TEST
+  struct gc_arena gc = gc_new ();
+  uint8_t rndbuf[8];
+  int i;
+  prng_init ("sha1", 16);
+  const int factor = 1;
+  for (i = 0; i < factor * 8; ++i)
+    {
+      prng_bytes (rndbuf, sizeof (rndbuf));
+      printf ("[%d] %s\n", i, format_hex (rndbuf, sizeof (rndbuf), 0, &gc));
+    }
+  gc_free (&gc);
+  prng_uninit ();
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool
 do_test_crypto (const struct options *o)
 {
 #ifdef ENABLE_CRYPTO
src/openvpn/init.h +1 -0
index 5a1d1dc..ed95f85 100644
@@ -70,6 +70,7 @@ void do_route (const struct options *options,
 
 void close_instance (struct context *c);
 
+bool do_test_prng ();
 bool do_test_crypto (const struct options *o);
 
 void context_gc_free (struct context *c);
src/openvpn/openvpn.c +22 -0
index 104c9e9..170abe1 100644
@@ -187,6 +187,25 @@ openvpn_main (int argc, char *argv[])
 	  /* parse command line options, and read configuration file */
 	  parse_argv (&c.options, argc, argv, M_USAGE, OPT_P_DEFAULT, NULL, c.es);
 
+#ifdef ENABLE_CRYPTO
+#ifdef DMALLOC
+          crypto_init_dmalloc ();
+#endif
+          /* initialize crypto and ssl/tls libraries */
+          if (c.options.engine)
+            crypto_init_lib_engine (c.options.engine);
+          init_ssl_lib ();
+
+          /*
+           * init PRNG used for IV generation
+           * when forking, copy this to more places in the code to avoid fork
+           * random-state predictability
+           */
+          prng_init (NULL, 0);
+          if (do_test_prng ())
+            break;
+#endif
+
 #ifdef ENABLE_PLUGIN
 	  /* plugins may contribute options configuration */
 	  init_verb_mute (&c, IVM_LEVEL_1);
@@ -269,6 +288,9 @@ openvpn_main (int argc, char *argv[])
 	    }
 	  while (c.sig->signal_received == SIGUSR1);
 
+#ifdef ENABLE_CRYPTO
+          free_ssl_lib ();
+#endif
 	  uninit_options (&c.options);
 	  gc_reset (&c.gc);
 	}
Signature · 1 line
1.7.9.5
author
#8 lore raw

PATCH 3/7 remove API for crypto engine initialization

In reply to Heiko Hund

Since the crypto library and the crypto engine initialization are now happening at the same time, there's no apparent need for two distinct APIs the init them anymore.

The crypto engine is now initialized within the crypto library init function, which makes to code look a bit cleaner.

---
 src/openvpn/crypto.c          |    4 ++--
 src/openvpn/crypto.h          |    2 +-
 src/openvpn/crypto_backend.h  |    7 +------
 src/openvpn/crypto_openssl.c  |    7 +++++--
 src/openvpn/crypto_polarssl.c |   18 ++++--------------
 src/openvpn/openvpn.c         |    4 +---
 src/openvpn/ssl.c             |    5 ++---
 src/openvpn/ssl.h             |    2 +-
 8 files changed, 17 insertions(+), 32 deletions(-)
src/openvpn/crypto.c +2 -2
index 2f67e5e..b95865e 100644
@@ -1376,9 +1376,9 @@ get_random()
 #ifndef ENABLE_SSL
 
 void
-init_ssl_lib (void)
+init_ssl_lib (const char *engine_name)
 {
-  crypto_init_lib ();
+  crypto_init_lib (engine_name);
 }
 
 void
src/openvpn/crypto.h +1 -1
index 3b4b88e..cd08cf3 100644
@@ -358,7 +358,7 @@ void get_tls_handshake_key (const struct key_type *key_type,
 
 #else
 
-void init_ssl_lib (void);
+void init_ssl_lib (const char *engine_name);
 void free_ssl_lib (void);
 
 #endif /* ENABLE_SSL */
src/openvpn/crypto_backend.h +1 -6
index 1eac611..9727a92 100644
@@ -43,17 +43,12 @@
  * This routine should have additional OpenSSL crypto library initialisations
  * used by both crypto and ssl components of OpenVPN.
  */
-void crypto_init_lib (void);
+void crypto_init_lib (const char *engine_name);
 
 void crypto_uninit_lib (void);
 
 void crypto_clear_error (void);
 
-/*
- * Initialise the given named crypto engine.
- */
-void crypto_init_lib_engine (const char *engine_name);
-
 #ifdef DMALLOC
 /*
  * OpenSSL memory debugging.  If dmalloc debugging is enabled, tell
src/openvpn/crypto_openssl.c +5 -2
index 5342502..a7ee168 100644
@@ -169,7 +169,7 @@ setup_engine (const char *engine)
 
 #endif /* HAVE_OPENSSL_ENGINE */
 
-void
+static void
 crypto_init_lib_engine (const char *engine_name)
 {
 #if HAVE_OPENSSL_ENGINE
@@ -192,8 +192,11 @@ crypto_init_lib_engine (const char *engine_name)
  */
 
 void
-crypto_init_lib (void)
+crypto_init_lib (const char *engine_name)
 {
+  if (engine_name)
+    crypto_init_lib_engine (engine_name);
+
 #ifndef USE_SSL
 #ifndef ENABLE_SMALL
   ERR_load_crypto_strings ();
src/openvpn/crypto_polarssl.c +4 -14
index 3978a3c..b7f13e3 100644
@@ -54,26 +54,16 @@
 
 /*
  *
- * Hardware engine support. Allows loading/unloading of engines.
- *
- */
-
-void
-crypto_init_lib_engine (const char *engine_name)
-{
-  msg (M_WARN, "Note: PolarSSL hardware crypto engine functionality is not "
-      "available");
-}
-
-/*
- *
  * Functions related to the core crypto library
  *
  */
 
 void
-crypto_init_lib (void)
+crypto_init_lib (const char *engine_name)
 {
+  if (engine_name)
+    msg (M_WARN, "Note: PolarSSL hardware crypto engine functionality is not "
+        "available");
 }
 
 void
src/openvpn/openvpn.c +1 -3
index 170abe1..65f43c3 100644
@@ -192,9 +192,7 @@ openvpn_main (int argc, char *argv[])
           crypto_init_dmalloc ();
 #endif
           /* initialize crypto and ssl/tls libraries */
-          if (c.options.engine)
-            crypto_init_lib_engine (c.options.engine);
-          init_ssl_lib ();
+          init_ssl_lib (c.options.engine);
 
           /*
            * init PRNG used for IV generation
src/openvpn/ssl.c +2 -3
index 19512c0..e9a7d0a 100644
@@ -153,11 +153,10 @@ tls_init_control_channel_frame_parameters(const struct frame *data_channel_frame
 }
 
 void
-init_ssl_lib ()
+init_ssl_lib (const char *engine_name)
 {
+  crypto_init_lib (engine_name);
   tls_init_lib ();
-
-  crypto_init_lib ();
 }
 
 void
src/openvpn/ssl.h +1 -1
index cd7cae2..daa654c 100644
@@ -144,7 +144,7 @@ struct tls_auth_standalone
 /*
  * Prepare the SSL library for use
  */
-void init_ssl_lib (void);
+void init_ssl_lib (const char *engine_name);
 
 /*
  * Free any internal state that the SSL library might have
Signature · 1 line
1.7.9.5
author
#9 lore raw

PATCH 4/7 support crypto engine options

In reply to Heiko Hund

OpenVPN supports using OpenSSL engines by loading them with the --engine configuration option. Some of those engines require configuration options themself.

This patch extends the --engine option so that engine-options can be specified as well.

---
 doc/openvpn.8                 |   11 ++++++-----
 src/openvpn/crypto.c          |    4 ++--
 src/openvpn/crypto.h          |    2 +-
 src/openvpn/crypto_backend.h  |   17 ++++++++++++++++-
 src/openvpn/crypto_openssl.c  |   33 +++++++++++++++++++++------------
 src/openvpn/crypto_polarssl.c |    4 ++--
 src/openvpn/options.c         |   32 +++++++++++++++++++++++++++-----
 src/openvpn/options.h         |    3 ++-
 src/openvpn/ssl.c             |    4 ++--
 src/openvpn/ssl.h             |    2 +-
 10 files changed, 80 insertions(+), 32 deletions(-)
doc/openvpn.8 +6 -5
index 56be29e..d967ebd 100644
@@ -3704,13 +3704,14 @@ to disable the PRNG and use the OpenSSL RAND_bytes function
 instead for all of OpenVPN's pseudo-random number needs.
 .\"*********************************************************
 .TP
-.B \-\-engine [engine-name]
-Enable OpenSSL hardware-based crypto engine functionality.
-
+.B \-\-engine [engine-name [engine-option ...]]
+Enable OpenSSL crypto engine functionality.
 If
 .B engine-name
-is specified,
-use a specific crypto engine.  Use the
+is specified, use a specific crypto engine.
+.B engine-options
+must be given as name=value pairs.
+Use the
 .B \-\-show-engines
 standalone option to list the crypto engines which are
 supported by OpenSSL.
src/openvpn/crypto.c +2 -2
index b95865e..7fdbb95 100644
@@ -1376,9 +1376,9 @@ get_random()
 #ifndef ENABLE_SSL
 
 void
-init_ssl_lib (const char *engine_name)
+init_ssl_lib (const struct crypto_engine *engine)
 {
-  crypto_init_lib (engine_name);
+  crypto_init_lib (engine);
 }
 
 void
src/openvpn/crypto.h +1 -1
index cd08cf3..5c34597 100644
@@ -358,7 +358,7 @@ void get_tls_handshake_key (const struct key_type *key_type,
 
 #else
 
-void init_ssl_lib (const char *engine_name);
+void init_ssl_lib (const struct crypto_engine *engine);
 void free_ssl_lib (void);
 
 #endif /* ENABLE_SSL */
src/openvpn/crypto_backend.h +16 -1
index 9727a92..4b68687 100644
@@ -40,10 +40,25 @@
 
 
 /*
+ * Structures for crypto library engine configuration.
+ */
+struct crypto_engine_option
+{
+  struct crypto_engine_option *next;
+  const char *name;
+  const char *value;
+};
+struct crypto_engine
+{
+  const char *name;
+  struct crypto_engine_option *options;
+};
+
+/*
  * This routine should have additional OpenSSL crypto library initialisations
  * used by both crypto and ssl components of OpenVPN.
  */
-void crypto_init_lib (const char *engine_name);
+void crypto_init_lib (const struct crypto_engine *engine);
 
 void crypto_uninit_lib (void);
 
src/openvpn/crypto_openssl.c +21 -12
index a7ee168..deaf0ca 100644
@@ -135,7 +135,7 @@ try_load_engine (const char *engine)
 }
 
 static ENGINE *
-setup_engine (const char *engine)
+setup_engine (const struct crypto_engine *engine)
 {
   ENGINE *e = NULL;
 
@@ -143,24 +143,33 @@ setup_engine (const char *engine)
 
   if (engine)
     {
-      if (strcmp (engine, "auto") == 0)
+      struct crypto_engine_option *o;
+      
+      if (strcmp (engine->name, "auto") == 0)
 	{
 	  msg (M_INFO, "Initializing OpenSSL auto engine support");
 	  ENGINE_register_all_complete ();
 	  return NULL;
 	}
-      if ((e = ENGINE_by_id (engine)) == NULL
-	 && (e = try_load_engine (engine)) == NULL)
+      if ((e = ENGINE_by_id (engine->name)) == NULL
+	 && (e = try_load_engine (engine->name)) == NULL)
 	{
-	  msg (M_FATAL, "OpenSSL error: cannot load engine '%s'", engine);
+	  msg (M_FATAL, "OpenSSL error: cannot load engine '%s'", engine->name);
 	}
 
       if (!ENGINE_set_default (e, ENGINE_METHOD_ALL))
 	{
 	  msg (M_FATAL, "OpenSSL error: ENGINE_set_default failed on engine '%s'",
-	       engine);
+	       engine->name);
 	}
 
+      for (o = engine->options; o; o = o->next)
+        {
+          if (!ENGINE_ctrl_cmd_string (e, o->name, o->value, 0))
+            msg (M_FATAL, "OpenSSL error: ENGINE_ctrl_cmd_string failed on engine '%s'",
+                engine->name);
+        }
+
       msg (M_INFO, "Initializing OpenSSL support for engine '%s'",
 	   ENGINE_get_id (e));
     }
@@ -170,14 +179,14 @@ setup_engine (const char *engine)
 #endif /* HAVE_OPENSSL_ENGINE */
 
 static void
-crypto_init_lib_engine (const char *engine_name)
+crypto_init_lib_engine (const struct crypto_engine *engine)
 {
 #if HAVE_OPENSSL_ENGINE
   if (!engine_initialized)
     {
-      ASSERT (engine_name);
+      ASSERT (engine->name);
       ASSERT (!engine_persist);
-      engine_persist = setup_engine (engine_name);
+      engine_persist = setup_engine (engine);
       engine_initialized = true;
     }
 #else
@@ -192,10 +201,10 @@ crypto_init_lib_engine (const char *engine_name)
  */
 
 void
-crypto_init_lib (const char *engine_name)
+crypto_init_lib (const struct crypto_engine *engine)
 {
-  if (engine_name)
-    crypto_init_lib_engine (engine_name);
+  if (engine)
+    crypto_init_lib_engine (engine);
 
 #ifndef USE_SSL
 #ifndef ENABLE_SMALL
src/openvpn/crypto_polarssl.c +2 -2
index b7f13e3..6b1193a 100644
@@ -59,9 +59,9 @@
  */
 
 void
-crypto_init_lib (const char *engine_name)
+crypto_init_lib (const struct crypto_engine *engine)
 {
-  if (engine_name)
+  if (engine)
     msg (M_WARN, "Note: PolarSSL hardware crypto engine functionality is not "
         "available");
 }
src/openvpn/options.c +27 -5
index 19690e1..b78ff15 100644
@@ -531,7 +531,7 @@ static const char usage_message[] =
   "                  If unspecified, defaults to cipher-specific default.\n"
 #endif
 #ifndef ENABLE_CRYPTO_POLARSSL
-  "--engine [name] : Enable OpenSSL hardware crypto engine functionality.\n"
+  "--engine [name [opts]] : Enable OpenSSL crypto engine functionality.\n"
 #endif
   "--no-replay     : Disable replay protection.\n"
   "--mute-replay-warnings : Silence the output of replay warnings to log file.\n"
@@ -6287,12 +6287,34 @@ add_option (struct options *options,
   else if (streq (p[0], "engine"))
     {
       VERIFY_PERMISSION (OPT_P_GENERAL);
+      ALLOC_OBJ_CLEAR_GC (options->engine, struct crypto_engine, &options->gc);
+      
       if (p[1])
-	{
-	  options->engine = p[1];
-	}
+        {
+          int i;
+
+          options->engine->name = p[1];
+
+          for (i = 2; p[i]; i++)
+            {
+              struct crypto_engine_option *next_option;
+              char *eq = strchr (p[i], '=');
+              if (eq == NULL)
+                {
+                  msg (msglevel, "Bad option for engine %s: %s", p[1], p[i]);
+                  goto err;
+                }
+              *eq = '\0';
+
+              next_option = options->engine->options;
+              ALLOC_OBJ_GC (options->engine->options, struct crypto_engine_option, &options->gc);
+              options->engine->options->next = next_option;
+              options->engine->options->name = p[i];
+              options->engine->options->value = eq + 1;
+            }
+        }
       else
-	options->engine = "auto";
+        options->engine->name = "auto";
     }  
 #endif /* ENABLE_CRYPTO_POLARSSL */
 #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH
src/openvpn/options.h +2 -1
index 306520b..36eab25 100644
@@ -42,6 +42,7 @@
 #include "lzo.h"
 #include "pushlist.h"
 #include "clinat.h"
+#include "crypto.h"
 
 /*
  * Maximum number of parameters associated with an option,
@@ -481,7 +482,7 @@ struct options
   int keysize;
   const char *prng_hash;
   int prng_nonce_secret_len;
-  const char *engine;
+  struct crypto_engine *engine;
   bool replay;
   bool mute_replay_warnings;
   int replay_window;
src/openvpn/ssl.c +2 -2
index e9a7d0a..a1a0628 100644
@@ -153,9 +153,9 @@ tls_init_control_channel_frame_parameters(const struct frame *data_channel_frame
 }
 
 void
-init_ssl_lib (const char *engine_name)
+init_ssl_lib (const struct crypto_engine *engine)
 {
-  crypto_init_lib (engine_name);
+  crypto_init_lib (engine);
   tls_init_lib ();
 }
 
src/openvpn/ssl.h +1 -1
index daa654c..001e4fd 100644
@@ -144,7 +144,7 @@ struct tls_auth_standalone
 /*
  * Prepare the SSL library for use
  */
-void init_ssl_lib (const char *engine_name);
+void init_ssl_lib (const struct crypto_engine *engine);
 
 /*
  * Free any internal state that the SSL library might have
Signature · 1 line
1.7.9.5
author
#10 lore raw

PATCH 5/7 have crypto backends report the MAC key length

In reply to Heiko Hund

This is in preparation for GOST MAC support. GOST MAC takes a 256 bit key and produces a 32 bit signature. Hence there needs to be an API for querying the key length as well.

---
 src/openvpn/crypto.c          |   45 +++++++++++++++++++++--------------------
 src/openvpn/crypto.h          |    1 +
 src/openvpn/crypto_backend.h  |    9 +++++++++
 src/openvpn/crypto_openssl.c  |    7 +++++++
 src/openvpn/crypto_polarssl.c |    8 ++++++++
 src/openvpn/openvpn.h         |    2 +-
 6 files changed, 49 insertions(+), 23 deletions(-)
src/openvpn/crypto.c +23 -22
index 7fdbb95..f86c83a 100644
@@ -430,6 +430,7 @@ init_key_type (struct key_type *kt, const char *ciphername,
     {
       kt->digest = md_kt_get (authname);
       kt->hmac_length = md_kt_size (kt->digest);
+      kt->hmac_key_length = hmac_key_size (kt->digest);
     }
   else
     {
@@ -465,17 +466,17 @@ init_key_ctx (struct key_ctx *ctx, struct key *key,
           cipher_kt_block_size(kt->cipher),
           cipher_kt_iv_size(kt->cipher));
     }
-  if (kt->digest && kt->hmac_length > 0)
+  if (kt->digest && kt->hmac_key_length > 0)
     {
       ALLOC_OBJ(ctx->hmac, hmac_ctx_t);
-      hmac_ctx_init (ctx->hmac, key->hmac, kt->hmac_length, kt->digest);
+      hmac_ctx_init (ctx->hmac, key->hmac, kt->hmac_key_length, kt->digest);
 
       msg (D_HANDSHAKE,
       "%s: Using %d bit message hash '%s' for HMAC authentication",
       prefix, md_kt_size(kt->digest) * 8, md_kt_name(kt->digest));
 
       dmsg (D_SHOW_KEYS, "%s: HMAC KEY: %s", prefix,
-	  format_hex (key->hmac, kt->hmac_length, 0, &gc));
+	  format_hex (key->hmac, kt->hmac_key_length, 0, &gc));
 
       dmsg (D_CRYPTO_DEBUG, "%s: HMAC size=%d block_size=%d",
 	prefix,
@@ -610,7 +611,7 @@ void
 generate_key_random (struct key *key, const struct key_type *kt)
 {
   int cipher_len = MAX_CIPHER_KEY_LENGTH;
-  int hmac_len = MAX_HMAC_KEY_LENGTH;
+  int hmac_key_len = MAX_HMAC_KEY_LENGTH;
 
   struct gc_arena gc = gc_new ();
 
@@ -621,15 +622,15 @@ generate_key_random (struct key *key, const struct key_type *kt)
 	if (kt->cipher && kt->cipher_length > 0 && kt->cipher_length <= cipher_len)
 	  cipher_len = kt->cipher_length;
 
-	if (kt->digest && kt->hmac_length > 0 && kt->hmac_length <= hmac_len)
-	  hmac_len = kt->hmac_length;
+	if (kt->digest && kt->hmac_key_length > 0 && kt->hmac_key_length <= hmac_key_len)
+	  hmac_key_len = kt->hmac_key_length;
       }
     if (!rand_bytes (key->cipher, cipher_len)
-	|| !rand_bytes (key->hmac, hmac_len))
+	|| !rand_bytes (key->hmac, hmac_key_len))
       msg (M_FATAL, "ERROR: Random number generator cannot obtain entropy for key generation");
 
     dmsg (D_SHOW_KEY_SOURCE, "Cipher source entropy: %s", format_hex (key->cipher, cipher_len, 0, &gc));
-    dmsg (D_SHOW_KEY_SOURCE, "HMAC source entropy: %s", format_hex (key->hmac, hmac_len, 0, &gc));
+    dmsg (D_SHOW_KEY_SOURCE, "HMAC source entropy: %s", format_hex (key->hmac, hmac_key_len, 0, &gc));
 
     if (kt)
       fixup_key (key, kt);
@@ -654,13 +655,13 @@ key2_print (const struct key2* k,
        format_hex (k->keys[0].cipher, kt->cipher_length, 0, &gc));
   dmsg (D_SHOW_KEY_SOURCE, "%s (hmac): %s",
        prefix0,
-       format_hex (k->keys[0].hmac, kt->hmac_length, 0, &gc));
+       format_hex (k->keys[0].hmac, kt->hmac_key_length, 0, &gc));
   dmsg (D_SHOW_KEY_SOURCE, "%s (cipher): %s",
        prefix1,
        format_hex (k->keys[1].cipher, kt->cipher_length, 0, &gc));
   dmsg (D_SHOW_KEY_SOURCE, "%s (hmac): %s",
        prefix1,
-       format_hex (k->keys[1].hmac, kt->hmac_length, 0, &gc));
+       format_hex (k->keys[1].hmac, kt->hmac_key_length, 0, &gc));
   gc_free (&gc);
 }
 
@@ -727,7 +728,7 @@ get_tls_handshake_key (const struct key_type *key_type,
 		       const int key_direction,
 		       const unsigned int flags)
 {
-  if (passphrase_file && key_type->hmac_length)
+  if (passphrase_file && key_type->hmac_key_length)
     {
       struct key2 key2;
       struct key_type kt = *key_type;
@@ -762,16 +763,16 @@ get_tls_handshake_key (const struct key_type *key_type,
 	  }
 	else
 	  {
-	    int hash_size;
+	    int hash_key_size;
 
 	    CLEAR (key2);
 
 	    /* failed, now try to get hash from a freeform file */
-	    hash_size = read_passphrase_hash (passphrase_file,
+	    hash_key_size = read_passphrase_hash (passphrase_file,
 					      kt.digest,
 					      key2.keys[0].hmac,
 					      MAX_HMAC_KEY_LENGTH);
-	    ASSERT (hash_size == kt.hmac_length);
+	    ASSERT (hash_key_size == kt.hmac_key_length);
 
 	    /* suceeded */
 	    key2.n = 1;
@@ -1223,15 +1224,15 @@ write_key (const struct key *key, const struct key_type *kt,
 	   struct buffer *buf)
 {
   ASSERT (kt->cipher_length <= MAX_CIPHER_KEY_LENGTH
-	  && kt->hmac_length <= MAX_HMAC_KEY_LENGTH);
+	  && kt->hmac_key_length <= MAX_HMAC_KEY_LENGTH);
 
   if (!buf_write (buf, &kt->cipher_length, 1))
     return false;
-  if (!buf_write (buf, &kt->hmac_length, 1))
+  if (!buf_write (buf, &kt->hmac_key_length, 1))
     return false;
   if (!buf_write (buf, key->cipher, kt->cipher_length))
     return false;
-  if (!buf_write (buf, key->hmac, kt->hmac_length))
+  if (!buf_write (buf, key->hmac, kt->hmac_key_length))
     return false;
 
   return true;
@@ -1247,20 +1248,20 @@ int
 read_key (struct key *key, const struct key_type *kt, struct buffer *buf)
 {
   uint8_t cipher_length;
-  uint8_t hmac_length;
+  uint8_t hmac_key_length;
 
   CLEAR (*key);
   if (!buf_read (buf, &cipher_length, 1))
     goto read_err;
-  if (!buf_read (buf, &hmac_length, 1))
+  if (!buf_read (buf, &hmac_key_length, 1))
     goto read_err;
 
   if (!buf_read (buf, key->cipher, cipher_length))
     goto read_err;
-  if (!buf_read (buf, key->hmac, hmac_length))
+  if (!buf_read (buf, key->hmac, hmac_key_length))
     goto read_err;
 
-  if (cipher_length != kt->cipher_length || hmac_length != kt->hmac_length)
+  if (cipher_length != kt->cipher_length || hmac_key_length != kt->hmac_key_length)
     goto key_len_err;
 
   return 1;
@@ -1272,7 +1273,7 @@ read_err:
 key_len_err:
   msg (D_TLS_ERRORS,
        "TLS Error: key length mismatch, local cipher/hmac %d/%d, remote cipher/hmac %d/%d",
-       kt->cipher_length, kt->hmac_length, cipher_length, hmac_length);
+       kt->cipher_length, kt->hmac_key_length, cipher_length, hmac_key_length);
   return 0;
 }
 
src/openvpn/crypto.h +1 -0
index 5c34597..6f91b6f 100644
@@ -47,6 +47,7 @@ struct key_type
 {
   uint8_t cipher_length; 	/**< Cipher length, in bytes */
   uint8_t hmac_length;		/**< HMAC length, in bytes */
+  uint8_t hmac_key_length;      /**< HMAC key length, in bytes */
   const cipher_kt_t *cipher;	/**< Cipher static parameters */
   const md_kt_t *digest;	/**< Message digest static parameters */
 };
src/openvpn/crypto_backend.h +9 -0
index 4b68687..deff011 100644
@@ -443,6 +443,15 @@ void md_ctx_final (md_ctx_t *ctx, uint8_t *dst);
  */
 
 /*
+ * Returns the size of the HMAC key by the given message digest.
+ *
+ * @param ctx           Message digest context. May not be NULL.
+ *
+ * @return              Size of the HMAC key in bytes.
+ */
+int hmac_key_size (const md_kt_t *ctx);
+
+/*
  * Initialises the given HMAC context, using the given digest
  * and key.
  *
src/openvpn/crypto_openssl.c +7 -0
index deaf0ca..5665e29 100644
@@ -714,6 +714,13 @@ md_ctx_final (EVP_MD_CTX *ctx, uint8_t *dst)
  *
  */
 
+int
+hmac_key_size (const EVP_MD *kt)
+{
+  if (NULL == kt)
+    return 0;
+  return md_kt_size (kt);
+}
 
 void
 hmac_ctx_init (HMAC_CTX *ctx, const uint8_t *key, int key_len,
src/openvpn/crypto_polarssl.c +8 -0
index 6b1193a..b44ea12 100644
@@ -546,6 +546,14 @@ md_ctx_final (md_context_t *ctx, uint8_t *dst)
 /*
  * TODO: re-enable dmsg for crypto debug
  */
+int
+hmac_key_size (const md_info_t *kt)
+{
+  if (NULL == kt)
+    return 0;
+  return md_get_size (kt);
+}
+
 void
 hmac_ctx_init (md_context_t *ctx, const uint8_t *key, int key_len, const md_info_t *kt)
 {
src/openvpn/openvpn.h +1 -1
index 0732d0f..3ff5470 100644
@@ -572,7 +572,7 @@ struct context
 #define PROTO_DUMP(buf, gc) protocol_dump((buf), \
 				      PROTO_DUMP_FLAGS | \
 				      (c->c2.tls_multi ? PD_TLS : 0) | \
-				      (c->options.tls_auth_file ? c->c1.ks.key_type.hmac_length : 0), \
+				      (c->options.tls_auth_file ? c->c1.ks.key_type.hmac_key_length : 0), \
 				      gc)
 #else
 #define TLS_MODE(c) (false)
Signature · 1 line
1.7.9.5
author
#11 lore raw

PATCH 6/7 do MACs using EVP_MD_CTX with openssl >= 1.0.0

In reply to Heiko Hund

Using EVP_MD_CTX for MAC calculation allows to use other algorithms than HMAC. In this particular case it allows the GOST-MAC to be used. GOST-MAC uses a 256 bit key and produces a 32 bit signature.

Unfortunately OpenSSL has no API for querying a MAC's key length, so the key length is returned statically in the case of GOST-MAC.

---
 src/openvpn/crypto_openssl.c |   62 ++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/crypto_openssl.h |    4 +++
 2 files changed, 66 insertions(+)
src/openvpn/crypto_openssl.c +62 -0
index 5665e29..b5f3cef 100644
@@ -714,6 +714,66 @@ md_ctx_final (EVP_MD_CTX *ctx, uint8_t *dst)
  *
  */
 
+#if SSLEAY_VERSION_NUMBER >= 0x10000000L
+
+int
+hmac_key_size (const EVP_MD *kt)
+{
+  if (NULL == kt)
+    return 0;
+  return (EVP_MD_type (kt) == NID_id_Gost28147_89_MAC ? 32 : md_kt_size (kt));
+}
+
+void
+hmac_ctx_init (EVP_MD_CTX *ctx, const uint8_t *key, int key_len,
+    const EVP_MD *kt)
+{
+  int pkey_id;
+
+  ASSERT (NULL != kt && NULL != ctx);
+
+  pkey_id = ( EVP_MD_type (kt) == NID_id_Gost28147_89_MAC
+              ? NID_id_Gost28147_89_MAC : EVP_PKEY_HMAC );
+
+  EVP_MD_CTX_init (ctx);
+  EVP_DigestSignInit (ctx, NULL, kt, NULL,
+              EVP_PKEY_new_mac_key (pkey_id, NULL, (uint8_t *)key, key_len));
+}
+
+void
+hmac_ctx_cleanup (EVP_MD_CTX *ctx)
+{
+  /* frees the key implicitly */
+  EVP_MD_CTX_cleanup (ctx);
+}
+
+int
+hmac_ctx_size (const EVP_MD_CTX *ctx)
+{
+  return EVP_MD_CTX_size (ctx);
+}
+
+void
+hmac_ctx_reset (EVP_MD_CTX *ctx)
+{
+  EVP_DigestInit_ex (ctx, EVP_MD_CTX_md (ctx), NULL);
+}
+
+void
+hmac_ctx_update (EVP_MD_CTX *ctx, const uint8_t *src, int src_len)
+{
+  EVP_DigestSignUpdate (ctx, src, src_len);
+}
+
+void
+hmac_ctx_final (EVP_MD_CTX *ctx, uint8_t *dst)
+{
+  size_t mac_len = hmac_ctx_size (ctx);
+  EVP_DigestSignFinal (ctx, dst, &mac_len);
+}
+
+#else /* SSLEAY_VERSION_NUMBER >= 0x10000000L */
+
 int
 hmac_key_size (const EVP_MD *kt)
 {
@@ -769,4 +829,6 @@ hmac_ctx_final (HMAC_CTX *ctx, uint8_t *dst)
   HMAC_Final (ctx, dst, &in_hmac_len);
 }
 
+#endif /* SSLEAY_VERSION_NUMBER >= 0x10000000L */
+
 #endif /* ENABLE_CRYPTO && ENABLE_CRYPTO_OPENSSL */
src/openvpn/crypto_openssl.h +4 -0
index f883c2a..d7c9dd8 100644
@@ -47,7 +47,11 @@ typedef EVP_CIPHER_CTX cipher_ctx_t;
 typedef EVP_MD_CTX md_ctx_t;
 
 /** Generic HMAC %context. */
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+typedef EVP_MD_CTX hmac_ctx_t;
+#else
 typedef HMAC_CTX hmac_ctx_t;
+#endif
 
 /** Maximum length of an IV */
 #define OPENVPN_MAX_IV_LENGTH 	EVP_MAX_IV_LENGTH
Signature · 1 line
1.7.9.5
author
#12 lore raw

PATCH 7/7 change HMAC to MAC where applicable

In reply to Heiko Hund

Sine there's --auth gost-mac, using HMAC throughout the code is misleading. Especially in the crypto code itself.

This changes function and variable names as well as comments to use the more generic MAC instead.

---
 doc/openvpn.8                          |   46 ++++++-------
 sample/sample-config-files/server.conf |    2 +-
 src/openvpn/crypto.c                   |  118 ++++++++++++++++----------------
 src/openvpn/crypto.h                   |   42 ++++++------
 src/openvpn/crypto_backend.h           |   58 ++++++++--------
 src/openvpn/crypto_openssl.c           |   42 ++++++------
 src/openvpn/crypto_openssl.h           |    6 +-
 src/openvpn/crypto_polarssl.c          |   22 +++---
 src/openvpn/crypto_polarssl.h          |    4 +-
 src/openvpn/forward.c                  |    4 +-
 src/openvpn/forward.h                  |    2 +-
 src/openvpn/init.c                     |    2 +-
 src/openvpn/ntlm.c                     |   10 +--
 src/openvpn/openvpn.h                  |    8 +--
 src/openvpn/options.c                  |    2 +-
 src/openvpn/ssl.c                      |   94 ++++++++++++-------------
 src/openvpn/ssl.h                      |   12 ++--
 src/openvpn/ssl_common.h               |    4 +-
 18 files changed, 239 insertions(+), 239 deletions(-)
doc/openvpn.8 +23 -23
index d967ebd..c10283c 100644
@@ -3565,14 +3565,14 @@ which was generated with
 The optional
 .B direction
 parameter enables the use of 4 distinct keys
-(HMAC-send, cipher-encrypt, HMAC-receive, cipher-decrypt), so that
-each data flow direction has a different set of HMAC and cipher keys.
+(MAC-send, cipher-encrypt, MAC-receive, cipher-decrypt), so that
+each data flow direction has a different set of MAC and cipher keys.
 This has a number of desirable security properties including
 eliminating certain kinds of DoS and message replay attacks.
 
 When the
 .B direction
-parameter is omitted, 2 keys are used bidirectionally, one for HMAC
+parameter is omitted, 2 keys are used bidirectionally, one for MAC
 and the other for encryption/decryption.
 
 The
@@ -3622,25 +3622,25 @@ but random-looking data.
 .\"*********************************************************
 .TP
 .B \-\-auth alg
-Authenticate packets with HMAC using message
-digest algorithm
+Authenticate packets with a message authentication algorithm (MAC) using
+message digest algorithm
 .B alg.
 (The default is
 .B SHA1
 ).
-HMAC is a commonly used message authentication algorithm (MAC) that uses
+The commonly used message authentication algorithm is HMAC that uses
 a data string, a secure hash algorithm, and a key, to produce
 a digital signature.
 
-OpenVPN's usage of HMAC is to first encrypt a packet, then HMAC the resulting ciphertext.
+OpenVPN's usage of the MAC is to first encrypt a packet, then MAC the resulting ciphertext.
 
-In static-key encryption mode, the HMAC key
+In static-key encryption mode, the MAC key
 is included in the key file generated by
 .B \-\-genkey.
-In TLS mode, the HMAC key is dynamically generated and shared
+In TLS mode, the MAC key is dynamically generated and shared
 between peers via the TLS control channel.  If OpenVPN receives a packet with
-a bad HMAC it will drop the packet.
-HMAC usually adds 16 or 20 bytes per packet.
+a bad MAC it will drop the packet.
+MACs usually adds 16 or 20 bytes per packet.
 Set
 .B alg=none
 to disable authentication.
@@ -3945,12 +3945,12 @@ TLS mode is the most powerful crypto mode of OpenVPN in both security and flexib
 TLS mode works by establishing control and
 data channels which are multiplexed over a single TCP/UDP port.  OpenVPN initiates
 a TLS session over the control channel and uses it to exchange cipher
-and HMAC keys to protect the data channel.  TLS mode uses a robust reliability
+and MAC keys to protect the data channel.  TLS mode uses a robust reliability
 layer over the UDP connection for all control channel communication, while
 the data channel, over which encrypted tunnel data passes, is forwarded without
 any mediation.  The result is the best of both worlds: a fast data channel
 that forwards over UDP with only the overhead of encrypt,
-decrypt, and HMAC functions,
+decrypt, and MAC functions,
 and a control channel that provides all of the security features of TLS,
 including certificate-based authentication and Diffie Hellman forward secrecy.
 
@@ -4226,7 +4226,7 @@ for protecting the tunnel data channel is generated and
 exchanged over the TLS session.
 
 In method 1 (the default for OpenVPN 1.x), both sides generate
-random encrypt and HMAC-send keys which are forwarded to
+random encrypt and MAC-send keys which are forwarded to
 the other host over the TLS channel.
 
 In method 2, (the default for OpenVPN 2.0)
@@ -4364,14 +4364,14 @@ Exit on TLS negotiation failure.
 .\"*********************************************************
 .TP
 .B \-\-tls-auth file [direction]
-Add an additional layer of HMAC authentication on top of the TLS
+Add an additional layer of MAC authentication on top of the TLS
 control channel to protect against DoS attacks.
 
 In a nutshell,
 .B \-\-tls-auth
-enables a kind of "HMAC firewall" on OpenVPN's TCP/UDP port,
+enables a kind of "MAC firewall" on OpenVPN's TCP/UDP port,
 where TLS control channel packets
-bearing an incorrect HMAC signature can be dropped immediately without
+bearing an incorrect MAC signature can be dropped immediately without
 response.
 
 .B file
@@ -4385,7 +4385,7 @@ An OpenVPN static key file generated by
 parameter is used).
 
 .B (2)
-A freeform passphrase file.  In this case the HMAC key will
+A freeform passphrase file.  In this case the MAC key will
 be derived by taking a secure hash of this file, similar to
 the
 .BR md5sum (1)
@@ -4430,14 +4430,14 @@ fallen to buffer overflow attacks.
 So as a second line of defense, OpenVPN offers
 this special layer of authentication on top of the TLS control channel so that
 every packet on the control channel is authenticated by an
-HMAC signature and a unique ID for replay protection.
+MAC signature and a unique ID for replay protection.
 This signature will also help protect against DoS (Denial of Service) attacks.
 An important rule of thumb in reducing vulnerability to DoS attacks is to
 minimize the amount of resources a potential, but as yet unauthenticated,
 client is able to consume.
 
 .B \-\-tls-auth
-does this by signing every TLS control channel packet with an HMAC signature,
+does this by signing every TLS control channel packet with an MAC signature,
 including packets which are sent before the TLS level has had a chance
 to authenticate the peer.
 The result is that packets without
@@ -6214,9 +6214,9 @@ packets.  On Linux 2.4+:
 This will allow incoming packets on UDP port 1194 (OpenVPN's default UDP port)
 from an OpenVPN peer at 1.2.3.4.
 
-If you are using HMAC-based packet authentication (the default in any of
+If you are using MAC-based packet authentication (the default in any of
 OpenVPN's secure modes), having the firewall filter on source
-address can be considered optional, since HMAC packet authentication
+address can be considered optional, since MAC packet authentication
 is a much more secure method of verifying the authenticity of
 a packet source.  In that case:
 .IP
@@ -6263,7 +6263,7 @@ other hosts on the local network.
 These rules are secure if you use packet authentication,
 since no incoming packets will arrive on a TUN or TAP
 virtual device
-unless they first pass an HMAC authentication test.
+unless they first pass an MAC authentication test.
 .\"*********************************************************
 .SH FAQ
 .I http://openvpn.net/faq.html
sample/sample-config-files/server.conf +1 -1
index f483b6b..60d1355 100644
@@ -226,7 +226,7 @@ ifconfig-pool-persist ipp.txt
 keepalive 10 120
 
 # For extra security beyond that provided
-# by SSL/TLS, create an "HMAC firewall"
+# by SSL/TLS, create an "MAC firewall"
 # to help block DoS attacks and UDP port flooding.
 #
 # Generate with:
src/openvpn/crypto.c +59 -59

255 lines not on this page · raw message

src/openvpn/crypto.h +21 -21

127 lines not on this page · raw message

src/openvpn/crypto_backend.h +29 -29

117 lines not on this page · raw message

src/openvpn/crypto_openssl.c +21 -21

147 lines not on this page · raw message

src/openvpn/crypto_openssl.h +3 -3
index d7c9dd8..4c172db 100644
@@ -46,11 +46,11 @@ typedef EVP_CIPHER_CTX cipher_ctx_t;
 /** Generic message digest %context. */
 typedef EVP_MD_CTX md_ctx_t;
 
-/** Generic HMAC %context. */
+/** Generic MAC %context. */
 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
-typedef EVP_MD_CTX hmac_ctx_t;
+typedef EVP_MD_CTX mac_ctx_t;
 #else
-typedef HMAC_CTX hmac_ctx_t;
+typedef HMAC_CTX mac_ctx_t;
 #endif
 
 /** Maximum length of an IV */
src/openvpn/crypto_polarssl.c +11 -11
index b44ea12..e35fc07 100644
@@ -119,7 +119,7 @@ show_available_digests ()
 #ifndef ENABLE_SMALL
   printf ("The following message digests are available for use with\n"
 	  PACKAGE_NAME ".  A message digest is used in conjunction with\n"
-	  "the HMAC function, to authenticate received packets.\n"
+	  "the MAC function, to authenticate received packets.\n"
 	  "You can specify a message digest as parameter to\n"
 	  "the --auth option.\n\n");
 #endif
@@ -461,11 +461,11 @@ md_kt_get (const char *digest)
   md = md_info_from_string(digest);
   if (!md)
     msg (M_FATAL, "Message hash algorithm '%s' not found", digest);
-  if (md->size > MAX_HMAC_KEY_LENGTH)
+  if (md->size > MAX_MAC_KEY_LENGTH)
     msg (M_FATAL, "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum hash size (%d bytes)",
 	 digest,
 	 md->size,
-	 MAX_HMAC_KEY_LENGTH);
+	 MAX_MAC_KEY_LENGTH);
   return md;
 }
 
@@ -538,7 +538,7 @@ md_ctx_final (md_context_t *ctx, uint8_t *dst)
 
 /*
  *
- * Generic HMAC functions
+ * Generic MAC functions
  *
  */
 
@@ -547,7 +547,7 @@ md_ctx_final (md_context_t *ctx, uint8_t *dst)
  * TODO: re-enable dmsg for crypto debug
  */
 int
-hmac_key_size (const md_info_t *kt)
+mac_key_size (const md_info_t *kt)
 {
   if (NULL == kt)
     return 0;
@@ -555,7 +555,7 @@ hmac_key_size (const md_info_t *kt)
 }
 
 void
-hmac_ctx_init (md_context_t *ctx, const uint8_t *key, int key_len, const md_info_t *kt)
+mac_ctx_init (md_context_t *ctx, const uint8_t *key, int key_len, const md_info_t *kt)
 {
   ASSERT(NULL != kt && NULL != ctx);
 
@@ -569,13 +569,13 @@ hmac_ctx_init (md_context_t *ctx, const uint8_t *key, int key_len, const md_info
 }
 
 void
-hmac_ctx_cleanup(md_context_t *ctx)
+mac_ctx_cleanup(md_context_t *ctx)
 {
   ASSERT(0 == md_free_ctx(ctx));
 }
 
 int
-hmac_ctx_size (const md_context_t *ctx)
+mac_ctx_size (const md_context_t *ctx)
 {
   if (NULL == ctx)
     return 0;
@@ -583,19 +583,19 @@ hmac_ctx_size (const md_context_t *ctx)
 }
 
 void
-hmac_ctx_reset (md_context_t *ctx)
+mac_ctx_reset (md_context_t *ctx)
 {
   ASSERT(0 == md_hmac_reset(ctx));
 }
 
 void
-hmac_ctx_update (md_context_t *ctx, const uint8_t *src, int src_len)
+mac_ctx_update (md_context_t *ctx, const uint8_t *src, int src_len)
 {
   ASSERT(0 == md_hmac_update(ctx, src, src_len));
 }
 
 void
-hmac_ctx_final (md_context_t *ctx, uint8_t *dst)
+mac_ctx_final (md_context_t *ctx, uint8_t *dst)
 {
   ASSERT(0 == md_hmac_finish(ctx, dst));
 }
src/openvpn/crypto_polarssl.h +2 -2
index bfabb91..7590353 100644
@@ -47,8 +47,8 @@ typedef cipher_context_t cipher_ctx_t;
 /** Generic message digest %context. */
 typedef md_context_t md_ctx_t;
 
-/** Generic HMAC %context. */
-typedef md_context_t hmac_ctx_t;
+/** Generic MAC %context. */
+typedef md_context_t mac_ctx_t;
 
 /** Maximum length of an IV */
 #define OPENVPN_MAX_IV_LENGTH 	POLARSSL_MAX_IV_LENGTH
src/openvpn/forward.c +2 -2
index 57c7846..156703c 100644
@@ -423,7 +423,7 @@ buffer_turnover (const uint8_t *orig_buf, struct buffer *dest_stub, struct buffe
 }
 
 /*
- * Compress, fragment, encrypt and HMAC-sign an outgoing packet.
+ * Compress, fragment, encrypt and MAC-sign an outgoing packet.
  * Input: c->c2.buf
  * Output: c->c2.to_link
  */
@@ -469,7 +469,7 @@ encrypt_sign (struct context *c, bool comp_frag)
 
   /*
    * Encrypt the packet and write an optional
-   * HMAC signature.
+   * MAC signature.
    */
   openvpn_encrypt (&c->c2.buf, b->encrypt_buf, &c->c2.crypto_options, &c->c2.frame);
 #endif
src/openvpn/forward.h +1 -1
index 0f829bd..efca2bb 100644
@@ -88,7 +88,7 @@ void show_wait_status (struct context *c);
  *   security operations on the packet.
  *   - Call \c tls_pre_encrypt() to choose the appropriate security
  *     parameters for this packet.
- *   - Call \c openvpn_encrypt() to encrypt and HMAC signed the packet.
+ *   - Call \c openvpn_encrypt() to encrypt and MAC signed the packet.
  *   - Call \c tls_post_encrypt() to prepend the one-byte OpenVPN header
  *     and do some TLS accounting.
  * - Place the resulting packet in \c c->c2.to_link so that it can be sent
src/openvpn/init.c +1 -1
index 564621d..118e2f9 100644
@@ -1961,7 +1961,7 @@ do_init_crypto_static (struct context *c, const unsigned int flags)
 		     options->authname_defined, options->keysize,
 		     options->test_crypto, true);
 
-      /* Read cipher and hmac keys from shared secret file */
+      /* Read cipher and MAC keys from shared secret file */
       {
 	unsigned int rkf_flags = RKF_MUST_SUCCEED;
 	const char *rkf_file = options->shared_secret_file;
src/openvpn/ntlm.c +5 -5
index 3390bdd..570a375 100644
@@ -87,13 +87,13 @@ static void
 gen_hmac_md5 (const char* data, int data_len, const char* key, int key_len,char *result)
 {
 	const md_kt_t *md5_kt = md_kt_get("MD5");
-	hmac_ctx_t hmac_ctx;
+	mac_ctx_t hmac_ctx;
 	CLEAR(hmac_ctx);
 
-	hmac_ctx_init(&hmac_ctx, key, key_len, md5_kt);
-	hmac_ctx_update(&hmac_ctx, (const unsigned char *)data, data_len);
-	hmac_ctx_final(&hmac_ctx, (unsigned char *)result);
-	hmac_ctx_cleanup(&hmac_ctx);
+	mac_ctx_init(&hmac_ctx, key, key_len, md5_kt);
+	mac_ctx_update(&hmac_ctx, (const unsigned char *)data, data_len);
+	mac_ctx_final(&hmac_ctx, (unsigned char *)result);
+	mac_ctx_cleanup(&hmac_ctx);
 }
 
 static void
src/openvpn/openvpn.h +4 -4
index 3ff5470..a96beab 100644
@@ -56,7 +56,7 @@
 struct key_schedule
 {
 #ifdef ENABLE_CRYPTO
-  /* which cipher, HMAC digest, and key sizes are we using? */
+  /* which cipher, MAC digest, and key sizes are we using? */
   struct key_type key_type;
 
   /* pre-shared static key, read from a file */
@@ -66,7 +66,7 @@ struct key_schedule
   /* our global SSL context */
   struct tls_root_ctx ssl_ctx;
 
-  /* optional authentication HMAC key for TLS control channel */
+  /* optional authentication MAC key for TLS control channel */
   struct key_ctx_bi tls_auth_key;
 
 #endif				/* ENABLE_SSL */
@@ -347,7 +347,7 @@ struct context_2
                                  *   connection attempt.  This structure
                                  *   is used by the \c
                                  *   tls_pre_decrypt_lite() function when
-                                 *   it performs the HMAC firewall check
+                                 *   it performs the MAC firewall check
                                  *   on the first connection packet
                                  *   received from a new client.  See the
                                  *   \c --tls-auth commandline option. */
@@ -572,7 +572,7 @@ struct context
 #define PROTO_DUMP(buf, gc) protocol_dump((buf), \
 				      PROTO_DUMP_FLAGS | \
 				      (c->c2.tls_multi ? PD_TLS : 0) | \
-				      (c->options.tls_auth_file ? c->c1.ks.key_type.hmac_key_length : 0), \
+				      (c->options.tls_auth_file ? c->c1.ks.key_type.mac_key_length : 0), \
 				      gc)
 #else
 #define TLS_MODE(c) (false)
src/openvpn/options.c +1 -1
index b78ff15..225c453 100644
@@ -517,7 +517,7 @@ static const char usage_message[] =
   "                  If d is specified, use separate keys for each\n"
   "                  direction, set d=0 on one side of the connection,\n"
   "                  and d=1 on the other side.\n"
-  "--auth alg      : Authenticate packets with HMAC using message\n"
+  "--auth alg      : Authenticate packets with MAC using message\n"
   "                  digest algorithm alg (default=%s).\n"
   "                  (usually adds 16 or 20 bytes per packet)\n"
   "                  Set alg=none to disable authentication.\n"
src/openvpn/ssl.c +47 -47

237 lines not on this page · raw message

src/openvpn/ssl.h +6 -6
index 001e4fd..f5046e7 100644
@@ -326,7 +326,7 @@ bool tls_pre_decrypt (struct tls_multi *multi,
  * The tests performed by this function are whether the packet's opcode is
  * correct for establishing a new VPN tunnel, whether its key ID is 0, and
  * whether its size is not too large.  This function also performs the
- * initial HMAC firewall test, if configured to do so.
+ * initial MAC firewall test, if configured to do so.
  *
  * The incoming packet and the local VPN tunnel state are not modified by
  * this function.  Its sole purpose is to inspect the packet and determine
@@ -341,7 +341,7 @@ bool tls_pre_decrypt (struct tls_multi *multi,
  * @return
  * @li True if the packet is valid and a new VPN tunnel should be created
  *     for this client.
- * @li False if the packet is not valid, did not pass the HMAC firewall
+ * @li False if the packet is not valid, did not pass the MAC firewall
  *     test, or some other error occurred.
  */
 bool tls_pre_decrypt_lite (const struct tls_auth_standalone *tas,
@@ -482,10 +482,10 @@ tls_set_single_session (struct tls_multi *multi)
 /*
  * protocol_dump() flags
  */
-#define PD_TLS_AUTH_HMAC_SIZE_MASK 0xFF
-#define PD_SHOW_DATA               (1<<8)
-#define PD_TLS                     (1<<9)
-#define PD_VERBOSE                 (1<<10)
+#define PD_TLS_AUTH_MAC_SIZE_MASK 0xFF
+#define PD_SHOW_DATA              (1<<8)
+#define PD_TLS                    (1<<9)
+#define PD_VERBOSE                (1<<10)
 
 const char *protocol_dump (struct buffer *buffer,
 			   unsigned int flags,
src/openvpn/ssl_common.h +2 -2
index f3f43be..3adf507 100644
@@ -162,7 +162,7 @@ struct key_state
   struct link_socket_actual remote_addr; /* peer's IP addr */
   struct packet_id packet_id;	       /* for data channel, to prevent replay attacks */
 
-  struct key_ctx_bi key;	       /* data channel keys for encrypt/decrypt/hmac */
+  struct key_ctx_bi key;	       /* data channel keys for encrypt/decrypt/MAC */
 
   struct key_source2 *key_src;         /* source entropy for key expansion */
 
@@ -209,7 +209,7 @@ struct tls_options
   /* our master TLS context from which all SSL objects derived */
   struct tls_root_ctx ssl_ctx;
 
-  /* data channel cipher, hmac, and key lengths */
+  /* data channel cipher, MAC, and key lengths */
   struct key_type key_type;
 
   /* true if we are a TLS server, client otherwise */
Signature · 1 line
1.7.9.5