From: Jim Carroll <j...@carroll.com>

Signed-off-by: Jim Carroll <j...@carroll.com>
---
 INSTALL                      | 78 ++++++++++++++++++++++++++++++++++++++++++++
 Makefile.am                  |  5 +++
 configure.ac                 | 41 +++++++++++++++++++++++
 src/openvpn/crypto.c         |  2 +-
 src/openvpn/crypto_backend.h |  3 +-
 src/openvpn/crypto_openssl.c | 16 ++++++++-
 src/openvpn/crypto_openssl.h |  8 +++++
 src/openvpn/ntlm.c           |  2 +-
 src/openvpn/openvpn.c        |  9 +++++
 src/openvpn/options.c        | 18 ++++++++++
 src/openvpn/options.h        |  3 ++
 src/openvpn/ssl.c            | 12 +++++--
 src/openvpn/ssl.h            |  4 +++
 13 files changed, 195 insertions(+), 6 deletions(-)

diff --git a/INSTALL b/INSTALL
index 3a31e6f..b001cb1 100644
--- a/INSTALL
+++ b/INSTALL
@@ -305,6 +305,84 @@ TUN/TAP Driver Configuration:
 
 *************************************************************************
 
+OpenSSL FIPS Object Module v2.0 Configuration:
+
+These instructions were adapted from
+
+    https://www.openssl.org/docs/fipsnotes.html
+
+Requirements:
+
+    * OpenSSL 1.0.2m
+    * openssl-fips-2.0.2
+
+WARNING
+
+To install FIPS Validated encryption, you must follow the instructions in the
+FIPS 2.0 User's Guide precisely. You are not permitted to modify any of the 
FIPS
+build artifacts, makefiles or scripts. The FIPS 2.0 module is only compatible 
with
+OpenSSL 1.0.1 and 1.0.2.
+
+These instructions describe the use of OpenSSL 1.0.2m.
+
+PRE-INSTALLATION CHECKUP:
+
+    The INSTALLATION procecure describes how to install an OpenSSL library that
+    is built with FIPS support. If your platform already provides a FIPS
+    enabled library you can skip to step 6 (build OpenVPN).
+
+INSTALLATION:
+
+    1. Surf to https://www.openssl.org/source/
+    2. Download source AND validate the download was correct (preferably using 
PGP)
+    3. Untar and uncompress tarball
+    4. You must build using this precise command (do NOT choose any other 
options):
+
+            # ./config && make install
+
+            (you may optionslly pass 'no-asm' to config)
+
+       If the above procedure does not build on your system -- STOP. You are 
not
+       building on a FIPS supported platform, and therefore will not have a
+       FIPS validated encryption environment. See chapter 3 of the FIPS 2.0
+       User's Guide for the complete list of supported platforms:
+
+            https://openssl.org/docs/fips/UserGuide-2.0.pdf
+
+    5. Download, build & install openssl 1.0.2m (you are permitted to
+       modify this step to suite your preferences):
+
+            # git clone https://github.com/openssl/openssl.git
+            # (cd openssl && \
+                    git checkout OpenSSL_1_0_2m && \
+                    ./config fips && \
+                    make depend && \
+                    make install)
+
+    6. Now build openvpn and tell it where to find you recently installed 
OpenSSL
+
+            # ./configure --enable-fips-mode \
+                    OPENSSL_CFLAGS=-I/usr/local/ssl/include \
+                    OPENSSL_LIBS="-ldl -L/usr/local/ssl/lib -lssl -lcrypto"
+
+            # make install
+
+    7. You can confirm FIPS mode is available with the command
+
+            # ./openvpn --version | grep 'library version'
+            library versions: OpenSSL 1.0.2m-fips  2 Nov 2017, LZO 2.08
+
+USAGE:
+
+The above adds a new '--enable-fips-mode' command line option to OpenVPN. Add 
this to your
+invocation statement. If you've successfully configured OpenVPN for FIPS mode, 
check your
+OpenVPN logs for the statement:
+
+    *** FIPS MODE ENABLE ***
+
+
+*************************************************************************
+
 CAVEATS & BUGS:
 
 * I have noticed cases where TCP sessions tunneled over the Linux
diff --git a/Makefile.am b/Makefile.am
index 773b786..6d571ec 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -83,6 +83,11 @@ rootdir=$(prefix)
 root_DATA = version.sh
 endif
 
+if FIPSMODE
+export CC
+export FIPSLD_CC
+endif
+
 config-version.h:
        @CONFIGURE_GIT_CHFILES="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) 
diff-files --name-status -r --ignore-submodules --quiet -- || echo \"+\"`"; \
        CONFIGURE_GIT_UNCOMMITTED="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) 
diff-index --cached  --quiet --ignore-submodules HEAD || echo \"*\"`"; \
diff --git a/configure.ac b/configure.ac
index b4fd1b3..dc74230 100644
--- a/configure.ac
+++ b/configure.ac
@@ -286,6 +286,17 @@ AC_ARG_WITH(
        [with_crypto_library="openssl"]
 )
 
+AC_ARG_ENABLE(
+    [fips-mode],
+    [AS_HELP_STRING([--enable-fips-mode], [OpenSSL FIPS Object Module 2.0 
@<:@default=no@:>@])],
+    [
+        if test "${with_crypto_library}" != "openssl"; then
+            AC_MSG_ERROR([enable_fips_mode requires 
--with_crypto_library=openssl])
+        fi
+    ],
+    [enable_fips_mode="no"]
+)
+
 AC_ARG_VAR([PLUGINDIR], [Path of plug-in directory 
@<:@default=LIBDIR/openvpn/plugins@:>@])
 if test -n "${PLUGINDIR}"; then
        plugindir="${PLUGINDIR}"
@@ -948,6 +959,35 @@ if test "${with_crypto_library}" = "openssl"; then
                ]
        )
 
+    if test "${enable_fips_mode}" = "yes"; then
+        AC_CHECK_FUNCS(
+            [ \
+                FIPS_mode \
+                FIPS_mode_set \
+                SSLeay_version
+            ],
+            [],
+            [AC_MSG_ERROR([Incorrect version of OpenSSL, require 1.0.2])]
+            )
+        AC_RUN_IFELSE(
+            [AC_LANG_PROGRAM(
+                [[#include <openssl/crypto.h>]],
+                [[printf("%s\n", SSLeay_version(SSLEAY_DIR));]])
+            ],
+            [AC_SUBST(OPENSSLDIR,
+                [[`./conftest$EXEEXT | $SED -n 's/.*"\(.*\)".*/\1/p'`]])
+            ]
+        )
+        if ! test -x "${OPENSSLDIR}/fips-2.0/bin/fipsld"; then
+            AC_MSG_ERROR([Incomplete OpenSSL FIPS installation; missing 
fipsld])
+        fi
+        AC_SUBST([FIPSLD_CC], ["${CC}"])
+        AC_SUBST([CC], ["${OPENSSLDIR}/fips-2.0/bin/fipsld"])
+        export CC
+        export FIPSLD_CC
+        AC_DEFINE([ENABLE_FIPS], [1], [Enable OpenSSL FIPS 2.0 Options])
+    fi
+
        CFLAGS="${saved_CFLAGS}"
        LIBS="${saved_LIBS}"
 
@@ -1359,6 +1399,7 @@ AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = 
"yes"])
 AM_CONDITIONAL([ENABLE_PLUGIN_AUTH_PAM], [test "${enable_plugin_auth_pam}" = 
"yes"])
 AM_CONDITIONAL([ENABLE_PLUGIN_DOWN_ROOT], [test "${enable_plugin_down_root}" = 
"yes"])
 AM_CONDITIONAL([HAVE_LD_WRAP_SUPPORT], [test "${have_ld_wrap_support}" = 
"yes"])
+AM_CONDITIONAL([FIPSMODE], [test "${enable_fips_mode}" = "yes"])
 
 sampledir="\$(docdir)/sample"
 AC_SUBST([plugindir])
diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
index 3096f3b..97d117b 100644
--- a/src/openvpn/crypto.c
+++ b/src/openvpn/crypto.c
@@ -852,7 +852,7 @@ init_key_ctx(struct key_ctx *ctx, const struct key *key,
     if (kt->digest && kt->hmac_length > 0)
     {
         ctx->hmac = hmac_ctx_new();
-        hmac_ctx_init(ctx->hmac, key->hmac, kt->hmac_length, kt->digest);
+        hmac_ctx_init(ctx->hmac, key->hmac, kt->hmac_length, kt->digest, 
false);
 
         msg(D_HANDSHAKE,
             "%s: Using %d bit message hash '%s' for HMAC authentication",
diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h
index 567fd9b..8790ca5 100644
--- a/src/openvpn/crypto_backend.h
+++ b/src/openvpn/crypto_backend.h
@@ -604,10 +604,11 @@ void hmac_ctx_free(hmac_ctx_t *ctx);
  * @param key           The key to use for the HMAC
  * @param key_len       The key length to use
  * @param kt            Static message digest parameters
+ * @param prf_use       Intended use for PRF in TLS protocol
  *
  */
 void hmac_ctx_init(hmac_ctx_t *ctx, const uint8_t *key, int key_length,
-                   const md_kt_t *kt);
+                   const md_kt_t *kt, bool prf_use);
 
 /*
  * Free the given HMAC context.
diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index 20a519e..fe4cef3 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -159,6 +159,18 @@ crypto_init_lib(void)
 #endif
 }
 
+int
+crypto_enable_fips_mode(int mode)
+{
+    if (!FIPS_mode_set(mode))
+    {
+        ERR_print_errors_fp(stderr);
+        return 1;
+    }
+    msg(M_INFO, "*** FIPS MODE ENABLED ***");
+    return 0;
+}
+
 void
 crypto_uninit_lib(void)
 {
@@ -926,11 +938,13 @@ hmac_ctx_free(HMAC_CTX *ctx)
 
 void
 hmac_ctx_init(HMAC_CTX *ctx, const uint8_t *key, int key_len,
-              const EVP_MD *kt)
+              const EVP_MD *kt, bool prf_use)
 {
     ASSERT(NULL != kt && NULL != ctx);
 
     HMAC_CTX_reset(ctx);
+    if (kt == EVP_md5() && prf_use)
+        HMAC_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
     HMAC_Init_ex(ctx, key, key_len, kt, NULL);
 
     /* make sure we used a big enough key */
diff --git a/src/openvpn/crypto_openssl.h b/src/openvpn/crypto_openssl.h
index 60a2812..fbc8b2a 100644
--- a/src/openvpn/crypto_openssl.h
+++ b/src/openvpn/crypto_openssl.h
@@ -102,4 +102,12 @@ void crypto_print_openssl_errors(const unsigned int flags);
     } while (false)
 
 
+/**
+ * Enable FIPS Mode. Returns non-zero to indicate an error.
+ *
+ * @param mode         Should be 1. Future versions of OpenSSL FIPS
+ *                     code are expected to accept extended modes.
+ */
+int crypto_enable_fips_mode(int mode);
+
 #endif /* CRYPTO_OPENSSL_H_ */
diff --git a/src/openvpn/ntlm.c b/src/openvpn/ntlm.c
index 077fa3e..fe39ab1 100644
--- a/src/openvpn/ntlm.c
+++ b/src/openvpn/ntlm.c
@@ -88,7 +88,7 @@ gen_hmac_md5(const uint8_t *data, int data_len, const uint8_t 
*key, int key_len,
     const md_kt_t *md5_kt = md_kt_get("MD5");
     hmac_ctx_t *hmac_ctx = hmac_ctx_new();
 
-    hmac_ctx_init(hmac_ctx, key, key_len, md5_kt);
+    hmac_ctx_init(hmac_ctx, key, key_len, md5_kt, false);
     hmac_ctx_update(hmac_ctx, data, data_len);
     hmac_ctx_final(hmac_ctx, result);
     hmac_ctx_cleanup(hmac_ctx);
diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c
index e237ee5..da8e852 100644
--- a/src/openvpn/openvpn.c
+++ b/src/openvpn/openvpn.c
@@ -210,6 +210,15 @@ openvpn_main(int argc, char *argv[])
             /* parse command line options, and read configuration file */
             parse_argv(&c.options, argc, argv, M_USAGE, OPT_P_DEFAULT, NULL, 
c.es);
 
+#if ENABLE_FIPS
+            if (c.options.fips_mode)
+            {
+                if (enable_fips_mode(c.options.fips_mode))
+                {
+                    break;
+                }
+            }
+#endif
 #ifdef ENABLE_PLUGIN
             /* plugins may contribute options configuration */
             init_verb_mute(&c, IVM_LEVEL_1);
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 7be5f38..99d3ccc 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -517,6 +517,11 @@ static const char usage_message[] =
     "\n"
     "Data Channel Encryption Options (must be compatible between peers):\n"
     "(These options are meaningful for both Static Key & TLS-mode)\n"
+#ifdef ENABLE_FIPS
+       "--enable-fips-mode : Enable OpenSSL FIPS Object Module v2.0.\n"
+       "                  Setting this on the server will enforce FIPS 
validated\n"
+       "                  encryption on both client and server.\n"
+#endif
     "--secret f [d]  : Enable Static Key encryption mode (non-TLS).\n"
     "                  Use shared secret file f, generate with --genkey.\n"
     "                  The optional d parameter controls key directionality.\n"
@@ -847,6 +852,9 @@ init_options(struct options *o, const bool init_gc)
     o->scheduled_exit_interval = 5;
 #endif
     o->ciphername = "BF-CBC";
+#ifdef ENABLE_FIPS
+       o->fips_mode = 0;
+#endif
 #ifdef HAVE_AEAD_CIPHER_MODES /* IV_NCP=2 requires GCM support */
     o->ncp_enabled = true;
 #else
@@ -1550,6 +1558,9 @@ show_settings(const struct options *o)
     SHOW_INT(persist_mode);
 #endif
 
+#ifdef ENABLE_FIPS
+    SHOW_INT(fips_mode);
+#endif
     SHOW_BOOL(show_ciphers);
     SHOW_BOOL(show_digests);
     SHOW_BOOL(show_engines);
@@ -7389,6 +7400,13 @@ add_option(struct options *options,
         }
     }
 #endif /* USE_COMP */
+#ifdef ENABLE_FIPS
+    else if (streq(p[0], "enable-fips-mode") && !p[1])
+    {
+        VERIFY_PERMISSION(OPT_P_GENERAL);
+        options->fips_mode = 1;
+    }
+#endif
     else if (streq(p[0], "show-ciphers") && !p[1])
     {
         VERIFY_PERMISSION(OPT_P_GENERAL);
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index f70760c..6ffe646 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -186,6 +186,9 @@ struct options
     bool persist_config;
     int persist_mode;
 
+#ifdef ENABLE_FIPS
+       int fips_mode;
+#endif
     const char *key_pass_file;
     bool show_ciphers;
     bool show_digests;
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index 7b42845..3992f4d 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -352,6 +352,14 @@ init_ssl_lib(void)
     crypto_init_lib();
 }
 
+#if ENABLE_FIPS
+int
+enable_fips_mode(int mode)
+{
+       return crypto_enable_fips_mode(mode);
+}
+#endif
+
 void
 free_ssl_lib(void)
 {
@@ -1638,8 +1646,8 @@ tls1_P_hash(const md_kt_t *md_kt,
     chunk = md_kt_size(md_kt);
     A1_len = md_kt_size(md_kt);
 
-    hmac_ctx_init(ctx, sec, sec_len, md_kt);
-    hmac_ctx_init(ctx_tmp, sec, sec_len, md_kt);
+    hmac_ctx_init(ctx, sec, sec_len, md_kt, true);
+    hmac_ctx_init(ctx_tmp, sec, sec_len, md_kt, true);
 
     hmac_ctx_update(ctx,seed,seed_len);
     hmac_ctx_final(ctx, A1);
diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h
index dd1ab0f..f251765 100644
--- a/src/openvpn/ssl.h
+++ b/src/openvpn/ssl.h
@@ -598,4 +598,8 @@ bool is_hard_reset(int op, int key_method);
 
 void delayed_auth_pass_purge(void);
 
+#if ENABLE_FIPS
+int enable_fips_mode(int mode);
+#endif
+
 #endif /* ifndef OPENVPN_SSL_H */
-- 
2.1.4


>From 85a23fd158f36c444e59ff41c35d0750917898b1 Mon Sep 17 00:00:00 2001
From: Jim Carroll <j...@carroll.com>
Date: Mon, 4 Dec 2017 16:12:42 -0500
Subject: [PATCH 2/2] fixed typo

Signed-off-by: Jim Carroll <j...@carroll.com>
---
 INSTALL | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/INSTALL b/INSTALL
index b001cb1..0bb25b4 100644
--- a/INSTALL
+++ b/INSTALL
@@ -327,7 +327,7 @@ These instructions describe the use of OpenSSL 1.0.2m.
 
 PRE-INSTALLATION CHECKUP:
 
-    The INSTALLATION procecure describes how to install an OpenSSL library that
+    The INSTALLATION procedure describes how to install an OpenSSL library that
     is built with FIPS support. If your platform already provides a FIPS
     enabled library you can skip to step 6 (build OpenVPN).
 
-- 
2.1.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to