Refactor OpenSSL crypto functions
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
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
@@ -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
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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
@@ -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 usebool 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
@@ -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
@@ -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
@@ -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
@@ -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
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
@@ -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
@@ -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_typeconst EVP_MD *digest; }; -/** * Container for unidirectional cipher and HMAC %key material. * @ingroup control_processor
crypto_backend.h +34 -0
@@ -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
@@ -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
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
@@ -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
@@ -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
@@ -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
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
@@ -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
@@ -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
@@ -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
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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
@@ -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
@@ -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
@@ -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
@@ -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
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
@@ -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
@@ -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
@@ -196,8 +196,6 @@ ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, struct gc_archar 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_armemcpy (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
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
@@ -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
@@ -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 flagint 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
@@ -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
@@ -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
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
@@ -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
@@ -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
@@ -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
@@ -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
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
@@ -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
@@ -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
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
@@ -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 usebool 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
@@ -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
@@ -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
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
@@ -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
@@ -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
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
@@ -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
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
@@ -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
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
@@ -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
@@ -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
@@ -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
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
@@ -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_archar 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
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
@@ -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
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 functionsHi 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 incrypto_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