Skip to contentSkip to conversation

Refactor OpenSSL crypto functions

PATCH In review Adriaan de Jong 1 participant 21 messages Jun 24, 2011 Kbuild

lore
Share & tools
lore
#0 lore raw

cover Refactor OpenSSL crypto functions

Hi everyone,

This is the second series of patches for the master branch.

This patch separates the OpenSSL crypto functions (those in crypto.c) into a separate OpenSSL backend. The API for this backend is defined in crypto_backend.h.

Note that I also migrated all functions within OpenVPN that use crypto primitives, for compatibility with other SSL backends. The exception here is the functions in ssl.c, since they will be migrated in the next series of patches.

Enjoy!

Regards,
Adriaan de Jong

#1 lore raw

PATCH 10/28 Changed configure to accept --with-ssl-type=openssl

---
 configure.ac |  153 ++++++++++++++++++++++++++++++++--------------------------
 1 files changed, 84 insertions(+), 69 deletions(-)
configure.ac +84 -69
index a3789d9..5e7c10d 100644
@@ -75,13 +75,13 @@ AC_ARG_ENABLE(lzo-stub,
 )
 
 AC_ARG_ENABLE(crypto,
-   [  --disable-crypto        Disable OpenSSL crypto support],
+   [  --disable-crypto        Disable crypto support],
    [CRYPTO="$enableval"],
    [CRYPTO="yes"]
 )
 
 AC_ARG_ENABLE(ssl,
-   [  --disable-ssl           Disable OpenSSL SSL support for TLS-based key exchange],
+   [  --disable-ssl           Disable SSL support for TLS-based key exchange],
    [SSL="$enableval"],
    [SSL="yes"]
 )
@@ -296,6 +296,16 @@ AC_ARG_WITH(mem-check,
    [MEMCHECK="$withval"]
 )
 
+AC_ARG_WITH([ssl-type],
+   [  --with-ssl-type=TYPE  Build with the given SSL library, TYPE = openssl ],
+   [case "${withval}" in 
+        openssl) SSL_LIB=openssl ;;
+        *) AC_MSG_ERROR([bad value ${withval} for --with-ssl-type]) ;;
+   esac],
+   [SSL_LIB="openssl"]
+)
+AM_CONDITIONAL([USE_OPENSSL], [test x$SSL_LIB = xopenssl])
+
 dnl fix search path, to allow compilers to find syshead.h
 CPPFLAGS="$CPPFLAGS -I${srcdir}"
 
@@ -309,7 +319,7 @@ case "$host" in
 *-*-linux*)
 	AC_DEFINE(TARGET_LINUX, 1, [Are we running on Linux?])
 	dnl RH9 SSL headers workaround
-        if test -z $CS_HDR_DIR && test "$CRYPTO" = "yes"; then
+	    if test -z $CS_HDR_DIR && test "$CRYPTO" = "yes"; then
            CPPFLAGS="$CPPFLAGS $(pkg-config --cflags openssl 2>/dev/null)"
         fi
 	;;
@@ -708,80 +718,84 @@ if test "$LZO_STUB" = "yes"; then
 fi
 
 dnl
-dnl check for OpenSSL-crypto library
+dnl check for SSL-crypto library
 dnl
 
 if test "$CRYPTO" = "yes"; then
-   AC_CHECKING([for OpenSSL Crypto Library and Header files])
-   AC_CHECK_HEADER(openssl/evp.h,,
-	[AC_MSG_ERROR([OpenSSL Crypto headers not found.])])
-
-   for lib in crypto eay32; do
-      AC_CHECK_LIB($lib, EVP_CIPHER_CTX_init,
-            [
-		cryptofound=1
-		OPENVPN_ADD_LIBS(-l$lib)
-	    ]
-      )
-   done
-
-   test -n "$cryptofound" || AC_MSG_ERROR([OpenSSL Crypto library not found.])
-
-   AC_MSG_CHECKING([that OpenSSL Library is at least version 0.9.6])
-   AC_EGREP_CPP(yes,
-     [
-       #include <openssl/evp.h>
-       #if SSLEAY_VERSION_NUMBER >= 0x00906000L
-	 yes
-       #endif
-     ],
-     [
-       AC_MSG_RESULT([yes])
-       AC_DEFINE(USE_CRYPTO, 1, [Use OpenSSL crypto library])
-       AC_CHECK_FUNCS(EVP_CIPHER_CTX_set_key_length)
-
-       dnl check for OpenSSL crypto acceleration capability
-       AC_CHECK_HEADERS(openssl/engine.h)
-       AC_CHECK_FUNCS(ENGINE_load_builtin_engines)
-       AC_CHECK_FUNCS(ENGINE_register_all_complete)
-       AC_CHECK_FUNCS(ENGINE_cleanup)
-     ],
-     [AC_MSG_ERROR([OpenSSL crypto Library is too old.])]
-   )
+   if test "$SSL_LIB" = "openssl"; then  
+       AC_CHECKING([for OpenSSL Crypto Library and Header files])
+       AC_CHECK_HEADER(openssl/evp.h,,
+	       [AC_MSG_ERROR([OpenSSL Crypto headers not found.])])
+
+       for lib in crypto eay32; do
+          AC_CHECK_LIB($lib, EVP_CIPHER_CTX_init,
+                [
+            		cryptofound=1
+            		OPENVPN_ADD_LIBS(-l$lib)
+    	        ]
+          )
+       done
+       test -n "$cryptofound" || AC_MSG_ERROR([OpenSSL Crypto library not found.])
+
+       AC_MSG_CHECKING([that OpenSSL Library is at least version 0.9.6])
+       AC_EGREP_CPP(yes,
+         [
+           #include <openssl/evp.h>
+           #if SSLEAY_VERSION_NUMBER >= 0x00906000L
+    	       yes
+           #endif
+         ],
+         [
+           AC_MSG_RESULT([yes])
+           AC_DEFINE(USE_CRYPTO, 1, [Use crypto library])
+           AC_DEFINE(USE_OPENSSL, 1, [Use OpenSSL library])
+           AC_CHECK_FUNCS(EVP_CIPHER_CTX_set_key_length)
+    
+           dnl check for OpenSSL crypto acceleration capability
+           AC_CHECK_HEADERS(openssl/engine.h)
+           AC_CHECK_FUNCS(ENGINE_load_builtin_engines)
+           AC_CHECK_FUNCS(ENGINE_register_all_complete)
+           AC_CHECK_FUNCS(ENGINE_cleanup)
+         ],
+         [AC_MSG_ERROR([OpenSSL crypto Library is too old.])]
+       )
+   fi
 
-dnl
-dnl check for OpenSSL-SSL library
-dnl
+   dnl
+   dnl check for OpenSSL-SSL library
+   dnl
 
    if test "$SSL" = "yes"; then
-      AC_CHECKING([for OpenSSL SSL Library and Header files])
-      AC_CHECK_HEADER(openssl/ssl.h,,
-	   [AC_MSG_ERROR([OpenSSL SSL headers not found.])]
-      )
-
-      for lib in ssl ssl32; do
-	  AC_CHECK_LIB($lib, SSL_CTX_new,
-		[
-			sslfound=1
-			OPENVPN_ADD_LIBS(-l$lib)
-		]
-	  )
-      done
-
-      test -n "${sslfound}" || AC_MSG_ERROR([OpenSSL SSL library not found.])
-
-      if test "$MEMCHECK" = "ssl"; then
-	     AC_CHECKING([for Memory Debugging Capabilities in OpenSSL Library])
-	     AC_CHECK_LIB(ssl, CRYPTO_mem_ctrl,
-		 [
-		     AC_DEFINE(CRYPTO_MDEBUG, 1, [Use memory debugging function in OpenSSL])
-		     AC_MSG_RESULT([NOTE: OpenSSL library must be compiled with CRYPTO_MDEBUG])
-		 ],
-		 [AC_MSG_ERROR([Memory Debugging function in OpenSSL library not found.])]
+      if test "$SSL_LIB" = "openssl"; then  
+         AC_CHECKING([for OpenSSL SSL Library and Header files])
+         AC_CHECK_HEADER(openssl/ssl.h,,
+	      [AC_MSG_ERROR([OpenSSL SSL headers not found.])]
+         )
+
+         for lib in ssl ssl32; do
+	     AC_CHECK_LIB($lib, SSL_CTX_new,
+		   [
+			   sslfound=1
+			   OPENVPN_ADD_LIBS(-l$lib)
+		   ]
 	     )
+         done
+
+         test -n "${sslfound}" || AC_MSG_ERROR([OpenSSL SSL library not found.])
+
+         if test "$MEMCHECK" = "ssl"; then
+	        AC_CHECKING([for Memory Debugging Capabilities in OpenSSL Library])
+	        AC_CHECK_LIB(ssl, CRYPTO_mem_ctrl,
+		    [
+		        AC_DEFINE(CRYPTO_MDEBUG, 1, [Use memory debugging function in OpenSSL])
+		        AC_MSG_RESULT([NOTE: OpenSSL library must be compiled with CRYPTO_MDEBUG])
+		    ],
+		    [AC_MSG_ERROR([Memory Debugging function in OpenSSL library not found.])]
+	        )
+         fi
+
+         AC_DEFINE(USE_SSL, 1, [Use OpenSSL SSL library])
       fi
-
-      AC_DEFINE(USE_SSL, 1, [Use OpenSSL SSL library])
    fi
 fi
 
@@ -791,6 +805,7 @@ if test "$X509ALTUSERNAME" = "yes"; then
 fi
 
 dnl enable pkcs11 capability
+
 if test "$PKCS11" = "yes"; then
    AC_CHECKING([for pkcs11-helper Library and Header files])
    AC_CHECK_HEADER(pkcs11-helper-1.0/pkcs11h-core.h,
Signature · 1 line
1.7.4.1
#2 lore raw

PATCH 11/28 Refactored to rand_bytes for OpenSSL-independency

In reply to Adriaan de Jong
---
 Makefile.am      |    7 +++++-
 crypto.c         |   11 +++++----
 crypto_backend.h |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 crypto_openssl.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++
 crypto_openssl.h |   37 ++++++++++++++++++++++++++++++++
 init.c           |    2 +-
 proxy.c          |    2 +-
 ssl.c            |    2 +-
 8 files changed, 166 insertions(+), 9 deletions(-)
 create mode 100644 crypto_backend.h
 create mode 100644 crypto_openssl.c
 create mode 100644 crypto_openssl.h
Makefile.am +6 -1
index 32b40bb..aeba51c 100644
@@ -85,7 +85,7 @@ openvpn_SOURCES = \
 	clinat.c clinat.h \
 	common.h \
 	config-win32.h \
-	crypto.c crypto.h \
+	crypto.c crypto.h crypto_backend.h \
 	dhcp.c dhcp.h \
 	errlevel.h \
 	error.c error.h \
@@ -153,6 +153,11 @@ configure.h: Makefile
 	awk -f $(srcdir)/configure_h.awk config.h > $@
 	awk -f $(srcdir)/configure_log.awk config.log >> $@
 
+if USE_OPENSSL
+openvpn_SOURCES += \
+	crypto_openssl.c crypto_openssl.h
+endif
+
 dist-hook:
 	cd $(distdir) && for i in $(EXTRA_DIST) $(SUBDIRS) ; do find $$i -name .svn -type d -prune -exec rm -rf '{}' ';' ; rm -f `find $$i -type f | grep -E '(^|\/)\.?\#|\~$$|\.s?o$$'` ; done
 
crypto.c +6 -5
index 5cfc34a..68b8564 100644
@@ -6,6 +6,7 @@
  *             packet compression.
  *
  *  Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <[email protected]...>
+ *  Copyright (C) 2010 Fox Crypto B.V. <[email protected]...>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2
@@ -803,8 +804,8 @@ generate_key_random (struct key *key, const struct key_type *kt)
 	if (kt->digest && kt->hmac_length > 0 && kt->hmac_length <= hmac_len)
 	  hmac_len = kt->hmac_length;
       }
-    if (!RAND_bytes (key->cipher, cipher_len)
-	|| !RAND_bytes (key->hmac, hmac_len))
+    if (!rand_bytes (key->cipher, cipher_len)
+	|| !rand_bytes (key->hmac, hmac_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));
@@ -870,7 +871,7 @@ test_crypto (const struct crypto_options *co, struct frame* frame)
       ASSERT (buf_init (&src, 0));
       ASSERT (i <= src.capacity);
       src.len = i;
-      ASSERT (RAND_pseudo_bytes (BPTR (&src), BLEN (&src)));
+      ASSERT (rand_bytes (BPTR (&src), BLEN (&src)));
 
       /* copy source to input buf */
       buf = work;
@@ -1671,7 +1672,7 @@ prng_init (const char *md_name, const int nonce_secret_len_parm)
 	nonce_data = (uint8_t*) malloc (size);
 	check_malloc_return (nonce_data);
 #if 1 /* Must be 1 for real usage */
-	if (!RAND_bytes (nonce_data, size))
+	if (!rand_bytes (nonce_data, size))
 	  msg (M_FATAL, "ERROR: Random number generator cannot obtain entropy for PRNG");
 #else
 	/* Only for testing -- will cause a predictable PRNG sequence */
@@ -1716,7 +1717,7 @@ prng_bytes (uint8_t *output, int len)
 	}
     }
   else
-    RAND_bytes (output, len);
+    rand_bytes (output, len);
 }
 
 /* an analogue to the random() function, but use prng_bytes */
crypto_backend.h new file +61 -0

61 lines not on this page · raw message

crypto_openssl.c new file +53 -0

53 lines not on this page · raw message

crypto_openssl.h new file +37 -0
new file mode 100644
index 0000000..cae00b9
@@ -0,0 +1,37 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ *             over a single TCP/UDP port, with support for SSL/TLS-based
+ *             session authentication and key exchange,
+ *             packet encryption, packet authentication, and
+ *             packet compression.
+ *
+ *  Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <[email protected]...>
+ *  Copyright (C) 2010 Fox Crypto B.V. <[email protected]...>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/**
+ * @file Data Channel Cryptography OpenSSL-specific backend interface
+ */
+
+#ifndef CRYPTO_OPENSSL_H_
+#define CRYPTO_OPENSSL_H_
+
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/md5.h>
+
+#endif /* CRYPTO_OPENSSL_H_ */
init.c +1 -1
index 4a16fba..cb8dc42 100644
@@ -664,7 +664,7 @@ init_static (void)
 #if 1
 	prng_bytes (rndbuf, sizeof (rndbuf));
 #else
-	ASSERT(RAND_bytes (rndbuf, sizeof (rndbuf)));
+	ASSERT(rand_bytes (rndbuf, sizeof (rndbuf)));
 #endif
 	printf ("[%d] %s\n", i, format_hex (rndbuf, sizeof (rndbuf), 0, &gc));
       }
proxy.c +1 -1
index fce64a1..7963673 100644
@@ -745,7 +745,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
 	      const char *opaque = get_pa_var("opaque", pa, &gc);
 
 	      /* generate a client nonce */
-	      ASSERT(RAND_bytes(cnonce_raw, sizeof(cnonce_raw)));
+	      ASSERT(rand_bytes(cnonce_raw, sizeof(cnonce_raw)));
 	      cnonce = make_base64_string2(cnonce_raw, sizeof(cnonce_raw), &gc);
 
 
ssl.c +1 -1
index 2260ccb..4477b54 100644
@@ -3883,7 +3883,7 @@ random_bytes_to_buf (struct buffer *buf,
 		     uint8_t *out,
 		     int outlen)
 {
-  if (!RAND_bytes (out, outlen))
+  if (!rand_bytes (out, outlen))
     msg (M_FATAL, "ERROR: Random number generator cannot obtain entropy for key generation [SSL]");
   if (!buf_write (buf, out, outlen))
     return false;
Signature · 1 line
1.7.4.1
#3 lore raw

PATCH 12/28 Refactored OpenSSL-specific constants

In reply to Adriaan de Jong
---
 crypto.c         |   28 ++++++++++++++--------------
 crypto.h         |    7 ++++---
 crypto_openssl.h |   18 ++++++++++++++++++
 init.c           |    4 ++--
 ssl.c            |    8 ++++----
 5 files changed, 42 insertions(+), 23 deletions(-)
crypto.c +14 -14
index 68b8564..8af5b7a 100644
@@ -86,12 +86,12 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
       /* Do Encrypt from buf -> work */
       if (ctx->cipher)
 	{
-	  uint8_t iv_buf[EVP_MAX_IV_LENGTH];
+	  uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH];
 	  const int iv_size = EVP_CIPHER_CTX_iv_length (ctx->cipher);
 	  const unsigned int mode = EVP_CIPHER_CTX_mode (ctx->cipher);  
 	  int outlen;
 
-	  if (mode == EVP_CIPH_CBC_MODE)
+	  if (mode == OPENVPN_MODE_CBC)
 	    {
 	      CLEAR (iv_buf);
 
@@ -107,7 +107,7 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
 		  ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true));
 		}
 	    }
-	  else if (mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE)
+	  else if (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB)
 	    {
 	      struct packet_id_net pin;
 	      struct buffer b;
@@ -267,7 +267,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
 	{
 	  const unsigned int mode = EVP_CIPHER_CTX_mode (ctx->cipher);
 	  const int iv_size = EVP_CIPHER_CTX_iv_length (ctx->cipher);
-	  uint8_t iv_buf[EVP_MAX_IV_LENGTH];
+	  uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH];
 	  int outlen;
 
 	  /* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */
@@ -313,7 +313,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
 
 	  /* Get packet ID from plaintext buffer or IV, depending on cipher mode */
 	  {
-	    if (mode == EVP_CIPH_CBC_MODE)
+	    if (mode == OPENVPN_MODE_CBC)
 	      {
 		if (opt->packet_id)
 		  {
@@ -322,7 +322,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
 		    have_pin = true;
 		  }
 	      }
-	    else if (mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE)
+	    else if (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB)
 	      {
 		struct buffer b;
 
@@ -512,9 +512,9 @@ init_key_type (struct key_type *kt, const char *ciphername,
       /* check legal cipher mode */
       {
 	const unsigned int mode = EVP_CIPHER_mode (kt->cipher);
-	if (!(mode == EVP_CIPH_CBC_MODE
+	if (!(mode == OPENVPN_MODE_CBC
 #ifdef ALLOW_NON_CBC_CIPHERS
-	      || (cfb_ofb_allowed && (mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE))
+	      || (cfb_ofb_allowed && (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB))
 #endif
 	      ))
 #ifdef ENABLE_SMALL
@@ -775,11 +775,11 @@ check_replay_iv_consistency (const struct key_type *kt, bool packet_id, bool use
 bool
 cfb_ofb_mode (const struct key_type* kt)
 {
-  if (kt->cipher) {
     const unsigned int mode = EVP_CIPHER_mode (kt->cipher);
-    return mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE;
-  } else
-    return false;
+  if (kt && kt->cipher) {
+      return mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB;
+  }
+  return false;
 }
 
 /*
@@ -970,9 +970,9 @@ get_tls_handshake_key (const struct key_type *key_type,
 
       /* initialize hmac key in both directions */
 
-      init_key_ctx (&ctx->encrypt, &key2.keys[kds.out_key], &kt, DO_ENCRYPT,
+      init_key_ctx (&ctx->encrypt, &key2.keys[kds.out_key], &kt, OPENVPN_OP_ENCRYPT,
 		    "Outgoing Control Channel Authentication");
-      init_key_ctx (&ctx->decrypt, &key2.keys[kds.in_key], &kt, DO_DECRYPT,
+      init_key_ctx (&ctx->decrypt, &key2.keys[kds.in_key], &kt, OPENVPN_OP_DECRYPT,
 		    "Incoming Control Channel Authentication");
 
       CLEAR (key2);
crypto.h +4 -3
index 973677d..f56456d 100644
@@ -6,6 +6,7 @@
  *             packet compression.
  *
  *  Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <[email protected]...>
+ *  Copyright (C) 2010 Fox Crypto B.V. <[email protected]...>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2
@@ -22,14 +23,13 @@
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-
 /**
- * @file
+ * @file Data Channel Cryptography Module
  */
 
-
 #ifndef CRYPTO_H
 #define CRYPTO_H
+
 #ifdef USE_CRYPTO
 
 #define ALLOW_NON_CBC_CIPHERS
@@ -63,6 +63,7 @@
 #include <openssl/des_old.h>
 #endif
 
+#include "crypto_backend.h"
 #include "basic.h"
 #include "buffer.h"
 #include "packet_id.h"
crypto_openssl.h +18 -0
index cae00b9..ea3601e 100644
@@ -34,4 +34,22 @@
 #include <openssl/hmac.h>
 #include <openssl/md5.h>
 
+/** Maximum length of an IV */
+#define OPENVPN_MAX_IV_LENGTH 	EVP_MAX_IV_LENGTH
+
+/** Cipher is in CBC mode */
+#define OPENVPN_MODE_CBC 	EVP_CIPH_CBC_MODE
+
+/** Cipher is in OFB mode */
+#define OPENVPN_MODE_OFB	EVP_CIPH_OFB_MODE
+
+/** Cipher is in CFB mode */
+#define OPENVPN_MODE_CFB 	EVP_CIPH_CFB_MODE
+
+/** Cipher should encrypt */
+#define OPENVPN_OP_ENCRYPT 	1
+
+/** Cipher should decrypt */
+#define OPENVPN_OP_DECRYPT 	0
+
 #endif /* CRYPTO_OPENSSL_H_ */
init.c +2 -2
index cb8dc42..972b093 100644
@@ -1942,9 +1942,9 @@ do_init_crypto_static (struct context *c, const unsigned int flags)
       must_have_n_keys (options->shared_secret_file, "secret", &key2,
 			kds.need_keys);
       init_key_ctx (&c->c1.ks.static_key.encrypt, &key2.keys[kds.out_key],
-		    &c->c1.ks.key_type, DO_ENCRYPT, "Static Encrypt");
+		    &c->c1.ks.key_type, OPENVPN_OP_ENCRYPT, "Static Encrypt");
       init_key_ctx (&c->c1.ks.static_key.decrypt, &key2.keys[kds.in_key],
-		    &c->c1.ks.key_type, DO_DECRYPT, "Static Decrypt");
+		    &c->c1.ks.key_type, OPENVPN_OP_DECRYPT, "Static Decrypt");
 
       /* Erase the temporary copy of key */
       CLEAR (key2);
ssl.c +4 -4
index 4477b54..d0fd77b 100644
@@ -3860,13 +3860,13 @@ generate_key_expansion (struct key_ctx_bi *key,
   init_key_ctx (&key->encrypt,
 		&key2.keys[(int)server],
 		key_type,
-		DO_ENCRYPT,
+		OPENVPN_OP_ENCRYPT,
 		"Data Channel Encrypt");
 
   init_key_ctx (&key->decrypt,
 		&key2.keys[1-(int)server],
 		key_type,
-		DO_DECRYPT,
+		OPENVPN_OP_DECRYPT,
 		"Data Channel Decrypt");
 
   ret = true;
@@ -4234,7 +4234,7 @@ key_method_1_write (struct buffer *buf, struct tls_session *session)
     }
 
   init_key_ctx (&ks->key.encrypt, &key, &session->opt->key_type,
-		DO_ENCRYPT, "Data Channel Encrypt");
+      OPENVPN_OP_ENCRYPT, "Data Channel Encrypt");
   CLEAR (key);
 
   /* send local options string */
@@ -4446,7 +4446,7 @@ key_method_1_read (struct buffer *buf, struct tls_session *session)
   buf_clear (buf);
 
   init_key_ctx (&ks->key.decrypt, &key, &session->opt->key_type,
-		DO_DECRYPT, "Data Channel Decrypt");
+      OPENVPN_OP_DECRYPT, "Data Channel Decrypt");
   CLEAR (key);
   ks->authenticated = true;
   return true;
Signature · 1 line
1.7.4.1
#4 lore raw

PATCH 13/28 Refactored maximum cipher and hmac length constants

In reply to Adriaan de Jong
---
 crypto.c         |   12 ------------
 crypto.h         |   24 ------------------------
 crypto_backend.h |   34 ++++++++++++++++++++++++++++++++++
 crypto_openssl.c |   12 ++++++++++++
 4 files changed, 46 insertions(+), 36 deletions(-)
crypto.c +0 -12
index 8af5b7a..a1986e0 100644
@@ -34,18 +34,6 @@
 #include "memdbg.h"
 
 /*
- * Check for key size creepage.
- */
-
-#if MAX_CIPHER_KEY_LENGTH < EVP_MAX_KEY_LENGTH
-#warning Some OpenSSL EVP ciphers now support key lengths greater than MAX_CIPHER_KEY_LENGTH -- consider increasing MAX_CIPHER_KEY_LENGTH
-#endif
-
-#if MAX_HMAC_KEY_LENGTH < EVP_MAX_MD_SIZE
-#warning Some OpenSSL HMAC message digests now support key lengths greater than MAX_HMAC_KEY_LENGTH -- consider increasing MAX_HMAC_KEY_LENGTH
-#endif
-
-/*
  * Encryption and Compression Routines.
  *
  * On entry, buf contains the input data and length.
crypto.h +0 -24
index f56456d..069a66f 100644
@@ -173,29 +173,6 @@ cipher_ok (const char* name)
 #endif
 
 /*
- * Max size in bytes of any cipher key that might conceivably be used.
- *
- * This value is checked at compile time in crypto.c to make sure
- * it is always at least EVP_MAX_KEY_LENGTH.
- *
- * We define our own value, since this parameter
- * is used to control the size of static key files.
- * If the OpenSSL library increases EVP_MAX_KEY_LENGTH,
- * we don't want our key files to be suddenly rendered
- * unusable.
- */
-#define MAX_CIPHER_KEY_LENGTH 64
-
-/*
- * Max size in bytes of any HMAC key that might conceivably be used.
- *
- * This value is checked at compile time in crypto.c to make sure
- * it is always at least EVP_MAX_MD_SIZE.  We define our own value
- * for the same reason as above.
- */
-#define MAX_HMAC_KEY_LENGTH 64
-
-/*
  * Defines a key type and key length for both cipher and HMAC.
  */
 struct key_type
@@ -206,7 +183,6 @@ struct key_type
   const EVP_MD *digest;
 };
 
-
 /**
  * Container for unidirectional cipher and HMAC %key material.
  * @ingroup control_processor
crypto_backend.h +34 -0
index 9f8eb04..31935ed 100644
@@ -58,4 +58,38 @@
  */
 int rand_bytes (uint8_t *output, int len);
 
+/*
+ *
+ * Generic cipher key type functions
+ *
+ */
+/*
+ * Max size in bytes of any cipher key that might conceivably be used.
+ *
+ * This value is checked at compile time in crypto.c to make sure
+ * it is always at least EVP_MAX_KEY_LENGTH.
+ *
+ * We define our own value, since this parameter
+ * is used to control the size of static key files.
+ * If the OpenSSL library increases EVP_MAX_KEY_LENGTH,
+ * we don't want our key files to be suddenly rendered
+ * unusable.
+ */
+#define MAX_CIPHER_KEY_LENGTH 64
+
+/*
+ *
+ * Generic message digest information functions
+ *
+ */
+
+/*
+ * Max size in bytes of any HMAC key that might conceivably be used.
+ *
+ * This value is checked at compile time in crypto.c to make sure
+ * it is always at least EVP_MAX_MD_SIZE.  We define our own value
+ * for the same reason as above.
+ */
+#define MAX_HMAC_KEY_LENGTH 64
+
 #endif /* CRYPTO_BACKEND_H_ */
crypto_openssl.c +12 -0
index cbe559a..9e547b4 100644
@@ -38,6 +38,18 @@
 #include <openssl/des.h>
 
 /*
+ * Check for key size creepage.
+ */
+
+#if MAX_CIPHER_KEY_LENGTH < EVP_MAX_KEY_LENGTH
+#warning Some OpenSSL EVP ciphers now support key lengths greater than MAX_CIPHER_KEY_LENGTH -- consider increasing MAX_CIPHER_KEY_LENGTH
+#endif
+
+#if MAX_HMAC_KEY_LENGTH < EVP_MAX_MD_SIZE
+#warning Some OpenSSL HMAC message digests now support key lengths greater than MAX_HMAC_KEY_LENGTH -- consider increasing MAX_HMAC_KEY_LENGTH
+#endif
+
+/*
  *
  * Random number functions, used in cases where we want
  * reasonably strong cryptographic random number generation
Signature · 1 line
1.7.4.1
#5 lore raw

PATCH 14/28 Refactored show_available_* functions

In reply to Adriaan de Jong
---
 crypto.c         |   85 --------------------------------------
 crypto.h         |    6 ---
 crypto_backend.h |    6 +++
 crypto_openssl.c |  121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 127 insertions(+), 91 deletions(-)
crypto.c +0 -85
index a1986e0..409c298 100644
@@ -1451,91 +1451,6 @@ key_len_err:
   return 0;
 }
 
-void
-show_available_ciphers ()
-{
-  int nid;
-
-
-#ifndef ENABLE_SMALL
-  printf ("The following ciphers and cipher modes are available\n"
-	  "for use with " PACKAGE_NAME ".  Each cipher shown below may be\n"
-	  "used as a parameter to the --cipher option.  The default\n"
-	  "key size is shown as well as whether or not it can be\n"
-          "changed with the --keysize directive.  Using a CBC mode\n"
-	  "is recommended.\n\n");
-#endif
-
-  for (nid = 0; nid < 10000; ++nid)	/* is there a better way to get the size of the nid list? */
-    {
-      const EVP_CIPHER *cipher = EVP_get_cipherbynid (nid);
-      if (cipher && cipher_ok (OBJ_nid2sn (nid)))
-	{
-	  const unsigned int mode = EVP_CIPHER_mode (cipher);
-	  if (mode == EVP_CIPH_CBC_MODE
-#ifdef ALLOW_NON_CBC_CIPHERS
-	      || mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE
-#endif
-	      )
-	    printf ("%s %d bit default key (%s)\n",
-		    OBJ_nid2sn (nid),
-		    EVP_CIPHER_key_length (cipher) * 8,
-		    ((EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ?
-		     "variable" : "fixed"));
-	}
-    }
-  printf ("\n");
-}
-
-void
-show_available_digests ()
-{
-  int nid;
-
-#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"
-	  "You can specify a message digest as parameter to\n"
-	  "the --auth option.\n\n");
-#endif
-
-  for (nid = 0; nid < 10000; ++nid)
-    {
-      const EVP_MD *digest = EVP_get_digestbynid (nid);
-      if (digest)
-	{
-	  printf ("%s %d bit digest size\n",
-		  OBJ_nid2sn (nid), EVP_MD_size (digest) * 8);
-	}
-    }
-  printf ("\n");
-}
-
-void
-show_available_engines ()
-{
-#if CRYPTO_ENGINE
-  ENGINE *e;
-
-  printf ("OpenSSL Crypto Engines\n\n");
-
-  ENGINE_load_builtin_engines ();
-
-  e = ENGINE_get_first ();
-  while (e)
-    {
-      printf ("%s [%s]\n",
-	      ENGINE_get_name (e),
-	      ENGINE_get_id (e));
-      e = ENGINE_get_next (e);
-    }
-  ENGINE_cleanup ();
-#else
-  printf ("Sorry, OpenSSL hardware crypto engine functionality is not available.\n");
-#endif
-}
-
 /*
  * Enable crypto acceleration, if available
  */
crypto.h +0 -6
index 069a66f..abb2e4c 100644
@@ -434,12 +434,6 @@ void test_crypto (const struct crypto_options *co, struct frame* f);
 
 const char *md5sum(uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc);
 
-void show_available_ciphers (void);
-
-void show_available_digests (void);
-
-void show_available_engines (void);
-
 void init_crypto_lib_engine (const char *engine_name);
 
 void init_crypto_lib (void);
crypto_backend.h +6 -0
index 31935ed..b099f47 100644
@@ -38,6 +38,12 @@
 
 #include "basic.h"
 
+void show_available_ciphers (void);
+
+void show_available_digests (void);
+
+void show_available_engines (void);
+
 /*
  *
  * Random number functions, used in cases where we want
crypto_openssl.c +121 -0

127 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#6 lore raw

PATCH 15/28 Refactored SSL_clear_error()

In reply to Adriaan de Jong
---
 crypto.c         |    6 +++---
 crypto_backend.h |    2 ++
 crypto_openssl.c |    6 ++++++
 3 files changed, 11 insertions(+), 3 deletions(-)
crypto.c +3 -3
index 409c298..bdb3b1d 100644
@@ -191,8 +191,8 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
   gc_free (&gc);
   return;
 
- err:
-  ERR_clear_error ();
+err:
+  crypto_clear_error();
   buf->len = 0;
   gc_free (&gc);
   return;
@@ -363,7 +363,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
   return true;
 
  error_exit:
-  ERR_clear_error ();
+  crypto_clear_error();
   buf->len = 0;
   gc_free (&gc);
   return false;
crypto_backend.h +2 -0
index b099f47..50eef7b 100644
@@ -38,6 +38,8 @@
 
 #include "basic.h"
 
+void crypto_clear_error (void);
+
 void show_available_ciphers (void);
 
 void show_available_digests (void);
crypto_openssl.c +6 -0
index 9edcf40..8e228ee 100644
@@ -87,6 +87,12 @@ cipher_ok (const char* name)
 #endif
 
 void
+crypto_clear_error (void)
+{
+  ERR_clear_error ();
+}
+
+void
 show_available_ciphers ()
 {
   int nid;
Signature · 1 line
1.7.4.1
#7 lore raw

PATCH 16/28 Refactored crypto initialisation functions

In reply to Adriaan de Jong
---
 crypto.c         |  138 +--------------------------------------------
 crypto.h         |   22 -------
 crypto_backend.h |   23 ++++++++
 crypto_openssl.c |  164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 init.c           |    4 +-
 ssl.c            |    4 +-
 6 files changed, 193 insertions(+), 162 deletions(-)
crypto.c +2 -136
index bdb3b1d..ff34d5f 100644
@@ -1452,104 +1452,6 @@ key_len_err:
 }
 
 /*
- * Enable crypto acceleration, if available
- */
-
-static bool engine_initialized = false; /* GLOBAL */
-
-#if CRYPTO_ENGINE
-
-static ENGINE *engine_persist = NULL;   /* GLOBAL */
-
-/* Try to load an engine in a shareable library */
-static ENGINE *
-try_load_engine (const char *engine)
-{
-  ENGINE *e = ENGINE_by_id ("dynamic");
-  if (e)
-    {
-      if (!ENGINE_ctrl_cmd_string (e, "SO_PATH", engine, 0)
-	  || !ENGINE_ctrl_cmd_string (e, "LOAD", NULL, 0))
-	{
-	  ENGINE_free (e);
-	  e = NULL;
-	}
-    }
-  return e;
-}
-
-static ENGINE *
-setup_engine (const char *engine)
-{
-  ENGINE *e = NULL;
-
-  ENGINE_load_builtin_engines ();
-
-  if (engine)
-    {
-      if (strcmp (engine, "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)
-	{
-	  msg (M_FATAL, "OpenSSL error: cannot load engine '%s'", engine);
-	}
-
-      if (!ENGINE_set_default (e, ENGINE_METHOD_ALL))
-	{
-	  msg (M_FATAL, "OpenSSL error: ENGINE_set_default failed on engine '%s'",
-	       engine);
-	}
-
-      msg (M_INFO, "Initializing OpenSSL support for engine '%s'",
-	   ENGINE_get_id (e));
-    }
-  return e;
-}
-#endif
-
-void
-init_crypto_lib_engine (const char *engine_name)
-{
-  if (!engine_initialized)
-    {
-#if CRYPTO_ENGINE
-      ASSERT (engine_name);
-      ASSERT (!engine_persist);
-      engine_persist = setup_engine (engine_name);
-#else
-      msg (M_WARN, "Note: OpenSSL hardware crypto engine functionality is not available");
-#endif
-      engine_initialized = true;
-    }
-}
-
-/*
- * This routine should have additional OpenSSL crypto library initialisations
- * used by both crypto and ssl components of OpenVPN.
- */
-void init_crypto_lib ()
-{
-}
-
-void uninit_crypto_lib ()
-{
-#if CRYPTO_ENGINE
-  if (engine_initialized)
-    {
-      ENGINE_cleanup ();
-      engine_persist = NULL;
-      engine_initialized = false;
-    }
-#endif
-  prng_uninit ();
-}
-
-/*
  * Random number functions, used in cases where we want
  * reasonably strong cryptographic random number generation
  * without depleting our entropy pool.  Used for random
@@ -1642,42 +1544,6 @@ md5sum (uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc)
   return format_hex (digest, MD5_DIGEST_LENGTH, n_print_chars, gc);
 }
 
-/*
- * OpenSSL memory debugging.  If dmalloc debugging is enabled, tell
- * OpenSSL to use our private malloc/realloc/free functions so that
- * we can dispatch them to dmalloc.
- */
-
-#ifdef DMALLOC
-
-static void *
-crypto_malloc (size_t size, const char *file, int line)
-{
-  return dmalloc_malloc(file, line, size, DMALLOC_FUNC_MALLOC, 0, 0);
-}
-
-static void *
-crypto_realloc (void *ptr, size_t size, const char *file, int line)
-{
-  return dmalloc_realloc(file, line, ptr, size, DMALLOC_FUNC_REALLOC, 0);
-}
-
-static void
-crypto_free (void *ptr)
-{
-  dmalloc_free (__FILE__, __LINE__, ptr, DMALLOC_FUNC_FREE);
-}
-
-void
-openssl_dmalloc_init (void)
-{
-   CRYPTO_set_mem_ex_functions (crypto_malloc,
-				crypto_realloc,
-				crypto_free);
-}
-
-#endif /* DMALLOC */
-
 #ifndef USE_SSL
 
 void
@@ -1685,13 +1551,13 @@ init_ssl_lib (void)
 {
   ERR_load_crypto_strings ();
   OpenSSL_add_all_algorithms ();
-  init_crypto_lib ();
+  crypto_init_lib ();
 }
 
 void
 free_ssl_lib (void)
 {
-  uninit_crypto_lib ();
+  crypto_uninit_lib ();
   EVP_cleanup ();
   ERR_free_strings ();
 }
crypto.h +0 -22
index abb2e4c..7fa7418 100644
@@ -34,15 +34,6 @@
 
 #define ALLOW_NON_CBC_CIPHERS
 
-/*
- * Does our OpenSSL library support crypto hardware acceleration?
- */
-#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_LOAD_BUILTIN_ENGINES) && defined(HAVE_ENGINE_REGISTER_ALL_COMPLETE) && defined(HAVE_ENGINE_CLEANUP)
-#define CRYPTO_ENGINE 1
-#else
-#define CRYPTO_ENGINE 0
-#endif
-
 #include <openssl/objects.h>
 #include <openssl/rand.h>
 #include <openssl/evp.h>
@@ -55,10 +46,6 @@
 #include <openssl/sha.h>
 #include <openssl/err.h>
 
-#if CRYPTO_ENGINE
-#include <openssl/engine.h>
-#endif
-
 #if SSLEAY_VERSION_NUMBER >= 0x00907000L
 #include <openssl/des_old.h>
 #endif
@@ -434,12 +421,6 @@ void test_crypto (const struct crypto_options *co, struct frame* f);
 
 const char *md5sum(uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc);
 
-void init_crypto_lib_engine (const char *engine_name);
-
-void init_crypto_lib (void);
-
-void uninit_crypto_lib (void);
-
 /* key direction functions */
 
 void key_direction_state_init (struct key_direction_state *kds, int key_direction);
@@ -458,9 +439,6 @@ void key2_print (const struct key2* k,
 		 const char* prefix0,
 		 const char* prefix1);
 
-/* memory debugging */
-void openssl_dmalloc_init (void);
-
 #ifdef USE_SSL
 
 #define GHK_INLINE  (1<<0)
crypto_backend.h +23 -0
index 50eef7b..1b85dec 100644
@@ -38,8 +38,31 @@
 
 #include "basic.h"
 
+
+/*
+ * 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_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
+ * OpenSSL to use our private malloc/realloc/free functions so that
+ * we can dispatch them to dmalloc.
+ */
+void crypto_init_dmalloc (void);
+#endif /* DMALLOC */
+
 void show_available_ciphers (void);
 
 void show_available_digests (void);
crypto_openssl.c +164 -0

178 lines not on this page · raw message

init.c +2 -2
index 972b093..25d9fd9 100644
@@ -530,7 +530,7 @@ init_static (void)
   /* configure_path (); */
 
 #if defined(USE_CRYPTO) && defined(DMALLOC)
-  openssl_dmalloc_init ();
+  crypto_init_dmalloc();
 #endif
 
   init_random_seed ();		/* init random() function, only used as
@@ -1863,7 +1863,7 @@ static void
 init_crypto_pre (struct context *c, const unsigned int flags)
 {
   if (c->options.engine)
-    init_crypto_lib_engine (c->options.engine);
+    crypto_init_lib_engine (c->options.engine);
 
   if (flags & CF_LOAD_PERSISTED_PACKET_ID)
     {
ssl.c +2 -2
index d0fd77b..4effb49 100644
@@ -225,7 +225,7 @@ init_ssl_lib ()
   SSL_load_error_strings ();
   OpenSSL_add_all_algorithms ();
 
-  init_crypto_lib();
+  crypto_init_lib();
 
   /*
    * If you build the OpenSSL library and OpenVPN with
@@ -249,7 +249,7 @@ free_ssl_lib ()
   fclose (fp);
 #endif
 
-  uninit_crypto_lib ();
+  crypto_uninit_lib ();
   EVP_cleanup ();
   ERR_free_strings ();
 }
Signature · 1 line
1.7.4.1
#8 lore raw

PATCH 17/28 Refactored DES key manipulation functions

In reply to Adriaan de Jong
---
 crypto.c         |   85 ++--------------------------------------------------
 crypto_backend.h |   37 +++++++++++++++++++++++
 crypto_openssl.c |   87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 crypto_openssl.h |   15 +++++++++
 ntlm.c           |    2 +-
 5 files changed, 144 insertions(+), 82 deletions(-)
crypto.c +4 -81
index ff34d5f..ea04cdd 100644
@@ -601,83 +601,6 @@ free_key_ctx_bi (struct key_ctx_bi *ctx)
   free_key_ctx(&ctx->decrypt);
 }
 
-/*
- * Return number of DES cblocks for the current
- * key type or 0 if not a DES cipher.
- */
-static int
-n_DES_cblocks (const struct key_type *kt)
-{
-  int ret = 0;
-  const char *name = OBJ_nid2sn (EVP_CIPHER_nid (kt->cipher));
-  if (name)
-    {
-      if (!strncmp (name, "DES-", 4))
-	{
-	  ret = EVP_CIPHER_key_length (kt->cipher) / sizeof (DES_cblock);
-	}
-      else if (!strncmp (name, "DESX-", 5))
-	{
-	  ret = 1;
-	}
-    }
-  dmsg (D_CRYPTO_DEBUG, "CRYPTO INFO: n_DES_cblocks=%d", ret);
-  return ret;
-}
-
-static bool
-check_key_DES (struct key *key, const struct key_type *kt, int ndc)
-{
-  int i;
-  struct buffer b;
-
-  buf_set_read (&b, key->cipher, kt->cipher_length);
-
-  for (i = 0; i < ndc; ++i)
-    {
-      DES_cblock *dc = (DES_cblock*) buf_read_alloc (&b, sizeof (DES_cblock));
-      if (!dc)
-	{
-	  msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material");
-	  goto err;
-	}
-      if (DES_is_weak_key(dc))
-	{
-	  msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected");
-	  goto err;
-	}
-      if (!DES_check_key_parity (dc))
-	{
-	  msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected");
-	  goto err;
-	}
-    }
-  return true;
-
- err:
-  ERR_clear_error ();
-  return false;
-}
-
-static void
-fixup_key_DES (struct key *key, const struct key_type *kt, int ndc)
-{
-  int i;
-  struct buffer b;
-
-  buf_set_read (&b, key->cipher, kt->cipher_length);
-  for (i = 0; i < ndc; ++i)
-    {
-      DES_cblock *dc = (DES_cblock*) buf_read_alloc(&b, sizeof(DES_cblock));
-      if (!dc)
-	{
-	  msg (D_CRYPT_ERRORS, "CRYPTO INFO: fixup_key_DES: insufficient key material");
-	  ERR_clear_error ();
-	  return;
-	}
-      DES_set_odd_parity (dc);
-    }
-}
 
 static bool
 key_is_zero (struct key *key, const struct key_type *kt)
@@ -708,9 +631,9 @@ check_key (struct key *key, const struct key_type *kt)
        * Check for weak or semi-weak DES keys.
        */
       {
-	const int ndc = n_DES_cblocks (kt);
+	const int ndc = key_des_num_cblocks (kt->cipher);
 	if (ndc)
-	  return check_key_DES (key, kt, ndc);
+	  return key_des_check (key->cipher, kt->cipher_length, ndc);
 	else
 	  return true;
       }
@@ -735,10 +658,10 @@ fixup_key (struct key *key, const struct key_type *kt)
 #ifdef ENABLE_DEBUG
       const struct key orig = *key;
 #endif
-      const int ndc = n_DES_cblocks (kt);
+      const int ndc = key_des_num_cblocks (kt->cipher);
 
       if (ndc)
-	fixup_key_DES (key, kt, ndc);
+	key_des_fixup (key->cipher, kt->cipher_length, ndc);
 
 #ifdef ENABLE_DEBUG
       if (check_debug_level (D_CRYPTO_DEBUG))
crypto_backend.h +37 -0
index 1b85dec..f0e7b18 100644
@@ -91,6 +91,43 @@ int rand_bytes (uint8_t *output, int len);
 
 /*
  *
+ * Key functions, allow manipulation of keys.
+ *
+ */
+
+
+/**
+ * Return number of DES cblocks (1 cblock = length of a single-DES key) for the
+ * current key type or 0 if not a DES cipher.
+ *
+ * @param kt		Type of key
+ *
+ * @return 		Number of DES cblocks that the key consists of, or 0.
+ */
+int key_des_num_cblocks (const cipher_kt_t *kt);
+
+/*
+ * Check the given DES key. Checks the given key's length, weakness and parity.
+ *
+ * @param key		Key to check
+ * @param key_len	Length of the key, in bytes
+ * @param ndc		Number of DES cblocks that the key is made up of.
+ *
+ * @return 		\c true if the key is valid, \c false otherwise.
+ */
+bool key_des_check (uint8_t *key, int key_len, int ndc);
+
+/*
+ * Fix the given DES key, setting its parity to odd.
+ *
+ * @param key		Key to check
+ * @param key_len	Length of the key, in bytes
+ * @param ndc		Number of DES cblocks that the key is made up of.
+ */
+void key_des_fixup (uint8_t *key, int key_len, int ndc);
+
+/*
+ *
  * Generic cipher key type functions
  *
  */
crypto_openssl.c +87 -0

96 lines not on this page · raw message

crypto_openssl.h +15 -0
index ea3601e..9bc106a 100644
@@ -34,6 +34,21 @@
 #include <openssl/hmac.h>
 #include <openssl/md5.h>
 
+/** Generic cipher key type %context. */
+typedef EVP_CIPHER cipher_kt_t;
+
+/** Generic message digest key type %context. */
+typedef EVP_MD md_kt_t;
+
+/** Generic cipher %context. */
+typedef EVP_CIPHER_CTX cipher_ctx_t;
+
+/** Generic message digest %context. */
+typedef EVP_MD_CTX md_ctx_t;
+
+/** Generic HMAC %context. */
+typedef HMAC_CTX hmac_ctx_t;
+
 /** Maximum length of an IV */
 #define OPENVPN_MAX_IV_LENGTH 	EVP_MAX_IV_LENGTH
 
ntlm.c +1 -1
index 4dfeed3..3440c12 100644
@@ -63,7 +63,7 @@ create_des_keys(const unsigned char *hash, unsigned char *key)
   key[5] = ((hash[4]&31)<<3)|(hash[5]>>5);
   key[6] = ((hash[5]&63)<<2)|(hash[6]>>6);
   key[7] = ((hash[6]&127)<<1);
-  des_set_odd_parity((des_cblock *)key);
+  key_des_fixup(key, 8, 1);
 }
 
 static void
Signature · 1 line
1.7.4.1
#9 lore raw

PATCH 18/28 Refactored NTLM DES key generation

In reply to Adriaan de Jong
---
 crypto_backend.h |   11 +++++++++++
 crypto_openssl.c |   11 +++++++++++
 ntlm.c           |   12 ++++--------
 3 files changed, 26 insertions(+), 8 deletions(-)
crypto_backend.h +11 -0
index f0e7b18..6c2bd0c 100644
@@ -126,6 +126,17 @@ bool key_des_check (uint8_t *key, int key_len, int ndc);
  */
 void key_des_fixup (uint8_t *key, int key_len, int ndc);
 
+/**
+ * Encrypt the given block, using DES ECB mode
+ *
+ * @param key		DES key to use.
+ * @param src		Buffer containing the 8-byte source.
+ * @param dst		Buffer containing the 8-byte destination
+ */
+void cipher_des_encrypt_ecb (const unsigned char key[8],
+    unsigned char src[8],
+    unsigned char dst[8]);
+
 /*
  *
  * Generic cipher key type functions
crypto_openssl.c +11 -0
index 9fbbf11..3842463 100644
@@ -441,3 +441,14 @@ key_des_fixup (uint8_t *key, int key_len, int ndc)
 }
 
 
+void
+cipher_des_encrypt_ecb (const unsigned char key[8],
+    unsigned char *src,
+    unsigned char *dst)
+{
+    des_key_schedule sched;
+
+    des_set_key_unchecked((des_cblock*)key, sched);
+    des_ecb_encrypt((des_cblock *)src, (des_cblock *)dst, sched, DES_ENCRYPT);
+}
+
ntlm.c +4 -8
index 3440c12..40a11b9 100644
@@ -196,8 +196,6 @@ ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, struct gc_ar
   char md4_hash[21];
   char challenge[8], ntlm_response[24];
   int i, ret_val;
-  des_cblock key1, key2, key3;
-  des_key_schedule sched1, sched2, sched3;
 
 	char ntlmv2_response[144];
 	char userdomain_u[256]; /* for uppercase unicode username and domain */
@@ -303,18 +301,16 @@ ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, struct gc_ar
 		memcpy(ntlmv2_response, ntlmv2_hmacmd5, 16); /* Note: This overwrites challenge previously written at ntlmv2_response[8..15] */
 	
 	} else { /* Generate NTLM response */
+		unsigned char key1[8], key2[8], key3[8];
 
 		create_des_keys ((unsigned char *)md4_hash, key1);
-		des_set_key_unchecked ((des_cblock *)key1, sched1);
-		des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)ntlm_response, sched1, DES_ENCRYPT);
+		cipher_des_encrypt_ecb (key1, challenge, ntlm_response);
 
 		create_des_keys ((unsigned char *)&(md4_hash[7]), key2);
-		des_set_key_unchecked ((des_cblock *)key2, sched2);
-		des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)&(ntlm_response[8]), sched2, DES_ENCRYPT);
+		cipher_des_encrypt_ecb (key2, challenge, &ntlm_response[8]);
 
 		create_des_keys ((unsigned char *)&(md4_hash[14]), key3);
-		des_set_key_unchecked ((des_cblock *)key3, sched3);
-		des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)&(ntlm_response[16]), sched3, DES_ENCRYPT);
+		cipher_des_encrypt_ecb (key3, challenge, &ntlm_response[16]);
 	}
 	
 	
Signature · 1 line
1.7.4.1
#10 lore raw

PATCH 19/28 Refactored message digest type functions

In reply to Adriaan de Jong
---
 crypto.c         |   49 ++++++++++++-------------------------------------
 crypto.h         |   18 +++++++++---------
 crypto_backend.h |   33 +++++++++++++++++++++++++++++++++
 crypto_openssl.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 options.c        |    2 +-
 5 files changed, 104 insertions(+), 47 deletions(-)
crypto.c +12 -37
index ea04cdd..9baf9d4 100644
@@ -404,22 +404,6 @@ get_cipher (const char *ciphername)
   return cipher;
 }
 
-static const EVP_MD *
-get_md (const char *digest)
-{
-  const EVP_MD *md = NULL;
-  ASSERT (digest);
-  md = EVP_get_digestbyname (digest);
-  if (!md)
-    msg (M_SSLERR, "Message hash algorithm '%s' not found", digest);
-  if (EVP_MD_size (md) > MAX_HMAC_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,
-	 EVP_MD_size (md),
-	 MAX_HMAC_KEY_LENGTH);
-  return md;
-}
-
 static void
 init_cipher (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
 	     struct key *key, const struct key_type *kt, int enc,
@@ -519,8 +503,8 @@ init_key_type (struct key_type *kt, const char *ciphername,
     }
   if (authname && authname_defined)
     {
-      kt->digest = get_md (authname);
-      kt->hmac_length = EVP_MD_size (kt->digest);
+      kt->digest = md_kt_get (authname);
+      kt->hmac_length = md_kt_size (kt->digest);
     }
   else
     {
@@ -538,15 +522,6 @@ kt_cipher_name (const struct key_type *kt)
     return "[null-cipher]";
 }
 
-const char *
-kt_digest_name (const struct key_type *kt)
-{
-  if (kt->digest)
-    return EVP_MD_name (kt->digest);
-  else
-    return "[null-digest]";
-}
-
 int
 kt_key_size (const struct key_type *kt)
 {
@@ -1103,14 +1078,14 @@ read_key_file (struct key2 *key2, const char *file, const unsigned int flags)
 
 int
 read_passphrase_hash (const char *passphrase_file,
-		      const EVP_MD *digest,
+		      const md_kt_t *digest,
 		      uint8_t *output,
 		      int len)
 {
   unsigned int outlen = 0;
-  EVP_MD_CTX md;
+  md_ctx_t md;
 
-  ASSERT (len >= EVP_MD_size (digest));
+  ASSERT (len >= md_kt_size(digest));
   memset (output, 0, len);
 
   EVP_DigestInit (&md, digest);
@@ -1381,22 +1356,22 @@ key_len_err:
  * IV values and a number of other miscellaneous tasks.
  */
 
-static uint8_t *nonce_data; /* GLOBAL */
-static const EVP_MD *nonce_md = NULL; /* GLOBAL */
-static int nonce_secret_len; /* GLOBAL */
+static uint8_t *nonce_data = NULL; /* GLOBAL */
+static const md_kt_t *nonce_md = NULL; /* GLOBAL */
+static int nonce_secret_len = 0; /* GLOBAL */
 
 void
 prng_init (const char *md_name, const int nonce_secret_len_parm)
 {
   prng_uninit ();
-  nonce_md = md_name ? get_md (md_name) : NULL;
+  nonce_md = md_name ? md_kt_get (md_name) : NULL;
   if (nonce_md)
     {
       ASSERT (nonce_secret_len_parm >= NONCE_SECRET_LEN_MIN && nonce_secret_len_parm <= NONCE_SECRET_LEN_MAX);
       nonce_secret_len = nonce_secret_len_parm;
       {
-	const int size = EVP_MD_size (nonce_md) + nonce_secret_len;
-	dmsg (D_CRYPTO_DEBUG, "PRNG init md=%s size=%d", EVP_MD_name (nonce_md), size);
+	const int size = md_kt_size(nonce_md) + nonce_secret_len;
+	dmsg (D_CRYPTO_DEBUG, "PRNG init md=%s size=%d", md_kt_name(nonce_md), size);
 	nonce_data = (uint8_t*) malloc (size);
 	check_malloc_return (nonce_data);
 #if 1 /* Must be 1 for real usage */
@@ -1429,7 +1404,7 @@ prng_bytes (uint8_t *output, int len)
   if (nonce_md)
     {
       EVP_MD_CTX ctx;
-      const int md_size = EVP_MD_size (nonce_md);
+      const int md_size = md_kt_size (nonce_md);
       while (len > 0)
 	{
 	  unsigned int outlen = 0;
crypto.h +9 -9
index 7fa7418..432e7f3 100644
@@ -165,9 +165,9 @@ cipher_ok (const char* name)
 struct key_type
 {
   uint8_t cipher_length;
-  uint8_t hmac_length;
+  uint8_t hmac_length;		/**< HMAC length, in bytes */
   const EVP_CIPHER *cipher;
-  const EVP_MD *digest;
+  const md_kt_t *digest;	/**< Message digest static parameters */
 };
 
 /**
@@ -283,11 +283,6 @@ struct crypto_options
                                  *   security operation functions. */
 };
 
-void init_key_type (struct key_type *kt, const char *ciphername,
-		    bool ciphername_defined, const char *authname,
-		    bool authname_defined, int keysize,
-		    bool cfb_ofb_allowed, bool warn);
-
 #define RKF_MUST_SUCCEED (1<<0)
 #define RKF_INLINE       (1<<1)
 void read_key_file (struct key2 *key2, const char *file, const unsigned int flags);
@@ -295,7 +290,7 @@ void read_key_file (struct key2 *key2, const char *file, const unsigned int flag
 int write_key_file (const int nkeys, const char *filename);
 
 int read_passphrase_hash (const char *passphrase_file,
-			  const EVP_MD *digest,
+			  const md_kt_t *digest,
 			  uint8_t *output,
 			  int len);
 
@@ -315,12 +310,17 @@ int read_key (struct key *key, const struct key_type *kt, struct buffer *buf);
 bool cfb_ofb_mode (const struct key_type* kt);
 
 const char *kt_cipher_name (const struct key_type *kt);
-const char *kt_digest_name (const struct key_type *kt);
 int kt_key_size (const struct key_type *kt);
+void init_key_type (struct key_type *kt, const char *ciphername,
+    bool ciphername_defined, const char *authname, bool authname_defined,
+    int keysize, bool cfb_ofb_allowed, bool warn);
 
 /* enc parameter in init_key_ctx */
 #define DO_ENCRYPT 1
 #define DO_DECRYPT 0
+/*
+ * Key context functions
+ */
 
 void init_key_ctx (struct key_ctx *ctx, struct key *key,
 		   const struct key_type *kt, int enc,
crypto_backend.h +33 -0
index 6c2bd0c..527f6b6 100644
@@ -171,4 +171,37 @@ void cipher_des_encrypt_ecb (const unsigned char key[8],
  */
 #define MAX_HMAC_KEY_LENGTH 64
 
+/**
+ * Return message digest parameters, based on the given digest name. The
+ * contents of these parameters are library-specific, and can be used to
+ * initialise HMAC or message digest operations.
+ *
+ * @param digest	Name of the digest to retrieve parameters for (e.g.
+ * 			\c MD5).
+ *
+ * @return		A statically allocated structure containing parameters
+ * 			for the given message digest.
+ */
+const md_kt_t * md_kt_get (const char *digest);
+
+/**
+ * Retrieve a string describing the digest digest (e.g. \c SHA1).
+ *
+ * @param kt 		Static message digest parameters
+ *
+ * @return 		Statically allocated string describing the message
+ * 			digest.
+ */
+const char * md_kt_name (const md_kt_t *kt);
+
+/**
+ * Returns the size of the message digest, in bytes.
+ *
+ * @param kt 		Static message digest parameters
+ *
+ * @return 		Message digest size, in bytes, or 0 if ctx was NULL.
+ */
+int md_kt_size (const md_kt_t *kt);
+
+
 #endif /* CRYPTO_BACKEND_H_ */
crypto_openssl.c +49 -0

64 lines not on this page · raw message

options.c +1 -1
index ab4228d..f61cd16 100644
@@ -2803,7 +2803,7 @@ options_string (const struct options *o,
 		       o->keysize, true, false);
 
 	buf_printf (&out, ",cipher %s", kt_cipher_name (&kt));
-	buf_printf (&out, ",auth %s", kt_digest_name (&kt));
+	buf_printf (&out, ",auth %s", md_kt_name (kt.digest));
 	buf_printf (&out, ",keysize %d", kt_key_size (&kt));
 	if (o->shared_secret_file)
 	  buf_printf (&out, ",secret");
Signature · 1 line
1.7.4.1
#11 lore raw

PATCH 20/28 Refactored message digest functions

In reply to Adriaan de Jong
---
 crypto.c         |   47 +++++++++++++++++----------------
 crypto.h         |    4 +-
 crypto_backend.h |   60 ++++++++++++++++++++++++++++++++++++++++++
 crypto_openssl.c |   52 ++++++++++++++++++++++++++++++++++++
 httpdigest.c     |   77 ++++++++++++++++++++++++++++-------------------------
 misc.c           |   15 ++++++----
 ntlm.c           |    8 +----
 7 files changed, 190 insertions(+), 73 deletions(-)
crypto.c +24 -23
index 9baf9d4..4c16979 100644
@@ -1088,7 +1088,7 @@ read_passphrase_hash (const char *passphrase_file,
   ASSERT (len >= md_kt_size(digest));
   memset (output, 0, len);
 
-  EVP_DigestInit (&md, digest);
+  md_ctx_init(&md, digest);
 
   /* read passphrase file */
   {
@@ -1108,7 +1108,7 @@ read_passphrase_hash (const char *passphrase_file,
 	if (size == -1)
 	  msg (M_ERR, "Read error on passphrase file: '%s'",
 	       passphrase_file);
-	EVP_DigestUpdate (&md, buf, size);
+	md_ctx_update(&md, buf, size);
 	total_size += size;
       }
     close (fd);
@@ -1120,10 +1120,9 @@ read_passphrase_hash (const char *passphrase_file,
 	   "Passphrase file '%s' is too small (must have at least %d characters)",
 	   passphrase_file, min_passphrase_size);
   }
-
-  EVP_DigestFinal (&md, output, &outlen);
-  EVP_MD_CTX_cleanup (&md);
-  return outlen;
+  md_ctx_final(&md, output);
+  md_ctx_cleanup(&md);
+  return md_kt_size(digest);
 }
 
 /*
@@ -1403,17 +1402,13 @@ prng_bytes (uint8_t *output, int len)
 {
   if (nonce_md)
     {
-      EVP_MD_CTX ctx;
+      md_ctx_t ctx;
       const int md_size = md_kt_size (nonce_md);
       while (len > 0)
 	{
 	  unsigned int outlen = 0;
 	  const int blen = min_int (len, md_size);
-	  EVP_DigestInit (&ctx, nonce_md);
-	  EVP_DigestUpdate (&ctx, nonce_data, md_size + nonce_secret_len);
-	  EVP_DigestFinal (&ctx, nonce_data, &outlen);
-	  ASSERT (outlen == md_size);
-	  EVP_MD_CTX_cleanup (&ctx);
+	  md_full(nonce_md, nonce_data, md_size + nonce_secret_len, nonce_data);
 	  memcpy (output, nonce_data, blen);
 	  output += blen;
 	  len -= blen;
@@ -1434,14 +1429,6 @@ get_random()
   return l;
 }
 
-const char *
-md5sum (uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc)
-{
-  uint8_t digest[MD5_DIGEST_LENGTH];
-  MD5 (buf, len, digest);
-  return format_hex (digest, MD5_DIGEST_LENGTH, n_print_chars, gc);
-}
-
 #ifndef USE_SSL
 
 void
@@ -1466,22 +1453,36 @@ free_ssl_lib (void)
  * md5 functions
  */
 
+const char *
+md5sum (uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc)
+{
+  uint8_t digest[MD5_DIGEST_LENGTH];
+  const md_kt_t *md5_kt = md_kt_get("MD5");
+
+  md_full(md5_kt, buf, len, digest);
+
+  return format_hex (digest, MD5_DIGEST_LENGTH, n_print_chars, gc);
+}
+
 void
 md5_state_init (struct md5_state *s)
 {
-  MD5_Init (&s->ctx);
+  const md_kt_t *md5_kt = md_kt_get("MD5");
+
+  md_ctx_init(&s->ctx, md5_kt);
 }
 
 void
 md5_state_update (struct md5_state *s, void *data, size_t len)
 {
-  MD5_Update (&s->ctx, data, len);
+  md_ctx_update(&s->ctx, data, len);
 }
 
 void
 md5_state_final (struct md5_state *s, struct md5_digest *out)
 {
-  MD5_Final (out->digest, &s->ctx);
+  md_ctx_final(&s->ctx, out->digest);
+  md_ctx_cleanup(&s->ctx);
 }
 
 void
crypto.h +2 -2
index 432e7f3..fea1b7b 100644
@@ -419,7 +419,6 @@ void prng_uninit ();
 
 void test_crypto (const struct crypto_options *co, struct frame* f);
 
-const char *md5sum(uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc);
 
 /* key direction functions */
 
@@ -470,13 +469,14 @@ key_ctx_bi_defined(const struct key_ctx_bi* key)
  */
 
 struct md5_state {
-  MD5_CTX ctx;
+  md_ctx_t ctx;
 };
 
 struct md5_digest {
   uint8_t digest [MD5_DIGEST_LENGTH];
 };
 
+const char *md5sum(uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc);
 void md5_state_init (struct md5_state *s);
 void md5_state_update (struct md5_state *s, void *data, size_t len);
 void md5_state_final (struct md5_state *s, struct md5_digest *out);
crypto_backend.h +60 -0

64 lines not on this page · raw message

crypto_openssl.c +52 -0

55 lines not on this page · raw message

httpdigest.c +41 -36

108 lines not on this page · raw message

misc.c +9 -6
index 2d6c6f3..6eaadcc 100644
@@ -1664,23 +1664,26 @@ void
 get_user_pass_auto_userid (struct user_pass *up, const char *tag)
 {
   struct gc_arena gc = gc_new ();
-  MD5_CTX ctx;
   struct buffer buf;
   uint8_t macaddr[6];
   static uint8_t digest [MD5_DIGEST_LENGTH];
   static const uint8_t hashprefix[] = "AUTO_USERID_DIGEST";
 
+  const md_kt_t *md5_kt = md_kt_get("MD5");
+  md_ctx_t ctx;
+
   CLEAR (*up);
   buf_set_write (&buf, (uint8_t*)up->username, USER_PASS_LEN);
   buf_printf (&buf, "%s", get_platform_prefix ());
   if (get_default_gateway_mac_addr (macaddr))
     {
       dmsg (D_AUTO_USERID, "GUPAU: macaddr=%s", format_hex_ex (macaddr, sizeof (macaddr), 0, 1, ":", &gc));
-      MD5_Init (&ctx);
-      MD5_Update (&ctx, hashprefix, sizeof (hashprefix) - 1);
-      MD5_Update (&ctx, macaddr, sizeof (macaddr));
-      MD5_Final (digest, &ctx);
-      buf_printf (&buf, "%s", format_hex_ex (digest, sizeof (digest), 0, 256, " ", &gc));
+      md_ctx_init(&ctx, md5_kt);
+      md_ctx_update(&ctx, hashprefix, sizeof (hashprefix) - 1);
+      md_ctx_update(&ctx, macaddr, sizeof (macaddr));
+      md_ctx_final(&ctx, digest);
+      md_ctx_cleanup(&ctx)
+      buf_printf(&buf, "%s", format_hex_ex (digest, sizeof (digest), 0, 256, " ", &gc));
     }
   else
     {
ntlm.c +2 -6
index 40a11b9..512c26f 100644
@@ -70,14 +70,10 @@ static void
 gen_md4_hash (const char* data, int data_len, char *result)
 {
   /* result is 16 byte md4 hash */
-
-  MD4_CTX c;
+  const md_kt_t *md4_kt = md_kt_get("MD4");
   char md[16];
 
-  MD4_Init (&c);
-  MD4_Update (&c, data, data_len);
-  MD4_Final ((unsigned char *)md, &c);
-
+  md_full(md4_kt, data, data_len, md);
   memcpy (result, md, 16);
 }
 
Signature · 1 line
1.7.4.1
#12 lore raw

PATCH 21/28 Refactored HMAC functions

In reply to Adriaan de Jong
---
 crypto.c         |   57 ++++++++++--------------------------------
 crypto_backend.h |   60 +++++++++++++++++++++++++++++++++++++++++++++
 crypto_openssl.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ntlm.c           |   15 ++++++-----
 4 files changed, 153 insertions(+), 50 deletions(-)
crypto.c +14 -43
index 4c16979..cf1c8be 100644
@@ -174,15 +174,13 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
       /* HMAC the ciphertext (or plaintext if !cipher) */
       if (ctx->hmac)
 	{
-	  int hmac_len;
-	  uint8_t *output;
+	  uint8_t *output = NULL;
 
-	  HMAC_Init_ex (ctx->hmac, NULL, 0, NULL, NULL);
-	  HMAC_Update (ctx->hmac, BPTR (&work), BLEN (&work));
-	  output = buf_prepend (&work, HMAC_size (ctx->hmac));
+	  hmac_ctx_reset (ctx->hmac);
+	  hmac_ctx_update (ctx->hmac, BPTR(&work), BLEN(&work));
+	  output = buf_prepend (&work, hmac_ctx_size(ctx->hmac));
 	  ASSERT (output);
-	  HMAC_Final (ctx->hmac, output, (unsigned int *)&hmac_len);
-	  ASSERT (hmac_len == HMAC_size (ctx->hmac));
+	  hmac_ctx_final (ctx->hmac, output);
 	}
 
       *buf = work;
@@ -226,21 +224,18 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
 	{
 	  int hmac_len;
 	  uint8_t local_hmac[MAX_HMAC_KEY_LENGTH]; /* HMAC of ciphertext computed locally */
-	  int in_hmac_len;
 
-	  HMAC_Init_ex (ctx->hmac, NULL, 0, NULL, NULL);
+	  hmac_ctx_reset(ctx->hmac);
 
 	  /* Assume the length of the input HMAC */
-	  hmac_len = HMAC_size (ctx->hmac);
+	  hmac_len = hmac_ctx_size (ctx->hmac);
 
 	  /* Authentication fails if insufficient data in packet for HMAC */
 	  if (buf->len < hmac_len)
 	    CRYPT_ERROR ("missing authentication info");
 
-	  HMAC_Update (ctx->hmac, BPTR (buf) + hmac_len,
-		       BLEN (buf) - hmac_len);
-	  HMAC_Final (ctx->hmac, local_hmac, (unsigned int *)&in_hmac_len);
-	  ASSERT (hmac_len == in_hmac_len);
+	  hmac_ctx_update (ctx->hmac, BPTR (buf) + hmac_len, BLEN (buf) - hmac_len);
+	  hmac_ctx_final (ctx->hmac, local_hmac);
 
 	  /* Compare locally computed HMAC with packet HMAC */
 	  if (memcmp (local_hmac, BPTR (buf), hmac_len))
@@ -439,31 +434,6 @@ init_cipher (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
   gc_free (&gc);
 }
 
-static void
-init_hmac (HMAC_CTX *ctx, const EVP_MD *digest,
-	   struct key *key, const struct key_type *kt, const char *prefix)
-{
-  struct gc_arena gc = gc_new ();
-
-  HMAC_CTX_init (ctx);
-  HMAC_Init_ex (ctx, key->hmac, kt->hmac_length, digest, NULL);
-  msg (D_HANDSHAKE,
-       "%s: Using %d bit message hash '%s' for HMAC authentication",
-       prefix, HMAC_size (ctx) * 8, OBJ_nid2sn (EVP_MD_type (digest)));
-
-  /* make sure we used a big enough key */
-  ASSERT (HMAC_size (ctx) <= kt->hmac_length);
-
-  dmsg (D_SHOW_KEYS, "%s: HMAC KEY: %s", prefix,
-       format_hex (key->hmac, kt->hmac_length, 0, &gc));
-  dmsg (D_CRYPTO_DEBUG, "%s: HMAC size=%d block_size=%d",
-       prefix,
-       EVP_MD_size (digest),
-       EVP_MD_block_size (digest));
-
-  gc_free (&gc);
-}
-
 /*
  * Build a struct key_type.
  */
@@ -547,8 +517,9 @@ init_key_ctx (struct key_ctx *ctx, struct key *key,
     }
   if (kt->digest && kt->hmac_length > 0)
     {
-      ALLOC_OBJ (ctx->hmac, HMAC_CTX);
-      init_hmac (ctx->hmac, kt->digest, key, kt, prefix);
+      ALLOC_OBJ(ctx->hmac, hmac_ctx_t);
+      hmac_ctx_init (ctx->hmac, key->hmac, kt->hmac_length, kt->digest,
+	  prefix);
     }
 }
 
@@ -563,8 +534,8 @@ free_key_ctx (struct key_ctx *ctx)
     }
   if (ctx->hmac)
     {
-      HMAC_CTX_cleanup (ctx->hmac);
-      free (ctx->hmac);
+      hmac_ctx_cleanup(ctx->hmac);
+      free(ctx->hmac);
       ctx->hmac = NULL;
     }
 }
crypto_backend.h +60 -0

64 lines not on this page · raw message

crypto_openssl.c +71 -0

74 lines not on this page · raw message

ntlm.c +8 -7
index 512c26f..30d5d11 100644
@@ -80,13 +80,14 @@ gen_md4_hash (const char* data, int data_len, char *result)
 static void
 gen_hmac_md5 (const char* data, int data_len, const char* key, int key_len,char *result)
 {
-	unsigned int len;
-
-	HMAC_CTX c;
-	HMAC_Init (&c, key, key_len, EVP_md5());
-	HMAC_Update (&c, (const unsigned char *)data, data_len);
-	HMAC_Final (&c, (unsigned char *)result, &len);
-	HMAC_CTX_cleanup(&c);
+	const md_kt_t *md5_kt = md_kt_get("MD5");
+	hmac_ctx_t hmac_ctx;
+	CLEAR(hmac_ctx);
+
+	hmac_ctx_init(&hmac_ctx, key, key_len, md5_kt, NULL);
+	hmac_ctx_update(&hmac_ctx, (const unsigned char *)data, data_len);
+	hmac_ctx_final(&hmac_ctx, (unsigned char *)result);
+	hmac_ctx_cleanup(&hmac_ctx);
 }
 
 static void
Signature · 1 line
1.7.4.1
#13 lore raw

PATCH 22/28 Refactored cipher key types

In reply to Adriaan de Jong
---
 crypto.c         |   48 +++---------------------
 crypto.h         |    6 +--
 crypto_backend.h |   63 +++++++++++++++++++++++++++++++
 crypto_openssl.c |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 options.c        |    4 +-
 5 files changed, 181 insertions(+), 48 deletions(-)
crypto.c +6 -42
index cf1c8be..13c54b5 100644
@@ -378,27 +378,11 @@ crypto_adjust_frame_parameters(struct frame *frame,
 {
   frame_add_to_extra_frame (frame,
 			    (packet_id ? packet_id_size (packet_id_long_form) : 0) +
-			    ((cipher_defined && use_iv) ? EVP_CIPHER_iv_length (kt->cipher) : 0) +
-			    (cipher_defined ? EVP_CIPHER_block_size (kt->cipher) : 0) + /* worst case padding expansion */
+			    ((cipher_defined && use_iv) ? cipher_kt_iv_size (kt->cipher) : 0) +
+			    (cipher_defined ? cipher_kt_block_size (kt->cipher) : 0) + /* worst case padding expansion */
 			    kt->hmac_length);
 }
 
-static const EVP_CIPHER *
-get_cipher (const char *ciphername)
-{
-  const EVP_CIPHER *cipher = NULL;
-  ASSERT (ciphername);
-  cipher = EVP_get_cipherbyname (ciphername);
-  if ( !(cipher && cipher_ok (OBJ_nid2sn (EVP_CIPHER_nid (cipher)))))
-    msg (M_SSLERR, "Cipher algorithm '%s' not found", ciphername);
-  if (EVP_CIPHER_key_length (cipher) > MAX_CIPHER_KEY_LENGTH)
-    msg (M_FATAL, "Cipher algorithm '%s' uses a default key size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum key size (%d bytes)",
-	 ciphername,
-	 EVP_CIPHER_key_length (cipher),
-	 MAX_CIPHER_KEY_LENGTH);
-  return cipher;
-}
-
 static void
 init_cipher (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
 	     struct key *key, const struct key_type *kt, int enc,
@@ -446,14 +430,14 @@ init_key_type (struct key_type *kt, const char *ciphername,
   CLEAR (*kt);
   if (ciphername && ciphername_defined)
     {
-      kt->cipher = get_cipher (ciphername);
-      kt->cipher_length = EVP_CIPHER_key_length (kt->cipher);
+      kt->cipher = cipher_kt_get (ciphername);
+      kt->cipher_length = cipher_kt_key_size (kt->cipher);
       if (keysize > 0 && keysize <= MAX_CIPHER_KEY_LENGTH)
 	kt->cipher_length = keysize;
 
       /* check legal cipher mode */
       {
-	const unsigned int mode = EVP_CIPHER_mode (kt->cipher);
+	const unsigned int mode = cipher_kt_mode (kt->cipher);
 	if (!(mode == OPENVPN_MODE_CBC
 #ifdef ALLOW_NON_CBC_CIPHERS
 	      || (cfb_ofb_allowed && (mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB))
@@ -483,26 +467,6 @@ init_key_type (struct key_type *kt, const char *ciphername,
     }
 }
 
-const char *
-kt_cipher_name (const struct key_type *kt)
-{
-  if (kt->cipher)
-    return EVP_CIPHER_name (kt->cipher);
-  else
-    return "[null-cipher]";
-}
-
-int
-kt_key_size (const struct key_type *kt)
-{
-  if (kt->cipher_length)
-    return kt->cipher_length * 8;
-  else if (kt->cipher)
-    return EVP_CIPHER_key_length (kt->cipher) * 8;
-  else
-    return 0;
-}
-
 /* given a key and key_type, build a key_ctx */
 void
 init_key_ctx (struct key_ctx *ctx, struct key *key,
@@ -632,8 +596,8 @@ check_replay_iv_consistency (const struct key_type *kt, bool packet_id, bool use
 bool
 cfb_ofb_mode (const struct key_type* kt)
 {
-    const unsigned int mode = EVP_CIPHER_mode (kt->cipher);
   if (kt && kt->cipher) {
+      const unsigned int mode = cipher_kt_mode (kt->cipher);
       return mode == OPENVPN_MODE_CFB || mode == OPENVPN_MODE_OFB;
   }
   return false;
crypto.h +2 -4
index fea1b7b..daa083f 100644
@@ -164,9 +164,9 @@ cipher_ok (const char* name)
  */
 struct key_type
 {
-  uint8_t cipher_length;
+  uint8_t cipher_length; 	/**< Cipher length, in bytes */
   uint8_t hmac_length;		/**< HMAC length, in bytes */
-  const EVP_CIPHER *cipher;
+  const cipher_kt_t *cipher;	/**< Cipher static parameters */
   const md_kt_t *digest;	/**< Message digest static parameters */
 };
 
@@ -309,8 +309,6 @@ int read_key (struct key *key, const struct key_type *kt, struct buffer *buf);
 
 bool cfb_ofb_mode (const struct key_type* kt);
 
-const char *kt_cipher_name (const struct key_type *kt);
-int kt_key_size (const struct key_type *kt);
 void init_key_type (struct key_type *kt, const char *ciphername,
     bool ciphername_defined, const char *authname, bool authname_defined,
     int keysize, bool cfb_ofb_allowed, bool warn);
crypto_backend.h +63 -0

69 lines not on this page · raw message

crypto_openssl.c +108 -0

138 lines not on this page · raw message

options.c +2 -2
index f61cd16..c634318 100644
@@ -2802,9 +2802,9 @@ options_string (const struct options *o,
 		       o->authname, o->authname_defined,
 		       o->keysize, true, false);
 
-	buf_printf (&out, ",cipher %s", kt_cipher_name (&kt));
+	buf_printf (&out, ",cipher %s", cipher_kt_name (kt.cipher));
 	buf_printf (&out, ",auth %s", md_kt_name (kt.digest));
-	buf_printf (&out, ",keysize %d", kt_key_size (&kt));
+	buf_printf (&out, ",keysize %d", kt.cipher_length);
 	if (o->shared_secret_file)
 	  buf_printf (&out, ",secret");
 	if (!o->replay)
Signature · 1 line
1.7.4.1
#14 lore raw

PATCH 23/28 Refactored cipher functions

In reply to Adriaan de Jong
---
 crypto.c         |   68 +++++++++---------------------------
 crypto.h         |   26 ++++++-------
 crypto_backend.h |  100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 crypto_openssl.c |   89 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 218 insertions(+), 65 deletions(-)
crypto.c +17 -51
index 13c54b5..995558b 100644
@@ -75,8 +75,8 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
       if (ctx->cipher)
 	{
 	  uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH];
-	  const int iv_size = EVP_CIPHER_CTX_iv_length (ctx->cipher);
-	  const unsigned int mode = EVP_CIPHER_CTX_mode (ctx->cipher);  
+          const int iv_size = cipher_ctx_iv_length (ctx->cipher);
+	  const unsigned int mode = cipher_ctx_mode (ctx->cipher);
 	  int outlen;
 
 	  if (mode == OPENVPN_MODE_CBC)
@@ -124,10 +124,10 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
 	       format_hex (BPTR (buf), BLEN (buf), 80, &gc));
 
 	  /* cipher_ctx was already initialized with key & keylen */
-	  ASSERT (EVP_CipherInit_ov (ctx->cipher, NULL, NULL, iv_buf, DO_ENCRYPT));
+	  ASSERT (cipher_ctx_reset(ctx->cipher, iv_buf));
 
 	  /* Buffer overflow check */
-	  if (!buf_safe (&work, buf->len + EVP_CIPHER_CTX_block_size (ctx->cipher)))
+	  if (!buf_safe (&work, buf->len + cipher_ctx_block_size(ctx->cipher)))
 	    {
 	      msg (D_CRYPT_ERRORS, "ENCRYPT: buffer size error, bc=%d bo=%d bl=%d wc=%d wo=%d wl=%d cbs=%d",
 		   buf->capacity,
@@ -136,16 +136,16 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
 		   work.capacity,
 		   work.offset,
 		   work.len,
-		   EVP_CIPHER_CTX_block_size (ctx->cipher));
+		   cipher_ctx_block_size (ctx->cipher));
 	      goto err;
 	    }
 
 	  /* Encrypt packet ID, payload */
-	  ASSERT (EVP_CipherUpdate_ov (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf)));
+	  ASSERT (cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf)));
 	  work.len += outlen;
 
 	  /* Flush the encryption buffer */
-	  ASSERT (EVP_CipherFinal (ctx->cipher, BPTR (&work) + outlen, &outlen));
+	  ASSERT(cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen));
 	  work.len += outlen;
 	  ASSERT (outlen == iv_size);
 
@@ -248,8 +248,8 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
 
       if (ctx->cipher)
 	{
-	  const unsigned int mode = EVP_CIPHER_CTX_mode (ctx->cipher);
-	  const int iv_size = EVP_CIPHER_CTX_iv_length (ctx->cipher);
+	  const unsigned int mode = cipher_ctx_mode (ctx->cipher);
+	  const int iv_size = cipher_ctx_iv_length (ctx->cipher);
 	  uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH];
 	  int outlen;
 
@@ -274,7 +274,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
 	    CRYPT_ERROR ("missing payload");
 
 	  /* ctx->cipher was already initialized with key & keylen */
-	  if (!EVP_CipherInit_ov (ctx->cipher, NULL, NULL, iv_buf, DO_DECRYPT))
+	  if (!cipher_ctx_reset (ctx->cipher, iv_buf))
 	    CRYPT_ERROR ("cipher init failed");
 
 	  /* Buffer overflow check (should never happen) */
@@ -282,12 +282,12 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
 	    CRYPT_ERROR ("buffer overflow");
 
 	  /* Decrypt packet ID, payload */
-	  if (!EVP_CipherUpdate_ov (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf)))
+	  if (!cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf)))
 	    CRYPT_ERROR ("cipher update failed");
 	  work.len += outlen;
 
 	  /* Flush the decryption buffer */
-	  if (!EVP_CipherFinal (ctx->cipher, BPTR (&work) + outlen, &outlen))
+	  if (!cipher_ctx_final (ctx->cipher, BPTR (&work) + outlen, &outlen))
 	    CRYPT_ERROR ("cipher final failed");
 	  work.len += outlen;
 
@@ -383,41 +383,6 @@ crypto_adjust_frame_parameters(struct frame *frame,
 			    kt->hmac_length);
 }
 
-static void
-init_cipher (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
-	     struct key *key, const struct key_type *kt, int enc,
-	     const char *prefix)
-{
-  struct gc_arena gc = gc_new ();
-
-  EVP_CIPHER_CTX_init (ctx);
-  if (!EVP_CipherInit_ov (ctx, cipher, NULL, NULL, enc))
-    msg (M_SSLERR, "EVP cipher init #1");
-#ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH
-  if (!EVP_CIPHER_CTX_set_key_length (ctx, kt->cipher_length))
-    msg (M_SSLERR, "EVP set key size");
-#endif
-  if (!EVP_CipherInit_ov (ctx, NULL, key->cipher, NULL, enc))
-    msg (M_SSLERR, "EVP cipher init #2");
-
-  msg (D_HANDSHAKE, "%s: Cipher '%s' initialized with %d bit key",
-       prefix,
-       OBJ_nid2sn (EVP_CIPHER_CTX_nid (ctx)),
-       EVP_CIPHER_CTX_key_length (ctx) * 8);
-
-  /* make sure we used a big enough key */
-  ASSERT (EVP_CIPHER_CTX_key_length (ctx) <= kt->cipher_length);
-
-  dmsg (D_SHOW_KEYS, "%s: CIPHER KEY: %s", prefix,
-       format_hex (key->cipher, kt->cipher_length, 0, &gc));
-  dmsg (D_CRYPTO_DEBUG, "%s: CIPHER block_size=%d iv_size=%d",
-       prefix,
-       EVP_CIPHER_CTX_block_size (ctx),
-       EVP_CIPHER_CTX_iv_length (ctx));
-
-  gc_free (&gc);
-}
-
 /*
  * Build a struct key_type.
  */
@@ -476,8 +441,9 @@ init_key_ctx (struct key_ctx *ctx, struct key *key,
   CLEAR (*ctx);
   if (kt->cipher && kt->cipher_length > 0)
     {
-      ALLOC_OBJ (ctx->cipher, EVP_CIPHER_CTX);
-      init_cipher (ctx->cipher, kt->cipher, key, kt, enc, prefix);
+      ALLOC_OBJ(ctx->cipher, cipher_ctx_t);
+      cipher_ctx_init (ctx->cipher, key->cipher, kt->cipher_length,
+	  kt->cipher, enc, prefix);
     }
   if (kt->digest && kt->hmac_length > 0)
     {
@@ -492,8 +458,8 @@ free_key_ctx (struct key_ctx *ctx)
 {
   if (ctx->cipher)
     {
-      EVP_CIPHER_CTX_cleanup (ctx->cipher);
-      free (ctx->cipher);
+      cipher_ctx_cleanup(ctx->cipher);
+      free(ctx->cipher);
       ctx->cipher = NULL;
     }
   if (ctx->hmac)
crypto.h +12 -14
index daa083f..1f9eca9 100644
@@ -182,6 +182,17 @@ struct key
                                 /**< %Key material for HMAC operations. */
 };
 
+
+/**
+ * Container for one set of OpenSSL cipher and/or HMAC contexts.
+ * @ingroup control_processor
+ */
+struct key_ctx
+{
+  cipher_ctx_t *cipher;      	/**< Generic cipher %context. */
+  hmac_ctx_t *hmac;               /**< Generic HMAC %context. */
+};
+
 #define KEY_DIRECTION_BIDIRECTIONAL 0 /* same keys for both directions */
 #define KEY_DIRECTION_NORMAL        1 /* encrypt with keys[0], decrypt with keys[1] */
 #define KEY_DIRECTION_INVERSE       2 /* encrypt with keys[1], decrypt with keys[0] */
@@ -224,16 +235,6 @@ struct key_direction_state
 };
 
 /**
- * Container for one set of OpenSSL cipher and/or HMAC contexts.
- * @ingroup control_processor
- */
-struct key_ctx
-{
-  EVP_CIPHER_CTX *cipher;       /**< OpenSSL cipher %context. */
-  HMAC_CTX *hmac;               /**< OpenSSL HMAC %context. */
-};
-
-/**
  * Container for two sets of OpenSSL cipher and/or HMAC contexts for both
  * sending and receiving directions.
  * @ingroup control_processor
@@ -313,9 +314,6 @@ void init_key_type (struct key_type *kt, const char *ciphername,
     bool ciphername_defined, const char *authname, bool authname_defined,
     int keysize, bool cfb_ofb_allowed, bool warn);
 
-/* enc parameter in init_key_ctx */
-#define DO_ENCRYPT 1
-#define DO_DECRYPT 0
 /*
  * Key context functions
  */
@@ -325,6 +323,7 @@ void init_key_ctx (struct key_ctx *ctx, struct key *key,
 		   const char *prefix);
 
 void free_key_ctx (struct key_ctx *ctx);
+
 void free_key_ctx_bi (struct key_ctx_bi *ctx);
 
 
@@ -401,7 +400,6 @@ bool openvpn_decrypt (struct buffer *buf, struct buffer work,
 
 /** @} name Functions for performing security operations on data channel packets */
 
-
 void crypto_adjust_frame_parameters(struct frame *frame,
 				    const struct key_type* kt,
 				    bool cipher_defined,
crypto_backend.h +100 -0

106 lines not on this page · raw message

crypto_openssl.c +89 -0

95 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#15 lore raw

PATCH 24/28 Added PRNG doxygen

In reply to Adriaan de Jong
---
 crypto.h |   29 +++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)
crypto.h +29 -0
index 1f9eca9..2888021 100644
@@ -407,10 +407,39 @@ void crypto_adjust_frame_parameters(struct frame *frame,
 				    bool packet_id,
 				    bool packet_id_long_form);
 
+
+/* Minimum length of the nonce used by the PRNG */
 #define NONCE_SECRET_LEN_MIN 16
+
+/* Maximum length of the nonce used by the PRNG */
 #define NONCE_SECRET_LEN_MAX 64
+
+/**
+ * Pseudo-random number generator initialisation.
+ * (see \c prng_rand_bytes())
+ *
+ * @param md_name			Name of the message digest to use
+ * @param nonce_secret_len_param	Length of the nonce to use
+ */
 void prng_init (const char *md_name, const int nonce_secret_len_parm);
+
+/*
+ * Message digest-based pseudo random number generator.
+ *
+ * If the PRNG was initialised with a certain message digest, uses the digest
+ * to calculate the next random number, and prevent depletion of the entropy
+ * pool.
+ *
+ * This PRNG is aimed at IV generation and similar miscellaneous tasks. Use
+ * \c rand_bytes() for higher-assurance functionality.
+ *
+ * Retrieves len bytes of pseudo random data, and places it in output.
+ *
+ * @param output	Output buffer
+ * @param len		Length of the output buffer
+ */
 void prng_bytes (uint8_t *output, int len);
+
 void prng_uninit ();
 
 void test_crypto (const struct crypto_options *co, struct frame* f);
Signature · 1 line
1.7.4.1
#16 lore raw

PATCH 25/28 Refactored: Moved crypto.h inline functions to end of file

In reply to Adriaan de Jong
---
 crypto.h |   21 +++++++++++----------
 1 files changed, 11 insertions(+), 10 deletions(-)
crypto.h +11 -10
index 2888021..dd99598 100644
@@ -480,16 +480,6 @@ void free_ssl_lib (void);
 #endif /* USE_SSL */
 
 /*
- * Inline functions
- */
-
-static inline bool
-key_ctx_bi_defined(const struct key_ctx_bi* key)
-{
-  return key->encrypt.cipher || key->encrypt.hmac || key->decrypt.cipher || key->decrypt.hmac;
-}
-
-/*
  * md5 functions
  */
 
@@ -509,5 +499,16 @@ void md5_digest_clear (struct md5_digest *digest);
 bool md5_digest_defined (const struct md5_digest *digest);
 bool md5_digest_equal (const struct md5_digest *d1, const struct md5_digest *d2);
 
+/*
+ * Inline functions
+ */
+
+static inline bool
+key_ctx_bi_defined(const struct key_ctx_bi* key)
+{
+  return key->encrypt.cipher || key->encrypt.hmac || key->decrypt.cipher || key->decrypt.hmac;
+}
+
+
 #endif /* USE_CRYPTO */
 #endif /* CRYPTO_H */
Signature · 1 line
1.7.4.1
#17 lore raw

PATCH 26/28 Removed stale OpenSSL defines from crypto.h

In reply to Adriaan de Jong
---
 crypto.h         |  119 ------------------------------------------------------
 crypto_openssl.c |    2 +
 ssl.c            |    3 +
 3 files changed, 5 insertions(+), 119 deletions(-)
crypto.h +0 -119
index dd99598..24ab9fa 100644
@@ -34,22 +34,6 @@
 
 #define ALLOW_NON_CBC_CIPHERS
 
-#include <openssl/objects.h>
-#include <openssl/rand.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/des.h>
-#include <openssl/md5.h>
-#if NTLM
-#include <openssl/md4.h>
-#endif
-#include <openssl/sha.h>
-#include <openssl/err.h>
-
-#if SSLEAY_VERSION_NUMBER >= 0x00907000L
-#include <openssl/des_old.h>
-#endif
-
 #include "crypto_backend.h"
 #include "basic.h"
 #include "buffer.h"
@@ -57,109 +41,6 @@
 #include "mtu.h"
 
 /*
- * Workarounds for incompatibilites between OpenSSL libraries.
- * Right now we accept OpenSSL libraries from 0.9.5 to 0.9.7.
- */
-
-#if SSLEAY_VERSION_NUMBER < 0x00907000L
-
-/* Workaround: EVP_CIPHER_mode is defined wrong in OpenSSL 0.9.6 but is fixed in 0.9.7 */
-#undef EVP_CIPHER_mode
-#define EVP_CIPHER_mode(e)                (((e)->flags) & EVP_CIPH_MODE)
-
-#define DES_cblock                        des_cblock
-#define DES_is_weak_key                   des_is_weak_key
-#define DES_check_key_parity              des_check_key_parity
-#define DES_set_odd_parity                des_set_odd_parity
-
-#define HMAC_CTX_init(ctx)                CLEAR (*ctx)
-#define HMAC_Init_ex(ctx,sec,len,md,impl) HMAC_Init(ctx, sec, len, md) 
-#define HMAC_CTX_cleanup(ctx)             HMAC_cleanup(ctx)
-#define EVP_MD_CTX_cleanup(md)            CLEAR (*md)
-
-#define INFO_CALLBACK_SSL_CONST
-
-#endif
-
-#ifndef INFO_CALLBACK_SSL_CONST
-#define INFO_CALLBACK_SSL_CONST const
-#endif
-
-#if SSLEAY_VERSION_NUMBER < 0x00906000
-
-#undef EVP_CIPHER_mode
-#define EVP_CIPHER_mode(x) 1
-#define EVP_CIPHER_CTX_mode(x) 1
-#define EVP_CIPHER_flags(x) 0
-
-#define EVP_CIPH_CBC_MODE 1
-#define EVP_CIPH_CFB_MODE 0
-#define EVP_CIPH_OFB_MODE 0
-#define EVP_CIPH_VARIABLE_LENGTH 0
-
-#define OPENSSL_malloc(x) malloc(x)
-#define OPENSSL_free(x) free(x)
-
-static inline int
-EVP_CipherInit_ov (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, uint8_t *key, uint8_t *iv, int enc)
-{
-  EVP_CipherInit (ctx, type, key, iv, enc);
-  return 1;
-}
-
-static inline int
-EVP_CipherUpdate_ov (EVP_CIPHER_CTX *ctx, uint8_t *out, int *outl, uint8_t *in, int inl)
-{
-  EVP_CipherUpdate (ctx, out, outl, in, inl);
-  return 1;
-}
-
-static inline bool
-cipher_ok (const char* name)
-{
-  const int i = strlen (name) - 4;
-  if (i >= 0)
-    return !strcmp (name + i, "-CBC");
-  else
-    return false;
-}
-
-#else
-
-static inline int
-EVP_CipherInit_ov (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, uint8_t *key, uint8_t *iv, int enc)
-{
-  return EVP_CipherInit (ctx, type, key, iv, enc);
-}
-
-static inline int
-EVP_CipherUpdate_ov (EVP_CIPHER_CTX *ctx, uint8_t *out, int *outl, uint8_t *in, int inl)
-{
-  return EVP_CipherUpdate (ctx, out, outl, in, inl);
-}
-
-static inline bool
-cipher_ok (const char* name)
-{
-  return true;
-}
-
-#endif
-
-#if SSLEAY_VERSION_NUMBER < 0x0090581f
-#undef DES_check_key_parity
-#define DES_check_key_parity(x) 1
-#endif
-
-#ifndef EVP_CIPHER_name
-#define EVP_CIPHER_name(e)		OBJ_nid2sn(EVP_CIPHER_nid(e))
-#endif
-
-#ifndef EVP_MD_name
-#define EVP_MD_name(e)			OBJ_nid2sn(EVP_MD_type(e))
-#endif
-
-/*
  * Defines a key type and key length for both cipher and HMAC.
  */
 struct key_type
crypto_openssl.c +2 -0
index 57f10ae..0981117 100644
@@ -139,6 +139,8 @@ cipher_ok (const char* name)
 
 #if SSLEAY_VERSION_NUMBER < 0x0090581f
 
+#undef DES_check_key_parity
+#define DES_check_key_parity(x) 1
 #endif /* SSLEAY_VERSION_NUMBER < 0x0090581f */
 
 #ifndef EVP_CIPHER_name
ssl.c +3 -0
index 4effb49..c20f1ae 100644
@@ -1639,6 +1639,9 @@ tls_deauthenticate (struct tls_multi *multi)
     }
 }
 
+#ifndef INFO_CALLBACK_SSL_CONST
+#define INFO_CALLBACK_SSL_CONST const
+#endif
 /*
  * Print debugging information on SSL/TLS session negotiation.
  */
Signature · 1 line
1.7.4.1
#18 lore raw

PATCH 27/28 Whitespace fixes in ntlm.c

In reply to Adriaan de Jong
---
 ntlm.c |  388 ++++++++++++++++++++++++++++++++++------------------------------
 1 files changed, 204 insertions(+), 184 deletions(-)
ntlm.c +204 -184
index 30d5d11..3bcf6e8 100644
@@ -37,7 +37,6 @@
 
 #include "memdbg.h"
 
-
 /* 64bit datatype macros */
 #ifdef _MSC_VER 
 	/* MS compilers */
@@ -49,9 +48,6 @@
 #	define UINT64(c) c ## LL
 #endif
 
-
-
-
 static void
 create_des_keys(const unsigned char *hash, unsigned char *key)
 {
@@ -78,63 +74,70 @@ gen_md4_hash (const char* data, int data_len, char *result)
 }
 
 static void
-gen_hmac_md5 (const char* data, int data_len, const char* key, int key_len,char *result)
+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;
-	CLEAR(hmac_ctx);
-
-	hmac_ctx_init(&hmac_ctx, key, key_len, md5_kt, NULL);
-	hmac_ctx_update(&hmac_ctx, (const unsigned char *)data, data_len);
-	hmac_ctx_final(&hmac_ctx, (unsigned char *)result);
-	hmac_ctx_cleanup(&hmac_ctx);
+  const md_kt_t *md5_kt = md_kt_get("MD5");
+  hmac_ctx_t hmac_ctx;
+  CLEAR(hmac_ctx);
+
+  hmac_ctx_init(&hmac_ctx, key, key_len, md5_kt, NULL);
+  hmac_ctx_update(&hmac_ctx, (const unsigned char *) data, data_len);
+  hmac_ctx_final(&hmac_ctx, (unsigned char *) result);
+  hmac_ctx_cleanup(&hmac_ctx);
 }
 
 static void
-gen_timestamp (unsigned char *timestamp)
-{ 
-	/* Copies 8 bytes long timestamp into "timestamp" buffer. 
-	 * Timestamp is Little-endian, 64-bit signed value representing the number of tenths of a microsecond since January 1, 1601.
-	 */
-
-	UINTEGER64 timestamp_ull;
-
-	timestamp_ull = openvpn_time(NULL);
-	timestamp_ull = (timestamp_ull + UINT64(11644473600)) * UINT64(10000000);
-
-	/* store little endian value */
-	timestamp[0]= timestamp_ull & UINT64(0xFF);
-	timestamp[1]= (timestamp_ull  >> 8)  & UINT64(0xFF);
-	timestamp[2]= (timestamp_ull  >> 16) & UINT64(0xFF);
-	timestamp[3]= (timestamp_ull  >> 24) & UINT64(0xFF);
-	timestamp[4]= (timestamp_ull  >> 32) & UINT64(0xFF);
-	timestamp[5]= (timestamp_ull  >> 40) & UINT64(0xFF);
-	timestamp[6]= (timestamp_ull  >> 48) & UINT64(0xFF);
-	timestamp[7]= (timestamp_ull  >> 56) & UINT64(0xFF);
+gen_timestamp(unsigned char *timestamp)
+{
+  /* Copies 8 bytes long timestamp into "timestamp" buffer.
+   * Timestamp is Little-endian, 64-bit signed value representing the number
+   * of tenths of a microsecond since January 1, 1601.
+   */
+
+  UINTEGER64 timestamp_ull;
+
+  timestamp_ull = openvpn_time(NULL);
+  timestamp_ull = (timestamp_ull + UINT64(11644473600)) * UINT64(10000000);
+
+  /* store little endian value */
+  timestamp[0] = timestamp_ull & UINT64(0xFF);
+  timestamp[1] = (timestamp_ull >> 8) & UINT64(0xFF);
+  timestamp[2] = (timestamp_ull >> 16) & UINT64(0xFF);
+  timestamp[3] = (timestamp_ull >> 24) & UINT64(0xFF);
+  timestamp[4] = (timestamp_ull >> 32) & UINT64(0xFF);
+  timestamp[5] = (timestamp_ull >> 40) & UINT64(0xFF);
+  timestamp[6] = (timestamp_ull >> 48) & UINT64(0xFF);
+  timestamp[7] = (timestamp_ull >> 56) & UINT64(0xFF);
 }
 
 static void
-gen_nonce (unsigned char *nonce)
-{ 
-	/* Generates 8 random bytes to be used as client nonce */
-	int i;
+gen_nonce(unsigned char *nonce)
+{
+  /* Generates 8 random bytes to be used as client nonce */
+  int i;
 
-	for(i=0;i<8;i++){
-		nonce[i] = (unsigned char)get_random();
-	}
+  for (i = 0; i < 8; i++)
+    {
+      nonce[i] = (unsigned char) get_random();
+    }
 }
 
-unsigned char *my_strupr(unsigned char *str)
-{ 
-	/* converts string to uppercase in place */
-	unsigned char *tmp = str;;
+unsigned char
+*my_strupr(unsigned char *str)
+{
+  /* converts string to uppercase in place */
+  unsigned char *tmp = str;
+  ;
 
-	do *str = toupper(*str); while (*(++str));
-	return tmp;
+  do
+    *str = toupper(*str);
+  while (*(++str));
+  return tmp;
 }
 
 static int
-unicodize (char *dst, const char *src)
+unicodize(char *dst, const char *src)
 {
   /* not really unicode... */
   int i = 0;
@@ -149,21 +152,22 @@ unicodize (char *dst, const char *src)
 }
 
 static void
-add_security_buffer(int sb_offset, void *data, int length, unsigned char *msg_buf, int *msg_bufpos)
+add_security_buffer(int sb_offset, void *data, int length,
+    unsigned char *msg_buf, int *msg_bufpos)
 {
-	/* Adds security buffer data to a message and sets security buffer's offset and length */
-	msg_buf[sb_offset] = (unsigned char)length;
-	msg_buf[sb_offset + 2] = msg_buf[sb_offset];
-	msg_buf[sb_offset + 4] = (unsigned char)(*msg_bufpos & 0xff);
-	msg_buf[sb_offset + 5] = (unsigned char)((*msg_bufpos >> 8) & 0xff);
-	memcpy(&msg_buf[*msg_bufpos], data, msg_buf[sb_offset]);
-	*msg_bufpos += length;
+  /* Adds security buffer data to a message and sets security buffer's offset and length */
+  msg_buf[sb_offset] = (unsigned char) length;
+  msg_buf[sb_offset + 2] = msg_buf[sb_offset];
+  msg_buf[sb_offset + 4] = (unsigned char) (*msg_bufpos & 0xff);
+  msg_buf[sb_offset + 5] = (unsigned char) ((*msg_bufpos >> 8) & 0xff);
+  memcpy(&msg_buf[*msg_bufpos], data, msg_buf[sb_offset]);
+  *msg_bufpos += length;
 }
 
 const char *
-ntlm_phase_1 (const struct http_proxy_info *p, struct gc_arena *gc)
+ntlm_phase_1(const struct http_proxy_info *p, struct gc_arena *gc)
 {
-  struct buffer out = alloc_buf_gc (96, gc);
+  struct buffer out = alloc_buf_gc(96, gc);
   /* try a minimal NTLM handshake
    *
    * http://davenport.sourceforge.net/ntlm.html
@@ -173,20 +177,21 @@ ntlm_phase_1 (const struct http_proxy_info *p, struct gc_arena *gc)
    * and the minimal set of flags (Negotiate NTLM and Negotiate OEM).
    *
    */
-  buf_printf (&out, "%s", "TlRMTVNTUAABAAAAAgIAAA==");
+  buf_printf(&out, "%s", "TlRMTVNTUAABAAAAAgIAAA==");
   return (BSTR (&out));
 }
 
 const char *
-ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, struct gc_arena *gc)
+ntlm_phase_3(const struct http_proxy_info *p, const char *phase_2,
+    struct gc_arena *gc)
 {
-	/* NTLM handshake
-	 *
-	 * http://davenport.sourceforge.net/ntlm.html
-	 *
-	 */
-	
-  char pwbuf[sizeof (p->up.password) * 2]; /* for unicode password */
+  /* NTLM handshake
+   *
+   * http://davenport.sourceforge.net/ntlm.html
+   *
+   */
+
+  char pwbuf[sizeof(p->up.password) * 2]; /* for unicode password */
   char buf2[128]; /* decoded reply from proxy */
   unsigned char phase3[464];
 
@@ -194,48 +199,51 @@ ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, struct gc_ar
   char challenge[8], ntlm_response[24];
   int i, ret_val;
 
-	char ntlmv2_response[144];
-	char userdomain_u[256]; /* for uppercase unicode username and domain */
-	char userdomain[128];   /* the same as previous but ascii */
-	char ntlmv2_hash[16];
-	char ntlmv2_hmacmd5[16];
-	char *ntlmv2_blob = ntlmv2_response + 16; /* inside ntlmv2_response, length: 128 */
-	int ntlmv2_blob_size=0;
-	int phase3_bufpos = 0x40; /* offset to next security buffer data to be added */
-	size_t len;
+  char ntlmv2_response[144];
+  char userdomain_u[256]; /* for uppercase unicode username and domain */
+  char userdomain[128]; /* the same as previous but ascii */
+  char ntlmv2_hash[16];
+  char ntlmv2_hmacmd5[16];
+  char *ntlmv2_blob = ntlmv2_response + 16; /* inside ntlmv2_response, length: 128 */
+  int ntlmv2_blob_size = 0;
+  int phase3_bufpos = 0x40; /* offset to next security buffer data to be added */
+  size_t len;
 
-	char domain[128];
-	char username[128];
-	char *separator;
+  char domain[128];
+  char username[128];
+  char *separator;
 
-	bool ntlmv2_enabled = (p->auth_method == HTTP_AUTH_NTLM2);
+  bool ntlmv2_enabled = (p->auth_method == HTTP_AUTH_NTLM2);
 
   CLEAR (buf2);
 
   ASSERT (strlen (p->up.username) > 0);
   ASSERT (strlen (p->up.password) > 0);
-	
-	/* username parsing */
-	separator = strchr(p->up.username, '\\');
-	if (separator == NULL) {
-		strncpy(username, p->up.username, sizeof(username)-1);
-		username[sizeof(username)-1]=0;
-		domain[0]=0;
-	} else {
-		strncpy(username, separator+1, sizeof(username)-1);
-		username[sizeof(username)-1]=0;
-		len = separator - p->up.username;
-		if (len > sizeof(domain) - 1) len = sizeof(domain) - 1;
-		strncpy(domain, p->up.username,  len);
-		domain[len]=0;
-	}
 
+  /* username parsing */
+  separator = strchr(p->up.username, '\\');
+  if (separator == NULL)
+    {
+      strncpy(username, p->up.username, sizeof(username) - 1);
+      username[sizeof(username) - 1] = 0;
+      domain[0] = 0;
+    }
+  else
+    {
+      strncpy(username, separator + 1, sizeof(username) - 1);
+      username[sizeof(username) - 1] = 0;
+      len = separator - p->up.username;
+      if (len > sizeof(domain) - 1)
+	len = sizeof(domain) - 1;
+      strncpy(domain, p->up.username, len);
+      domain[len] = 0;
+    }
 
   /* fill 1st 16 bytes with md4 hash, disregard terminating null */
-  gen_md4_hash (pwbuf, unicodize (pwbuf, p->up.password) - 2, md4_hash);
+  gen_md4_hash(pwbuf, unicodize(pwbuf, p->up.password) - 2, md4_hash);
 
   /* pad to 21 bytes */
-  memset (md4_hash + 16, 0, 5);
+  memset(md4_hash + 16, 0, 5);
 
   ret_val = base64_decode( phase_2, (void *)buf2, -1);
   if (ret_val < 0)
@@ -245,100 +253,112 @@ ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, struct gc_ar
    * therefore buf2 needs to be (3/4 * 128) */
 
   /* extract the challenge from bytes 24-31 */
-  for (i=0; i<8; i++)
-  {
-    challenge[i] = buf2[i+24];
-  }
-
-	if (ntlmv2_enabled){ /* Generate NTLMv2 response */
-	        int tib_len;
-
-		/* NTLMv2 hash */
-	        my_strupr((unsigned char *)strcpy(userdomain, username));
-		if (strlen(username) + strlen(domain) < sizeof(userdomain))
-			strcat(userdomain, domain);
-		else
-			msg (M_INFO, "Warning: Username or domain too long");
-		unicodize (userdomain_u, userdomain);
-		gen_hmac_md5(userdomain_u, 2 * strlen(userdomain), md4_hash, 16, ntlmv2_hash);
-
-		/* NTLMv2 Blob */
-		memset(ntlmv2_blob, 0, 128);                /* Clear blob buffer */ 
-		ntlmv2_blob[0x00]=1;                        /* Signature */
-		ntlmv2_blob[0x01]=1;                        /* Signature */
-		ntlmv2_blob[0x04]=0;                        /* Reserved */
-		gen_timestamp((unsigned char *)&ntlmv2_blob[0x08]);          /* 64-bit Timestamp */
-		gen_nonce((unsigned char *)&ntlmv2_blob[0x10]);              /* 64-bit Client Nonce */
-		ntlmv2_blob[0x18]=0;                        /* Unknown, zero should work */
-
-		/* Add target information block to the blob */
-		if (( *((long *)&buf2[0x14]) & 0x00800000) == 0x00800000){ /* Check for Target Information block */
-			tib_len = buf2[0x28];/* Get Target Information block size */
-			if (tib_len > 96) tib_len = 96;
-			{
-			  char *tib_ptr = buf2 + buf2[0x2c]; /* Get Target Information block pointer */
-			  memcpy(&ntlmv2_blob[0x1c], tib_ptr, tib_len); /* Copy Target Information block into the blob */
-			}
-		} else {
-			tib_len = 0;
-		}
-
-		ntlmv2_blob[0x1c + tib_len] = 0;            /* Unknown, zero works */ 
-
-		/* Get blob length */
-		ntlmv2_blob_size = 0x20 + tib_len; 
-
-		/* Add challenge from message 2 */
-		memcpy(&ntlmv2_response[8], challenge, 8);
-
-		/* hmac-md5 */
-		gen_hmac_md5(&ntlmv2_response[8], ntlmv2_blob_size + 8, ntlmv2_hash, 16, ntlmv2_hmacmd5);
-		
-		/* Add hmac-md5 result to the blob */
-		memcpy(ntlmv2_response, ntlmv2_hmacmd5, 16); /* Note: This overwrites challenge previously written at ntlmv2_response[8..15] */
-	
-	} else { /* Generate NTLM response */
-		unsigned char key1[8], key2[8], key3[8];
-
-		create_des_keys ((unsigned char *)md4_hash, key1);
-		cipher_des_encrypt_ecb (key1, challenge, ntlm_response);
-
-		create_des_keys ((unsigned char *)&(md4_hash[7]), key2);
-		cipher_des_encrypt_ecb (key2, challenge, &ntlm_response[8]);
-
-		create_des_keys ((unsigned char *)&(md4_hash[14]), key3);
-		cipher_des_encrypt_ecb (key3, challenge, &ntlm_response[16]);
+  for (i = 0; i < 8; i++)
+    {
+      challenge[i] = buf2[i + 24];
+    }
+
+  if (ntlmv2_enabled)
+    { /* Generate NTLMv2 response */
+      int tib_len;
+
+      /* NTLMv2 hash */
+      my_strupr((unsigned char *) strcpy(userdomain, username));
+      if (strlen(username) + strlen(domain) < sizeof(userdomain))
+	strcat(userdomain, domain);
+      else
+	msg (M_INFO, "Warning: Username or domain too long");
+      unicodize(userdomain_u, userdomain);
+      gen_hmac_md5(userdomain_u, 2 * strlen(userdomain), md4_hash, 16,
+	  ntlmv2_hash);
+
+      /* NTLMv2 Blob */
+      memset(ntlmv2_blob, 0, 128); /* Clear blob buffer */
+      ntlmv2_blob[0x00] = 1; /* Signature */
+      ntlmv2_blob[0x01] = 1; /* Signature */
+      ntlmv2_blob[0x04] = 0; /* Reserved */
+      gen_timestamp((unsigned char *) &ntlmv2_blob[0x08]); /* 64-bit Timestamp */
+      gen_nonce((unsigned char *) &ntlmv2_blob[0x10]); /* 64-bit Client Nonce */
+      ntlmv2_blob[0x18] = 0; /* Unknown, zero should work */
+
+      /* Add target information block to the blob */
+      if ((*((long *) &buf2[0x14]) & 0x00800000) == 0x00800000)
+	{ /* Check for Target Information block */
+	  tib_len = buf2[0x28];/* Get Target Information block size */
+	  if (tib_len > 96)
+	    tib_len = 96;
+	    {
+	      char *tib_ptr = buf2 + buf2[0x2c]; /* Get Target Information block pointer */
+	      memcpy(&ntlmv2_blob[0x1c], tib_ptr, tib_len); /* Copy Target Information block into the blob */
+	    }
+	}
+      else
+	{
+	  tib_len = 0;
 	}
-	
-	
-	memset (phase3, 0, sizeof (phase3)); /* clear reply */
 
-	strcpy ((char *)phase3, "NTLMSSP\0"); /* signature */
-	phase3[8] = 3; /* type 3 */
+      ntlmv2_blob[0x1c + tib_len] = 0; /* Unknown, zero works */
 
-	if (ntlmv2_enabled){ /* NTLMv2 response */
-		add_security_buffer(0x14, ntlmv2_response, ntlmv2_blob_size + 16, phase3, &phase3_bufpos);
-	}else{ /* NTLM response */
-		add_security_buffer(0x14, ntlm_response, 24, phase3, &phase3_bufpos);
-	}
-	
-	/* username in ascii */
-	add_security_buffer(0x24, username, strlen (username), phase3, &phase3_bufpos);
-
-	/* Set domain. If <domain> is empty, default domain will be used (i.e. proxy's domain) */ 
-	add_security_buffer(0x1c, domain, strlen (domain), phase3, &phase3_bufpos);
-	
-
-	/* other security buffers will be empty */
-	phase3[0x10] = phase3_bufpos; /* lm not used */
-	phase3[0x30] = phase3_bufpos; /* no workstation name supplied */
-	phase3[0x38] = phase3_bufpos; /* no session key */
-	
-	/* flags */
+      /* Get blob length */
+      ntlmv2_blob_size = 0x20 + tib_len;
+
+      /* Add challenge from message 2 */
+      memcpy(&ntlmv2_response[8], challenge, 8);
+
+      /* hmac-md5 */
+      gen_hmac_md5(&ntlmv2_response[8], ntlmv2_blob_size + 8, ntlmv2_hash, 16,
+	  ntlmv2_hmacmd5);
+
+      /* Add hmac-md5 result to the blob */
+      memcpy(ntlmv2_response, ntlmv2_hmacmd5, 16); /* Note: This overwrites challenge previously written at ntlmv2_response[8..15] */
+
+    }
+  else
+    { /* Generate NTLM response */
+      unsigned char key1[8], key2[8], key3[8];
+
+      create_des_keys((unsigned char *) md4_hash, key1);
+      cipher_des_encrypt_ecb(key1, challenge, ntlm_response);
+
+      create_des_keys((unsigned char *) &(md4_hash[7]), key2);
+      cipher_des_encrypt_ecb(key2, challenge, &ntlm_response[8]);
+
+      create_des_keys((unsigned char *) &(md4_hash[14]), key3);
+      cipher_des_encrypt_ecb(key3, challenge, &ntlm_response[16]);
+    }
+
+  memset(phase3, 0, sizeof(phase3)); /* clear reply */
+
+  strcpy((char *) phase3, "NTLMSSP\0"); /* signature */
+  phase3[8] = 3; /* type 3 */
+
+  if (ntlmv2_enabled)
+    { /* NTLMv2 response */
+      add_security_buffer(0x14, ntlmv2_response, ntlmv2_blob_size + 16, phase3,
+	  &phase3_bufpos);
+    }
+  else
+    { /* NTLM response */
+      add_security_buffer(0x14, ntlm_response, 24, phase3, &phase3_bufpos);
+    }
+
+  /* username in ascii */
+  add_security_buffer(0x24, username, strlen(username), phase3, &phase3_bufpos);
+
+  /* Set domain. If <domain> is empty, default domain will be used (i.e. proxy's domain) */
+  add_security_buffer(0x1c, domain, strlen(domain), phase3, &phase3_bufpos);
+
+  /* other security buffers will be empty */
+  phase3[0x10] = phase3_bufpos; /* lm not used */
+  phase3[0x30] = phase3_bufpos; /* no workstation name supplied */
+  phase3[0x38] = phase3_bufpos; /* no session key */
+
+  /* flags */
   phase3[0x3c] = 0x02; /* negotiate oem */
   phase3[0x3d] = 0x02; /* negotiate ntlm */
 
-  return ((const char *)make_base64_string2 ((unsigned char *)phase3, phase3_bufpos, gc));
+  return ((const char *) make_base64_string2((unsigned char *) phase3,
+      phase3_bufpos, gc));
 }
 
 #else
Signature · 1 line
1.7.4.1
#19 lore raw

PATCH 28/28 Added a check for Openssl or PolarSSL defines

In reply to Adriaan de Jong
---
 options.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
options.h +3 -0
index 8a51502..39ca68a 100644
@@ -77,6 +77,9 @@ struct options_pre_pull
 };
 
 #endif
+#if !defined(USE_OPENSSL) && !defined(USE_POLARSSL)
+# error "At least on of OpenSSL or PolarSSL needs to be defined."
+#endif
 
 struct connection_entry
 {
Signature · 1 line
1.7.4.1
#20 lore raw
In reply to Adriaan de Jong

As a quick bootnote: the numbering of these patches starts at 10, continuing from the previous doxygen patches...

Adriaan

Quoted 37 lines

-----Original Message-----
From: Adriaan de Jong [mailto:[email protected]...]
Sent: vrijdag 24 juni 2011 11:55
To: [email protected]
Subject: [Openvpn-devel] [PATCH 0/28] Refactor OpenSSL crypto functions

Hi everyone,

This is the second series of patches for the master branch.

This patch separates the OpenSSL crypto functions (those in crypto.c) into a separate OpenSSL backend. The API for this backend is defined in crypto_backend.h.

Note that I also migrated all functions within OpenVPN that use crypto primitives, for compatibility with other SSL backends. The exception here is the functions in ssl.c, since they will be migrated in the next series of patches.

Enjoy!

Regards,
Adriaan de Jong

-----------------------------------------------------------------------
-------
All the data continuously generated in your IT infrastructure contains a
definitive record of customers, application performance, security threats, fraudulent activity and more. Splunk takes this data and makes sense of it. Business sense. IT sense. Common sense..
http://p.sf.net/sfu/splunk-d2d-c1
_______________________________________________
Openvpn-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel