Blame SOURCES/openssl-1.0.2i-fips.patch

450916
diff -up openssl-1.0.2i/apps/speed.c.fips openssl-1.0.2i/apps/speed.c
450916
--- openssl-1.0.2i/apps/speed.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/apps/speed.c	2016-09-22 13:35:57.007220767 +0200
450916
@@ -197,7 +197,6 @@
450916
 #  ifdef OPENSSL_DOING_MAKEDEPEND
450916
 #   undef AES_set_encrypt_key
450916
 #   undef AES_set_decrypt_key
450916
-#   undef DES_set_key_unchecked
450916
 #  endif
450916
 #  define BF_set_key      private_BF_set_key
450916
 #  define CAST_set_key    private_CAST_set_key
450916
@@ -205,7 +204,6 @@
450916
 #  define SEED_set_key    private_SEED_set_key
450916
 #  define RC2_set_key     private_RC2_set_key
450916
 #  define RC4_set_key     private_RC4_set_key
450916
-#  define DES_set_key_unchecked   private_DES_set_key_unchecked
450916
 #  define AES_set_encrypt_key     private_AES_set_encrypt_key
450916
 #  define AES_set_decrypt_key     private_AES_set_decrypt_key
450916
 #  define Camellia_set_key        private_Camellia_set_key
450916
@@ -974,7 +972,12 @@ int MAIN(int argc, char **argv)
450916
 # endif
450916
 # ifndef OPENSSL_NO_RSA
450916
         if (strcmp(*argv, "rsa") == 0) {
450916
-            rsa_doit[R_RSA_512] = 1;
450916
+#  ifdef OPENSSL_FIPS
450916
+            if (!FIPS_mode())
450916
+#  endif
450916
+            {
450916
+                rsa_doit[R_RSA_512] = 1;
450916
+            }
450916
             rsa_doit[R_RSA_1024] = 1;
450916
             rsa_doit[R_RSA_2048] = 1;
450916
             rsa_doit[R_RSA_4096] = 1;
450916
@@ -982,7 +985,12 @@ int MAIN(int argc, char **argv)
450916
 # endif
450916
 # ifndef OPENSSL_NO_DSA
450916
         if (strcmp(*argv, "dsa") == 0) {
450916
-            dsa_doit[R_DSA_512] = 1;
450916
+#  ifdef OPENSSL_FIPS
450916
+            if (!FIPS_mode())
450916
+#  endif
450916
+            {
450916
+                dsa_doit[R_DSA_512] = 1;
450916
+            }
450916
             dsa_doit[R_DSA_1024] = 1;
450916
             dsa_doit[R_DSA_2048] = 1;
450916
         } else
450916
@@ -1233,13 +1241,19 @@ int MAIN(int argc, char **argv)
450916
 
450916
     if (j == 0) {
450916
         for (i = 0; i < ALGOR_NUM; i++) {
450916
-            if (i != D_EVP)
450916
+            if (i != D_EVP &&
450916
+                (!FIPS_mode() || (i != D_WHIRLPOOL &&
450916
+                                  i != D_MD2 && i != D_MD4 &&
450916
+                                  i != D_MD5 && i != D_MDC2 &&
450916
+                                  i != D_RMD160)))
450916
                 doit[i] = 1;
450916
         }
450916
         for (i = 0; i < RSA_NUM; i++)
450916
-            rsa_doit[i] = 1;
450916
+            if (!FIPS_mode() || i != R_RSA_512)
450916
+                rsa_doit[i] = 1;
450916
         for (i = 0; i < DSA_NUM; i++)
450916
-            dsa_doit[i] = 1;
450916
+            if (!FIPS_mode() || i != R_DSA_512)
450916
+                dsa_doit[i] = 1;
450916
 # ifndef OPENSSL_NO_ECDSA
450916
         for (i = 0; i < EC_NUM; i++)
450916
             ecdsa_doit[i] = 1;
450916
@@ -1299,30 +1313,46 @@ int MAIN(int argc, char **argv)
450916
     AES_set_encrypt_key(key32, 256, &aes_ks3);
450916
 # endif
450916
 # ifndef OPENSSL_NO_CAMELLIA
450916
-    Camellia_set_key(key16, 128, &camellia_ks1);
450916
-    Camellia_set_key(ckey24, 192, &camellia_ks2);
450916
-    Camellia_set_key(ckey32, 256, &camellia_ks3);
450916
+    if (doit[D_CBC_128_CML] || doit[D_CBC_192_CML] || doit[D_CBC_256_CML]) {
450916
+        Camellia_set_key(key16, 128, &camellia_ks1);
450916
+        Camellia_set_key(ckey24, 192, &camellia_ks2);
450916
+        Camellia_set_key(ckey32, 256, &camellia_ks3);
450916
+    }
450916
 # endif
450916
 # ifndef OPENSSL_NO_IDEA
450916
-    idea_set_encrypt_key(key16, &idea_ks);
450916
+    if (doit[D_CBC_IDEA]) {
450916
+        idea_set_encrypt_key(key16, &idea_ks);
450916
+    }
450916
 # endif
450916
 # ifndef OPENSSL_NO_SEED
450916
-    SEED_set_key(key16, &seed_ks);
450916
+    if (doit[D_CBC_SEED]) {
450916
+        SEED_set_key(key16, &seed_ks);
450916
+    }
450916
 # endif
450916
 # ifndef OPENSSL_NO_RC4
450916
-    RC4_set_key(&rc4_ks, 16, key16);
450916
+    if (doit[D_RC4]) {
450916
+        RC4_set_key(&rc4_ks, 16, key16);
450916
+    }
450916
 # endif
450916
 # ifndef OPENSSL_NO_RC2
450916
-    RC2_set_key(&rc2_ks, 16, key16, 128);
450916
+    if (doit[D_CBC_RC2]) {
450916
+        RC2_set_key(&rc2_ks, 16, key16, 128);
450916
+    }
450916
 # endif
450916
 # ifndef OPENSSL_NO_RC5
450916
-    RC5_32_set_key(&rc5_ks, 16, key16, 12);
450916
+    if (doit[D_CBC_RC5]) {
450916
+        RC5_32_set_key(&rc5_ks, 16, key16, 12);
450916
+    }
450916
 # endif
450916
 # ifndef OPENSSL_NO_BF
450916
-    BF_set_key(&bf_ks, 16, key16);
450916
+    if (doit[D_CBC_BF]) {
450916
+        BF_set_key(&bf_ks, 16, key16);
450916
+    }
450916
 # endif
450916
 # ifndef OPENSSL_NO_CAST
450916
-    CAST_set_key(&cast_ks, 16, key16);
450916
+    if (doit[D_CBC_CAST]) {
450916
+        CAST_set_key(&cast_ks, 16, key16);
450916
+    }
450916
 # endif
450916
 # ifndef OPENSSL_NO_RSA
450916
     memset(rsa_c, 0, sizeof(rsa_c));
450916
@@ -1605,6 +1635,7 @@ int MAIN(int argc, char **argv)
450916
         HMAC_CTX hctx;
450916
 
450916
         HMAC_CTX_init(&hctx);
450916
+        HMAC_CTX_set_flags(&hctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
450916
         HMAC_Init_ex(&hctx, (unsigned char *)"This is a key...",
450916
                      16, EVP_md5(), NULL);
450916
 
450916
diff -up openssl-1.0.2i/Configure.fips openssl-1.0.2i/Configure
450916
--- openssl-1.0.2i/Configure.fips	2016-09-22 13:35:56.993220444 +0200
450916
+++ openssl-1.0.2i/Configure	2016-09-22 13:35:57.008220790 +0200
450916
@@ -1067,11 +1067,6 @@ if (defined($disabled{"md5"}) || defined
450916
 	$disabled{"ssl2"} = "forced";
450916
 	}
450916
 
450916
-if ($fips && $fipslibdir eq "")
450916
-	{
450916
-	$fipslibdir = $fipsdir . "/lib/";
450916
-	}
450916
-
450916
 # RSAX ENGINE sets default non-FIPS RSA method.
450916
 if ($fips)
450916
 	{
450916
@@ -1556,7 +1551,6 @@ $cflags.=" -DOPENSSL_BN_ASM_GF2m" if ($b
450916
 if ($fips)
450916
 	{
450916
 	$openssl_other_defines.="#define OPENSSL_FIPS\n";
450916
-	$cflags .= " -I\$(FIPSDIR)/include";
450916
 	}
450916
 
450916
 $cpuid_obj="mem_clr.o"	unless ($cpuid_obj =~ /\.o$/);
450916
@@ -1768,9 +1762,12 @@ while (<IN>)
450916
 
450916
 	s/^FIPSDIR=.*/FIPSDIR=$fipsdir/;
450916
 	s/^FIPSLIBDIR=.*/FIPSLIBDIR=$fipslibdir/;
450916
-	s/^FIPSCANLIB=.*/FIPSCANLIB=libcrypto/ if $fips;
450916
 	s/^BASEADDR=.*/BASEADDR=$baseaddr/;
450916
 
450916
+	if ($fips)
450916
+		{
450916
+		s/^FIPS=.*/FIPS=yes/;
450916
+		}
450916
 	s/^SHLIB_TARGET=.*/SHLIB_TARGET=$shared_target/;
450916
 	s/^SHLIB_MARK=.*/SHLIB_MARK=$shared_mark/;
450916
 	s/^SHARED_LIBS=.*/SHARED_LIBS=\$(SHARED_CRYPTO) \$(SHARED_SSL)/ if (!$no_shared);
450916
diff -up openssl-1.0.2i/crypto/aes/aes_misc.c.fips openssl-1.0.2i/crypto/aes/aes_misc.c
450916
--- openssl-1.0.2i/crypto/aes/aes_misc.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/aes/aes_misc.c	2016-09-22 13:35:57.008220790 +0200
450916
@@ -70,17 +70,11 @@ const char *AES_options(void)
450916
 int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
450916
                         AES_KEY *key)
450916
 {
450916
-#ifdef OPENSSL_FIPS
450916
-    fips_cipher_abort(AES);
450916
-#endif
450916
     return private_AES_set_encrypt_key(userKey, bits, key);
450916
 }
450916
 
450916
 int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
450916
                         AES_KEY *key)
450916
 {
450916
-#ifdef OPENSSL_FIPS
450916
-    fips_cipher_abort(AES);
450916
-#endif
450916
     return private_AES_set_decrypt_key(userKey, bits, key);
450916
 }
450916
diff -up openssl-1.0.2i/crypto/cmac/cmac.c.fips openssl-1.0.2i/crypto/cmac/cmac.c
450916
--- openssl-1.0.2i/crypto/cmac/cmac.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/cmac/cmac.c	2016-09-22 13:35:57.008220790 +0200
450916
@@ -105,12 +105,6 @@ CMAC_CTX *CMAC_CTX_new(void)
450916
 
450916
 void CMAC_CTX_cleanup(CMAC_CTX *ctx)
450916
 {
450916
-#ifdef OPENSSL_FIPS
450916
-    if (FIPS_mode() && !ctx->cctx.engine) {
450916
-        FIPS_cmac_ctx_cleanup(ctx);
450916
-        return;
450916
-    }
450916
-#endif
450916
     EVP_CIPHER_CTX_cleanup(&ctx->cctx);
450916
     OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
450916
     OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH);
450916
@@ -160,20 +154,6 @@ int CMAC_Init(CMAC_CTX *ctx, const void
450916
             EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS);
450916
             return 0;
450916
         }
450916
-
450916
-        /* Switch to FIPS cipher implementation if possible */
450916
-        if (cipher != NULL) {
450916
-            const EVP_CIPHER *fcipher;
450916
-            fcipher = FIPS_get_cipherbynid(EVP_CIPHER_nid(cipher));
450916
-            if (fcipher != NULL)
450916
-                cipher = fcipher;
450916
-        }
450916
-        /*
450916
-         * Other algorithm blocking will be done in FIPS_cmac_init, via
450916
-         * FIPS_cipherinit().
450916
-         */
450916
-        if (!impl && !ctx->cctx.engine)
450916
-            return FIPS_cmac_init(ctx, key, keylen, cipher, NULL);
450916
     }
450916
 #endif
450916
     /* All zeros means restart */
450916
@@ -219,10 +199,6 @@ int CMAC_Update(CMAC_CTX *ctx, const voi
450916
 {
450916
     const unsigned char *data = in;
450916
     size_t bl;
450916
-#ifdef OPENSSL_FIPS
450916
-    if (FIPS_mode() && !ctx->cctx.engine)
450916
-        return FIPS_cmac_update(ctx, in, dlen);
450916
-#endif
450916
     if (ctx->nlast_block == -1)
450916
         return 0;
450916
     if (dlen == 0)
450916
@@ -262,10 +238,6 @@ int CMAC_Update(CMAC_CTX *ctx, const voi
450916
 int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
450916
 {
450916
     int i, bl, lb;
450916
-#ifdef OPENSSL_FIPS
450916
-    if (FIPS_mode() && !ctx->cctx.engine)
450916
-        return FIPS_cmac_final(ctx, out, poutlen);
450916
-#endif
450916
     if (ctx->nlast_block == -1)
450916
         return 0;
450916
     bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
450916
diff -up openssl-1.0.2i/crypto/crypto.h.fips openssl-1.0.2i/crypto/crypto.h
450916
--- openssl-1.0.2i/crypto/crypto.h.fips	2016-09-22 13:35:56.890218070 +0200
450916
+++ openssl-1.0.2i/crypto/crypto.h	2016-09-22 13:35:57.008220790 +0200
450916
@@ -600,24 +600,29 @@ int FIPS_mode_set(int r);
450916
 void OPENSSL_init(void);
450916
 
450916
 # define fips_md_init(alg) fips_md_init_ctx(alg, alg)
450916
+# define nonfips_md_init(alg) nonfips_md_init_ctx(alg, alg)
450916
+# define fips_md_init_ctx(alg, cx) \
450916
+        int alg##_Init(cx##_CTX *c)
450916
 
450916
 # ifdef OPENSSL_FIPS
450916
-#  define fips_md_init_ctx(alg, cx) \
450916
+#  define nonfips_md_init_ctx(alg, cx) \
450916
         int alg##_Init(cx##_CTX *c) \
450916
         { \
450916
         if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
450916
-                "Low level API call to digest " #alg " forbidden in FIPS mode!"); \
450916
+                "Digest " #alg " forbidden in FIPS mode!"); \
450916
         return private_##alg##_Init(c); \
450916
         } \
450916
         int private_##alg##_Init(cx##_CTX *c)
450916
 
450916
 #  define fips_cipher_abort(alg) \
450916
         if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
450916
-                "Low level API call to cipher " #alg " forbidden in FIPS mode!")
450916
+                "Cipher " #alg " forbidden in FIPS mode!")
450916
+
450916
+/* die if FIPS selftest failed */
450916
+void FIPS_selftest_check(void);
450916
 
450916
 # else
450916
-#  define fips_md_init_ctx(alg, cx) \
450916
-        int alg##_Init(cx##_CTX *c)
450916
+#  define nonfips_md_init_ctx(alg, cx) fips_md_init_ctx(alg, cx)
450916
 #  define fips_cipher_abort(alg) while(0)
450916
 # endif
450916
 
450916
@@ -637,6 +642,9 @@ int CRYPTO_memcmp(const volatile void *a
450916
  */
450916
 void ERR_load_CRYPTO_strings(void);
450916
 
450916
+# define OPENSSL_HAVE_INIT       1
450916
+void OPENSSL_init_library(void);
450916
+
450916
 /* Error codes for the CRYPTO functions. */
450916
 
450916
 /* Function codes. */
450916
diff -up openssl-1.0.2i/crypto/des/des.h.fips openssl-1.0.2i/crypto/des/des.h
450916
--- openssl-1.0.2i/crypto/des/des.h.fips	2016-09-22 13:35:56.918218715 +0200
450916
+++ openssl-1.0.2i/crypto/des/des.h	2016-09-22 13:35:57.008220790 +0200
450916
@@ -231,10 +231,6 @@ int DES_set_key(const_DES_cblock *key, D
450916
 int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule);
450916
 int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule);
450916
 void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule);
450916
-# ifdef OPENSSL_FIPS
450916
-void private_DES_set_key_unchecked(const_DES_cblock *key,
450916
-                                   DES_key_schedule *schedule);
450916
-# endif
450916
 void DES_string_to_key(const char *str, DES_cblock *key);
450916
 void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2);
450916
 void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
450916
diff -up openssl-1.0.2i/crypto/des/set_key.c.fips openssl-1.0.2i/crypto/des/set_key.c
450916
--- openssl-1.0.2i/crypto/des/set_key.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/des/set_key.c	2016-09-22 13:35:57.008220790 +0200
450916
@@ -359,15 +359,6 @@ int DES_set_key_checked(const_DES_cblock
450916
 }
450916
 
450916
 void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
450916
-#ifdef OPENSSL_FIPS
450916
-{
450916
-    fips_cipher_abort(DES);
450916
-    private_DES_set_key_unchecked(key, schedule);
450916
-}
450916
-
450916
-void private_DES_set_key_unchecked(const_DES_cblock *key,
450916
-                                   DES_key_schedule *schedule)
450916
-#endif
450916
 {
450916
     static const int shifts2[16] =
450916
         { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 };
450916
diff -up openssl-1.0.2i/crypto/dh/dh_gen.c.fips openssl-1.0.2i/crypto/dh/dh_gen.c
450916
--- openssl-1.0.2i/crypto/dh/dh_gen.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/dh/dh_gen.c	2016-09-22 13:35:57.009220813 +0200
450916
@@ -85,10 +85,6 @@ int DH_generate_parameters_ex(DH *ret, i
450916
 #endif
450916
     if (ret->meth->generate_params)
450916
         return ret->meth->generate_params(ret, prime_len, generator, cb);
450916
-#ifdef OPENSSL_FIPS
450916
-    if (FIPS_mode())
450916
-        return FIPS_dh_generate_parameters_ex(ret, prime_len, generator, cb);
450916
-#endif
450916
     return dh_builtin_genparams(ret, prime_len, generator, cb);
450916
 }
450916
 
450916
@@ -126,6 +122,18 @@ static int dh_builtin_genparams(DH *ret,
450916
     int g, ok = -1;
450916
     BN_CTX *ctx = NULL;
450916
 
450916
+#ifdef OPENSSL_FIPS
450916
+    if (FIPS_selftest_failed()) {
450916
+        FIPSerr(FIPS_F_DH_BUILTIN_GENPARAMS, FIPS_R_FIPS_SELFTEST_FAILED);
450916
+        return 0;
450916
+    }
450916
+
450916
+    if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) {
450916
+        DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_KEY_SIZE_TOO_SMALL);
450916
+        goto err;
450916
+    }
450916
+#endif
450916
+
450916
     ctx = BN_CTX_new();
450916
     if (ctx == NULL)
450916
         goto err;
450916
diff -up openssl-1.0.2i/crypto/dh/dh.h.fips openssl-1.0.2i/crypto/dh/dh.h
450916
--- openssl-1.0.2i/crypto/dh/dh.h.fips	2016-09-22 13:35:56.863217447 +0200
450916
+++ openssl-1.0.2i/crypto/dh/dh.h	2016-09-22 13:35:57.009220813 +0200
450916
@@ -77,6 +77,8 @@
450916
 #  define OPENSSL_DH_MAX_MODULUS_BITS    10000
450916
 # endif
450916
 
450916
+# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024
450916
+
450916
 # define DH_FLAG_CACHE_MONT_P     0x01
450916
 
450916
 /*
450916
diff -up openssl-1.0.2i/crypto/dh/dh_key.c.fips openssl-1.0.2i/crypto/dh/dh_key.c
450916
--- openssl-1.0.2i/crypto/dh/dh_key.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/dh/dh_key.c	2016-09-22 13:35:57.009220813 +0200
450916
@@ -61,6 +61,9 @@
450916
 #include <openssl/bn.h>
450916
 #include <openssl/rand.h>
450916
 #include <openssl/dh.h>
450916
+#ifdef OPENSSL_FIPS
450916
+# include <openssl/fips.h>
450916
+#endif
450916
 
450916
 static int generate_key(DH *dh);
450916
 static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
450916
@@ -97,7 +100,7 @@ int DH_compute_key(unsigned char *key, c
450916
 int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh)
450916
 {
450916
     int rv, pad;
450916
-    rv = dh->meth->compute_key(key, pub_key, dh);
450916
+    rv = DH_compute_key(key, pub_key, dh);
450916
     if (rv <= 0)
450916
         return rv;
450916
     pad = BN_num_bytes(dh->p) - rv;
450916
@@ -115,7 +118,7 @@ static DH_METHOD dh_ossl = {
450916
     dh_bn_mod_exp,
450916
     dh_init,
450916
     dh_finish,
450916
-    0,
450916
+    DH_FLAG_FIPS_METHOD,
450916
     NULL,
450916
     NULL
450916
 };
450916
@@ -134,6 +137,14 @@ static int generate_key(DH *dh)
450916
     BN_MONT_CTX *mont = NULL;
450916
     BIGNUM *pub_key = NULL, *priv_key = NULL;
450916
 
450916
+#ifdef OPENSSL_FIPS
450916
+    if (FIPS_mode()
450916
+        && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) {
450916
+        DHerr(DH_F_GENERATE_KEY, DH_R_KEY_SIZE_TOO_SMALL);
450916
+        return 0;
450916
+    }
450916
+#endif
450916
+
450916
     ctx = BN_CTX_new();
450916
     if (ctx == NULL)
450916
         goto err;
450916
@@ -217,6 +228,13 @@ static int compute_key(unsigned char *ke
450916
         DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE);
450916
         goto err;
450916
     }
450916
+#ifdef OPENSSL_FIPS
450916
+    if (FIPS_mode()
450916
+        && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) {
450916
+        DHerr(DH_F_COMPUTE_KEY, DH_R_KEY_SIZE_TOO_SMALL);
450916
+        goto err;
450916
+    }
450916
+#endif
450916
 
450916
     ctx = BN_CTX_new();
450916
     if (ctx == NULL)
450916
@@ -277,6 +295,9 @@ static int dh_bn_mod_exp(const DH *dh, B
450916
 
450916
 static int dh_init(DH *dh)
450916
 {
450916
+#ifdef OPENSSL_FIPS
450916
+    FIPS_selftest_check();
450916
+#endif
450916
     dh->flags |= DH_FLAG_CACHE_MONT_P;
450916
     return (1);
450916
 }
450916
diff -up openssl-1.0.2i/crypto/dh/dh_lib.c.fips openssl-1.0.2i/crypto/dh/dh_lib.c
450916
--- openssl-1.0.2i/crypto/dh/dh_lib.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/dh/dh_lib.c	2016-09-22 13:35:57.009220813 +0200
450916
@@ -80,14 +80,7 @@ void DH_set_default_method(const DH_METH
450916
 const DH_METHOD *DH_get_default_method(void)
450916
 {
450916
     if (!default_DH_method) {
450916
-#ifdef OPENSSL_FIPS
450916
-        if (FIPS_mode())
450916
-            return FIPS_dh_openssl();
450916
-        else
450916
-            return DH_OpenSSL();
450916
-#else
450916
         default_DH_method = DH_OpenSSL();
450916
-#endif
450916
     }
450916
     return default_DH_method;
450916
 }
450916
diff -up openssl-1.0.2i/crypto/dsa/dsa_err.c.fips openssl-1.0.2i/crypto/dsa/dsa_err.c
450916
--- openssl-1.0.2i/crypto/dsa/dsa_err.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/dsa/dsa_err.c	2016-09-22 13:35:57.009220813 +0200
450916
@@ -74,6 +74,8 @@ static ERR_STRING_DATA DSA_str_functs[]
450916
     {ERR_FUNC(DSA_F_DO_DSA_PRINT), "DO_DSA_PRINT"},
450916
     {ERR_FUNC(DSA_F_DSAPARAMS_PRINT), "DSAparams_print"},
450916
     {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"},
450916
+    {ERR_FUNC(DSA_F_DSA_BUILTIN_KEYGEN), "dsa_builtin_keygen"},
450916
+    {ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN), "dsa_builtin_paramgen"},
450916
     {ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN2), "DSA_BUILTIN_PARAMGEN2"},
450916
     {ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"},
450916
     {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"},
450916
@@ -109,6 +111,8 @@ static ERR_STRING_DATA DSA_str_reasons[]
450916
     {ERR_REASON(DSA_R_DECODE_ERROR), "decode error"},
450916
     {ERR_REASON(DSA_R_INVALID_DIGEST_TYPE), "invalid digest type"},
450916
     {ERR_REASON(DSA_R_INVALID_PARAMETERS), "invalid parameters"},
450916
+    {ERR_REASON(DSA_R_KEY_SIZE_INVALID), "key size invalid"},
450916
+    {ERR_REASON(DSA_R_KEY_SIZE_TOO_SMALL), "key size too small"},
450916
     {ERR_REASON(DSA_R_MISSING_PARAMETERS), "missing parameters"},
450916
     {ERR_REASON(DSA_R_MODULUS_TOO_LARGE), "modulus too large"},
450916
     {ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES), "need new setup values"},
450916
diff -up openssl-1.0.2i/crypto/dsa/dsa_gen.c.fips openssl-1.0.2i/crypto/dsa/dsa_gen.c
450916
--- openssl-1.0.2i/crypto/dsa/dsa_gen.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/dsa/dsa_gen.c	2016-09-22 13:42:54.389840662 +0200
450916
@@ -91,6 +91,16 @@
450916
 #  include <openssl/fips.h>
450916
 # endif
450916
 
450916
+# ifndef OPENSSL_FIPS
450916
+static int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits,
450916
+                                const EVP_MD *evpmd, unsigned char *seed,
450916
+                                int seed_len, BIGNUM **p_ret, BIGNUM **q_ret,
450916
+                                int *counter_ret, BN_GENCB *cb);
450916
+static int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q,
450916
+                               BIGNUM **g_ret, unsigned long *h_ret,
450916
+                               BN_GENCB *cb);
450916
+# endif
450916
+
450916
 int DSA_generate_parameters_ex(DSA *ret, int bits,
450916
                                const unsigned char *seed_in, int seed_len,
450916
                                int *counter_ret, unsigned long *h_ret,
450916
@@ -106,83 +116,146 @@ int DSA_generate_parameters_ex(DSA *ret,
450916
     if (ret->meth->dsa_paramgen)
450916
         return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
450916
                                        counter_ret, h_ret, cb);
450916
-# ifdef OPENSSL_FIPS
450916
-    else if (FIPS_mode()) {
450916
-        return FIPS_dsa_generate_parameters_ex(ret, bits,
450916
-                                               seed_in, seed_len,
450916
-                                               counter_ret, h_ret, cb);
450916
-    }
450916
-# endif
450916
     else {
450916
         const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1();
450916
         size_t qbits = EVP_MD_size(evpmd) * 8;
450916
 
450916
         return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
450916
-                                    seed_in, seed_len, NULL, counter_ret,
450916
+                                    seed_in, seed_len, counter_ret,
450916
                                     h_ret, cb);
450916
     }
450916
 }
450916
 
450916
+# ifdef OPENSSL_FIPS
450916
+int FIPS_dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
450916
+                              const EVP_MD *evpmd,
450916
+                              const unsigned char *seed_in, size_t seed_len,
450916
+                              int *counter_ret, unsigned long *h_ret,
450916
+                              BN_GENCB *cb)
450916
+{
450916
+    return dsa_builtin_paramgen(ret, bits, qbits,
450916
+                                evpmd, seed_in, seed_len,
450916
+                                counter_ret, h_ret, cb);
450916
+}
450916
+# endif
450916
+
450916
 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
450916
                          const EVP_MD *evpmd, const unsigned char *seed_in,
450916
-                         size_t seed_len, unsigned char *seed_out,
450916
+                         size_t seed_len,
450916
                          int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
450916
 {
450916
     int ok = 0;
450916
     unsigned char seed[SHA256_DIGEST_LENGTH];
450916
+    BIGNUM *g = NULL, *q = NULL, *p = NULL;
450916
+    size_t qsize = qbits >> 3;
450916
+    BN_CTX *ctx = NULL;
450916
+    
450916
+# ifdef OPENSSL_FIPS
450916
+    if (FIPS_selftest_failed()) {
450916
+        FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN, FIPS_R_FIPS_SELFTEST_FAILED);
450916
+        goto err;
450916
+    }
450916
+
450916
+    if (FIPS_module_mode() &&
450916
+        (bits != 1024 || qbits != 160) &&
450916
+        (bits != 2048 || qbits != 224) &&
450916
+        (bits != 2048 || qbits != 256) && (bits != 3072 || qbits != 256)) {
450916
+        DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_INVALID);
450916
+        goto err;
450916
+    }
450916
+# endif
450916
+    if (seed_len && (seed_len < (size_t)qsize))
450916
+        seed_in = NULL;         /* seed buffer too small -- ignore */
450916
+    if (seed_len > sizeof(seed))
450916
+        seed_len = sizeof(seed); /* App. 2.2 of FIPS PUB 186 allows larger SEED,
450916
+                                  * but our internal buffers are restricted to 256 bits*/
450916
+    if (seed_in != NULL)
450916
+        memcpy(seed, seed_in, seed_len);
450916
+    else
450916
+        seed_len = 0;
450916
+        
450916
+    if ((ctx = BN_CTX_new()) == NULL)
450916
+        goto err;
450916
+ 
450916
+    BN_CTX_start(ctx);
450916
+ 
450916
+    if (!FIPS_dsa_generate_pq(ctx, bits, qbits, evpmd,
450916
+                              seed, seed_len, &p, &q, counter_ret, cb))
450916
+        goto err;
450916
+ 
450916
+    if (!FIPS_dsa_generate_g(ctx, p, q, &g, h_ret, cb))
450916
+        goto err;
450916
+ 
450916
+    ok = 1;
450916
+ err:
450916
+    if (ok) {
450916
+        if (ret->p) {
450916
+            BN_free(ret->p);
450916
+            ret->p = NULL;
450916
+        }
450916
+        if (ret->q) {
450916
+            BN_free(ret->q);
450916
+            ret->q = NULL;
450916
+        }
450916
+        if (ret->g) {
450916
+            BN_free(ret->g);
450916
+            ret->g = NULL;
450916
+        }
450916
+        ret->p = BN_dup(p);
450916
+        ret->q = BN_dup(q);
450916
+        ret->g = BN_dup(g);
450916
+        if (ret->p == NULL || ret->q == NULL || ret->g == NULL)
450916
+            ok = 0;
450916
+    }
450916
+    if (ctx) {
450916
+        BN_CTX_end(ctx);
450916
+        BN_CTX_free(ctx);
450916
+    }
450916
+    return ok;
450916
+}
450916
+
450916
+# ifndef OPENSSL_FIPS
450916
+static
450916
+# endif
450916
+int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits,
450916
+                         const EVP_MD *evpmd, unsigned char *seed,
450916
+                         int seed_len, BIGNUM **p_ret, BIGNUM **q_ret,
450916
+                         int *counter_ret, BN_GENCB *cb)
450916
+{
450916
+    int ok = 0;
450916
     unsigned char md[SHA256_DIGEST_LENGTH];
450916
-    unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
450916
+    unsigned char buf[SHA256_DIGEST_LENGTH];
450916
     BIGNUM *r0, *W, *X, *c, *test;
450916
-    BIGNUM *g = NULL, *q = NULL, *p = NULL;
450916
-    BN_MONT_CTX *mont = NULL;
450916
-    int i, k, n = 0, m = 0, qsize = qbits >> 3;
450916
+    BIGNUM *q = NULL, *p = NULL;
450916
+    int i, k, b, n = 0, m = 0, qsize = qbits >> 3;
450916
     int counter = 0;
450916
     int r = 0;
450916
-    BN_CTX *ctx = NULL;
450916
-    unsigned int h = 2;
450916
 
450916
     if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
450916
         qsize != SHA256_DIGEST_LENGTH)
450916
         /* invalid q size */
450916
         return 0;
450916
 
450916
-    if (evpmd == NULL)
450916
-        /* use SHA1 as default */
450916
+    if (evpmd == NULL) {
450916
+        if (qbits <= 160)
450916
         evpmd = EVP_sha1();
450916
+        else if (qbits <= 224)
450916
+            evpmd = EVP_sha224();
450916
+        else
450916
+            evpmd = EVP_sha256();
450916
+    }
450916
 
450916
     if (bits < 512)
450916
         bits = 512;
450916
 
450916
     bits = (bits + 63) / 64 * 64;
450916
 
450916
-    /*
450916
-     * NB: seed_len == 0 is special case: copy generated seed to seed_in if
450916
-     * it is not NULL.
450916
-     */
450916
-    if (seed_len && (seed_len < (size_t)qsize))
450916
-        seed_in = NULL;         /* seed buffer too small -- ignore */
450916
-    if (seed_len > (size_t)qsize)
450916
-        seed_len = qsize;       /* App. 2.2 of FIPS PUB 186 allows larger
450916
-                                 * SEED, but our internal buffers are
450916
-                                 * restricted to 160 bits */
450916
-    if (seed_in != NULL)
450916
-        memcpy(seed, seed_in, seed_len);
450916
-
450916
-    if ((mont = BN_MONT_CTX_new()) == NULL)
450916
-        goto err;
450916
-
450916
-    if ((ctx = BN_CTX_new()) == NULL)
450916
-        goto err;
450916
-
450916
-    BN_CTX_start(ctx);
450916
-
450916
     r0 = BN_CTX_get(ctx);
450916
-    g = BN_CTX_get(ctx);
450916
     W = BN_CTX_get(ctx);
450916
-    q = BN_CTX_get(ctx);
450916
+    *q_ret = q = BN_CTX_get(ctx);
450916
     X = BN_CTX_get(ctx);
450916
     c = BN_CTX_get(ctx);
450916
-    p = BN_CTX_get(ctx);
450916
+    *p_ret = p = BN_CTX_get(ctx);
450916
     test = BN_CTX_get(ctx);
450916
 
450916
     if (test == NULL)
450916
@@ -191,15 +264,20 @@ int dsa_builtin_paramgen(DSA *ret, size_
450916
     if (!BN_lshift(test, BN_value_one(), bits - 1))
450916
         goto err;
450916
 
450916
+    /* step 3 n = \lceil bits / qbits \rceil - 1 */
450916
+    n = (bits + qbits - 1) / qbits - 1;
450916
+    /* step 4 b = bits - 1 - n * qbits */
450916
+    b = bits - 1 - n * qbits;
450916
+
450916
     for (;;) {
450916
         for (;;) {              /* find q */
450916
             int seed_is_random;
450916
 
450916
-            /* step 1 */
450916
+            /* step 5 generate seed */
450916
             if (!BN_GENCB_call(cb, 0, m++))
450916
                 goto err;
450916
 
450916
-            if (!seed_len || !seed_in) {
450916
+            if (!seed_len) {
450916
                 if (RAND_bytes(seed, qsize) <= 0)
450916
                     goto err;
450916
                 seed_is_random = 1;
450916
@@ -209,29 +287,18 @@ int dsa_builtin_paramgen(DSA *ret, size_
450916
                                  * be bad */
450916
             }
450916
             memcpy(buf, seed, qsize);
450916
-            memcpy(buf2, seed, qsize);
450916
-            /* precompute "SEED + 1" for step 7: */
450916
-            for (i = qsize - 1; i >= 0; i--) {
450916
-                buf[i]++;
450916
-                if (buf[i] != 0)
450916
-                    break;
450916
-            }
450916
 
450916
-            /* step 2 */
450916
+            /* step 6 U = hash(seed) */
450916
             if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL))
450916
                 goto err;
450916
-            if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL))
450916
-                goto err;
450916
-            for (i = 0; i < qsize; i++)
450916
-                md[i] ^= buf2[i];
450916
 
450916
-            /* step 3 */
450916
+            /* step 7 q = 2^(qbits-1) + U + 1 - (U mod 2) */
450916
             md[0] |= 0x80;
450916
             md[qsize - 1] |= 0x01;
450916
             if (!BN_bin2bn(md, qsize, q))
450916
                 goto err;
450916
 
450916
-            /* step 4 */
450916
+            /* step 8 test for prime (64 round of Rabin-Miller) */
450916
             r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
450916
                                         seed_is_random, cb);
450916
             if (r > 0)
450916
@@ -239,8 +306,6 @@ int dsa_builtin_paramgen(DSA *ret, size_
450916
             if (r != 0)
450916
                 goto err;
450916
 
450916
-            /* do a callback call */
450916
-            /* step 5 */
450916
         }
450916
 
450916
         if (!BN_GENCB_call(cb, 2, 0))
450916
@@ -248,19 +313,16 @@ int dsa_builtin_paramgen(DSA *ret, size_
450916
         if (!BN_GENCB_call(cb, 3, 0))
450916
             goto err;
450916
 
450916
-        /* step 6 */
450916
+        /* step 11 */
450916
         counter = 0;
450916
-        /* "offset = 2" */
450916
-
450916
-        n = (bits - 1) / 160;
450916
+        /* "offset = 1" */
450916
 
450916
         for (;;) {
450916
             if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
450916
                 goto err;
450916
 
450916
-            /* step 7 */
450916
+            /* step 11.1, 11.2 obtain W */
450916
             BN_zero(W);
450916
-            /* now 'buf' contains "SEED + offset - 1" */
450916
             for (k = 0; k <= n; k++) {
450916
                 /*
450916
                  * obtain "SEED + offset + k" by incrementing:
450916
@@ -274,36 +336,37 @@ int dsa_builtin_paramgen(DSA *ret, size_
450916
                 if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL))
450916
                     goto err;
450916
 
450916
-                /* step 8 */
450916
                 if (!BN_bin2bn(md, qsize, r0))
450916
                     goto err;
450916
-                if (!BN_lshift(r0, r0, (qsize << 3) * k))
450916
+                if (k == n)
450916
+                    BN_mask_bits(r0, b);
450916
+                if (!BN_lshift(r0, r0, qbits * k))
450916
                     goto err;
450916
                 if (!BN_add(W, W, r0))
450916
                     goto err;
450916
             }
450916
 
450916
-            /* more of step 8 */
450916
-            if (!BN_mask_bits(W, bits - 1))
450916
-                goto err;
450916
+            /* step 11.3 X = W + 2^(L-1) */
450916
             if (!BN_copy(X, W))
450916
                 goto err;
450916
             if (!BN_add(X, X, test))
450916
                 goto err;
450916
 
450916
-            /* step 9 */
450916
+            /* step 11.4 c = X mod 2*q */
450916
             if (!BN_lshift1(r0, q))
450916
                 goto err;
450916
             if (!BN_mod(c, X, r0, ctx))
450916
                 goto err;
450916
+
450916
+            /* step 11.5 p = X - (c - 1) */
450916
             if (!BN_sub(r0, c, BN_value_one()))
450916
                 goto err;
450916
             if (!BN_sub(p, X, r0))
450916
                 goto err;
450916
 
450916
-            /* step 10 */
450916
+            /* step 11.6 */
450916
             if (BN_cmp(p, test) >= 0) {
450916
-                /* step 11 */
450916
+                /* step 11.7 */
450916
                 r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
450916
                 if (r > 0)
450916
                     goto end;   /* found it */
450916
@@ -311,12 +374,12 @@ int dsa_builtin_paramgen(DSA *ret, size_
450916
                     goto err;
450916
             }
450916
 
450916
-            /* step 13 */
450916
+            /* step 11.9 */
450916
             counter++;
450916
             /* "offset = offset + n + 1" */
450916
 
450916
-            /* step 14 */
450916
-            if (counter >= 4096)
450916
+            /* step 12 */
450916
+            if (counter >= 4 * bits)
450916
                 break;
450916
         }
450916
     }
450916
@@ -324,7 +387,33 @@ int dsa_builtin_paramgen(DSA *ret, size_
450916
     if (!BN_GENCB_call(cb, 2, 1))
450916
         goto err;
450916
 
450916
-    /* We now need to generate g */
450916
+    ok = 1;
450916
+ err:
450916
+    if (ok) {
450916
+        if (counter_ret != NULL)
450916
+            *counter_ret = counter;
450916
+    }
450916
+    return ok;
450916
+}
450916
+
450916
+# ifndef OPENSSL_FIPS
450916
+static
450916
+# endif
450916
+int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q,
450916
+                        BIGNUM **g_ret, unsigned long *h_ret, BN_GENCB *cb)
450916
+{
450916
+    int ok = 0;
450916
+    BIGNUM *r0, *test, *g = NULL;
450916
+    BN_MONT_CTX *mont;
450916
+    unsigned int h = 2;
450916
+
450916
+    if ((mont = BN_MONT_CTX_new()) == NULL)
450916
+        goto err;
450916
+
450916
+    r0 = BN_CTX_get(ctx);
450916
+    *g_ret = g = BN_CTX_get(ctx);
450916
+    test = BN_CTX_get(ctx);
450916
+
450916
     /* Set r0=(p-1)/q */
450916
     if (!BN_sub(test, p, BN_value_one()))
450916
         goto err;
450916
@@ -353,46 +442,14 @@ int dsa_builtin_paramgen(DSA *ret, size_
450916
     ok = 1;
450916
  err:
450916
     if (ok) {
450916
-        if (ret->p)
450916
-            BN_free(ret->p);
450916
-        if (ret->q)
450916
-            BN_free(ret->q);
450916
-        if (ret->g)
450916
-            BN_free(ret->g);
450916
-        ret->p = BN_dup(p);
450916
-        ret->q = BN_dup(q);
450916
-        ret->g = BN_dup(g);
450916
-        if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
450916
-            ok = 0;
450916
-            goto err;
450916
-        }
450916
-        if (counter_ret != NULL)
450916
-            *counter_ret = counter;
450916
         if (h_ret != NULL)
450916
             *h_ret = h;
450916
-        if (seed_out)
450916
-            memcpy(seed_out, seed, qsize);
450916
-    }
450916
-    if (ctx) {
450916
-        BN_CTX_end(ctx);
450916
-        BN_CTX_free(ctx);
450916
     }
450916
     if (mont != NULL)
450916
         BN_MONT_CTX_free(mont);
450916
     return ok;
450916
 }
450916
 
450916
-# ifdef OPENSSL_FIPS
450916
-#  undef fips_dsa_builtin_paramgen2
450916
-extern int fips_dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
450916
-                                      const EVP_MD *evpmd,
450916
-                                      const unsigned char *seed_in,
450916
-                                      size_t seed_len, int idx,
450916
-                                      unsigned char *seed_out,
450916
-                                      int *counter_ret, unsigned long *h_ret,
450916
-                                      BN_GENCB *cb);
450916
-# endif
450916
-
450916
 /*
450916
  * This is a parameter generation algorithm for the DSA2 algorithm as
450916
  * described in FIPS 186-3.
450916
@@ -418,14 +475,6 @@ int dsa_builtin_paramgen2(DSA *ret, size
450916
     EVP_MD_CTX mctx;
450916
     unsigned int h = 2;
450916
 
450916
-# ifdef OPENSSL_FIPS
450916
-
450916
-    if (FIPS_mode())
450916
-        return fips_dsa_builtin_paramgen2(ret, L, N, evpmd,
450916
-                                          seed_in, seed_len, idx,
450916
-                                          seed_out, counter_ret, h_ret, cb);
450916
-# endif
450916
-
450916
     EVP_MD_CTX_init(&mctx);
450916
 
450916
     if (evpmd == NULL) {
450916
diff -up openssl-1.0.2i/crypto/dsa/dsa.h.fips openssl-1.0.2i/crypto/dsa/dsa.h
450916
--- openssl-1.0.2i/crypto/dsa/dsa.h.fips	2016-09-22 13:35:56.789215742 +0200
450916
+++ openssl-1.0.2i/crypto/dsa/dsa.h	2016-09-22 13:35:57.010220836 +0200
450916
@@ -88,6 +88,8 @@
450916
 #  define OPENSSL_DSA_MAX_MODULUS_BITS   10000
450916
 # endif
450916
 
450916
+# define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024
450916
+
450916
 # define DSA_FLAG_CACHE_MONT_P   0x01
450916
 /*
450916
  * new with 0.9.7h; the built-in DSA implementation now uses constant time
450916
@@ -265,6 +267,20 @@ int DSA_print_fp(FILE *bp, const DSA *x,
450916
 DH *DSA_dup_DH(const DSA *r);
450916
 # endif
450916
 
450916
+# ifdef OPENSSL_FIPS
450916
+int FIPS_dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
450916
+                              const EVP_MD *evpmd,
450916
+                              const unsigned char *seed_in,
450916
+                              size_t seed_len, int *counter_ret,
450916
+                              unsigned long *h_ret, BN_GENCB *cb);
450916
+int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits,
450916
+                         const EVP_MD *evpmd, unsigned char *seed,
450916
+                         int seed_len, BIGNUM **p_ret, BIGNUM **q_ret,
450916
+                         int *counter_ret, BN_GENCB *cb);
450916
+int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q, BIGNUM **g_ret,
450916
+                            unsigned long *h_ret, BN_GENCB *cb);
450916
+# endif
450916
+
450916
 # define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \
450916
         EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
450916
                                 EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)
450916
@@ -287,11 +303,14 @@ void ERR_load_DSA_strings(void);
450916
 # define DSA_F_DO_DSA_PRINT                               104
450916
 # define DSA_F_DSAPARAMS_PRINT                            100
450916
 # define DSA_F_DSAPARAMS_PRINT_FP                         101
450916
-# define DSA_F_DSA_BUILTIN_PARAMGEN2                      126
450916
+# define DSA_F_DSA_BUILTIN_KEYGEN                         124
450916
+# define DSA_F_DSA_BUILTIN_PARAMGEN                       123
450916
+# define DSA_F_DSA_BUILTIN_PARAMGEN2                      226
450916
 # define DSA_F_DSA_DO_SIGN                                112
450916
 # define DSA_F_DSA_DO_VERIFY                              113
450916
-# define DSA_F_DSA_GENERATE_KEY                           124
450916
-# define DSA_F_DSA_GENERATE_PARAMETERS_EX                 123
450916
+# define DSA_F_DSA_GENERATE_KEY                           126
450916
+# define DSA_F_DSA_GENERATE_PARAMETERS_EX                 127
450916
+# define DSA_F_DSA_GENERATE_PARAMETERS   /* unused */     125
450916
 # define DSA_F_DSA_NEW_METHOD                             103
450916
 # define DSA_F_DSA_PARAM_DECODE                           119
450916
 # define DSA_F_DSA_PRINT_FP                               105
450916
@@ -317,12 +336,16 @@ void ERR_load_DSA_strings(void);
450916
 # define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE                100
450916
 # define DSA_R_DECODE_ERROR                               104
450916
 # define DSA_R_INVALID_DIGEST_TYPE                        106
450916
-# define DSA_R_INVALID_PARAMETERS                         112
450916
+# define DSA_R_INVALID_PARAMETERS                         212
450916
+# define DSA_R_KEY_SIZE_INVALID                           201
450916
+# define DSA_R_KEY_SIZE_TOO_SMALL                         110
450916
 # define DSA_R_MISSING_PARAMETERS                         101
450916
 # define DSA_R_MODULUS_TOO_LARGE                          103
450916
-# define DSA_R_NEED_NEW_SETUP_VALUES                      110
450916
+# define DSA_R_NEED_NEW_SETUP_VALUES                      112
450916
 # define DSA_R_NON_FIPS_DSA_METHOD                        111
450916
+# define DSA_R_NON_FIPS_METHOD                            111
450916
 # define DSA_R_NO_PARAMETERS_SET                          107
450916
+# define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE /* unused */ 112
450916
 # define DSA_R_PARAMETER_ENCODING_ERROR                   105
450916
 # define DSA_R_Q_NOT_PRIME                                113
450916
 
450916
diff -up openssl-1.0.2i/crypto/dsa/dsa_key.c.fips openssl-1.0.2i/crypto/dsa/dsa_key.c
450916
--- openssl-1.0.2i/crypto/dsa/dsa_key.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/dsa/dsa_key.c	2016-09-22 13:35:57.010220836 +0200
450916
@@ -66,6 +66,34 @@
450916
 
450916
 # ifdef OPENSSL_FIPS
450916
 #  include <openssl/fips.h>
450916
+#  include <openssl/evp.h>
450916
+
450916
+static int fips_check_dsa(DSA *dsa)
450916
+{
450916
+    EVP_PKEY *pk;
450916
+    unsigned char tbs[] = "DSA Pairwise Check Data";
450916
+    int ret = 0;
450916
+
450916
+    if ((pk = EVP_PKEY_new()) == NULL)
450916
+        goto err;
450916
+
450916
+    EVP_PKEY_set1_DSA(pk, dsa);
450916
+
450916
+    if (fips_pkey_signature_test(pk, tbs, -1, NULL, 0, NULL, 0, NULL))
450916
+        ret = 1;
450916
+
450916
+ err:
450916
+    if (ret == 0) {
450916
+        FIPSerr(FIPS_F_FIPS_CHECK_DSA, FIPS_R_PAIRWISE_TEST_FAILED);
450916
+        fips_set_selftest_fail();
450916
+    }
450916
+
450916
+    if (pk)
450916
+        EVP_PKEY_free(pk);
450916
+
450916
+    return ret;
450916
+}
450916
+
450916
 # endif
450916
 
450916
 static int dsa_builtin_keygen(DSA *dsa);
450916
@@ -81,10 +109,6 @@ int DSA_generate_key(DSA *dsa)
450916
 # endif
450916
     if (dsa->meth->dsa_keygen)
450916
         return dsa->meth->dsa_keygen(dsa);
450916
-# ifdef OPENSSL_FIPS
450916
-    if (FIPS_mode())
450916
-        return FIPS_dsa_generate_key(dsa);
450916
-# endif
450916
     return dsa_builtin_keygen(dsa);
450916
 }
450916
 
450916
@@ -94,6 +118,14 @@ static int dsa_builtin_keygen(DSA *dsa)
450916
     BN_CTX *ctx = NULL;
450916
     BIGNUM *pub_key = NULL, *priv_key = NULL;
450916
 
450916
+# ifdef OPENSSL_FIPS
450916
+    if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)
450916
+        && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) {
450916
+        DSAerr(DSA_F_DSA_BUILTIN_KEYGEN, DSA_R_KEY_SIZE_TOO_SMALL);
450916
+        goto err;
450916
+    }
450916
+# endif
450916
+
450916
     if ((ctx = BN_CTX_new()) == NULL)
450916
         goto err;
450916
 
450916
@@ -131,6 +163,13 @@ static int dsa_builtin_keygen(DSA *dsa)
450916
 
450916
     dsa->priv_key = priv_key;
450916
     dsa->pub_key = pub_key;
450916
+# ifdef OPENSSL_FIPS
450916
+    if (FIPS_mode() && !fips_check_dsa(dsa)) {
450916
+        dsa->pub_key = NULL;
450916
+        dsa->priv_key = NULL;
450916
+        goto err;
450916
+    }
450916
+# endif
450916
     ok = 1;
450916
 
450916
  err:
450916
diff -up openssl-1.0.2i/crypto/dsa/dsa_lib.c.fips openssl-1.0.2i/crypto/dsa/dsa_lib.c
450916
--- openssl-1.0.2i/crypto/dsa/dsa_lib.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/dsa/dsa_lib.c	2016-09-22 13:35:57.010220836 +0200
450916
@@ -86,14 +86,7 @@ void DSA_set_default_method(const DSA_ME
450916
 const DSA_METHOD *DSA_get_default_method(void)
450916
 {
450916
     if (!default_DSA_method) {
450916
-#ifdef OPENSSL_FIPS
450916
-        if (FIPS_mode())
450916
-            return FIPS_dsa_openssl();
450916
-        else
450916
-            return DSA_OpenSSL();
450916
-#else
450916
         default_DSA_method = DSA_OpenSSL();
450916
-#endif
450916
     }
450916
     return default_DSA_method;
450916
 }
450916
diff -up openssl-1.0.2i/crypto/dsa/dsa_locl.h.fips openssl-1.0.2i/crypto/dsa/dsa_locl.h
450916
--- openssl-1.0.2i/crypto/dsa/dsa_locl.h.fips	2016-09-22 13:35:56.790215765 +0200
450916
+++ openssl-1.0.2i/crypto/dsa/dsa_locl.h	2016-09-22 13:35:57.010220836 +0200
450916
@@ -56,7 +56,7 @@
450916
 
450916
 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
450916
                          const EVP_MD *evpmd, const unsigned char *seed_in,
450916
-                         size_t seed_len, unsigned char *seed_out,
450916
+                         size_t seed_len,
450916
                          int *counter_ret, unsigned long *h_ret,
450916
                          BN_GENCB *cb);
450916
 
450916
diff -up openssl-1.0.2i/crypto/dsa/dsa_ossl.c.fips openssl-1.0.2i/crypto/dsa/dsa_ossl.c
450916
--- openssl-1.0.2i/crypto/dsa/dsa_ossl.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/dsa/dsa_ossl.c	2016-09-22 13:35:57.010220836 +0200
450916
@@ -65,6 +65,9 @@
450916
 #include <openssl/dsa.h>
450916
 #include <openssl/rand.h>
450916
 #include <openssl/asn1.h>
450916
+#ifdef OPENSSL_FIPS
450916
+# include <openssl/fips.h>
450916
+#endif
450916
 
450916
 static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
450916
 static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
450916
@@ -83,7 +86,7 @@ static DSA_METHOD openssl_dsa_meth = {
450916
     NULL,                       /* dsa_bn_mod_exp, */
450916
     dsa_init,
450916
     dsa_finish,
450916
-    0,
450916
+    DSA_FLAG_FIPS_METHOD,
450916
     NULL,
450916
     NULL,
450916
     NULL
450916
@@ -140,6 +143,19 @@ static DSA_SIG *dsa_do_sign(const unsign
450916
     DSA_SIG *ret = NULL;
450916
     int noredo = 0;
450916
 
450916
+#ifdef OPENSSL_FIPS
450916
+    if (FIPS_selftest_failed()) {
450916
+        FIPSerr(FIPS_F_DSA_DO_SIGN, FIPS_R_FIPS_SELFTEST_FAILED);
450916
+        return NULL;
450916
+    }
450916
+
450916
+    if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)
450916
+        && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) {
450916
+        DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL);
450916
+        return NULL;
450916
+    }
450916
+#endif
450916
+
450916
     BN_init(&m);
450916
     BN_init(&xr);
450916
 
450916
@@ -335,6 +351,18 @@ static int dsa_do_verify(const unsigned
450916
         DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE);
450916
         return -1;
450916
     }
450916
+#ifdef OPENSSL_FIPS
450916
+    if (FIPS_selftest_failed()) {
450916
+        FIPSerr(FIPS_F_DSA_DO_VERIFY, FIPS_R_FIPS_SELFTEST_FAILED);
450916
+        return -1;
450916
+    }
450916
+
450916
+    if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)
450916
+        && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) {
450916
+        DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL);
450916
+        return -1;
450916
+    }
450916
+#endif
450916
 
450916
     if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
450916
         DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE);
450916
@@ -415,6 +443,9 @@ static int dsa_do_verify(const unsigned
450916
 
450916
 static int dsa_init(DSA *dsa)
450916
 {
450916
+#ifdef OPENSSL_FIPS
450916
+    FIPS_selftest_check();
450916
+#endif
450916
     dsa->flags |= DSA_FLAG_CACHE_MONT_P;
450916
     return (1);
450916
 }
450916
diff -up openssl-1.0.2i/crypto/dsa/dsa_pmeth.c.fips openssl-1.0.2i/crypto/dsa/dsa_pmeth.c
450916
--- openssl-1.0.2i/crypto/dsa/dsa_pmeth.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/dsa/dsa_pmeth.c	2016-09-22 13:35:57.010220836 +0200
450916
@@ -253,7 +253,7 @@ static int pkey_dsa_paramgen(EVP_PKEY_CT
450916
     if (!dsa)
450916
         return 0;
450916
     ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd,
450916
-                               NULL, 0, NULL, NULL, NULL, pcb);
450916
+                               NULL, 0, NULL, NULL, pcb);
450916
     if (ret)
450916
         EVP_PKEY_assign_DSA(pkey, dsa);
450916
     else
450916
diff -up openssl-1.0.2i/crypto/dsa/dsatest.c.fips openssl-1.0.2i/crypto/dsa/dsatest.c
450916
--- openssl-1.0.2i/crypto/dsa/dsatest.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/dsa/dsatest.c	2016-09-22 13:35:57.010220836 +0200
450916
@@ -100,36 +100,41 @@ static int MS_CALLBACK dsa_cb(int p, int
450916
  * PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1
450916
  */
450916
 static unsigned char seed[20] = {
450916
-    0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, 0x1b, 0x40,
450916
-    0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3,
450916
+    0x02, 0x47, 0x11, 0x92, 0x11, 0x88, 0xC8, 0xFB, 0xAF, 0x48, 0x4C, 0x62,
450916
+    0xDF, 0xA5, 0xBE, 0xA0, 0xA4, 0x3C, 0x56, 0xE3,
450916
 };
450916
 
450916
 static unsigned char out_p[] = {
450916
-    0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa,
450916
-    0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 0xcb,
450916
-    0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 0xf7,
450916
-    0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5,
450916
-    0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf,
450916
-    0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 0xac,
450916
-    0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 0xc2,
450916
-    0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91,
450916
+    0xAC, 0xCB, 0x1E, 0x63, 0x60, 0x69, 0x0C, 0xFB, 0x06, 0x19, 0x68, 0x3E,
450916
+    0xA5, 0x01, 0x5A, 0xA2, 0x15, 0x5C, 0xE2, 0x99, 0x2D, 0xD5, 0x30, 0x99,
450916
+    0x7E, 0x5F, 0x8D, 0xE2, 0xF7, 0xC6, 0x2E, 0x8D, 0xA3, 0x9F, 0x58, 0xAD,
450916
+    0xD6, 0xA9, 0x7D, 0x0E, 0x0D, 0x95, 0x53, 0xA6, 0x71, 0x3A, 0xDE, 0xAB,
450916
+    0xAC, 0xE9, 0xF4, 0x36, 0x55, 0x9E, 0xB9, 0xD6, 0x93, 0xBF, 0xF3, 0x18,
450916
+    0x1C, 0x14, 0x7B, 0xA5, 0x42, 0x2E, 0xCD, 0x00, 0xEB, 0x35, 0x3B, 0x1B,
450916
+    0xA8, 0x51, 0xBB, 0xE1, 0x58, 0x42, 0x85, 0x84, 0x22, 0xA7, 0x97, 0x5E,
450916
+    0x99, 0x6F, 0x38, 0x20, 0xBD, 0x9D, 0xB6, 0xD9, 0x33, 0x37, 0x2A, 0xFD,
450916
+    0xBB, 0xD4, 0xBC, 0x0C, 0x2A, 0x67, 0xCB, 0x9F, 0xBB, 0xDF, 0xF9, 0x93,
450916
+    0xAA, 0xD6, 0xF0, 0xD6, 0x95, 0x0B, 0x5D, 0x65, 0x14, 0xD0, 0x18, 0x9D,
450916
+    0xC6, 0xAF, 0xF0, 0xC6, 0x37, 0x7C, 0xF3, 0x5F,
450916
 };
450916
 
450916
 static unsigned char out_q[] = {
450916
-    0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee,
450916
-    0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 0x8e,
450916
-    0xda, 0xce, 0x91, 0x5f,
450916
+    0xE3, 0x8E, 0x5E, 0x6D, 0xBF, 0x2B, 0x79, 0xF8, 0xC5, 0x4B, 0x89, 0x8B,
450916
+    0xBA, 0x2D, 0x91, 0xC3, 0x6C, 0x80, 0xAC, 0x87,
450916
 };
450916
 
450916
 static unsigned char out_g[] = {
450916
-    0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13,
450916
-    0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 0x00,
450916
-    0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 0xcb,
450916
-    0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e,
450916
-    0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf,
450916
-    0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 0x9c,
450916
-    0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 0x8c,
450916
-    0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02,
450916
+    0x42, 0x4A, 0x04, 0x4E, 0x79, 0xB4, 0x99, 0x7F, 0xFD, 0x58, 0x36, 0x2C,
450916
+    0x1B, 0x5F, 0x18, 0x7E, 0x0D, 0xCC, 0xAB, 0x81, 0xC9, 0x5D, 0x10, 0xCE,
450916
+    0x4E, 0x80, 0x7E, 0x58, 0xB4, 0x34, 0x3F, 0xA7, 0x45, 0xC7, 0xAA, 0x36,
450916
+    0x24, 0x42, 0xA9, 0x3B, 0xE8, 0x0E, 0x04, 0x02, 0x2D, 0xFB, 0xA6, 0x13,
450916
+    0xB9, 0xB5, 0x15, 0xA5, 0x56, 0x07, 0x35, 0xE4, 0x03, 0xB6, 0x79, 0x7C,
450916
+    0x62, 0xDD, 0xDF, 0x3F, 0x71, 0x3A, 0x9D, 0x8B, 0xC4, 0xF6, 0xE7, 0x1D,
450916
+    0x52, 0xA8, 0xA9, 0x43, 0x1D, 0x33, 0x51, 0x88, 0x39, 0xBD, 0x73, 0xE9,
450916
+    0x5F, 0xBE, 0x82, 0x49, 0x27, 0xE6, 0xB5, 0x53, 0xC1, 0x38, 0xAC, 0x2F,
450916
+    0x6D, 0x97, 0x6C, 0xEB, 0x67, 0xC1, 0x5F, 0x67, 0xF8, 0x35, 0x05, 0x5E,
450916
+    0xD5, 0x68, 0x80, 0xAA, 0x96, 0xCA, 0x0B, 0x8A, 0xE6, 0xF1, 0xB1, 0x41,
450916
+    0xC6, 0x75, 0x94, 0x0A, 0x0A, 0x2A, 0xFA, 0x29,
450916
 };
450916
 
450916
 static const unsigned char str1[] = "12345678901234567890";
450916
@@ -162,7 +167,7 @@ int main(int argc, char **argv)
450916
     BIO_printf(bio_err, "test generation of DSA parameters\n");
450916
 
450916
     BN_GENCB_set(&cb, dsa_cb, bio_err);
450916
-    if (((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 512,
450916
+    if (((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 1024,
450916
                                                                    seed, 20,
450916
                                                                    &counter,
450916
                                                                    &h, &cb))
450916
@@ -176,8 +181,8 @@ int main(int argc, char **argv)
450916
     BIO_printf(bio_err, "\ncounter=%d h=%ld\n", counter, h);
450916
 
450916
     DSA_print(bio_err, dsa, 0);
450916
-    if (counter != 105) {
450916
-        BIO_printf(bio_err, "counter should be 105\n");
450916
+    if (counter != 239) {
450916
+        BIO_printf(bio_err, "counter should be 239\n");
450916
         goto end;
450916
     }
450916
     if (h != 2) {
450916
diff -up openssl-1.0.2i/crypto/engine/eng_all.c.fips openssl-1.0.2i/crypto/engine/eng_all.c
450916
--- openssl-1.0.2i/crypto/engine/eng_all.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/engine/eng_all.c	2016-09-22 13:35:57.011220859 +0200
450916
@@ -59,11 +59,25 @@
450916
 
450916
 #include "cryptlib.h"
450916
 #include "eng_int.h"
450916
+#ifdef OPENSSL_FIPS
450916
+# include <openssl/fips.h>
450916
+#endif
450916
 
450916
 void ENGINE_load_builtin_engines(void)
450916
 {
450916
     /* Some ENGINEs need this */
450916
     OPENSSL_cpuid_setup();
450916
+#ifdef OPENSSL_FIPS
450916
+    OPENSSL_init_library();
450916
+    if (FIPS_mode()) {
450916
+        /* We allow loading dynamic engine as a third party
450916
+           engine might be FIPS validated.
450916
+           User is disallowed to load non-validated engines
450916
+           by security policy. */
450916
+        ENGINE_load_dynamic();
450916
+        return;
450916
+    }
450916
+#endif
450916
 #if 0
450916
     /*
450916
      * There's no longer any need for an "openssl" ENGINE unless, one day, it
450916
diff -up openssl-1.0.2i/crypto/evp/c_allc.c.fips openssl-1.0.2i/crypto/evp/c_allc.c
450916
--- openssl-1.0.2i/crypto/evp/c_allc.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/evp/c_allc.c	2016-09-22 13:35:57.011220859 +0200
450916
@@ -65,6 +65,10 @@
450916
 void OpenSSL_add_all_ciphers(void)
450916
 {
450916
 
450916
+#ifdef OPENSSL_FIPS
450916
+    OPENSSL_init_library();
450916
+    if (!FIPS_mode()) {
450916
+#endif
450916
 #ifndef OPENSSL_NO_DES
450916
     EVP_add_cipher(EVP_des_cfb());
450916
     EVP_add_cipher(EVP_des_cfb1());
450916
@@ -238,4 +242,64 @@ void OpenSSL_add_all_ciphers(void)
450916
     EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256");
450916
     EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256");
450916
 #endif
450916
+#ifdef OPENSSL_FIPS
450916
+    } else {
450916
+# ifndef OPENSSL_NO_DES
450916
+        EVP_add_cipher(EVP_des_ede_cfb());
450916
+        EVP_add_cipher(EVP_des_ede3_cfb());
450916
+
450916
+        EVP_add_cipher(EVP_des_ede_ofb());
450916
+        EVP_add_cipher(EVP_des_ede3_ofb());
450916
+
450916
+        EVP_add_cipher(EVP_des_ede_cbc());
450916
+        EVP_add_cipher(EVP_des_ede3_cbc());
450916
+        EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3");
450916
+        EVP_add_cipher_alias(SN_des_ede3_cbc, "des3");
450916
+
450916
+        EVP_add_cipher(EVP_des_ede());
450916
+        EVP_add_cipher(EVP_des_ede3());
450916
+# endif
450916
+
450916
+# ifndef OPENSSL_NO_AES
450916
+        EVP_add_cipher(EVP_aes_128_ecb());
450916
+        EVP_add_cipher(EVP_aes_128_cbc());
450916
+        EVP_add_cipher(EVP_aes_128_cfb());
450916
+        EVP_add_cipher(EVP_aes_128_cfb1());
450916
+        EVP_add_cipher(EVP_aes_128_cfb8());
450916
+        EVP_add_cipher(EVP_aes_128_ofb());
450916
+        EVP_add_cipher(EVP_aes_128_ctr());
450916
+        EVP_add_cipher(EVP_aes_128_gcm());
450916
+        EVP_add_cipher(EVP_aes_128_xts());
450916
+        EVP_add_cipher(EVP_aes_128_ccm());
450916
+        EVP_add_cipher(EVP_aes_128_wrap());
450916
+        EVP_add_cipher_alias(SN_aes_128_cbc, "AES128");
450916
+        EVP_add_cipher_alias(SN_aes_128_cbc, "aes128");
450916
+        EVP_add_cipher(EVP_aes_192_ecb());
450916
+        EVP_add_cipher(EVP_aes_192_cbc());
450916
+        EVP_add_cipher(EVP_aes_192_cfb());
450916
+        EVP_add_cipher(EVP_aes_192_cfb1());
450916
+        EVP_add_cipher(EVP_aes_192_cfb8());
450916
+        EVP_add_cipher(EVP_aes_192_ofb());
450916
+        EVP_add_cipher(EVP_aes_192_ctr());
450916
+        EVP_add_cipher(EVP_aes_192_gcm());
450916
+        EVP_add_cipher(EVP_aes_192_ccm());
450916
+        EVP_add_cipher(EVP_aes_192_wrap());
450916
+        EVP_add_cipher_alias(SN_aes_192_cbc, "AES192");
450916
+        EVP_add_cipher_alias(SN_aes_192_cbc, "aes192");
450916
+        EVP_add_cipher(EVP_aes_256_ecb());
450916
+        EVP_add_cipher(EVP_aes_256_cbc());
450916
+        EVP_add_cipher(EVP_aes_256_cfb());
450916
+        EVP_add_cipher(EVP_aes_256_cfb1());
450916
+        EVP_add_cipher(EVP_aes_256_cfb8());
450916
+        EVP_add_cipher(EVP_aes_256_ofb());
450916
+        EVP_add_cipher(EVP_aes_256_ctr());
450916
+        EVP_add_cipher(EVP_aes_256_gcm());
450916
+        EVP_add_cipher(EVP_aes_256_xts());
450916
+        EVP_add_cipher(EVP_aes_256_ccm());
450916
+        EVP_add_cipher(EVP_aes_256_wrap());
450916
+        EVP_add_cipher_alias(SN_aes_256_cbc, "AES256");
450916
+        EVP_add_cipher_alias(SN_aes_256_cbc, "aes256");
450916
+# endif
450916
+    }
450916
+#endif
450916
 }
450916
diff -up openssl-1.0.2i/crypto/evp/c_alld.c.fips openssl-1.0.2i/crypto/evp/c_alld.c
450916
--- openssl-1.0.2i/crypto/evp/c_alld.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/evp/c_alld.c	2016-09-22 13:35:57.011220859 +0200
450916
@@ -64,51 +64,81 @@
450916
 
450916
 void OpenSSL_add_all_digests(void)
450916
 {
450916
+#ifdef OPENSSL_FIPS
450916
+    OPENSSL_init_library();
450916
+    if (!FIPS_mode()) {
450916
+#endif
450916
 #ifndef OPENSSL_NO_MD4
450916
-    EVP_add_digest(EVP_md4());
450916
+        EVP_add_digest(EVP_md4());
450916
 #endif
450916
 #ifndef OPENSSL_NO_MD5
450916
-    EVP_add_digest(EVP_md5());
450916
-    EVP_add_digest_alias(SN_md5, "ssl2-md5");
450916
-    EVP_add_digest_alias(SN_md5, "ssl3-md5");
450916
+        EVP_add_digest(EVP_md5());
450916
+        EVP_add_digest_alias(SN_md5, "ssl2-md5");
450916
+        EVP_add_digest_alias(SN_md5, "ssl3-md5");
450916
 #endif
450916
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0)
450916
-    EVP_add_digest(EVP_sha());
450916
+        EVP_add_digest(EVP_sha());
450916
 # ifndef OPENSSL_NO_DSA
450916
-    EVP_add_digest(EVP_dss());
450916
+        EVP_add_digest(EVP_dss());
450916
 # endif
450916
 #endif
450916
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
450916
-    EVP_add_digest(EVP_sha1());
450916
-    EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
450916
-    EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
450916
+        EVP_add_digest(EVP_sha1());
450916
+        EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
450916
+        EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
450916
 # ifndef OPENSSL_NO_DSA
450916
-    EVP_add_digest(EVP_dss1());
450916
-    EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2);
450916
-    EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1");
450916
-    EVP_add_digest_alias(SN_dsaWithSHA1, "dss1");
450916
+        EVP_add_digest(EVP_dss1());
450916
+        EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2);
450916
+        EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1");
450916
+        EVP_add_digest_alias(SN_dsaWithSHA1, "dss1");
450916
 # endif
450916
 # ifndef OPENSSL_NO_ECDSA
450916
-    EVP_add_digest(EVP_ecdsa());
450916
+        EVP_add_digest(EVP_ecdsa());
450916
 # endif
450916
 #endif
450916
 #if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
450916
-    EVP_add_digest(EVP_mdc2());
450916
+        EVP_add_digest(EVP_mdc2());
450916
 #endif
450916
 #ifndef OPENSSL_NO_RIPEMD
450916
-    EVP_add_digest(EVP_ripemd160());
450916
-    EVP_add_digest_alias(SN_ripemd160, "ripemd");
450916
-    EVP_add_digest_alias(SN_ripemd160, "rmd160");
450916
+        EVP_add_digest(EVP_ripemd160());
450916
+        EVP_add_digest_alias(SN_ripemd160, "ripemd");
450916
+        EVP_add_digest_alias(SN_ripemd160, "rmd160");
450916
 #endif
450916
 #ifndef OPENSSL_NO_SHA256
450916
-    EVP_add_digest(EVP_sha224());
450916
-    EVP_add_digest(EVP_sha256());
450916
+        EVP_add_digest(EVP_sha224());
450916
+        EVP_add_digest(EVP_sha256());
450916
 #endif
450916
 #ifndef OPENSSL_NO_SHA512
450916
-    EVP_add_digest(EVP_sha384());
450916
-    EVP_add_digest(EVP_sha512());
450916
+        EVP_add_digest(EVP_sha384());
450916
+        EVP_add_digest(EVP_sha512());
450916
 #endif
450916
 #ifndef OPENSSL_NO_WHIRLPOOL
450916
-    EVP_add_digest(EVP_whirlpool());
450916
+        EVP_add_digest(EVP_whirlpool());
450916
+#endif
450916
+#ifdef OPENSSL_FIPS
450916
+    } else {
450916
+# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
450916
+        EVP_add_digest(EVP_sha1());
450916
+        EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
450916
+        EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
450916
+#  ifndef OPENSSL_NO_DSA
450916
+        EVP_add_digest(EVP_dss1());
450916
+        EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2);
450916
+        EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1");
450916
+        EVP_add_digest_alias(SN_dsaWithSHA1, "dss1");
450916
+#  endif
450916
+#  ifndef OPENSSL_NO_ECDSA
450916
+        EVP_add_digest(EVP_ecdsa());
450916
+#  endif
450916
+# endif
450916
+# ifndef OPENSSL_NO_SHA256
450916
+        EVP_add_digest(EVP_sha224());
450916
+        EVP_add_digest(EVP_sha256());
450916
+# endif
450916
+# ifndef OPENSSL_NO_SHA512
450916
+        EVP_add_digest(EVP_sha384());
450916
+        EVP_add_digest(EVP_sha512());
450916
+# endif
450916
+    }
450916
 #endif
450916
 }
450916
diff -up openssl-1.0.2i/crypto/evp/digest.c.fips openssl-1.0.2i/crypto/evp/digest.c
450916
--- openssl-1.0.2i/crypto/evp/digest.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/evp/digest.c	2016-09-22 13:45:40.054658929 +0200
450916
@@ -143,18 +143,55 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, cons
450916
     return EVP_DigestInit_ex(ctx, type, NULL);
450916
 }
450916
 
450916
+#ifdef OPENSSL_FIPS
450916
+
450916
+/* The purpose of these is to trap programs that attempt to use non FIPS
450916
+ * algorithms in FIPS mode and ignore the errors.
450916
+ */
450916
+
450916
+static int bad_init(EVP_MD_CTX *ctx)
450916
+{
450916
+    FIPS_ERROR_IGNORED("Digest init");
450916
+    return 0;
450916
+}
450916
+
450916
+static int bad_update(EVP_MD_CTX *ctx, const void *data, size_t count)
450916
+{
450916
+    FIPS_ERROR_IGNORED("Digest update");
450916
+    return 0;
450916
+}
450916
+
450916
+static int bad_final(EVP_MD_CTX *ctx, unsigned char *md)
450916
+{
450916
+    FIPS_ERROR_IGNORED("Digest Final");
450916
+    return 0;
450916
+}
450916
+
450916
+static const EVP_MD bad_md = {
450916
+    0,
450916
+    0,
450916
+    0,
450916
+    0,
450916
+    bad_init,
450916
+    bad_update,
450916
+    bad_final,
450916
+    NULL,
450916
+    NULL,
450916
+    NULL,
450916
+    0,
450916
+    {0, 0, 0, 0},
450916
+};
450916
+
450916
+#endif
450916
+
450916
 int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
450916
 {
450916
     EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
450916
 #ifdef OPENSSL_FIPS
450916
-    /* If FIPS mode switch to approved implementation if possible */
450916
-    if (FIPS_mode()) {
450916
-        const EVP_MD *fipsmd;
450916
-        if (type) {
450916
-            fipsmd = evp_get_fips_md(type);
450916
-            if (fipsmd)
450916
-                type = fipsmd;
450916
-        }
450916
+    if (FIPS_selftest_failed()) {
450916
+        FIPSerr(FIPS_F_EVP_DIGESTINIT_EX, FIPS_R_FIPS_SELFTEST_FAILED);
450916
+        ctx->digest = &bad_md;
450916
+        return 0;
450916
     }
450916
 #endif
450916
 #ifndef OPENSSL_NO_ENGINE
450916
@@ -212,6 +249,16 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, c
450916
     }
450916
 #endif
450916
     if (ctx->digest != type) {
450916
+#ifdef OPENSSL_FIPS
450916
+        if (FIPS_mode()) {
450916
+            if (!(type->flags & EVP_MD_FLAG_FIPS)
450916
+                && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) {
450916
+                EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_DISABLED_FOR_FIPS);
450916
+                ctx->digest = &bad_md;
450916
+                return 0;
450916
+            }
450916
+        }
450916
+#endif
450916
         if (ctx->digest && ctx->digest->ctx_size) {
450916
             OPENSSL_free(ctx->md_data);
450916
             ctx->md_data = NULL;
450916
@@ -238,23 +285,13 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, c
450916
     }
450916
     if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
450916
         return 1;
450916
-#ifdef OPENSSL_FIPS
450916
-    if (FIPS_mode()) {
450916
-        if (FIPS_digestinit(ctx, type))
450916
-            return 1;
450916
-        OPENSSL_free(ctx->md_data);
450916
-        ctx->md_data = NULL;
450916
-        return 0;
450916
-    }
450916
-#endif
450916
     return ctx->digest->init(ctx);
450916
 }
450916
 
450916
 int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
450916
 {
450916
 #ifdef OPENSSL_FIPS
450916
-    if (FIPS_mode())
450916
-        return FIPS_digestupdate(ctx, data, count);
450916
+    FIPS_selftest_check();
450916
 #endif
450916
     return ctx->update(ctx, data, count);
450916
 }
450916
@@ -272,11 +309,10 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, uns
450916
 int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
450916
 {
450916
     int ret;
450916
+
450916
 #ifdef OPENSSL_FIPS
450916
-    if (FIPS_mode())
450916
-        return FIPS_digestfinal(ctx, md, size);
450916
+    FIPS_selftest_check();
450916
 #endif
450916
-
450916
     OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
450916
     ret = ctx->digest->final(ctx, md);
450916
     if (size != NULL)
450916
@@ -375,7 +411,6 @@ void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
450916
 /* This call frees resources associated with the context */
450916
 int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
450916
 {
450916
-#ifndef OPENSSL_FIPS
450916
     /*
450916
      * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
450916
      * sometimes only copies of the context are ever finalised.
450916
@@ -388,7 +423,6 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
450916
         OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
450916
         OPENSSL_free(ctx->md_data);
450916
     }
450916
-#endif
450916
     if (ctx->pctx)
450916
         EVP_PKEY_CTX_free(ctx->pctx);
450916
 #ifndef OPENSSL_NO_ENGINE
450916
@@ -399,9 +433,6 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
450916
          */
450916
         ENGINE_finish(ctx->engine);
450916
 #endif
450916
-#ifdef OPENSSL_FIPS
450916
-    FIPS_md_ctx_cleanup(ctx);
450916
-#endif
450916
     memset(ctx, '\0', sizeof *ctx);
450916
 
450916
     return 1;
450916
diff -up openssl-1.0.2i/crypto/evp/e_aes.c.fips openssl-1.0.2i/crypto/evp/e_aes.c
450916
--- openssl-1.0.2i/crypto/evp/e_aes.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/evp/e_aes.c	2016-09-22 13:35:57.011220859 +0200
450916
@@ -60,9 +60,6 @@
450916
 # include "modes_lcl.h"
450916
 # include <openssl/rand.h>
450916
 
450916
-# undef EVP_CIPH_FLAG_FIPS
450916
-# define EVP_CIPH_FLAG_FIPS 0
450916
-
450916
 typedef struct {
450916
     union {
450916
         double align;
450916
@@ -1159,6 +1156,11 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *
450916
     case EVP_CTRL_GCM_SET_IVLEN:
450916
         if (arg <= 0)
450916
             return 0;
450916
+# ifdef OPENSSL_FIPS
450916
+        if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)
450916
+            && arg < 12)
450916
+            return 0;
450916
+# endif
450916
         /* Allocate memory for IV if needed */
450916
         if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) {
450916
             if (gctx->iv != c->iv)
450916
@@ -1727,6 +1729,14 @@ static int aes_xts_cipher(EVP_CIPHER_CTX
450916
         return 0;
450916
     if (!out || !in || len < AES_BLOCK_SIZE)
450916
         return 0;
450916
+# ifdef OPENSSL_FIPS
450916
+    /* Requirement of SP800-38E */
450916
+    if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) &&
450916
+        (len > (1UL << 20) * 16)) {
450916
+        EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE);
450916
+        return 0;
450916
+    }
450916
+# endif
450916
     if (xctx->stream)
450916
         (*xctx->stream) (in, out, len,
450916
                          xctx->xts.key1, xctx->xts.key2, ctx->iv);
450916
diff -up openssl-1.0.2i/crypto/evp/e_des3.c.fips openssl-1.0.2i/crypto/evp/e_des3.c
450916
--- openssl-1.0.2i/crypto/evp/e_des3.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/evp/e_des3.c	2016-09-22 13:35:57.012220882 +0200
450916
@@ -65,10 +65,6 @@
450916
 # include <openssl/des.h>
450916
 # include <openssl/rand.h>
450916
 
450916
-/* Block use of implementations in FIPS mode */
450916
-# undef EVP_CIPH_FLAG_FIPS
450916
-# define EVP_CIPH_FLAG_FIPS      0
450916
-
450916
 typedef struct {
450916
     union {
450916
         double align;
450916
diff -up openssl-1.0.2i/crypto/evp/e_null.c.fips openssl-1.0.2i/crypto/evp/e_null.c
450916
--- openssl-1.0.2i/crypto/evp/e_null.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/evp/e_null.c	2016-09-22 13:35:57.012220882 +0200
450916
@@ -68,7 +68,7 @@ static int null_cipher(EVP_CIPHER_CTX *c
450916
 static const EVP_CIPHER n_cipher = {
450916
     NID_undef,
450916
     1, 0, 0,
450916
-    0,
450916
+    EVP_CIPH_FLAG_FIPS,
450916
     null_init_key,
450916
     null_cipher,
450916
     NULL,
450916
diff -up openssl-1.0.2i/crypto/evp/evp_enc.c.fips openssl-1.0.2i/crypto/evp/evp_enc.c
450916
--- openssl-1.0.2i/crypto/evp/evp_enc.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/evp/evp_enc.c	2016-09-22 13:46:12.998418222 +0200
450916
@@ -69,16 +69,73 @@
450916
 #endif
450916
 #include "evp_locl.h"
450916
 
450916
-#ifdef OPENSSL_FIPS
450916
-# define M_do_cipher(ctx, out, in, inl) FIPS_cipher(ctx, out, in, inl)
450916
-#else
450916
-# define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl)
450916
-#endif
450916
+#define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl)
450916
 
450916
 const char EVP_version[] = "EVP" OPENSSL_VERSION_PTEXT;
450916
 
450916
+#ifdef OPENSSL_FIPS
450916
+
450916
+/* The purpose of these is to trap programs that attempt to use non FIPS
450916
+ * algorithms in FIPS mode and ignore the errors.
450916
+ */
450916
+
450916
+static int bad_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
450916
+                    const unsigned char *iv, int enc)
450916
+{
450916
+    FIPS_ERROR_IGNORED("Cipher init");
450916
+    return 0;
450916
+}
450916
+
450916
+static int bad_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
450916
+                         const unsigned char *in, unsigned int inl)
450916
+{
450916
+    FIPS_ERROR_IGNORED("Cipher update");
450916
+    return 0;
450916
+}
450916
+
450916
+/* NB: no cleanup because it is allowed after failed init */
450916
+
450916
+static int bad_set_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ)
450916
+{
450916
+    FIPS_ERROR_IGNORED("Cipher set_asn1");
450916
+    return 0;
450916
+}
450916
+
450916
+static int bad_get_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ)
450916
+{
450916
+    FIPS_ERROR_IGNORED("Cipher get_asn1");
450916
+    return 0;
450916
+}
450916
+
450916
+static int bad_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
450916
+{
450916
+    FIPS_ERROR_IGNORED("Cipher ctrl");
450916
+    return 0;
450916
+}
450916
+
450916
+static const EVP_CIPHER bad_cipher = {
450916
+    0,
450916
+    0,
450916
+    0,
450916
+    0,
450916
+    0,
450916
+    bad_init,
450916
+    bad_do_cipher,
450916
+    NULL,
450916
+    0,
450916
+    bad_set_asn1,
450916
+    bad_get_asn1,
450916
+    bad_ctrl,
450916
+    NULL
450916
+};
450916
+
450916
+#endif
450916
+
450916
 void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
450916
 {
450916
+#ifdef OPENSSL_FIPS
450916
+    FIPS_selftest_check();
450916
+#endif
450916
     memset(ctx, 0, sizeof(EVP_CIPHER_CTX));
450916
     /* ctx->cipher=NULL; */
450916
 }
450916
@@ -110,6 +167,13 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct
450916
             enc = 1;
450916
         ctx->encrypt = enc;
450916
     }
450916
+#ifdef OPENSSL_FIPS
450916
+    if (FIPS_selftest_failed()) {
450916
+        FIPSerr(FIPS_F_EVP_CIPHERINIT_EX, FIPS_R_FIPS_SELFTEST_FAILED);
450916
+        ctx->cipher = &bad_cipher;
450916
+        return 0;
450916
+    }
450916
+#endif
450916
 #ifndef OPENSSL_NO_ENGINE
450916
     /*
450916
      * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
450916
@@ -168,16 +232,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct
450916
             ctx->engine = NULL;
450916
 #endif
450916
 
450916
-#ifdef OPENSSL_FIPS
450916
-        if (FIPS_mode()) {
450916
-            const EVP_CIPHER *fcipher = NULL;
450916
-            if (cipher)
450916
-                fcipher = evp_get_fips_cipher(cipher);
450916
-            if (fcipher)
450916
-                cipher = fcipher;
450916
-            return FIPS_cipherinit(ctx, cipher, key, iv, enc);
450916
-        }
450916
-#endif
450916
         ctx->cipher = cipher;
450916
         if (ctx->cipher->ctx_size) {
450916
             ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size);
450916
@@ -204,10 +258,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct
450916
 #ifndef OPENSSL_NO_ENGINE
450916
  skip_to_init:
450916
 #endif
450916
-#ifdef OPENSSL_FIPS
450916
-    if (FIPS_mode())
450916
-        return FIPS_cipherinit(ctx, cipher, key, iv, enc);
450916
-#endif
450916
     /* we assume block size is a power of 2 in *cryptUpdate */
450916
     OPENSSL_assert(ctx->cipher->block_size == 1
450916
                    || ctx->cipher->block_size == 8
450916
@@ -253,6 +303,19 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct
450916
             break;
450916
         }
450916
     }
450916
+#ifdef OPENSSL_FIPS
450916
+    /* After 'key' is set no further parameters changes are permissible.
450916
+     * So only check for non FIPS enabling at this point.
450916
+     */
450916
+    if (key && FIPS_mode()) {
450916
+        if (!(ctx->cipher->flags & EVP_CIPH_FLAG_FIPS)
450916
+            & !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) {
450916
+            EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_DISABLED_FOR_FIPS);
450916
+            ctx->cipher = &bad_cipher;
450916
+            return 0;
450916
+        }
450916
+    }
450916
+#endif
450916
 
450916
     if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
450916
         if (!ctx->cipher->init(ctx, key, iv, enc))
450916
@@ -554,7 +617,6 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX
450916
 
450916
 int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
450916
 {
450916
-#ifndef OPENSSL_FIPS
450916
     if (c->cipher != NULL) {
450916
         if (c->cipher->cleanup && !c->cipher->cleanup(c))
450916
             return 0;
450916
@@ -564,7 +626,6 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CT
450916
     }
450916
     if (c->cipher_data)
450916
         OPENSSL_free(c->cipher_data);
450916
-#endif
450916
 #ifndef OPENSSL_NO_ENGINE
450916
     if (c->engine)
450916
         /*
450916
@@ -573,9 +634,6 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CT
450916
          */
450916
         ENGINE_finish(c->engine);
450916
 #endif
450916
-#ifdef OPENSSL_FIPS
450916
-    FIPS_cipher_ctx_cleanup(c);
450916
-#endif
450916
     memset(c, 0, sizeof(EVP_CIPHER_CTX));
450916
     return 1;
450916
 }
450916
diff -up openssl-1.0.2i/crypto/evp/evp.h.fips openssl-1.0.2i/crypto/evp/evp.h
450916
--- openssl-1.0.2i/crypto/evp/evp.h.fips	2016-09-22 13:35:56.902218346 +0200
450916
+++ openssl-1.0.2i/crypto/evp/evp.h	2016-09-22 13:35:57.012220882 +0200
450916
@@ -122,6 +122,10 @@
450916
 extern "C" {
450916
 #endif
450916
 
450916
+# ifdef OPENSSL_FIPS
450916
+#  include <openssl/fips.h>
450916
+# endif
450916
+
450916
 /*
450916
  * Type needs to be a bit field Sub-type needs to be for variations on the
450916
  * method, as in, can it do arbitrary encryption....
450916
@@ -285,11 +289,6 @@ struct env_md_ctx_st {
450916
                                                 * cleaned */
450916
 # define EVP_MD_CTX_FLAG_REUSE           0x0004/* Don't free up ctx->md_data
450916
                                                 * in EVP_MD_CTX_cleanup */
450916
-/*
450916
- * FIPS and pad options are ignored in 1.0.0, definitions are here so we
450916
- * don't accidentally reuse the values for other purposes.
450916
- */
450916
-
450916
 # define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW  0x0008/* Allow use of non FIPS
450916
                                                 * digest in FIPS mode */
450916
 
450916
@@ -302,6 +301,10 @@ struct env_md_ctx_st {
450916
 # define EVP_MD_CTX_FLAG_PAD_PKCS1       0x00/* PKCS#1 v1.5 mode */
450916
 # define EVP_MD_CTX_FLAG_PAD_X931        0x10/* X9.31 mode */
450916
 # define EVP_MD_CTX_FLAG_PAD_PSS         0x20/* PSS mode */
450916
+# define M_EVP_MD_CTX_FLAG_PSS_SALT(ctx) \
450916
+                ((ctx->flags>>16) &0xFFFF) /* seed length */
450916
+# define EVP_MD_CTX_FLAG_PSS_MDLEN       0xFFFF/* salt len same as digest */
450916
+# define EVP_MD_CTX_FLAG_PSS_MREC        0xFFFE/* salt max or auto recovered */
450916
 
450916
 # define EVP_MD_CTX_FLAG_NO_INIT         0x0100/* Don't initialize md_data */
450916
 
450916
@@ -363,15 +366,15 @@ struct evp_cipher_st {
450916
 /* cipher handles random key generation */
450916
 # define         EVP_CIPH_RAND_KEY               0x200
450916
 /* cipher has its own additional copying logic */
450916
-# define         EVP_CIPH_CUSTOM_COPY            0x400
450916
+# define         EVP_CIPH_CUSTOM_COPY            0x4000
450916
 /* Allow use default ASN1 get/set iv */
450916
 # define         EVP_CIPH_FLAG_DEFAULT_ASN1      0x1000
450916
 /* Buffer length in bits not bytes: CFB1 mode only */
450916
 # define         EVP_CIPH_FLAG_LENGTH_BITS       0x2000
450916
 /* Note if suitable for use in FIPS mode */
450916
-# define         EVP_CIPH_FLAG_FIPS              0x4000
450916
+# define         EVP_CIPH_FLAG_FIPS              0x400
450916
 /* Allow non FIPS cipher in FIPS mode */
450916
-# define         EVP_CIPH_FLAG_NON_FIPS_ALLOW    0x8000
450916
+# define         EVP_CIPH_FLAG_NON_FIPS_ALLOW    0x800
450916
 /*
450916
  * Cipher handles any and all padding logic as well as finalisation.
450916
  */
450916
diff -up openssl-1.0.2i/crypto/evp/evp_lib.c.fips openssl-1.0.2i/crypto/evp/evp_lib.c
450916
--- openssl-1.0.2i/crypto/evp/evp_lib.c.fips	2016-09-22 12:23:06.000000000 +0200
450916
+++ openssl-1.0.2i/crypto/evp/evp_lib.c	2016-09-22 13:35:57.012220882 +0200
450916
@@ -60,10 +60,6 @@
450916
 #include "cryptlib.h"
450916
 #include <openssl/evp.h>
450916
 #include <openssl/objects.h>
450916
-#ifdef OPENSSL_FIPS
450916
-# include <openssl/fips.h>
450916
-# include "evp_locl.h"
450916
-#endif
450916
 
450916
 int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
450916
 {
450916
@@ -224,6 +220,9 @@ int EVP_CIPHER_CTX_block_size(const EVP_
450916
 int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
450916
                const unsigned char *in, unsigned int inl)
450916
 {
450916
+#ifdef OPENSSL_FIPS
450916
+    FIPS_selftest_check();
450916
+#endif
450916
     return ctx->cipher->do_cipher(ctx, out, in, inl);
450916
 }
450916
 
450916
@@ -234,22 +233,12 @@ const EVP_CIPHER *EVP_CIPHER_CTX_cipher(
450916
 
450916
 unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
450916
 {
450916
-#ifdef OPENSSL_FIPS
450916
-    const EVP_CIPHER *fcipher;
450916
-    fcipher = evp_get_fips_cipher(cipher);
450916
-    if (fcipher && fcipher->flags & EVP_CIPH_FLAG_FIPS)
450916
-        return cipher->flags | EVP_CIPH_FLAG_FIPS;
450916
-#endif
450916
     return cipher->flags;
450916
 }
450916
 
450916
 unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
450916
 {
450916
-#ifdef OPENSSL_FIPS
450916
-    return EVP_CIPHER_flags(ctx->cipher);
450916
-#else
450916
     return ctx->cipher->flags;
450916
-#endif
450916
 }
450916
 
450916
 void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
450916
@@ -316,40 +305,8 @@ int EVP_MD_size(const EVP_MD *md)
450916
     return md->md_size;
450916
 }
450916
 
450916
-#ifdef OPENSSL_FIPS
450916
-
450916
-const EVP_MD *evp_get_fips_md(const EVP_MD *md)
450916
-{
450916
-    int nid = EVP_MD_type(md);
450916
-    if (nid == NID_dsa)
450916
-        return FIPS_evp_dss1();
450916
-    else if (nid == NID_dsaWithSHA)
450916
-        return FIPS_evp_dss();
450916
-    else if (nid == NID_ecdsa_with_SHA1)
450916
-        return FIPS_evp_ecdsa();
450916
-    else
450916
-        return FIPS_get_digestbynid(nid);
450916
-}
450916
-
450916
-const EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher)
450916
-{
450916
-    int nid = cipher->nid;
450916
-    if (nid == NID_undef)
450916
-        return FIPS_evp_enc_null();
450916
-    else