FIPS 140-2 OpenSSL(2007) patches

Oren Nechushtan oren at forescout.com
Tue Apr 22 02:08:03 EST 2008


Hi,
I am happy to (re)send a set of patches for compiling OpenSSH 4.7p1 with
FIPS 140-2 OpenSSL.
These are based on previously reported patches by Steve Marquess
<marquess at ieee.org> and Ben Laurie <ben at algroup.co.uk>,
 for ver. OpenSSH 3.8.
 
Note that these patches are NOT OFFICIAL, and MAY be used freely by
anyone.
 
Issues [partially] handled:
 SSL FIPS Self test.
 RC4, arcfour, et. al. are not 140-2 compliant (need to use 3DES built
in RNG instead)
 MD5 digest is not 140-2 compliant (need to use SHA instead).
 Make OpenSSH FIPS aware (limit the ciphers according to the FIPS mode.)
 fork() & FIPS RNG.
 openssl-fips-1.1.1 workaround.
 
Suggestions and Todos:
 Retest everything.
 Make OpenSSH FIPS 140-2 compliant (or even certified:)
 Add configuration for use of SHA1 instead/in addition to/ MD5.
 Configure blowfish as default in non FIPS mode.
 Disabled RSA1 in FIPS mode.
 Add central [FIPS] configuration (currently each binary has its own
configuration.)
 Improve fork() logic.
 Invite me for a drink.
 
Best,
Oren Nechushtan



P.S.

The patches are split into two due to mailing list size limitations:

 

[openssh.spec]
 
> %define openssldir /usr/local/ssl
> %define openssllib %{openssldir}/lib
> %define opensslinclude %{openssldir}/include

> export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):%{openssllib}
> export CC=gcc
> export LD=fipsld
>

> #     --with-md5-passwords
198d221
<       --with-md5-passwords \
209a233,240
>       --with-ssl-dir=%{openssldir} \
>       --with-fips \
>         --with-cppflags="%{fsgccopts}" \
>         --with-cflags="%{fsgccopts} -g" \
>         --with-ldflags="%{fsgccopts} -L%{openssllib} -Wl,-rpath
%{openssllib}" \
>
> export CC=fipsld
> export FIPSLD_CC=gcc
216c247
< make
---
> make CC=$CC FIPSLD_CC=$FIPSLD_CC
220c251,257
< %configure --libexecdir=%{_libexecdir}/openssh
---
> %configure --libexecdir=%{_libexecdir}/openssh \
>       --with-ssl-dir=%{openssldir} \
>       --with-fips \
>         --with-cppflags="%{fsgccopts}" \
>         --with-cflags="%{fsgccopts}" \
>         --with-ldflags="%{fsgccopts} -L%{openssllib} -Wl,-rpath
%{openssllib}" \

------------------------------------------------------------------------
--------------------
 
--- openssh-4.7p1/buildpkg.sh.in 25 Jul 2007
+++ openssh-4.7p1/buildpkg.sh.in 25 Jul 2007
@@ -128,3 +128,3 @@
 ## Fill in some details, like prefix and sysconfdir
-for confvar in prefix exec_prefix bindir sbindir libexecdir datadir
mandir sysconfdir piddir srcdir
+for confvar in prefix exec_prefix bindir sbindir libexecdir datadir
mandir sysconfdir piddir srcdir ssldir
 do
diff -u -r1.1 -r1.3
--- openssh-4.7p1/ChangeLog 19 May 2004 13:05:16 -0000 1.1
+++ openssh-4.7p1/ChangeLog 28 May 2004 13:30:29 -0000 1.3
@@ -1,3 +1,7 @@
+20071224 #orig 20040419
+ - Oren Nechushtan <oren at forescout.com>; Added patches for FIPS 140-2;
based on 
+ - Ben Laurie <ben at algroup.co.uk>, Steve Marquess <marquess at ieee.org>;
Add
+    support for OPENSSL FIPS mode
 20070817
  - (dtucker) [sshd.8] Many Linux variants use a single "!" to denote
locked
    accounts and that's what the code looks for, so make man page and
code
 
--- openssh-4.7p1/cipher.c Mon Dec 17 18:46:43 2007
+++ openssh-4.7p1/cipher.c Mon Dec 24 04:15:12 2007
@@ -47,6 +47,7 @@
 #include "xmalloc.h"
 #include "log.h"
 #include "cipher.h"
+#include "fips.h"
 
 /* compatibility with old or broken OpenSSL versions */
 #include "openbsd-compat/openssl-compat.h"
@@ -64,30 +65,31 @@
  u_int key_len;
  u_int discard_len;
  const EVP_CIPHER *(*evptype)(void);
+ u_int   fips_allowed;
 } ciphers[] = {
- { "none",  SSH_CIPHER_NONE, 8, 0, 0, EVP_enc_null },
- { "des",  SSH_CIPHER_DES, 8, 8, 0, EVP_des_cbc },
- { "3des",  SSH_CIPHER_3DES, 8, 16, 0, evp_ssh1_3des },
- { "blowfish",  SSH_CIPHER_BLOWFISH, 8, 32, 0, evp_ssh1_bf },
-
- { "3des-cbc",  SSH_CIPHER_SSH2, 8, 24, 0, EVP_des_ede3_cbc },
- { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, EVP_bf_cbc },
- { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, EVP_cast5_cbc },
- { "arcfour",  SSH_CIPHER_SSH2, 8, 16, 0, EVP_rc4 },
- { "arcfour128",  SSH_CIPHER_SSH2, 8, 16, 1536, EVP_rc4 },
- { "arcfour256",  SSH_CIPHER_SSH2, 8, 32, 1536, EVP_rc4 },
- { "aes128-cbc",  SSH_CIPHER_SSH2, 16, 16, 0, EVP_aes_128_cbc },
- { "aes192-cbc",  SSH_CIPHER_SSH2, 16, 24, 0, EVP_aes_192_cbc },
- { "aes256-cbc",  SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
+ { "none",  SSH_CIPHER_NONE, 8, 0, 0, EVP_enc_null, 0 },
+ { "des",  SSH_CIPHER_DES, 8, 8, 0, EVP_des_cbc, 0 },
+ { "3des",  SSH_CIPHER_3DES, 8, 16, 0, evp_ssh1_3des, 0 },
+ { "blowfish",  SSH_CIPHER_BLOWFISH, 8, 32, 0, evp_ssh1_bf, 0 },
+
+ { "3des-cbc",  SSH_CIPHER_SSH2, 8, 24, 0, EVP_des_ede3_cbc, 1 },
+ { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, EVP_bf_cbc, 0 },
+ { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, EVP_cast5_cbc, 0 },
+ { "arcfour",  SSH_CIPHER_SSH2, 8, 16, 0, EVP_rc4, 0 },
+ { "arcfour128",  SSH_CIPHER_SSH2, 8, 16, 1536, EVP_rc4, 0 },
+ { "arcfour256",  SSH_CIPHER_SSH2, 8, 32, 1536, EVP_rc4, 0 },
+ { "aes128-cbc",  SSH_CIPHER_SSH2, 16, 16, 0, EVP_aes_128_cbc, 1 },
+ { "aes192-cbc",  SSH_CIPHER_SSH2, 16, 24, 0, EVP_aes_192_cbc, 1 },
+ { "aes256-cbc",  SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc, 1 },
  { "rijndael-cbc at lysator.liu.se",
-    SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
- { "aes128-ctr",  SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_128_ctr },
- { "aes192-ctr",  SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_128_ctr },
- { "aes256-ctr",  SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_128_ctr },
+    SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc, 0 },
+ { "aes128-ctr",  SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_128_ctr, 1 },
+ { "aes192-ctr",  SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_128_ctr, 1 },
+ { "aes256-ctr",  SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_128_ctr, 1 },
 #ifdef USE_CIPHER_ACSS
- { "acss at openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, EVP_acss },
+ { "acss at openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, EVP_acss, 0 },
 #endif
- { NULL,   SSH_CIPHER_INVALID, 0, 0, 0, NULL }
+ { NULL,   SSH_CIPHER_INVALID, 0, 0, 0, NULL, 0 }
 };
 
 /*--*/
@@ -156,6 +158,13 @@
  for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
      (p = strsep(&cp, CIPHER_SEP))) {
   c = cipher_by_name(p);
+#ifdef OPENSSL_FIPS
+               if (fips_mode && !(c->fips_allowed)) {
+                       debug("cipher %s disallowed in FIPS mode [%s]",
p, names);
+                       xfree(cipher_list);
+                        return 0;
+               }
+#endif
   if (c == NULL || c->number != SSH_CIPHER_SSH2) {
    debug("bad cipher %s [%s]", p, names);
    xfree(cipher_list);
@@ -291,9 +300,25 @@
 cipher_set_key_string(CipherContext *cc, Cipher *cipher,
     const char *passphrase, int do_encrypt)
 {
+#ifdef OPENSSL_FIPS
+ SHA_CTX sha;
+#endif
  MD5_CTX md;
- u_char digest[16];
+ u_char digest[20];
 
+#ifdef OPENSSL_FIPS
+ if (fips_mode) {
+  SHA1_Init(&sha);
+  SHA1_Update(&sha, (const u_char *)passphrase, strlen(passphrase));
+  SHA1_Final(digest, &sha);
+ 
+  cipher_init(cc, cipher, digest, 20, NULL, 0, do_encrypt);
+
+  memset(digest, 0, sizeof(digest));
+  memset(&sha, 0, sizeof(sha));
+  return;
+ }
+#endif
  MD5_Init(&md);
  MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
  MD5_Final(digest, &md);
--- openssh-4.7p1/configure.ac Mon Dec 17 20:25:49 2007
+++ openssh-4.7p1/configure.ac Mon Dec 17 20:29:36 2007
@@ -438,6 +438,7 @@
   if test -z "$GCC"; then
    CFLAGS="$CFLAGS -Ae"
   fi
+  HPUX=1
   ;;
  *-*-hpux11*)
   AC_DEFINE(PAM_SUN_CODEBASE, 1,
@@ -449,6 +450,7 @@
   AC_DEFINE(USE_BTMP, 1, [Use btmp to log bad logins])
   check_for_hpux_broken_getaddrinfo=1
   check_for_conflicting_getspnam=1
+  HPUX=1
   ;;
  esac
 
@@ -460,6 +462,7 @@
    protected password database])
   disable_ptmx_check=yes
   LIBS="$LIBS -lsecpw"
+  HPUX=1
   ;;
  esac
  ;;
@@ -1768,6 +1771,8 @@
    case "$withval" in
     # Relative paths
     ./*|../*) withval="`pwd`/$withval"
    esac
+                        ssldir=$withval
+                        AC_SUBST(ssldir)
    if test -d "$withval/lib"; then
     if test -n "${need_dash_r}"; then
@@ -2099,6 +2104,34 @@
  )
 fi
 
+
+# Check for OpenSSL FIPS mode
+AC_ARG_WITH(fips,
+       [  --with-fips             Enable OpenSSL FIPS mode ],
+       [
+               if test "x$withval" != "xno" ; then
+                       AC_CACHE_CHECK([for FIPS mode], ac_cv_fips, [
+                               AC_TRY_COMPILE(
+                                       [ #include <openssl/fips.h> ],
+                                       [ FIPS_mode_set(1); ],
+                                       [ ac_cv_fips="yes" ],
+                                       [ ac_cv_fips="no" ]
+                               )
+                       ])
+               fi
+       ]
+)
+if test "x$ac_cv_fips" = "xyes" ; then
+       CPPFLAGS="$CPPFLAGS -DOPENSSL_FIPS"
+       if test "x$HPUX" = "x" ; then
+               LIBS=`echo $LIBS | sed 's/-lcrypto /-Wl,-Bstatic
-lcrypto -Wl,-Bdynamic /'`
+       else
+               LIBS=`echo $LIBS | sed 's/-lcrypto /-Wl,-aarchive
-lcrypto -Wl,-adefault /'`
+       fi
+       FIPS_MODE=yes
+       AC_SUBST(FIPS_MODE)
+fi
+
 # Do we want to force the use of the rand helper?
 AC_ARG_WITH(rand-helper,
  [  --with-rand-helper      Use subprocess to gather strong randomness
],
diff -u -r1.1 -r1.3
--- openssh-4.7p1/mac.c Mon Dec 17 20:59:35 2007
+++ openssh-4.7p1/mac.c Mon Dec 17 21:01:42 2007
@@ -41,5 +41,6 @@
 #include "kex.h"
 #include "mac.h"
 #include "misc.h"
+#include "fips.h"
 
 #include "umac.h"
@@ -54,15 +55,16 @@
  int  truncatebits; /* truncate digest if != 0 */
  int  key_len; /* just for UMAC */
  int  len;  /* just for UMAC */
+        int             fips_allowed;
 } macs[] = {
- { "hmac-sha1",   SSH_EVP, EVP_sha1, 0, -1, -1 },
- { "hmac-sha1-96",  SSH_EVP, EVP_sha1, 96, -1, -1 },
- { "hmac-md5",   SSH_EVP, EVP_md5, 0, -1, -1 },
- { "hmac-md5-96",  SSH_EVP, EVP_md5, 96, -1, -1 },
- { "hmac-ripemd160",  SSH_EVP, EVP_ripemd160, 0, -1, -1 },
- { "hmac-ripemd160 at openssh.com", SSH_EVP, EVP_ripemd160, 0, -1, -1 },
- { "umac-64 at openssh.com", SSH_UMAC, NULL, 0, 128, 64 },
- { NULL,    0, NULL, 0, -1, -1 }
+ { "hmac-sha1",   SSH_EVP, EVP_sha1, 0, -1, -1, 1 },
+ { "hmac-sha1-96",  SSH_EVP, EVP_sha1, 96, -1, -1, 1 },
+ { "hmac-md5",   SSH_EVP, EVP_md5, 0, -1, -1, 0 },
+ { "hmac-md5-96",  SSH_EVP, EVP_md5, 96, -1, -1, 0 },
+ { "hmac-ripemd160",  SSH_EVP, EVP_ripemd160, 0, -1, -1, 0 },
+ { "hmac-ripemd160 at openssh.com", SSH_EVP, EVP_ripemd160, 0, -1, -1, 0
},
+ { "umac-64 at openssh.com", SSH_UMAC, NULL, 0, 128, 64, 0 },
+ { NULL,    0, NULL, 0, -1, -1, 0 }
 };
 
 static void
@@ -91,6 +93,12 @@
 
  for (i = 0; macs[i].name; i++) {
   if (strcmp(name, macs[i].name) == 0) {
+#ifdef OPENSSL_FIPS
+                       if (fips_mode && !macs[i].fips_allowed) {
+                               debug2("mac_init: %s disallowed in fips
mode", name);
+                               return (-1);
+                       }
+#endif
    if (mac != NULL)
     mac_setup_by_id(mac, i);
    debug2("mac_setup: found %s", name);
--- openssh-4.7p1/Makefile.in Tue Dec 18 02:42:38 2007
+++ openssh-4.7p1/Makefile.in Tue Dec 18 02:42:21 2007
@@ -18,6 +18,7 @@
 piddir=@piddir@
 srcdir=@srcdir@
 top_srcdir=@top_srcdir@
+ssldir=@ssldir@
 
 DESTDIR=
 VPATH=@srcdir@
@@ -29,6 +30,7 @@
 PRIVSEP_PATH=@PRIVSEP_PATH@
 SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
 STRIP_OPT=@STRIP_OPT@
+FIPS_MODE=@FIPS_MODE@
 
 PATHS= -DSSHDIR=\"$(sysconfdir)\" \
  -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \
@@ -252,12 +254,18 @@
  $(srcdir)/mkinstalldirs $(DESTDIR)$(libexecdir)
  (umask 022 ; $(srcdir)/mkinstalldirs $(DESTDIR)$(PRIVSEP_PATH))
  $(INSTALL) -m 0755 $(STRIP_OPT) ssh $(DESTDIR)$(bindir)/ssh
+ if [ ! -z "FIPS_MODE" ]; then \
+  $(INSTALL) -m 0755 $(STRIP_OPT) ssh $(DESTDIR)$(bindir)/ssh.sha1; \
+ fi
  $(INSTALL) -m 0755 $(STRIP_OPT) scp $(DESTDIR)$(bindir)/scp
  $(INSTALL) -m 0755 $(STRIP_OPT) ssh-add $(DESTDIR)$(bindir)/ssh-add
  $(INSTALL) -m 0755 $(STRIP_OPT) ssh-agent
$(DESTDIR)$(bindir)/ssh-agent
  $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keygen
$(DESTDIR)$(bindir)/ssh-keygen
  $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keyscan
$(DESTDIR)$(bindir)/ssh-keyscan
  $(INSTALL) -m 0755 $(STRIP_OPT) sshd $(DESTDIR)$(sbindir)/sshd
+ if [ ! -z "FIPS_MODE" ]; then \
+  $(INSTALL) -m 0755 $(STRIP_OPT) sshd $(DESTDIR)$(bindir)/sshd.sha1; \
+ fi
  if test ! -z "$(INSTALL_SSH_RAND_HELPER)" ; then \
   $(INSTALL) -m 0755 $(STRIP_OPT) ssh-rand-helper
$(DESTDIR)$(libexecdir)/ssh-rand-helper ; \
  fi
diff -u -r1.1 -r1.3
--- openssh-4.7p1/myproposal.h Mon Dec 17 21:07:18 2007
+++ openssh-4.7p1/myproposal.h Mon Dec 17 21:09:50 2007
@@ -41,6 +41,7 @@
 #endif
 
 #define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss"
+#ifndef OPENSSL_FIPS
 #define KEX_DEFAULT_ENCRYPT \
  "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
  "arcfour128,arcfour256,arcfour," \
@@ -50,6 +51,16 @@
  "hmac-md5,hmac-sha1,umac-64 at openssh.com,hmac-ripemd160," \
  "hmac-ripemd160 at openssh.com," \
  "hmac-sha1-96,hmac-md5-96"
+#else
+  #define      KEX_DEFAULT_ENCRYPT \
+       "aes128-cbc,3des-cbc," \
+       "aes192-cbc,aes256-cbc,rijndael-cbc at lysator.liu.se," \
+       "aes128-ctr,aes192-ctr,aes256-ctr"
+  #define      KEX_DEFAULT_MAC \
+       "hmac-sha1," \
+       "hmac-sha1-96"
+#endif
+
 #define KEX_DEFAULT_COMP "none,zlib at openssh.com,zlib"
 #define KEX_DEFAULT_LANG ""
 
--- openssh-4.7p1/readconf.h Mon Dec 17 03:35:58 2007
+++ openssh-4.7p1/readconf.h Mon Dec 17 03:53:57 2007
@@ -120,6 +120,7 @@
 
  char *local_command;
  int permit_local_command;
+ int fips_mode;
 
 }       Options;
 
--- openssh-4.7p1/servconf.h Mon Dec 17 04:25:51 2007
+++ openssh-4.7p1/servconf.h Mon Dec 17 04:26:31 2007
@@ -141,6 +141,7 @@
  int permit_tun;
 
  int num_permitted_opens;
+ int fips_mode;
 }       ServerOptions;
 
 void  initialize_server_options(ServerOptions *);

--- openssh-4.7p1/readconf.c Mon Dec 17 03:46:49 2007
+++ openssh-4.7p1/readconf.c Fri Dec 21 15:40:50 2007
@@ -130,6 +130,7 @@
  oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
  oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
  oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
+ oFipsMode,
  oDeprecated, oUnsupported
 } OpCodes;
 
@@ -226,6 +227,7 @@
  { "tunneldevice", oTunnelDevice },
  { "localcommand", oLocalCommand },
  { "permitlocalcommand", oPermitLocalCommand },
+ { "fipsmode", oFipsMode},
  { NULL, oBadOption }
 };
 
@@ -915,6 +917,10 @@
   intptr = &options->permit_local_command;
   goto parse_flag;
 
+ case oFipsMode:
+  intptr = &options->fips_mode;
+  goto parse_flag;
+
  case oDeprecated:
   debug("%s line %d: Deprecated option \"%s\"",
       filename, linenum, keyword);
@@ -1065,6 +1071,7 @@
  options->tun_remote = -1;
  options->local_command = NULL;
  options->permit_local_command = -1;
+ options->fips_mode = -1;
 }
 
 /*
@@ -1132,9 +1139,9 @@
  /* Selected in ssh_login(). */
  if (options->cipher == -1)
   options->cipher = SSH_CIPHER_NOT_SET;
- /* options->ciphers, default set in myproposals.h */
- /* options->macs, default set in myproposals.h */
- /* options->hostkeyalgorithms, default set in myproposals.h */
+ /* options->ciphers, default set in myproposal.h */
+ /* options->macs, default set in myproposal.h */
+ /* options->hostkeyalgorithms, default set in myproposal.h */
  if (options->protocol == SSH_PROTO_UNKNOWN)
   options->protocol = SSH_PROTO_1|SSH_PROTO_2;
  if (options->num_identity_files == 0) {
@@ -1199,6 +1206,10 @@
   options->tun_remote = SSH_TUNID_ANY;
  if (options->permit_local_command == -1)
   options->permit_local_command = 0;
+ if (options->fips_mode == -1)
+  options->fips_mode = 0;
+ if (options->fips_mode && options->macs == NULL)
+  options->macs = "hmac-sha1,hmac-sha1-96";
  /* options->local_command should not be set by default */
  /* options->proxy_command should not be set by default */
  /* options->user will be set in the main program if appropriate */
--- openssh-4.7p1/servconf.c Mon Dec 17 04:25:51 2007
+++ openssh-4.7p1/servconf.c Fri Dec 21 15:59:15 2007
@@ -104,7 +104,11 @@
  options->num_allow_groups = 0;
  options->num_deny_groups = 0;
  options->ciphers = NULL;
+#ifdef OPENSSL_FIPS
+ options->macs = "hmac-sha1,hmac-sha1-96";
+#else
  options->macs = NULL;
+#endif
  options->protocol = SSH_PROTO_UNKNOWN;
  options->gateway_ports = -1;
  options->num_subsystems = 0;
@@ -122,8 +126,10 @@
  options->permit_tun = -1;
  options->num_permitted_opens = -1;
  options->adm_forced_command = NULL;
+ options->fips_mode = -1;
 }
 
+
 void
 fill_default_server_options(ServerOptions *options)
 {
@@ -249,6 +255,8 @@
   options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
  if (options->permit_tun == -1)
   options->permit_tun = SSH_TUNMODE_NO;
+ if (options->fips_mode == -1)
+  options->fips_mode = 0;
 
  /* Turn privilege separation on by default */
  if (use_privsep == -1)
@@ -293,6 +301,7 @@
  sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
  sMatch, sPermitOpen, sForceCommand,
  sUsePrivilegeSeparation,
+ sFipsMode,
  sDeprecated, sUnsupported
 } ServerOpCodes;
 
@@ -403,6 +412,7 @@
   { "match", sMatch, SSHCFG_ALL },
  { "permitopen", sPermitOpen, SSHCFG_ALL },
  { "forcecommand", sForceCommand, SSHCFG_ALL },
+ { "fipsmode", sFipsMode, SSHCFG_GLOBAL },
  { NULL, sBadOption, 0 }
 };
 
@@ -1253,6 +1263,10 @@
    options->adm_forced_command = xstrdup(cp + len);
   return 0;
 
+ case sFipsMode:
+  intptr = &options->fips_mode;
+  goto parse_flag;
+
  case sDeprecated:
   logit("%s line %d: Deprecated option %s",
       filename, linenum, arg);
 
--- openssh-4.7p1/ssh.c Mon Dec 17 03:23:08 2007
+++ openssh-4.7p1/ssh.c Fri Dec 21 15:55:04 2007
@@ -72,6 +72,11 @@
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+#endif
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -100,6 +105,16 @@
 #include "monitor_fdpass.h"
 #include "uidswap.h"
 #include "version.h"
+#include "fips.h"
+
+/*
+ * FIPS mode operation
+*/
+#ifdef OPENSSL_FIPS
+       int fips_mode = 1; //refined later
+#else
+       int fips_mode = 0;
+#endif
 
 #ifdef SMARTCARD
 #include "scard.h"
@@ -180,12 +195,17 @@
 u_int control_server_pid = 0;
 
 /* Prints a help message to the user.  This function never returns. */
+#ifdef OPENSSL_FIPS
+# define FIPS_OPTS "y"
+#else
+# define FIPS_OPTS
+#endif
 
 static void
 usage(void)
 {
  fprintf(stderr,
-"usage: ssh [-1246AaCfgKkMNnqsTtVvXxY] [-b bind_address] [-c
cipher_spec]\n"
+"usage: ssh [-1246AaCfgKkMNnqsTtVvXx" FIPS_OPTS "Y] [-b bind_address]
[-c cipher_spec]\n"
 "           [-D [bind_address:]port] [-e escape_char] [-F
configfile]\n"
 "           [-i identity_file] [-L
[bind_address:]port:host:hostport]\n"
 "           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p
port]\n"
@@ -272,8 +292,13 @@
 
  again:
  while ((opt = getopt(ac, av,
-     "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:KL:MNO:PR:S:TVw:XY")) !=
-1) {
+     "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:KL:MNO:PR:S:TVw:X"
FIPS_OPTS "Y")) != -1) {
   switch (opt) {
+#ifdef OPENSSL_FIPS
+               case 'y':
+                       fips_mode = 0;
+                       break;
+#endif
   case '1':
    options.protocol = SSH_PROTO_1;
    break;
@@ -637,6 +662,36 @@
  log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1);
 
  seed_rng();
+#ifdef OPENSSL_FIPS
+/* 
+ Priority setting:
+  !command line
+  env OPENSSH_FIPS
+  !env OPENSSH_NO_FIPS
+  ssh_config options (default: false)
+*/
+ if (fips_mode) { /* !command line */
+  if (getenv("OPENSSH_FIPS")) { /* env OPENSSH_FIPS */
+  }
+  else if (getenv("OPENSSH_NO_FIPS")) { /* !env OPENSSH_NO_FIPS */
+   fips_mode = 0;
+  }
+  else if (options.fips_mode == 0) { /* ssh_config options */
+                 fips_mode = 0;
+  }
+ }
+        if(fips_mode)
+        {
+          if(!FIPS_mode_set(1))
+          {
+            ERR_load_crypto_strings();
+            ERR_print_errors_fp(stderr);
+            exit(1);
+          }
+          else
+            fprintf(stderr,"*** IN FIPS MODE ***\n");
+        }
+#endif
 
  if (options.user == NULL)
   options.user = xstrdup(pw->pw_name);






More information about the openssh-unix-dev mailing list