From: "Jim Carroll" Date: Fri, 24 Nov 2017 12:09:13 -0500 Message-ID: <040701d36546$f3cc1270$db643750$@carroll.com> Content-Language: en-us MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=SHA1; boundary="----=_NextPart_000_03FF_01D3651D.09DA6140" Subject: [Openvpn-devel] [PATCH] Added OpenSSL FIPS 2.0 support to OpenVPN List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: openvpn-devel@lists.sourceforge.net This is a multipart message in MIME format. ------=_NextPart_000_03FF_01D3651D.09DA6140 Content-Type: multipart/alternative; boundary="----=_NextPart_001_0400_01D3651D.09DA6140" ------=_NextPart_001_0400_01D3651D.09DA6140 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Modified the autoconf, automake and code to support building OpenVPN with OpenSSL FIPS Object Module v2.0 validated encryption. * Adds: --enable-fips-mode switch to configure.ac * Adds: --enable-fips-mode command line switch to openvpn --- INSTALL | 72 ++++++++++++++++++++++++++++++++++++++++++++ Makefile.am | 5 +++ configure.ac | 42 ++++++++++++++++++++++++++ src/openvpn/crypto.c | 2 +- src/openvpn/crypto_backend.h | 3 +- src/openvpn/crypto_openssl.c | 15 ++++++++- src/openvpn/crypto_openssl.h | 8 +++++ src/openvpn/ntlm.c | 2 +- src/openvpn/openvpn.c | 7 +++++ src/openvpn/options.c | 16 ++++++++++ src/openvpn/options.h | 1 + src/openvpn/ssl.c | 12 ++++++-- src/openvpn/ssl.h | 4 +++ 13 files changed, 183 insertions(+), 6 deletions(-) diff --git a/INSTALL b/INSTALL index 3a31e6f..adb3df8 100644 --- a/INSTALL +++ b/INSTALL @@ -305,6 +305,78 @@ 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. + +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 optionally 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're recently installed OpenSSL + + # ./configure --enable-fips-mode \ + OPENSSL_CFLAGS=-/usr/local/ss/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 7f2e34f..83ac18d 100644 --- a/configure.ac +++ b/configure.ac @@ -293,6 +293,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}" @@ -954,6 +965,35 @@ if test "${enable_crypto}" = "yes" -a "${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 ]], + [[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}" @@ -1373,6 +1413,7 @@ AM_CONDITIONAL([ENABLE_PLUGIN_AUTH_PAM], [test "${enable_plugin_auth_pam}" = "ye AM_CONDITIONAL([ENABLE_PLUGIN_DOWN_ROOT], [test "${enable_plugin_down_root}" = "yes"]) AM_CONDITIONAL([ENABLE_CRYPTO], [test "${enable_crypto}" = "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]) @@ -1441,4 +1482,5 @@ AC_CONFIG_FILES([ sample/Makefile ]) AC_CONFIG_FILES([tests/t_client.sh], [chmod +x tests/t_client.sh]) + AC_OUTPUT diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c index 3f3caa1..0c05859 100644 --- a/src/openvpn/crypto.c +++ b/src/openvpn/crypto.c @@ -854,7 +854,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..d92ab7c 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 0134e55..caef17b 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -159,6 +159,17 @@ 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, "*** IN FIPS MODE ***\n"); + return 0; +} + void crypto_uninit_lib(void) { @@ -926,11 +937,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..11f3378 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..beb1d2a 100644 --- a/src/openvpn/openvpn.c +++ b/src/openvpn/openvpn.c @@ -210,6 +210,13 @@ 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 8e5cdf7..8a1501c 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -522,6 +522,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" @@ -854,6 +859,9 @@ init_options(struct options *o, const bool init_gc) #endif #ifdef ENABLE_CRYPTO 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 @@ -1561,6 +1569,7 @@ show_settings(const struct options *o) #endif #ifdef ENABLE_CRYPTO + SHOW_INT(fips_mode); SHOW_BOOL(show_ciphers); SHOW_BOOL(show_digests); SHOW_BOOL(show_engines); @@ -7442,6 +7451,13 @@ add_option(struct options *options, } #endif /* USE_COMP */ #ifdef ENABLE_CRYPTO +#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 035c6d1..55d2248 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -189,6 +189,7 @@ struct options int persist_mode; #ifdef ENABLE_CRYPTO + int fips_mode; const char *key_pass_file; bool show_ciphers; bool show_digests; diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 843bc39..6a212b8 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -354,6 +354,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) { @@ -1640,8 +1648,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 0e0f68f..ae23423 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -600,6 +600,10 @@ 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 /* ENABLE_CRYPTO */ #endif /* ifndef OPENVPN_SSL_H */ -- 2.1.4 ------=_NextPart_001_0400_01D3651D.09DA6140 Content-Type: text/html; charset="US-ASCII" Content-Transfer-Encoding: quoted-printable

Modified the = autoconf, automake and code to support building OpenVPN with

=

OpenSSL FIPS Object Module v2.0 validated encryptio= n.

 

        * Adds: --enable-fips= -mode switch to configure.ac

 &n= bsp;      * Adds: --enable-fips-mode command line = switch to openvpn

---

<= p class=3DMsoPlainText> INSTALL       &n= bsp;            = ;  | 72 ++++++++++++++++++++++++++++++++++++++++++++

Makefile.am       =            |  5 +++<= o:p>

configure.ac    =              | = 42 ++++++++++++++++++++++++++

src/op= envpn/crypto.c         |  2 +-=

src/openvpn/crypto_backend.h | = ; 3 +-

src/openvpn/crypto_openssl.c = | 15 ++++++++-

src/openvpn/crypto_op= enssl.h |  8 +++++

src/openvpn/= ntlm.c           |  = 2 +-

src/openvpn/openvpn.c &nbs= p;      |  7 +++++

src/openvpn/options.c       = ; | 16 ++++++++++

src/openvpn/option= s.h        |  1 +

src/openvpn/ssl.c      =       | 12 ++++++--

src/openvpn/ssl.h        &= nbsp;   |  4 +++

13 f= iles changed, 183 insertions(+), 6 deletions(-)

 

diff --git a/INSTAL= L b/INSTALL

index 3a31e6f..adb3df8 10= 0644

--- a/INSTALL

+++ b/INSTALL

@@ = -305,6 +305,78 @@ TUN/TAP Driver Configuration:

 ******************= *******************************************************

+OpenSSL FIPS Ob= ject 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 Va= lidated encryption, you must follow the instructions in the

<= p class=3DMsoPlainText>+FIPS 2.0 User's Guide precisely. You are not permit= ted to modify any of the FIPS

+build = artifacts, makefiles or scripts. The FIPS 2.0 module is only compatible wit= h

+OpenSSL 1.0.1 and 1.0.2.

+

+Thes= e instructions describe the use of OpenSSL 1.0.2m.

+

+INSTALLATION:=

+

+=     1. Surf to h= ttps://www.openssl.org/source/

+&= nbsp;   2. Download source AND validate the download was correct = (preferably using PGP)

+  &= nbsp; 3. Untar and uncompress tarball

+    4. You must build using this precise command (do NOT c= hoose any other options):

+

+       &nb= sp;    # ./config && make install

+

+  &n= bsp;         (you may optionally pa= ss 'no-asm' to config)

+

+       If the abov= e 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 e= ncryption environment. See chapter 3 of the FIPS 2.0

+       User's Guide for the = complete list of supported platforms:

+

+     &nb= sp;      https://openssl.org/docs/fips/UserGuide-2.0.pdf=

+

+=     5. Download, build & install openssl 1.0.2m (you are= permitted to

+   &nbs= p;   modify this step to suite your preferences):

<= p class=3DMsoPlainText>+

+  = ;          # git clone https://github.com/openssl/open= ssl.git

+    =         # (cd openssl && \<= /o:p>

+       = ;             g= it checkout OpenSSL_1_0_2m && \

+            = ;        ./config fips && \=

+      &nbs= p;             = make depend && \

+  = ;            &n= bsp;     make install)

+

+    6. Now bu= ild openvpn and tell it where to find you’re recently installed OpenS= SL

+

+            #= ./configure --enable-fips-mode \

+&n= bsp;            = ;       OPENSSL_CFLAGS=3D-/usr/local/ss/inclu= de \

+     &= nbsp;           &nbs= p;  OPENSSL_LIBS=3D"-ldl -L/usr/local/ssl/lib -lssl -lcrypto"= ;

+

+            # = make install

+

+    7. You can confirm FIPS mode is availab= le with the command

+

<= p class=3DMsoPlainText>+        &nb= sp;   # ./openvpn --version | grep 'library version'

+        =     library versions: OpenSSL 1.0.2m-fips  2 Nov 2017, = LZO 2.08

+

+USAGE:

+

<= p class=3DMsoPlainText>+The above adds a new '--enable-fips-mode' command l= ine option to OpenVPN. Add this to your

+invocation statement. If you've successfully configured OpenVPN for FIP= S mode, check your

+OpenVPN logs for = the statement:

+

+    *** FIPS MODE ENABLE ***

+

+

+*******************************************= ******************************

+=

CAVEATS & BUGS:

 * I have no= ticed 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 @@ rootdi= r=3D$(prefix)

root_DATA =3D version.= sh

endif

+if FIPSMODE<= /p>

+export CC

+export FIPSLD_CC

+endif<= /p>

+

config-= version.h:

    @CONFI= GURE_GIT_CHFILES=3D"`GIT_DIR=3D\"$(top_srcdir)/.git\" $(GIT)= diff-files --name-status -r --ignore-submodules --quiet -- || echo \"= +\"`"; \

   = ; CONFIGURE_GIT_UNCOMMITTED=3D"`GIT_DIR=3D\"$(top_srcdir)/.git\&q= uot; $(GIT) diff-index --cached  --quiet --ignore-submodules HEAD || e= cho \"*\"`"; \

diff --= git a/configure.ac b/configure.ac

ind= ex 7f2e34f..83ac18d 100644

--- a/conf= igure.ac

+++ b/configure.ac

@@ -293,6 +293,17 @@ AC_ARG_WITH(

    [with_crypto_library=3D"= openssl"]

)

+AC_ARG_ENABLE(<= o:p>

+    [fips-mode],=

+    [AS_HELP_STRING([--en= able-fips-mode], [OpenSSL FIPS Object Module 2.0 @<:@default=3Dno@:>@= ])],

+    [=

+        if = test "${with_crypto_library}" !=3D "openssl"; then=

+      &nbs= p;     AC_MSG_ERROR([enable_fips_mode requires --with_c= rypto_library=3Dopenssl])

+ &nbs= p;      fi

+=     ],

+  &n= bsp; [enable_fips_mode=3D"no"]

+)

+

AC_ARG_VAR([PLUGINDIR], [Path of plug-in directory @<:@defaul= t=3DLIBDIR/openvpn/plugins@:>@])

= if test -n "${PLUGINDIR}"; then

    plugindir=3D"${PLUGINDIR}"

@@ -954,6 +965,35 @@ if test "${enable_crypto= }" =3D "yes" -a "${with_crypto_library}" =3D "= ;openssl"; then

  &nb= sp;      ]

=     )

=

+    if test "${enable_fips_mod= e}" =3D "yes"; then

+&= nbsp;       AC_CHECK_FUNCS(

+         = ;   [ \

+   =              FI= PS_mode \

+    &n= bsp;           FIPS_mode_= set \

+     =            SSLeay_version=

+      = ;      ],

+&= nbsp;           [],<= /o:p>

+       = ;     [AC_MSG_ERROR([Incorrect version of OpenSSL, requ= ire 1.0.2])]

+    = ;        )

+        AC_RUN_IFELSE(

+       &= nbsp;    [AC_LANG_PROGRAM(

+           &nb= sp;    [[#include <openssl/crypto.h>]],

=

+        &n= bsp;       [[printf("%s\n", SSLeay_= version(SSLEAY_DIR));]])

+  = ;          ],

+        &nbs= p;   [AC_SUBST(OPENSSLDIR,

= +            &n= bsp;   [[`./conftest$EXEEXT | $SED -n 's/.*"\(.*\)".*/\= 1/p'`]])

+    &nb= sp;       ]

+        )

+        if ! test -x &q= uot;${OPENSSLDIR}/fips-2.0/bin/fipsld"; then

+          &= nbsp; AC_MSG_ERROR([Incomplete OpenSSL FIPS installation; missing fipsld])<= o:p>

+      =   fi

+    &n= bsp;   AC_SUBST([FIPSLD_CC], ["${CC}"])

<= p class=3DMsoPlainText>+        AC_SUBST= ([CC], ["${OPENSSLDIR}/fips-2.0/bin/fipsld"])

+        export CC

+      &n= bsp; export FIPSLD_CC

+  &n= bsp;     AC_DEFINE([ENABLE_FIPS], [1], [Enable OpenSSL = FIPS 2.0 Options])

+   = ; fi

+

    CFLAGS=3D"${saved_CFLAGS}"=

    LIBS=3D"${saved_LIBS}&= quot;

@@ -1373,6 +1413,7 @@ AM_CONDITIONAL([ENABLE_PLUGIN_AUTH_PAM], [te= st "${enable_plugin_auth_pam}" =3D "ye

AM_CONDITIONAL([ENABLE_PLUGIN_DOWN_ROOT], [test "${e= nable_plugin_down_root}" =3D "yes"])

AM_CONDITIONAL([ENABLE_CRYPTO], [test "${enable_crypt= o}" =3D "yes"])

AM_CO= NDITIONAL([HAVE_LD_WRAP_SUPPORT], [test "${have_ld_wrap_support}"= =3D "yes"])

+AM_CONDITIONA= L([FIPSMODE], [test "${enable_fips_mode}" =3D "yes"])

 sampledir=3D"\$(docdir)/sample"

AC_SUBST([plugindir])

@= @ -1441,4 +1482,5 @@ AC_CONFIG_FILES([

    sample/Makefile

])

AC_CONFIG_FILES([tests/t_client= .sh], [chmod +x tests/t_client.sh])

+=

AC_OUTPUT

diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c<= /o:p>

index 3f3caa1..0c05859 100644

--- a/src/openvpn/crypto.c

+++ b/src/openvpn/crypto.c

@@ -854,7 +854,7 @@ init_key_ctx(struct key_ctx *ctx, const struct ke= y *key,

     if (= kt->digest && kt->hmac_length > 0)

     {

         ctx->hmac =3D hma= c_ctx_new();

-    = ;    hmac_ctx_init(ctx->hmac, key->hmac, kt->hmac_l= ength, kt->digest);

+  &= nbsp;     hmac_ctx_init(ctx->hmac, key->hmac, kt-= >hmac_length, kt->digest, false);

     &n= bsp;   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

inde= x 567fd9b..d92ab7c 100644

--- a/src/o= penvpn/crypto_backend.h

+++ b/src/ope= nvpn/crypto_backend.h

@@ -604,10 +604= ,11 @@ void hmac_ctx_free(hmac_ctx_t *ctx);

  * @param key        &= nbsp;  The key to use for the HMAC

  * @param key_len       The key leng= th to use

  * @param kt &nb= sp;          Static message di= gest parameters

+ * @param prf_use&nb= sp;      Intended use for PRF in TLS protocol=

  *

  */

void hmac_ctx_init(h= mac_ctx_t *ctx, const uint8_t *key, int key_length,

-          &nb= sp;        const md_kt_t *kt);=

+      &nbs= p;            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 0134e55..caef17b 100644<= /o:p>

--- a/src/openvpn/crypto_openssl.c

+++ b/src/openvpn/crypto_openssl.c

@@ -159,6 +159,17 @@ crypto_init_lib(void)

#endif

}

+int

+crypto_enable_fips_= mode(int mode)

+{

+    if (!FIPS_mode_set(mode)) {

+       &n= bsp; ERR_print_errors_fp(stderr);

+&n= bsp;        return 1;

+         }

+    msg(M_INFO, "**= * IN FIPS MODE ***\n");

+ &= nbsp;  return 0;

+}

+

void

crypto_uninit_lib(void)

<= p class=3DMsoPlainText> {

@@ -926,11 = +937,13 @@ hmac_ctx_free(HMAC_CTX *ctx)

 void

hmac_ctx_init(HMAC_CTX *ctx, const uint8_t *key, int key_= len,

-     &= nbsp;        const EVP_MD *kt)

+       &nb= sp;      const EVP_MD *kt, bool prf_use)

{

 = ;    ASSERT(NULL !=3D kt && NULL !=3D ctx);

 = ;    HMAC_CTX_reset(ctx);

+    if (kt =3D=3D EVP_md5() && prf_use)

+      &n= bsp;  HMAC_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);

     HMAC_Init_ex(ctx, k= ey, key_len, kt, NULL);

<= /p>

     /* make sure we us= ed a big enough key */

diff --git a/s= rc/openvpn/crypto_openssl.h b/src/openvpn/crypto_openssl.h

index 60a2812..11f3378 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);

  &nb= sp;  } while (false)

 

+= /**

+ * Enable FIPS Mode. Returns non= -zero to indicate an error.

+ *<= /o:p>

+ * @param mode    &nb= sp;    Should be 1. Future versions of OpenSSL FIPS

+ *        = ;             &= nbsp;  code are expected to accept extended modes.

=

+ */

+int cry= pto_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<= /p>

+++ b/src/openvpn/ntlm.c

@@ -88,7 +88,7 @@ gen_hmac_md5(const uint8_t *data, int dat= a_len, const uint8_t *key, int key_len,

     const md_kt_t *md5_kt =3D md_kt_get("MD5&q= uot;);

     hmac_= ctx_t *hmac_ctx =3D hmac_ctx_new();

=

-    hmac_ctx_init(hm= ac_ctx, key, key_len, md5_kt);

+ = ;   hmac_ctx_init(hmac_ctx, key, key_len, md5_kt, false);

     hmac_ctx_update(hma= c_ctx, data, data_len);

  &= nbsp;  hmac_ctx_final(hmac_ctx, result);

     hmac_ctx_cleanup(hmac_ctx);

diff --git a/src/openvpn/openvpn.c b/src/openvpn/o= penvpn.c

index e237ee5..beb1d2a 10064= 4

--- a/src/openvpn/openvpn.c

+++ b/src/openvpn/openvpn.c

@@ -210,6 +210,13 @@ openvpn_main(int argc, char *arg= v[])

     &n= bsp;       /* parse command line options, and= read configuration file */

 &nb= sp;           parse_argv(= &c.options, argc, argv, M_USAGE, OPT_P_DEFAULT, NULL, c.es);=

+#if EN= ABLE_FIPS

+    &n= bsp;        if (c.options.fips_mode) {

+      &= nbsp;           if (enabl= e_fips_mode(c.options.fips_mode)) {

+=             &nb= sp;          break;=

+       &nbs= p;            &= nbsp;  }

+   &nbs= p;            &= nbsp; }

+#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<= o:p>

index 8e5cdf7..8a1501c 100644

--- a/src/openvpn/options.c

+++ b/src/openvpn/options.c

@@ -522,6 +522,11 @@ static const char usage_message[] =3D

     "\n"<= o:p>

     "Data C= hannel Encryption Options (must be compatible between peers):\n"<= /o:p>

     "(These opti= ons are meaningful for both Static Key & TLS-mode)\n"

+#ifdef ENABLE_FIPS

+    "--enable-fips-mode : Enable OpenSSL FIPS= Object Module v2.0.\n"

+ &= nbsp;  "         &nb= sp;        Setting this on the server wi= ll enforce FIPS validated\n"

+&n= bsp;   "        &nbs= p;         encryption on both clien= t and server.\n"

+#endif

     "--secret f [d= ]  : Enable Static Key encryption mode (non-TLS).\n"

     "   =             &nb= sp;  Use shared secret file f, generate with --genkey.\n"

     "  &= nbsp;           &nbs= p;   The optional d parameter controls key directionality.\n"= ;

@@ -854,6 +859,9 @@ init_options(st= ruct options *o, const bool init_gc)

= #endif

#ifdef ENABLE_CRYPTO

     o->ciphername = =3D "BF-CBC";

+#ifdef ENABL= E_FIPS

+    o->fips= _mode =3D 0;

+#endif

#ifdef HAVE_AEAD_CIPHER_MODES /* IV_NCP=3D2 requires= GCM support */

   &nb= sp; o->ncp_enabled =3D true;

#els= e

@@ -1561,6 +1569,7 @@ show_settings= (const struct options *o)

#endif

=  #ifdef ENABLE_CRYPTO

+ &nb= sp;  SHOW_INT(fips_mode);

 =     SHOW_BOOL(show_ciphers);

     SHOW_BOOL(show_digests);

     SHOW_BOOL(show_engines);<= /o:p>

@@ -7442,6 +7451,13 @@ add_option(struct o= ptions *options,

   &n= bsp; }

#endif /* USE_COMP */

#ifdef ENABLE_CRYPTO

+#ifdef ENABLE_FIPS

+=     else if (streq(p[0], "enable-fips-mode") &= & !p[1])

+    {

+      &n= bsp; VERIFY_PERMISSION(OPT_P_GENERAL);

+         options->fips_mode = =3D 1;

+    }

+#endif

     else if (streq(p[0], "show-ciphers") &a= mp;& !p[1])

   &nb= sp; {

     &= nbsp;   VERIFY_PERMISSION(OPT_P_GENERAL);

diff --git a/src/openvpn/options.h b/src/openvpn/options.h<= o:p>

index 035c6d1..55d2248 100644

--- a/src/openvpn/options.h

+++ b/src/openvpn/options.h

@@ -189,6 +189,7 @@ struct options

     int persist_mode;

 #ifdef ENABL= E_CRYPTO

+    int fips= _mode;

     const= char *key_pass_file;

  &nb= sp;  bool show_ciphers;

 &n= bsp;   bool show_digests;

d= iff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c

index 843bc39..6a212b8 100644

--- a/src/openvpn/ssl.c

+++ b/s= rc/openvpn/ssl.c

@@ -354,6 +354,14 @@= init_ssl_lib(void)

   = ;  crypto_init_lib();

}

+#if= ENABLE_FIPS

+int

+enable_fips_mode(int mode)

+{

+    retu= rn crypto_enable_fips_mode(mode);

+}<= o:p>

+#endif

+

void

free_ssl_lib(void)

{

@@ -1640,8 +1648,8 @@ tls1_P_hash= (const md_kt_t *md_kt,

  &n= bsp;  chunk =3D md_kt_size(md_kt);

     A1_len =3D md_kt_size(md_kt);

-  &= nbsp; hmac_ctx_init(ctx, sec, sec_len, md_kt);

-    hmac_ctx_init(ctx_tmp, sec, sec_len, md_kt);<= o:p>

+    hmac_ctx_init(ctx= , sec, sec_len, md_kt, true);

+ =    hmac_ctx_init(ctx_tmp, sec, sec_len, md_kt, true);<= /p>

 &n= bsp;   hmac_ctx_update(ctx,seed,seed_len);

     hmac_ctx_final(ctx, A1);=

diff --git a/src/openvpn/ssl.h b/src/open= vpn/ssl.h

index 0e0f68f..ae23423 1006= 44

--- a/src/openvpn/ssl.h=

+++ b/src/openvpn/ssl.h

@@ -600,6 +600,10 @@ bool is_hard_reset(int op, int key_met= hod);

 void delayed_auth_pass_purge(void);

+#if ENABLE_FIPS

+int enable_fips_mode(int mode);

+#endif

+

#endif /* ENABLE_CRYPTO */=

&= nbsp;#endif /* ifndef OPENVPN_SSL_H */

--

2.1.4

 

 

= ------=_NextPart_001_0400_01D3651D.09DA6140-- ------=_NextPart_000_03FF_01D3651D.09DA6140 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" 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 HQ4EFgQUkmFrguGioKpP7GfxwqP3tIAAwewwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYB Af8CAQAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMBEGA1UdIAQKMAgwBgYEVR0gADBE BgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vQWRkVHJ1c3RFeHRlcm5h bENBUm9vdC5jcmwwNQYIKwYBBQUHAQEEKTAnMCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2Vy dHJ1c3QuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAbKm6sVcE6q4jF2O3NVfOqa2ErwAkQI5kPxWZq b7H1tLV3Xg8CYQDffQX+ErOkgIAA/PsdW2pyAgpBvAW6wVjVJsLq1U2E+/6CmM9YG+MiY5xS+LsF Nqt9WKXeqztj5drVc+/s4Pt74qP/8EIjnMq2jU0+5EsYA7KoLdTYu0JLkGmFENumNzToe+ABEKWc yjrHn0+ING6KZdAairup3MrKNtH0/MJkKTWv1rGncRHSA0Oxjz6a7J4yU/R2ksqGNAe5LMrmHErY mQ3BhuKQkvtaQmojIRDpZcf11bt+6oyFIAJi6tE6ByxZxZkz8jiJ5bbpFnofeRT2ShAaJvp8ivub MIIFIDCCBAigAwIBAgIRAILNSHab46DG1Bne+wGXvqwwDQYJKoZIhvcNAQELBQAwgZsxCzAJBgNV BAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAY BgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMUEwPwYDVQQDEzhDT01PRE8gU0hBLTI1NiBDbGllbnQg QXV0aGVudGljYXRpb24gYW5kIFNlY3VyZSBFbWFpbCBDQTAeFw0xNzAxMTgwMDAwMDBaFw0yMDAx MTgyMzU5NTlaMCAxHjAcBgkqhkiG9w0BCQEWD2ppbUBjYXJyb2xsLmNvbTCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBALebl59lytkEMwbYCpX4f+APmWZ2zYPs/ol2IqDudAEz9bJ6Juzu jlrxxsK28J4K7Ta1DrGy0C9XA+IZP9ccJk9xjE9+jxiJ3WGnod9BzJCDi4DgRxJ6yurFAesB+U0U FKXzoUDsZ3KU0EVcK1yF80/VWuHanck5o2NZOdHiul1CHF05L79s56diejh9ukV4xIPiWnJELOUV SYUvi1UiuwGm+/nRMF+CEOM/ACJoxBr/p3AaOdQCqTY+yGBBKoDE2eCo8hK7sAdomKGbnSsHcYK+ 0Fi5LXzOTk7ewdnUvKDbLjUeM9xYHt4ShZgnEDsjHV93sUE56fd26LoCi/TTbG0CAwEAAaOCAdcw ggHTMB8GA1UdIwQYMBaAFJJha4LhoqCqT+xn8cKj97SAAMHsMB0GA1UdDgQWBBSzewP0b4CAvRYt sIWY2rg6IXcRSTAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEF BQcDBAYIKwYBBQUHAwIwRgYDVR0gBD8wPTA7BgwrBgEEAbIxAQIBAwUwKzApBggrBgEFBQcCARYd aHR0cHM6Ly9zZWN1cmUuY29tb2RvLm5ldC9DUFMwXQYDVR0fBFYwVDBSoFCgToZMaHR0cDovL2Ny bC5jb21vZG9jYS5jb20vQ09NT0RPU0hBMjU2Q2xpZW50QXV0aGVudGljYXRpb25hbmRTZWN1cmVF bWFpbENBLmNybDCBkAYIKwYBBQUHAQEEgYMwgYAwWAYIKwYBBQUHMAKGTGh0dHA6Ly9jcnQuY29t b2RvY2EuY29tL0NPTU9ET1NIQTI1NkNsaWVudEF1dGhlbnRpY2F0aW9uYW5kU2VjdXJlRW1haWxD QS5jcnQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9kb2NhLmNvbTAaBgNVHREEEzARgQ9q aW1AY2Fycm9sbC5jb20wDQYJKoZIhvcNAQELBQADggEBAH3TTAUCNH5TyxLPeawmzjgSYVTR5AR2 oCdfKgC9u6XLR4Gb0tkJPdrzcTi6uR4cKFmhmV00Yg8ZG5J3XGtSYOMnmPVM2HBClcNCIL6x1Gcz m5eVSJcYIoQkWOyicVCVsDlooN7Ypi9a3X3QJZc2o2ehTvmM49cNI4zVBRac25ePxNL86hbA84a8 PKDVZaEqkJYzO06SQaxIBj16Ll7hBN2WL5ZLZ/DSj4AnUjXskMKek/0fqf4OX+GtIK6ldLV4E/JX +aUNVnqjv7n5jKXPUnIEIQcnIiPYmvcdMF8t8N2KKL7rrtcFosghyWZMdo1A5/n1TwilB7qb3502 6ZX+fdwxggQjMIIEHwIBATCBsTCBmzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFu Y2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxQTA/ BgNVBAMTOENPTU9ETyBTSEEtMjU2IENsaWVudCBBdXRoZW50aWNhdGlvbiBhbmQgU2VjdXJlIEVt YWlsIENBAhEAgs1IdpvjoMbUGd77AZe+rDAJBgUrDgMCGgUAoIICRjAYBgkqhkiG9w0BCQMxCwYJ KoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNzExMjQxNzA5MTFaMCMGCSqGSIb3DQEJBDEWBBSz RR6hUGs0AetrnFKOTPs61vCy4TBbBgkqhkiG9w0BCQ8xTjBMMAoGCCqGSIb3DQMHMA4GCCqGSIb3 DQMCAgIAgDANBggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDAHBgUrDgMCGjCB wgYJKwYBBAGCNxAEMYG0MIGxMIGbMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5j aGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDFBMD8G A1UEAxM4Q09NT0RPIFNIQS0yNTYgQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBTZWN1cmUgRW1h aWwgQ0ECEQCCzUh2m+OgxtQZ3vsBl76sMIHEBgsqhkiG9w0BCRACCzGBtKCBsTCBmzELMAkGA1UE BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxQTA/BgNVBAMTOENPTU9ETyBTSEEtMjU2IENsaWVudCBB dXRoZW50aWNhdGlvbiBhbmQgU2VjdXJlIEVtYWlsIENBAhEAgs1IdpvjoMbUGd77AZe+rDANBgkq hkiG9w0BAQEFAASCAQBQ0DlRdGEgQoZx9zyEudPTSnuvsp/65tWnS90wosKGTJMDTmbJlesec+Zd G42nda8LNNqwluA29jI5o/pVD5N63qv/Zgo54ZEjJvr3W4kg2jup74Tym/HGps48yVWXukl2+m6q mdTsv2QrTdoSxKHCqkyKkj1PvLUiLLY5RW6aitUvyJ/BXrHJJef5crNJOvRD2qqpdGI85xblRLH6 LbolO2gbmLMI17Nu+0x9iIzr49LVk2eRmkwekH+0BYl5RlH8AkMSemyqXOsQhx6lGiJF/wb1ALpw hN58UxUzBx+ang+zVRVpGLm5IVpsbb9hR6b8ZTqkmU0vXs5OqQMfVpKUAAAAAAAA ------=_NextPart_000_03FF_01D3651D.09DA6140--