add FIPS support to ssl: doesn't do anything on this branch yet as there is no FIPS...
authorDr. Stephen Henson <steve@openssl.org>
Thu, 19 May 2011 18:22:16 +0000 (18:22 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Thu, 19 May 2011 18:22:16 +0000 (18:22 +0000)
CHANGES
ssl/s23_clnt.c
ssl/s23_srvr.c
ssl/s3_clnt.c
ssl/s3_enc.c
ssl/s3_srvr.c
ssl/ssl_ciph.c
ssl/ssl_lib.c
ssl/ssltest.c
ssl/t1_enc.c

diff --git a/CHANGES b/CHANGES
index e9b946c358eadef905d498c41dab8b2e02e6e436..9f37b80aa5f37553c7ea0542625b59282d8e55ce 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,10 @@
 
  Changes between 1.0.0d and 1.0.1  [xx XXX xxxx]
 
+  *) Add support for FIPS mode in ssl library: disable SSLv3, non-FIPS ciphers
+     and enable MD5.
+     [Steve Henson]
+
   *) Functions FIPS_mode_set() and FIPS_mode() which call the underlying
      FIPS modules versions.
      [Steve Henson]
index f49a95ba99aa3dd3fcf311c70ebdf3006ae47cf0..b3c48232d7bec748e659d295eb9f7b272696674a 100644 (file)
@@ -356,6 +356,14 @@ static int ssl23_client_hello(SSL *s)
                        version_major = TLS1_VERSION_MAJOR;
                        version_minor = TLS1_VERSION_MINOR;
                        }
+#ifdef OPENSSL_FIPS
+               else if(FIPS_mode())
+                       {
+                       SSLerr(SSL_F_SSL23_CLIENT_HELLO,
+                                       SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+                       return -1;
+                       }
+#endif
                else if (version == SSL3_VERSION)
                        {
                        version_major = SSL3_VERSION_MAJOR;
@@ -639,6 +647,14 @@ static int ssl23_get_server_hello(SSL *s)
                if ((p[2] == SSL3_VERSION_MINOR) &&
                        !(s->options & SSL_OP_NO_SSLv3))
                        {
+#ifdef OPENSSL_FIPS
+                       if(FIPS_mode())
+                               {
+                               SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,
+                                       SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+                               goto err;
+                               }
+#endif
                        s->version=SSL3_VERSION;
                        s->method=SSLv3_client_method();
                        }
index b21c57a1170a322bfb208cac16af295918c3082a..48778490135eb01130dcf009c3dda7534ffb341b 100644 (file)
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
 
 static const SSL_METHOD *ssl23_get_server_method(int ver);
 int ssl23_get_client_hello(SSL *s);
@@ -422,6 +425,15 @@ int ssl23_get_client_hello(SSL *s)
                        }
                }
 
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && (s->version < TLS1_VERSION))
+               {
+               SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,
+                                       SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+               goto err;
+               }
+#endif
+
        if (s->state == SSL23_ST_SR_CLNT_HELLO_B)
                {
                /* we have SSLv3/TLSv1 in an SSLv2 header
index e7dea7d72bd263a673dfb433abc53976757f1b30..fd131a6df8eb0ec461e15ab1633a5407ff2e2d4d 100644 (file)
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/md5.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
 #ifndef OPENSSL_NO_DH
 #include <openssl/dh.h>
 #endif
@@ -1691,6 +1694,8 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
                        q=md_buf;
                        for (num=2; num > 0; num--)
                                {
+                               EVP_MD_CTX_set_flags(&md_ctx,
+                                       EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
                                EVP_DigestInit_ex(&md_ctx,(num == 2)
                                        ?s->ctx->md5:s->ctx->sha1, NULL);
                                EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
index ac5ae40a7e5f7207c0be05b3b0bbdf6d114c10fa..9f5574a01ed5d2f905d60192179fc8c602eda161 100644 (file)
@@ -170,6 +170,7 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
 #endif
        k=0;
        EVP_MD_CTX_init(&m5);
+       EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        EVP_MD_CTX_init(&s1);
        for (i=0; (int)i<num; i+=MD5_DIGEST_LENGTH)
                {
@@ -614,6 +615,13 @@ int ssl3_digest_cached_records(SSL *s)
                        {
                        s->s3->handshake_dgst[i]=EVP_MD_CTX_create();
                        EVP_DigestInit_ex(s->s3->handshake_dgst[i],md,NULL);
+#ifdef OPENSSL_FIPS
+                       if (EVP_MD_nid(md) == NID_md5)
+                               {
+                               EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i],
+                                               EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+                               }
+#endif
                        EVP_DigestUpdate(s->s3->handshake_dgst[i],hdata,hdatalen);
                        } 
                else 
@@ -669,6 +677,7 @@ static int ssl3_handshake_mac(SSL *s, int md_nid,
                return 0;
        }       
        EVP_MD_CTX_init(&ctx);
+       EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        EVP_MD_CTX_copy_ex(&ctx,d);
        n=EVP_MD_CTX_size(&ctx);
        if (n < 0)
index 6300d5027ac5fe34f61649d4fdd39095fce61ea3..9dc2a38750601f5b4ad61ebc3e53628521ea36fc 100644 (file)
@@ -1855,6 +1855,8 @@ int ssl3_send_server_key_exchange(SSL *s)
                                        {
                                        EVP_DigestInit_ex(&md_ctx,(num == 2)
                                                ?s->ctx->md5:s->ctx->sha1, NULL);
+                                       EVP_MD_CTX_set_flags(&md_ctx,
+                                               EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
                                        EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
                                        EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
                                        EVP_DigestUpdate(&md_ctx,&(d[4]),n);
index 38d59774ef32b9bc35a1589575f0dc24787a2267..87a9f68ce9d7b68906588ab5f61cb2ef892b91c8 100644 (file)
@@ -740,6 +740,9 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
                c = ssl_method->get_cipher(i);
                /* drop those that use any of that is not available */
                if ((c != NULL) && c->valid &&
+#ifdef OPENSSL_FIPS
+                   (!FIPS_mode() || (c->algo_strength & SSL_FIPS)) &&
+#endif
                    !(c->algorithm_mkey & disabled_mkey) &&
                    !(c->algorithm_auth & disabled_auth) &&
                    !(c->algorithm_enc & disabled_enc) &&
@@ -1439,7 +1442,11 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
         */
        for (curr = head; curr != NULL; curr = curr->next)
                {
+#ifdef OPENSSL_FIPS
+               if (curr->active && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS))
+#else
                if (curr->active)
+#endif
                        {
                        sk_SSL_CIPHER_push(cipherstack, curr->cipher);
 #ifdef CIPHER_DEBUG
index 1c3e9454d6b938a12b9fc7eeff9f02dbb7759e60..b21b42927d8356f110278fd06465304224faabd5 100644 (file)
@@ -1532,6 +1532,14 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
                return(NULL);
                }
 
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && (meth->version < TLS1_VERSION))      
+               {
+               SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+               return NULL;
+               }
+#endif
+
        if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0)
                {
                SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
index 994522effea41547d4585504e0c0731c3ba34e3e..582b9ca1655df6a9f8fab53797e9eff245146f0e 100644 (file)
@@ -320,6 +320,9 @@ static void sv_usage(void)
        {
        fprintf(stderr,"usage: ssltest [args ...]\n");
        fprintf(stderr,"\n");
+#ifdef OPENSSL_FIPS
+       fprintf(stderr,"-F             - run test in FIPS mode\n");
+#endif
        fprintf(stderr," -server_auth  - check server certificate\n");
        fprintf(stderr," -client_auth  - do client authentication\n");
        fprintf(stderr," -proxy        - allow proxy certificates\n");
@@ -550,6 +553,9 @@ int main(int argc, char *argv[])
 #endif
        STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
        int test_cipherlist = 0;
+#ifdef OPENSSL_FIPS
+       int fips_mode=0;
+#endif
 
        verbose = 0;
        debug = 0;
@@ -581,7 +587,16 @@ int main(int argc, char *argv[])
 
        while (argc >= 1)
                {
-               if      (strcmp(*argv,"-server_auth") == 0)
+               if(!strcmp(*argv,"-F"))
+                       {
+#ifdef OPENSSL_FIPS
+                       fips_mode=1;
+#else
+                       fprintf(stderr,"not compiled with FIPS support, so exitting without running.\n");
+                       EXIT(0);
+#endif
+                       }
+               else if (strcmp(*argv,"-server_auth") == 0)
                        server_auth=1;
                else if (strcmp(*argv,"-client_auth") == 0)
                        client_auth=1;
@@ -791,6 +806,20 @@ bad:
                EXIT(1);
                }
 
+#ifdef OPENSSL_FIPS
+       if(fips_mode)
+               {
+               if(!FIPS_mode_set(1))
+                       {
+                       ERR_load_crypto_strings();
+                       ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
+                       EXIT(1);
+                       }
+               else
+                       fprintf(stderr,"*** IN FIPS MODE ***\n");
+               }
+#endif
+
        if (print_time)
                {
                if (!bio_pair)
index c60bccd2c00b1af21ad7a306ca1e76679e5dc87f..36128dcf6b5e9d9c744b0b7e9f4807edc32eb81d 100644 (file)
@@ -171,6 +171,8 @@ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
 
        EVP_MD_CTX_init(&ctx);
        EVP_MD_CTX_init(&ctx_tmp);
+       EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+       EVP_MD_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
        if (!mac_key)
                goto err;