You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by be...@apache.org on 2005/06/10 19:25:17 UTC

svn commit: r189992 - in /httpd/httpd/branches/fips-dev: README-FIPS modules/ssl/mod_ssl.c modules/ssl/ssl_engine_config.c modules/ssl/ssl_engine_init.c modules/ssl/ssl_engine_rand.c modules/ssl/ssl_private.h server/config.c server/main.c

Author: ben
Date: Fri Jun 10 10:25:17 2005
New Revision: 189992

URL: http://svn.apache.org/viewcvs?rev=189992&view=rev
Log:
First cut, working FIPS mode.

Modified:
    httpd/httpd/branches/fips-dev/README-FIPS
    httpd/httpd/branches/fips-dev/modules/ssl/mod_ssl.c
    httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_config.c
    httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_init.c
    httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_rand.c
    httpd/httpd/branches/fips-dev/modules/ssl/ssl_private.h
    httpd/httpd/branches/fips-dev/server/config.c
    httpd/httpd/branches/fips-dev/server/main.c

Modified: httpd/httpd/branches/fips-dev/README-FIPS
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/fips-dev/README-FIPS?rev=189992&r1=189991&r2=189992&view=diff
==============================================================================
--- httpd/httpd/branches/fips-dev/README-FIPS (original)
+++ httpd/httpd/branches/fips-dev/README-FIPS Fri Jun 10 10:25:17 2005
@@ -22,3 +22,13 @@
 Note this branch includes apr and apr-util, while the authors figure out what
 to do about apr MD5 and other fips issues are resolved.  That work will be
 submitted to the apr project, once the least distruptive change is ascertained.
+
+Stuff FIPS requires
+-------------------
+
+Random number seeding: strangeness about the FIPS PRNG means that at
+least one random source must supply at least 24 bytes of randomness in
+a single chunk (note that this could be relaxed at the cost of more
+code).
+
+Certificates: must be signed using SHA-1.

Modified: httpd/httpd/branches/fips-dev/modules/ssl/mod_ssl.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/fips-dev/modules/ssl/mod_ssl.c?rev=189992&r1=189991&r2=189992&view=diff
==============================================================================
--- httpd/httpd/branches/fips-dev/modules/ssl/mod_ssl.c (original)
+++ httpd/httpd/branches/fips-dev/modules/ssl/mod_ssl.c Fri Jun 10 10:25:17 2005
@@ -99,6 +99,9 @@
     SSL_CMD_SRV(Engine, TAKE1,
                 "SSL switch for the protocol engine "
                 "(`on', `off')")
+    SSL_CMD_SRV(FIPS, TAKE1,
+		"Enable FIPS-140 compliance "
+                "(`on', `off')")
     SSL_CMD_ALL(CipherSuite, TAKE1,
                 "Colon-delimited list of permitted SSL Ciphers "
                 "(`XXX:...:XXX' - see manual)")

Modified: httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_config.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_config.c?rev=189992&r1=189991&r2=189992&view=diff
==============================================================================
--- httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_config.c (original)
+++ httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_config.c Fri Jun 10 10:25:17 2005
@@ -254,6 +254,7 @@
 
     cfgMerge(mc, NULL);
     cfgMerge(enabled, SSL_ENABLED_UNSET);
+    cfgMerge(fips, SSL_FIPS_UNSET); // FIPS-XXX: make more than one setting an error?
     cfgMergeBool(proxy_enabled);
     cfgMergeInt(session_cache_timeout);
     cfgMergeBool(cipher_server_pref);
@@ -617,6 +618,22 @@
     }
 
     return "Argument must be On, Off, or Optional";
+}
+// FIPS-XXX: this is global, i.e. can only be set once, not per-server.
+const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, const char *arg)
+{
+    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+    if (!strcasecmp(arg, "On")) {
+        sc->fips = SSL_FIPS_TRUE;
+	return NULL;
+    }
+    else if (!strcasecmp(arg, "Off")) {
+        sc->fips = SSL_FIPS_FALSE;
+        return NULL;
+    }
+
+    return "Argument must be On or Off";
 }
 
 const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,

Modified: httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_init.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_init.c?rev=189992&r1=189991&r2=189992&view=diff
==============================================================================
--- httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_init.c (original)
+++ httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_init.c Fri Jun 10 10:25:17 2005
@@ -87,6 +87,20 @@
     MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_512); \
     MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_1024)
 
+/* FIPS-140 prevents automatic rekeying in child processes, so we have
+ * to do it */
+
+static void fips_rand_reseed(server_rec *s, apr_pool_t *ptemp)
+{
+    static int rand_seeded;
+    SSLSrvConfigRec *sc = mySrvConfig(s);
+
+    if(sc->fips == SSL_FIPS_TRUE && !rand_seeded) {
+	ssl_rand_seed(s, ptemp, SSL_RSCTX_STARTUP, "FIPS Child Init: ");
+	rand_seeded=1;
+    }
+}
+
 static void ssl_tmp_keys_free(server_rec *s)
 {
     SSLModConfigRec *mc = myModConfig(s);
@@ -95,8 +109,7 @@
     MODSSL_TMP_KEYS_FREE(mc, DH);
 }
 
-static int ssl_tmp_key_init_rsa(server_rec *s,
-                                int bits, int idx)
+static int ssl_tmp_key_init_rsa(server_rec *s, int bits, int idx)
 {
     SSLModConfigRec *mc = myModConfig(s);
 
@@ -106,6 +119,7 @@
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                      "Init: Failed to generate temporary "
                      "%d bit RSA private key", bits);
+	ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
         return !OK;
     }
 
@@ -157,8 +171,7 @@
 }
 
 /*
- *  Per-module initialization
- */
+ * Per-module initialization */
 int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
                     apr_pool_t *ptemp,
                     server_rec *base_server)
@@ -166,6 +179,7 @@
     SSLModConfigRec *mc = myModConfig(base_server);
     SSLSrvConfigRec *sc;
     server_rec *s;
+    static int fips_done;
 
     /* We initialize mc->pid per-process in the child init,
      * but it should be initialized for startup before we
@@ -212,6 +226,10 @@
         if (sc->enabled == SSL_ENABLED_UNSET) {
             sc->enabled = SSL_ENABLED_FALSE;
         }
+
+	if(sc->fips == SSL_FIPS_UNSET)
+	    sc->enabled = SSL_FIPS_FALSE;
+
         if (sc->proxy_enabled == UNSET) {
             sc->proxy_enabled = FALSE;
         }
@@ -247,6 +265,25 @@
      */
     ssl_rand_seed(base_server, ptemp, SSL_RSCTX_STARTUP, "Init: ");
 
+    /* Do this after randomness has been seeded */
+    // XXX: also need to set FIPS mode for APR (i.e. exclude all crypto/randomness from APR)
+    if(!fips_done) {
+	if(sc->fips == SSL_FIPS_TRUE) {
+	    if(FIPS_mode_set(1,ap_server_full_argv0))
+		ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
+			     "FIPS mode enabled");
+	    else {
+		ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
+			     "FIPS mode failed (%s)",ap_server_full_argv0);
+		ssl_log_ssl_error(APLOG_MARK, APLOG_EMERG, s);
+		exit(1);
+	    }
+	}
+	else
+	    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, "FIPS mode disabled");
+	fips_done=1;
+    }
+
     /*
      * read server private keys/public certs into memory.
      * decrypting any encrypted keys via configured SSLPassPhraseDialogs
@@ -1185,6 +1222,7 @@
 void ssl_init_Child(apr_pool_t *p, server_rec *s)
 {
     SSLModConfigRec *mc = myModConfig(s);
+
     mc->pid = getpid(); /* only call getpid() once per-process */
 
     /* XXX: there should be an ap_srand() function */
@@ -1192,6 +1230,8 @@
 
     /* open the mutex lockfile */
     ssl_mutex_reinit(s, p);
+
+    fips_rand_reseed(s, p);
 }
 
 #define MODSSL_CFG_ITEM_FREE(func, item) \

Modified: httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_rand.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_rand.c?rev=189992&r1=189991&r2=189992&view=diff
==============================================================================
--- httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_rand.c (original)
+++ httpd/httpd/branches/fips-dev/modules/ssl/ssl_engine_rand.c Fri Jun 10 10:25:17 2005
@@ -36,11 +36,29 @@
 */
 
 static int ssl_rand_choosenum(int, int);
-static int ssl_rand_feedfp(apr_pool_t *, apr_file_t *, int);
+static int ssl_rand_feedfp(int, apr_pool_t *, apr_file_t *, int);
+
+/* Deal with the arcanity of the FIPS PRNG, which requires keying
+ * indepently of seeding. */
+// FIPS-XXX: this means at least one random source _must_ inject 24 bytes or
+// FIPS will not be seeded and keyed
+static void inject_rand(int fips, const void *buf, int num)
+{
+    if(!fips)
+	RAND_seed(buf, num);
+
+    if(num > 16) {
+	FIPS_set_prng_key(buf, buf+8);
+	num -= 16;
+	buf += 16;
+    }
+    RAND_seed(buf, num);
+}
 
 int ssl_rand_seed(server_rec *s, apr_pool_t *p, ssl_rsctx_t nCtx, char *prefix)
 {
     SSLModConfigRec *mc;
+    SSLSrvConfigRec *sc = mySrvConfig(s);
     apr_array_header_t *apRandSeed;
     ssl_randseed_t *pRandSeeds;
     ssl_randseed_t *pRandSeed;
@@ -65,7 +83,8 @@
                 if (apr_file_open(&fp, pRandSeed->cpPath, 
                                   APR_READ, APR_OS_DEFAULT, p) != APR_SUCCESS)
                     continue;
-                nDone += ssl_rand_feedfp(p, fp, pRandSeed->nBytes);
+                nDone += ssl_rand_feedfp(sc->fips == SSL_FIPS_TRUE, p, fp,
+					 pRandSeed->nBytes);
                 apr_file_close(fp);
             }
             else if (pRandSeed->nSrc == SSL_RSSRC_EXEC) {
@@ -80,7 +99,8 @@
 
                 if ((fp = ssl_util_ppopen(s, p, cmd, argv)) == NULL)
                     continue;
-                nDone += ssl_rand_feedfp(p, fp, pRandSeed->nBytes);
+                nDone += ssl_rand_feedfp(sc->fips == SSL_FIPS_TRUE, p, fp,
+					 pRandSeed->nBytes);
                 ssl_util_ppclose(s, p, fp);
             }
 #ifdef HAVE_SSL_RAND_EGD
@@ -111,14 +131,14 @@
                 my_seed.pid = mc->pid;
 
                 l = sizeof(my_seed);
-                RAND_seed((unsigned char *)&my_seed, l);
+                inject_rand(sc->fips == SSL_FIPS_TRUE, &my_seed, l);
                 nDone += l;
                 
                 /*
                  * seed in some current state of the run-time stack (128 bytes)
                  */
                 n = ssl_rand_choosenum(0, sizeof(stackdata)-128-1);
-                RAND_seed(stackdata+n, 128);
+                inject_rand(sc->fips == SSL_FIPS_TRUE, stackdata+n, 128);
                 nDone += 128;
 
             }
@@ -136,7 +156,7 @@
 
 #define BUFSIZE 8192
 
-static int ssl_rand_feedfp(apr_pool_t *p, apr_file_t *fp, int nReq)
+static int ssl_rand_feedfp(int fips, apr_pool_t *p, apr_file_t *fp, int nReq)
 {
     apr_size_t nDone;
     unsigned char caBuf[BUFSIZE];
@@ -153,7 +173,7 @@
         nBuf = nRead;
         if (apr_file_read(fp, caBuf, &nBuf) != APR_SUCCESS)
             break;
-        RAND_seed(caBuf, nBuf);
+        inject_rand(fips, caBuf, nBuf);
         nDone += nBuf;
         if (nReq > 0) {
             nTodo -= nBuf;

Modified: httpd/httpd/branches/fips-dev/modules/ssl/ssl_private.h
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/fips-dev/modules/ssl/ssl_private.h?rev=189992&r1=189991&r2=189992&view=diff
==============================================================================
--- httpd/httpd/branches/fips-dev/modules/ssl/ssl_private.h (original)
+++ httpd/httpd/branches/fips-dev/modules/ssl/ssl_private.h Fri Jun 10 10:25:17 2005
@@ -278,9 +278,15 @@
     SSL_ENABLED_UNSET    = UNSET,
     SSL_ENABLED_FALSE    = 0,
     SSL_ENABLED_TRUE     = 1,
-	SSL_ENABLED_OPTIONAL = 3
+    SSL_ENABLED_OPTIONAL = 3
 } ssl_enabled_t;
 
+typedef enum {
+    SSL_FIPS_UNSET	= UNSET,
+    SSL_FIPS_FALSE	= 0,
+    SSL_FIPS_TRUE	= 1
+} fips_enabled_t;
+
 /*
  * Define the SSL requirement structure
  */
@@ -436,6 +442,7 @@
 struct SSLSrvConfigRec {
     SSLModConfigRec *mc;
     ssl_enabled_t    enabled;
+    fips_enabled_t   fips;
     BOOL             proxy_enabled;
     const char      *vhost_id;
     int              vhost_id_len;
@@ -487,6 +494,7 @@
 const char  *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *);
 const char  *ssl_cmd_SSLEngine(cmd_parms *, void *, const char *);
+const char  *ssl_cmd_SSLFIPS(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCertificateFile(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, void *, const char *);

Modified: httpd/httpd/branches/fips-dev/server/config.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/fips-dev/server/config.c?rev=189992&r1=189991&r2=189992&view=diff
==============================================================================
--- httpd/httpd/branches/fips-dev/server/config.c (original)
+++ httpd/httpd/branches/fips-dev/server/config.c Fri Jun 10 10:25:17 2005
@@ -55,6 +55,7 @@
 
 
 AP_DECLARE_DATA const char *ap_server_argv0 = NULL;
+AP_DECLARE_DATA const char *ap_server_full_argv0 = NULL;
 
 AP_DECLARE_DATA const char *ap_server_root = NULL;
 

Modified: httpd/httpd/branches/fips-dev/server/main.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/fips-dev/server/main.c?rev=189992&r1=189991&r2=189992&view=diff
==============================================================================
--- httpd/httpd/branches/fips-dev/server/main.c (original)
+++ httpd/httpd/branches/fips-dev/server/main.c Fri Jun 10 10:25:17 2005
@@ -429,6 +429,7 @@
 
     AP_MONCONTROL(0); /* turn off profiling of startup */
 
+    ap_server_full_argv0 = argv[0];
     apr_app_initialize(&argc, &argv, NULL);
 
     process = create_process(argc, argv);